Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2014 20:42:59 +0000 (13:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2014 20:42:59 +0000 (13:42 -0700)
Pull main powerpc updates from Ben Herrenschmidt:
 "This time around, the powerpc merges are going to be a little bit more
  complicated than usual.

  This is the main pull request with most of the work for this merge
  window.  I will describe it a bit more further down.

  There is some additional cpuidle driver work, however I haven't
  included it in this tree as it depends on some work in tip/timer-core
  which Thomas accidentally forgot to put in a topic branch.  Since I
  didn't want to carry all of that tip timer stuff in powerpc -next, I
  setup a separate branch on top of Thomas tree with just that cpuidle
  driver in it, and Stephen has been carrying that in next separately
  for a while now.  I'll send a separate pull request for it.

  Additionally, two new pieces in this tree add users for a sysfs API
  that Tejun and Greg have been deprecating in drivers-core-next.
  Thankfully Greg reverted the patch that removes the old API so this
  merge can happen cleanly, but once merged, I will send a patch
  adjusting our new code to the new API so that Greg can send you the
  removal patch.

  Now as for the content of this branch, we have a lot of perf work for
  power8 new counters including support for our new "nest" counters
  (also called 24x7) under pHyp (not natively yet).

  We have new functionality when running under the OPAL firmware
  (non-virtualized or KVM host), such as access to the firmware error
  logs and service processor dumps, system parameters and sensors, along
  with a hwmon driver for the latter.

  There's also a bunch of bug fixes accross the board, some LE fixes,
  and a nice set of selftests for validating our various types of copy
  loops.

  On the Freescale side, we see mostly new chip/board revisions, some
  clock updates, better support for machine checks and debug exceptions,
  etc..."

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (70 commits)
  powerpc/book3s: Fix CFAR clobbering issue in machine check handler.
  powerpc/compat: 32-bit little endian machine name is ppcle, not ppc
  powerpc/le: Big endian arguments for ppc_rtas()
  powerpc: Use default set of netfilter modules (CONFIG_NETFILTER_ADVANCED=n)
  powerpc/defconfigs: Enable THP in pseries defconfig
  powerpc/mm: Make sure a local_irq_disable prevent a parallel THP split
  powerpc: Rate-limit users spamming kernel log buffer
  powerpc/perf: Fix handling of L3 events with bank == 1
  powerpc/perf/hv_{gpci, 24x7}: Add documentation of device attributes
  powerpc/perf: Add kconfig option for hypervisor provided counters
  powerpc/perf: Add support for the hv 24x7 interface
  powerpc/perf: Add support for the hv gpci (get performance counter info) interface
  powerpc/perf: Add macros for defining event fields & formats
  powerpc/perf: Add a shared interface to get gpci version and capabilities
  powerpc/perf: Add 24x7 interface headers
  powerpc/perf: Add hv_gpci interface header
  powerpc: Add hvcalls for 24x7 and gpci (Get Performance Counter Info)
  sysfs: create bin_attributes under the requested group
  powerpc/perf: Enable BHRB access for EBB events
  powerpc/perf: Add BHRB constraint and IFM MMCRA handling for EBB
  ...

185 files changed:
Documentation/ABI/stable/sysfs-firmware-opal-dump [new file with mode: 0644]
Documentation/ABI/stable/sysfs-firmware-opal-elog [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-event_source-devices-events
Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci [new file with mode: 0644]
Documentation/devicetree/bindings/powerpc/fsl/l2cache.txt [new file with mode: 0644]
Documentation/devicetree/bindings/powerpc/fsl/mem-ctrlr.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/fsl-usb.txt
MAINTAINERS
arch/powerpc/Kconfig
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi
arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi
arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi
arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi
arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
arch/powerpc/boot/dts/t4240qds.dts
arch/powerpc/configs/40x/acadia_defconfig
arch/powerpc/configs/40x/ep405_defconfig
arch/powerpc/configs/40x/kilauea_defconfig
arch/powerpc/configs/40x/makalu_defconfig
arch/powerpc/configs/40x/walnut_defconfig
arch/powerpc/configs/44x/arches_defconfig
arch/powerpc/configs/44x/bluestone_defconfig
arch/powerpc/configs/44x/canyonlands_defconfig
arch/powerpc/configs/44x/ebony_defconfig
arch/powerpc/configs/44x/eiger_defconfig
arch/powerpc/configs/44x/icon_defconfig
arch/powerpc/configs/44x/iss476-smp_defconfig
arch/powerpc/configs/44x/katmai_defconfig
arch/powerpc/configs/44x/rainier_defconfig
arch/powerpc/configs/44x/redwood_defconfig
arch/powerpc/configs/44x/sequoia_defconfig
arch/powerpc/configs/44x/taishan_defconfig
arch/powerpc/configs/44x/warp_defconfig
arch/powerpc/configs/52xx/cm5200_defconfig
arch/powerpc/configs/52xx/motionpro_defconfig
arch/powerpc/configs/52xx/pcm030_defconfig
arch/powerpc/configs/52xx/tqm5200_defconfig
arch/powerpc/configs/83xx/asp8347_defconfig
arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
arch/powerpc/configs/83xx/mpc836x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
arch/powerpc/configs/83xx/sbc834x_defconfig
arch/powerpc/configs/85xx/ksi8560_defconfig
arch/powerpc/configs/85xx/ppa8548_defconfig
arch/powerpc/configs/85xx/socrates_defconfig
arch/powerpc/configs/85xx/tqm8540_defconfig
arch/powerpc/configs/85xx/tqm8541_defconfig
arch/powerpc/configs/85xx/tqm8548_defconfig
arch/powerpc/configs/85xx/tqm8555_defconfig
arch/powerpc/configs/85xx/tqm8560_defconfig
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
arch/powerpc/configs/86xx/gef_ppc9a_defconfig
arch/powerpc/configs/86xx/gef_sbc310_defconfig
arch/powerpc/configs/86xx/gef_sbc610_defconfig
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
arch/powerpc/configs/86xx/sbc8641d_defconfig
arch/powerpc/configs/c2k_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/linkstation_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/configs/ppc40x_defconfig
arch/powerpc/configs/ppc44x_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/ppc64e_defconfig
arch/powerpc/configs/prpmc2800_defconfig [deleted file]
arch/powerpc/configs/pseries_defconfig
arch/powerpc/configs/pseries_le_defconfig
arch/powerpc/configs/storcenter_defconfig
arch/powerpc/configs/tqm8xx_defconfig
arch/powerpc/include/asm/compat.h
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/exception-64e.h
arch/powerpc/include/asm/exception-64s.h
arch/powerpc/include/asm/hvcall.h
arch/powerpc/include/asm/kvm_booke_hv_asm.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mce.h
arch/powerpc/include/asm/mmu-book3e.h
arch/powerpc/include/asm/opal.h
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/perf_event_server.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cacheinfo.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/mce.c
arch/powerpc/kernel/mce_power.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vdso32/getcpu.S
arch/powerpc/kernel/vdso64/getcpu.S
arch/powerpc/kernel/vio.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_interrupts.S
arch/powerpc/kvm/bookehv_interrupts.S
arch/powerpc/lib/memcpy_64.S
arch/powerpc/mm/mem.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/tlb_low_64e.S
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/perf/Makefile
arch/powerpc/perf/core-book3s.c
arch/powerpc/perf/hv-24x7-catalog.h [new file with mode: 0644]
arch/powerpc/perf/hv-24x7.c [new file with mode: 0644]
arch/powerpc/perf/hv-24x7.h [new file with mode: 0644]
arch/powerpc/perf/hv-common.c [new file with mode: 0644]
arch/powerpc/perf/hv-common.h [new file with mode: 0644]
arch/powerpc/perf/hv-gpci.c [new file with mode: 0644]
arch/powerpc/perf/hv-gpci.h [new file with mode: 0644]
arch/powerpc/perf/power7-events-list.h
arch/powerpc/perf/power8-pmu.c
arch/powerpc/platforms/85xx/c293pcie.c
arch/powerpc/platforms/85xx/common.c
arch/powerpc/platforms/85xx/corenet_generic.c
arch/powerpc/platforms/85xx/ge_imp3a.c
arch/powerpc/platforms/85xx/mpc8536_ds.c
arch/powerpc/platforms/85xx/mpc85xx.h
arch/powerpc/platforms/85xx/mpc85xx_cds.c
arch/powerpc/platforms/85xx/mpc85xx_ds.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/85xx/mpc85xx_rdb.c
arch/powerpc/platforms/85xx/p1010rdb.c
arch/powerpc/platforms/85xx/p1022_ds.c
arch/powerpc/platforms/85xx/p1022_rdk.c
arch/powerpc/platforms/85xx/p1023_rds.c
arch/powerpc/platforms/85xx/qemu_e500.c
arch/powerpc/platforms/85xx/sbc8548.c
arch/powerpc/platforms/85xx/twr_p102x.c
arch/powerpc/platforms/85xx/xes_mpc85xx.c
arch/powerpc/platforms/embedded6xx/Kconfig
arch/powerpc/platforms/embedded6xx/Makefile
arch/powerpc/platforms/embedded6xx/prpmc2800.c [deleted file]
arch/powerpc/platforms/powernv/Makefile
arch/powerpc/platforms/powernv/opal-async.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-dump.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-elog.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-sensor.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-sysparam.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-wrappers.S
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/setup.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/hotplug-cpu.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/platforms/pseries/mobility.c
arch/powerpc/platforms/pseries/suspend.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_pci.h
arch/powerpc/xmon/xmon.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/ibmpowernv.c [new file with mode: 0644]
drivers/macintosh/adb.c
drivers/watchdog/booke_wdt.c
tools/testing/selftests/powerpc/Makefile
tools/testing/selftests/powerpc/copyloops/Makefile [new file with mode: 0644]
tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h [new file with mode: 0644]
tools/testing/selftests/powerpc/copyloops/asm/processor.h [new file with mode: 0644]
tools/testing/selftests/powerpc/copyloops/copyuser_64.S [new symlink]
tools/testing/selftests/powerpc/copyloops/copyuser_power7.S [new symlink]
tools/testing/selftests/powerpc/copyloops/memcpy_64.S [new symlink]
tools/testing/selftests/powerpc/copyloops/memcpy_power7.S [new symlink]
tools/testing/selftests/powerpc/copyloops/validate.c [new file with mode: 0644]
tools/testing/selftests/powerpc/utils.h

diff --git a/Documentation/ABI/stable/sysfs-firmware-opal-dump b/Documentation/ABI/stable/sysfs-firmware-opal-dump
new file mode 100644 (file)
index 0000000..32fe7f5
--- /dev/null
@@ -0,0 +1,41 @@
+What:          /sys/firmware/opal/dump
+Date:          Feb 2014
+Contact:       Stewart Smith <stewart@linux.vnet.ibm.com>
+Description:
+               This directory exposes interfaces for interacting with
+               the FSP and platform dumps through OPAL firmware interface.
+
+               This is only for the powerpc/powernv platform.
+
+               initiate_dump:  When '1' is written to it,
+                               we will initiate a dump.
+                               Read this file for supported commands.
+
+               0xXX-0xYYYY:    A directory for dump of type 0xXX and
+                               id 0xYYYY (in hex). The name of this
+                               directory should not be relied upon to
+                               be in this format, only that it's unique
+                               among all dumps. For determining the type
+                               and ID of the dump, use the id and type files.
+                               Do not rely on any particular size of dump
+                               type or dump id.
+
+               Each dump has the following files:
+               id:             An ASCII representation of the dump ID
+                               in hex (e.g. '0x01')
+               type:           An ASCII representation of the type of
+                               dump in the format "0x%x %s" with the ID
+                               in hex and a description of the dump type
+                               (or 'unknown').
+                               Type '0xffffffff unknown' is used when
+                               we could not get the type from firmware.
+                               e.g. '0x02 System/Platform Dump'
+               dump:           A binary file containing the dump.
+                               The size of the dump is the size of this file.
+               acknowledge:    When 'ack' is written to this, we will
+                               acknowledge that we've retrieved the
+                               dump to the service processor. It will
+                               then remove it, making the dump
+                               inaccessible.
+                               Reading this file will get a list of
+                               supported actions.
diff --git a/Documentation/ABI/stable/sysfs-firmware-opal-elog b/Documentation/ABI/stable/sysfs-firmware-opal-elog
new file mode 100644 (file)
index 0000000..e1f3058
--- /dev/null
@@ -0,0 +1,60 @@
+What:          /sys/firmware/opal/elog
+Date:          Feb 2014
+Contact:       Stewart Smith <stewart@linux.vnet.ibm.com>
+Description:
+               This directory exposes error log entries retrieved
+               through the OPAL firmware interface.
+
+               Each error log is identified by a unique ID and will
+               exist until explicitly acknowledged to firmware.
+
+               Each log entry has a directory in /sys/firmware/opal/elog.
+
+               Log entries may be purged by the service processor
+               before retrieved by firmware or retrieved/acknowledged by
+               Linux if there is no room for more log entries.
+
+               In the event that Linux has retrieved the log entries
+               but not explicitly acknowledged them to firmware and
+               the service processor needs more room for log entries,
+               the only remaining copy of a log message may be in
+               Linux.
+
+               Typically, a user space daemon will monitor for new
+               entries, read them out and acknowledge them.
+
+               The service processor may be able to store more log
+               entries than firmware can, so after you acknowledge
+               an event from Linux you may instantly get another one
+               from the queue that was generated some time in the past.
+
+               The raw log format is a binary format. We currently
+               do not parse this at all in kernel, leaving it up to
+               user space to solve the problem. In future, we may
+               do more parsing in kernel and add more files to make
+               it easier for simple user space processes to extract
+               more information.
+
+               For each log entry (directory), there are the following
+               files:
+
+               id:             An ASCII representation of the ID of the
+                               error log, in hex - e.g. "0x01".
+
+               type:           An ASCII representation of the type id and
+                               description of the type of error log.
+                               Currently just "0x00 PEL" - platform error log.
+                               In the future there may be additional types.
+
+               raw:            A read-only binary file that can be read
+                               to get the raw log entry. These are
+                               <16kb, often just hundreds of bytes and
+                               "average" 2kb.
+
+               acknowledge:    Writing 'ack' to this file will acknowledge
+                               the error log to firmware (and in turn
+                               the service processor, if applicable).
+                               Shortly after acknowledging it, the log
+                               entry will be removed from sysfs.
+                               Reading this file will list the supported
+                               operations (curently just acknowledge).
\ No newline at end of file
index 3c1cc24361bdf0ce40f13a1260fbdf98c90e7e3b..7b40a3cbc26a8026cd818535d1e27f51261353e2 100644 (file)
@@ -57,6 +57,523 @@ What:               /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
                /sys/devices/cpu/events/PM_LD_REF_L1
                /sys/devices/cpu/events/PM_RUN_CYC
                /sys/devices/cpu/events/PM_RUN_INST_CMPL
+               /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_ALL
+               /sys/devices/cpu/events/PM_GCT_UTIL_7_TO_10_SLOTS
+               /sys/devices/cpu/events/PM_PMC2_SAVED
+               /sys/devices/cpu/events/PM_VSU0_16FLOP
+               /sys/devices/cpu/events/PM_MRK_LSU_DERAT_MISS
+               /sys/devices/cpu/events/PM_MRK_ST_CMPL
+               /sys/devices/cpu/events/PM_NEST_PAIR3_ADD
+               /sys/devices/cpu/events/PM_L2_ST_DISP
+               /sys/devices/cpu/events/PM_L2_CASTOUT_MOD
+               /sys/devices/cpu/events/PM_ISEG
+               /sys/devices/cpu/events/PM_MRK_INST_TIMEO
+               /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_ADDR
+               /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM
+               /sys/devices/cpu/events/PM_IERAT_WR_64K
+               /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16M
+               /sys/devices/cpu/events/PM_IERAT_MISS
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_LMEM
+               /sys/devices/cpu/events/PM_FLOP
+               /sys/devices/cpu/events/PM_THRD_PRIO_4_5_CYC
+               /sys/devices/cpu/events/PM_BR_PRED_TA
+               /sys/devices/cpu/events/PM_EXT_INT
+               /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV
+               /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC
+               /sys/devices/cpu/events/PM_LSU1_LDF
+               /sys/devices/cpu/events/PM_IC_WRITE_ALL
+               /sys/devices/cpu/events/PM_LSU0_SRQ_STFWD
+               /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_MOD
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_DATA_FROM_L21_MOD
+               /sys/devices/cpu/events/PM_VSU1_SCAL_DOUBLE_ISSUED
+               /sys/devices/cpu/events/PM_VSU0_8FLOP
+               /sys/devices/cpu/events/PM_POWER_EVENT1
+               /sys/devices/cpu/events/PM_DISP_CLB_HELD_BAL
+               /sys/devices/cpu/events/PM_VSU1_2FLOP
+               /sys/devices/cpu/events/PM_LWSYNC_HELD
+               /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_SHR
+               /sys/devices/cpu/events/PM_INST_FROM_L21_MOD
+               /sys/devices/cpu/events/PM_IERAT_XLATE_WR_16MPLUS
+               /sys/devices/cpu/events/PM_IC_REQ_ALL
+               /sys/devices/cpu/events/PM_DSLB_MISS
+               /sys/devices/cpu/events/PM_L3_MISS
+               /sys/devices/cpu/events/PM_LSU0_L1_PREF
+               /sys/devices/cpu/events/PM_VSU_SCALAR_SINGLE_ISSUED
+               /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_CONFIRM_STRIDE
+               /sys/devices/cpu/events/PM_L2_INST
+               /sys/devices/cpu/events/PM_VSU0_FRSP
+               /sys/devices/cpu/events/PM_FLUSH_DISP
+               /sys/devices/cpu/events/PM_PTEG_FROM_L2MISS
+               /sys/devices/cpu/events/PM_VSU1_DQ_ISSUED
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM
+               /sys/devices/cpu/events/PM_LSU_FLUSH_ULD
+               /sys/devices/cpu/events/PM_PTEG_FROM_LMEM
+               /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16M
+               /sys/devices/cpu/events/PM_THRD_ALL_RUN_CYC
+               /sys/devices/cpu/events/PM_MEM0_PREFETCH_DISP
+               /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC_COUNT
+               /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_MOD
+               /sys/devices/cpu/events/PM_VSU_FRSP
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD
+               /sys/devices/cpu/events/PM_PMC1_OVERFLOW
+               /sys/devices/cpu/events/PM_VSU0_SINGLE
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3MISS
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_VSU0_VECTOR_SP_ISSUED
+               /sys/devices/cpu/events/PM_VSU1_FEST
+               /sys/devices/cpu/events/PM_MRK_INST_DISP
+               /sys/devices/cpu/events/PM_VSU0_COMPLEX_ISSUED
+               /sys/devices/cpu/events/PM_LSU1_FLUSH_UST
+               /sys/devices/cpu/events/PM_FXU_IDLE
+               /sys/devices/cpu/events/PM_LSU0_FLUSH_ULD
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD
+               /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_ALL_CYC
+               /sys/devices/cpu/events/PM_LSU1_REJECT_LMQ_FULL
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_MOD
+               /sys/devices/cpu/events/PM_INST_FROM_RL2L3_MOD
+               /sys/devices/cpu/events/PM_SHL_CREATED
+               /sys/devices/cpu/events/PM_L2_ST_HIT
+               /sys/devices/cpu/events/PM_DATA_FROM_DMEM
+               /sys/devices/cpu/events/PM_L3_LD_MISS
+               /sys/devices/cpu/events/PM_FXU1_BUSY_FXU0_IDLE
+               /sys/devices/cpu/events/PM_DISP_CLB_HELD_RES
+               /sys/devices/cpu/events/PM_L2_SN_SX_I_DONE
+               /sys/devices/cpu/events/PM_STCX_CMPL
+               /sys/devices/cpu/events/PM_VSU0_2FLOP
+               /sys/devices/cpu/events/PM_L3_PREF_MISS
+               /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_CYC
+               /sys/devices/cpu/events/PM_LSU_REJECT_ERAT_MISS
+               /sys/devices/cpu/events/PM_L1_ICACHE_MISS
+               /sys/devices/cpu/events/PM_LSU1_FLUSH_SRQ
+               /sys/devices/cpu/events/PM_LD_REF_L1_LSU0
+               /sys/devices/cpu/events/PM_VSU0_FEST
+               /sys/devices/cpu/events/PM_VSU_VECTOR_SINGLE_ISSUED
+               /sys/devices/cpu/events/PM_FREQ_UP
+               /sys/devices/cpu/events/PM_DATA_FROM_LMEM
+               /sys/devices/cpu/events/PM_LSU1_LDX
+               /sys/devices/cpu/events/PM_PMC3_OVERFLOW
+               /sys/devices/cpu/events/PM_MRK_BR_MPRED
+               /sys/devices/cpu/events/PM_SHL_MATCH
+               /sys/devices/cpu/events/PM_MRK_BR_TAKEN
+               /sys/devices/cpu/events/PM_ISLB_MISS
+               /sys/devices/cpu/events/PM_DISP_HELD_THERMAL
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_SHR
+               /sys/devices/cpu/events/PM_LSU1_SRQ_STFWD
+               /sys/devices/cpu/events/PM_PTEG_FROM_DMEM
+               /sys/devices/cpu/events/PM_VSU_2FLOP
+               /sys/devices/cpu/events/PM_GCT_FULL_CYC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3_CYC
+               /sys/devices/cpu/events/PM_LSU_SRQ_S0_ALLOC
+               /sys/devices/cpu/events/PM_MRK_DERAT_MISS_4K
+               /sys/devices/cpu/events/PM_BR_MPRED_TA
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2MISS
+               /sys/devices/cpu/events/PM_DPU_HELD_POWER
+               /sys/devices/cpu/events/PM_MRK_VSU_FIN
+               /sys/devices/cpu/events/PM_LSU_SRQ_S0_VALID
+               /sys/devices/cpu/events/PM_GCT_EMPTY_CYC
+               /sys/devices/cpu/events/PM_IOPS_DISP
+               /sys/devices/cpu/events/PM_RUN_SPURR
+               /sys/devices/cpu/events/PM_PTEG_FROM_L21_MOD
+               /sys/devices/cpu/events/PM_VSU0_1FLOP
+               /sys/devices/cpu/events/PM_SNOOP_TLBIE
+               /sys/devices/cpu/events/PM_DATA_FROM_L3MISS
+               /sys/devices/cpu/events/PM_VSU_SINGLE
+               /sys/devices/cpu/events/PM_DTLB_MISS_16G
+               /sys/devices/cpu/events/PM_FLUSH
+               /sys/devices/cpu/events/PM_L2_LD_HIT
+               /sys/devices/cpu/events/PM_NEST_PAIR2_AND
+               /sys/devices/cpu/events/PM_VSU1_1FLOP
+               /sys/devices/cpu/events/PM_IC_PREF_REQ
+               /sys/devices/cpu/events/PM_L3_LD_HIT
+               /sys/devices/cpu/events/PM_DISP_HELD
+               /sys/devices/cpu/events/PM_L2_LD
+               /sys/devices/cpu/events/PM_LSU_FLUSH_SRQ
+               /sys/devices/cpu/events/PM_BC_PLUS_8_CONV
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD_CYC
+               /sys/devices/cpu/events/PM_L2_RCST_BUSY_RC_FULL
+               /sys/devices/cpu/events/PM_TB_BIT_TRANS
+               /sys/devices/cpu/events/PM_THERMAL_MAX
+               /sys/devices/cpu/events/PM_LSU1_FLUSH_ULD
+               /sys/devices/cpu/events/PM_LSU1_REJECT_LHS
+               /sys/devices/cpu/events/PM_LSU_LRQ_S0_ALLOC
+               /sys/devices/cpu/events/PM_L3_CO_L31
+               /sys/devices/cpu/events/PM_POWER_EVENT4
+               /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_BR_UNCOND
+               /sys/devices/cpu/events/PM_LSU1_DC_PREF_STREAM_ALLOC
+               /sys/devices/cpu/events/PM_PMC4_REWIND
+               /sys/devices/cpu/events/PM_L2_RCLD_DISP
+               /sys/devices/cpu/events/PM_THRD_PRIO_2_3_CYC
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2MISS
+               /sys/devices/cpu/events/PM_IC_DEMAND_L2_BHT_REDIRECT
+               /sys/devices/cpu/events/PM_DATA_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_IC_PREF_CANCEL_L2
+               /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC_COUNT
+               /sys/devices/cpu/events/PM_BR_PRED_CCACHE
+               /sys/devices/cpu/events/PM_GCT_UTIL_1_TO_2_SLOTS
+               /sys/devices/cpu/events/PM_MRK_ST_CMPL_INT
+               /sys/devices/cpu/events/PM_LSU_TWO_TABLEWALK_CYC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3MISS
+               /sys/devices/cpu/events/PM_LSU_SET_MPRED
+               /sys/devices/cpu/events/PM_FLUSH_DISP_TLBIE
+               /sys/devices/cpu/events/PM_VSU1_FCONV
+               /sys/devices/cpu/events/PM_DERAT_MISS_16G
+               /sys/devices/cpu/events/PM_INST_FROM_LMEM
+               /sys/devices/cpu/events/PM_IC_DEMAND_L2_BR_REDIRECT
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L2
+               /sys/devices/cpu/events/PM_PTEG_FROM_L2
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR_CYC
+               /sys/devices/cpu/events/PM_MRK_DTLB_MISS_4K
+               /sys/devices/cpu/events/PM_VSU0_FPSCR
+               /sys/devices/cpu/events/PM_VSU1_VECT_DOUBLE_ISSUED
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_MOD
+               /sys/devices/cpu/events/PM_MEM0_RQ_DISP
+               /sys/devices/cpu/events/PM_L2_LD_MISS
+               /sys/devices/cpu/events/PM_VMX_RESULT_SAT_1
+               /sys/devices/cpu/events/PM_L1_PREF
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM_CYC
+               /sys/devices/cpu/events/PM_GRP_IC_MISS_NONSPEC
+               /sys/devices/cpu/events/PM_PB_NODE_PUMP
+               /sys/devices/cpu/events/PM_SHL_MERGED
+               /sys/devices/cpu/events/PM_NEST_PAIR1_ADD
+               /sys/devices/cpu/events/PM_DATA_FROM_L3
+               /sys/devices/cpu/events/PM_LSU_FLUSH
+               /sys/devices/cpu/events/PM_LSU_SRQ_SYNC_COUNT
+               /sys/devices/cpu/events/PM_PMC2_OVERFLOW
+               /sys/devices/cpu/events/PM_LSU_LDF
+               /sys/devices/cpu/events/PM_POWER_EVENT3
+               /sys/devices/cpu/events/PM_DISP_WT
+               /sys/devices/cpu/events/PM_IC_BANK_CONFLICT
+               /sys/devices/cpu/events/PM_BR_MPRED_CR_TA
+               /sys/devices/cpu/events/PM_L2_INST_MISS
+               /sys/devices/cpu/events/PM_NEST_PAIR2_ADD
+               /sys/devices/cpu/events/PM_MRK_LSU_FLUSH
+               /sys/devices/cpu/events/PM_L2_LDST
+               /sys/devices/cpu/events/PM_INST_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_VSU0_FIN
+               /sys/devices/cpu/events/PM_VSU1_FCONV
+               /sys/devices/cpu/events/PM_INST_FROM_RMEM
+               /sys/devices/cpu/events/PM_DISP_CLB_HELD_TLBIE
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_DMEM_CYC
+               /sys/devices/cpu/events/PM_BR_PRED_CR
+               /sys/devices/cpu/events/PM_LSU_REJECT
+               /sys/devices/cpu/events/PM_GCT_UTIL_3_TO_6_SLOTS
+               /sys/devices/cpu/events/PM_CMPLU_STALL_END_GCT_NOSLOT
+               /sys/devices/cpu/events/PM_LSU0_REJECT_LMQ_FULL
+               /sys/devices/cpu/events/PM_VSU_FEST
+               /sys/devices/cpu/events/PM_NEST_PAIR0_AND
+               /sys/devices/cpu/events/PM_PTEG_FROM_L3
+               /sys/devices/cpu/events/PM_POWER_EVENT2
+               /sys/devices/cpu/events/PM_IC_PREF_CANCEL_PAGE
+               /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV
+               /sys/devices/cpu/events/PM_MRK_GRP_CMPL
+               /sys/devices/cpu/events/PM_VSU0_SCAL_DOUBLE_ISSUED
+               /sys/devices/cpu/events/PM_GRP_DISP
+               /sys/devices/cpu/events/PM_LSU0_LDX
+               /sys/devices/cpu/events/PM_DATA_FROM_L2
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD
+               /sys/devices/cpu/events/PM_VSU0_VECT_DOUBLE_ISSUED
+               /sys/devices/cpu/events/PM_VSU1_2FLOP_DOUBLE
+               /sys/devices/cpu/events/PM_THRD_PRIO_6_7_CYC
+               /sys/devices/cpu/events/PM_BC_PLUS_8_RSLV_TAKEN
+               /sys/devices/cpu/events/PM_BR_MPRED_CR
+               /sys/devices/cpu/events/PM_L3_CO_MEM
+               /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_MOD
+               /sys/devices/cpu/events/PM_LSU_SRQ_FULL_CYC
+               /sys/devices/cpu/events/PM_TABLEWALK_CYC
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RMEM
+               /sys/devices/cpu/events/PM_LSU_SRQ_STFWD
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_RMEM
+               /sys/devices/cpu/events/PM_FXU0_FIN
+               /sys/devices/cpu/events/PM_LSU1_L1_SW_PREF
+               /sys/devices/cpu/events/PM_PTEG_FROM_L31_MOD
+               /sys/devices/cpu/events/PM_PMC5_OVERFLOW
+               /sys/devices/cpu/events/PM_LD_REF_L1_LSU1
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L21_SHR
+               /sys/devices/cpu/events/PM_DATA_FROM_RMEM
+               /sys/devices/cpu/events/PM_VSU0_SCAL_SINGLE_ISSUED
+               /sys/devices/cpu/events/PM_BR_MPRED_LSTACK
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_MOD_CYC
+               /sys/devices/cpu/events/PM_LSU0_FLUSH_UST
+               /sys/devices/cpu/events/PM_LSU_NCST
+               /sys/devices/cpu/events/PM_BR_TAKEN
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_LMEM
+               /sys/devices/cpu/events/PM_DTLB_MISS_4K
+               /sys/devices/cpu/events/PM_PMC4_SAVED
+               /sys/devices/cpu/events/PM_VSU1_PERMUTE_ISSUED
+               /sys/devices/cpu/events/PM_SLB_MISS
+               /sys/devices/cpu/events/PM_LSU1_FLUSH_LRQ
+               /sys/devices/cpu/events/PM_DTLB_MISS
+               /sys/devices/cpu/events/PM_VSU1_FRSP
+               /sys/devices/cpu/events/PM_VSU_VECTOR_DOUBLE_ISSUED
+               /sys/devices/cpu/events/PM_L2_CASTOUT_SHR
+               /sys/devices/cpu/events/PM_DATA_FROM_DL2L3_SHR
+               /sys/devices/cpu/events/PM_VSU1_STF
+               /sys/devices/cpu/events/PM_ST_FIN
+               /sys/devices/cpu/events/PM_PTEG_FROM_L21_SHR
+               /sys/devices/cpu/events/PM_L2_LOC_GUESS_WRONG
+               /sys/devices/cpu/events/PM_MRK_STCX_FAIL
+               /sys/devices/cpu/events/PM_LSU0_REJECT_LHS
+               /sys/devices/cpu/events/PM_IC_PREF_CANCEL_HIT
+               /sys/devices/cpu/events/PM_L3_PREF_BUSY
+               /sys/devices/cpu/events/PM_MRK_BRU_FIN
+               /sys/devices/cpu/events/PM_LSU1_NCLD
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_MOD
+               /sys/devices/cpu/events/PM_LSU_NCLD
+               /sys/devices/cpu/events/PM_LSU_LDX
+               /sys/devices/cpu/events/PM_L2_LOC_GUESS_CORRECT
+               /sys/devices/cpu/events/PM_THRESH_TIMEO
+               /sys/devices/cpu/events/PM_L3_PREF_ST
+               /sys/devices/cpu/events/PM_DISP_CLB_HELD_SYNC
+               /sys/devices/cpu/events/PM_VSU_SIMPLE_ISSUED
+               /sys/devices/cpu/events/PM_VSU1_SINGLE
+               /sys/devices/cpu/events/PM_DATA_TABLEWALK_CYC
+               /sys/devices/cpu/events/PM_L2_RC_ST_DONE
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_MOD
+               /sys/devices/cpu/events/PM_LARX_LSU1
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM
+               /sys/devices/cpu/events/PM_DISP_CLB_HELD
+               /sys/devices/cpu/events/PM_DERAT_MISS_4K
+               /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_ADDR
+               /sys/devices/cpu/events/PM_SEG_EXCEPTION
+               /sys/devices/cpu/events/PM_FLUSH_DISP_SB
+               /sys/devices/cpu/events/PM_L2_DC_INV
+               /sys/devices/cpu/events/PM_PTEG_FROM_DL2L3_MOD
+               /sys/devices/cpu/events/PM_DSEG
+               /sys/devices/cpu/events/PM_BR_PRED_LSTACK
+               /sys/devices/cpu/events/PM_VSU0_STF
+               /sys/devices/cpu/events/PM_LSU_FX_FIN
+               /sys/devices/cpu/events/PM_DERAT_MISS_16M
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_MOD
+               /sys/devices/cpu/events/PM_GCT_UTIL_11_PLUS_SLOTS
+               /sys/devices/cpu/events/PM_INST_FROM_L3
+               /sys/devices/cpu/events/PM_MRK_IFU_FIN
+               /sys/devices/cpu/events/PM_ITLB_MISS
+               /sys/devices/cpu/events/PM_VSU_STF
+               /sys/devices/cpu/events/PM_LSU_FLUSH_UST
+               /sys/devices/cpu/events/PM_L2_LDST_MISS
+               /sys/devices/cpu/events/PM_FXU1_FIN
+               /sys/devices/cpu/events/PM_SHL_DEALLOCATED
+               /sys/devices/cpu/events/PM_L2_SN_M_WR_DONE
+               /sys/devices/cpu/events/PM_LSU_REJECT_SET_MPRED
+               /sys/devices/cpu/events/PM_L3_PREF_LD
+               /sys/devices/cpu/events/PM_L2_SN_M_RD_DONE
+               /sys/devices/cpu/events/PM_MRK_DERAT_MISS_16G
+               /sys/devices/cpu/events/PM_VSU_FCONV
+               /sys/devices/cpu/events/PM_ANY_THRD_RUN_CYC
+               /sys/devices/cpu/events/PM_LSU_LMQ_FULL_CYC
+               /sys/devices/cpu/events/PM_MRK_LSU_REJECT_LHS
+               /sys/devices/cpu/events/PM_MRK_LD_MISS_L1_CYC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2_CYC
+               /sys/devices/cpu/events/PM_INST_IMC_MATCH_DISP
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_RMEM_CYC
+               /sys/devices/cpu/events/PM_VSU0_SIMPLE_ISSUED
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_RL2L3_SHR
+               /sys/devices/cpu/events/PM_VSU_FMA_DOUBLE
+               /sys/devices/cpu/events/PM_VSU_4FLOP
+               /sys/devices/cpu/events/PM_VSU1_FIN
+               /sys/devices/cpu/events/PM_NEST_PAIR1_AND
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_RL2L3_MOD
+               /sys/devices/cpu/events/PM_PTEG_FROM_RMEM
+               /sys/devices/cpu/events/PM_LSU_LRQ_S0_VALID
+               /sys/devices/cpu/events/PM_LSU0_LDF
+               /sys/devices/cpu/events/PM_FLUSH_COMPLETION
+               /sys/devices/cpu/events/PM_ST_MISS_L1
+               /sys/devices/cpu/events/PM_L2_NODE_PUMP
+               /sys/devices/cpu/events/PM_INST_FROM_DL2L3_SHR
+               /sys/devices/cpu/events/PM_MRK_STALL_CMPLU_CYC
+               /sys/devices/cpu/events/PM_VSU1_DENORM
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_SHR_CYC
+               /sys/devices/cpu/events/PM_NEST_PAIR0_ADD
+               /sys/devices/cpu/events/PM_INST_FROM_L3MISS
+               /sys/devices/cpu/events/PM_EE_OFF_EXT_INT
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_DMEM
+               /sys/devices/cpu/events/PM_INST_FROM_DL2L3_MOD
+               /sys/devices/cpu/events/PM_PMC6_OVERFLOW
+               /sys/devices/cpu/events/PM_VSU_2FLOP_DOUBLE
+               /sys/devices/cpu/events/PM_TLB_MISS
+               /sys/devices/cpu/events/PM_FXU_BUSY
+               /sys/devices/cpu/events/PM_L2_RCLD_DISP_FAIL_OTHER
+               /sys/devices/cpu/events/PM_LSU_REJECT_LMQ_FULL
+               /sys/devices/cpu/events/PM_IC_RELOAD_SHR
+               /sys/devices/cpu/events/PM_GRP_MRK
+               /sys/devices/cpu/events/PM_MRK_ST_NEST
+               /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV
+               /sys/devices/cpu/events/PM_LSU0_FLUSH_LRQ
+               /sys/devices/cpu/events/PM_LARX_LSU0
+               /sys/devices/cpu/events/PM_IBUF_FULL_CYC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR_CYC
+               /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_ALLOC
+               /sys/devices/cpu/events/PM_GRP_MRK_CYC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR_CYC
+               /sys/devices/cpu/events/PM_L2_GLOB_GUESS_CORRECT
+               /sys/devices/cpu/events/PM_LSU_REJECT_LHS
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_LMEM
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3
+               /sys/devices/cpu/events/PM_FREQ_DOWN
+               /sys/devices/cpu/events/PM_PB_RETRY_NODE_PUMP
+               /sys/devices/cpu/events/PM_INST_FROM_RL2L3_SHR
+               /sys/devices/cpu/events/PM_MRK_INST_ISSUED
+               /sys/devices/cpu/events/PM_PTEG_FROM_L3MISS
+               /sys/devices/cpu/events/PM_RUN_PURR
+               /sys/devices/cpu/events/PM_MRK_GRP_IC_MISS
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L3
+               /sys/devices/cpu/events/PM_PTEG_FROM_RL2L3_SHR
+               /sys/devices/cpu/events/PM_LSU_FLUSH_LRQ
+               /sys/devices/cpu/events/PM_MRK_DERAT_MISS_64K
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_MOD
+               /sys/devices/cpu/events/PM_L2_ST_MISS
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L21_SHR
+               /sys/devices/cpu/events/PM_LWSYNC
+               /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM_STRIDE
+               /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_LRQ
+               /sys/devices/cpu/events/PM_INST_IMC_MATCH_CMPL
+               /sys/devices/cpu/events/PM_NEST_PAIR3_AND
+               /sys/devices/cpu/events/PM_PB_RETRY_SYS_PUMP
+               /sys/devices/cpu/events/PM_MRK_INST_FIN
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DL2L3_SHR
+               /sys/devices/cpu/events/PM_INST_FROM_L31_MOD
+               /sys/devices/cpu/events/PM_MRK_DTLB_MISS_64K
+               /sys/devices/cpu/events/PM_LSU_FIN
+               /sys/devices/cpu/events/PM_MRK_LSU_REJECT
+               /sys/devices/cpu/events/PM_L2_CO_FAIL_BUSY
+               /sys/devices/cpu/events/PM_MEM0_WQ_DISP
+               /sys/devices/cpu/events/PM_DATA_FROM_L31_MOD
+               /sys/devices/cpu/events/PM_THERMAL_WARN
+               /sys/devices/cpu/events/PM_VSU0_4FLOP
+               /sys/devices/cpu/events/PM_BR_MPRED_CCACHE
+               /sys/devices/cpu/events/PM_L1_DEMAND_WRITE
+               /sys/devices/cpu/events/PM_FLUSH_BR_MPRED
+               /sys/devices/cpu/events/PM_MRK_DTLB_MISS_16G
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_DMEM
+               /sys/devices/cpu/events/PM_L2_RCST_DISP
+               /sys/devices/cpu/events/PM_LSU_PARTIAL_CDF
+               /sys/devices/cpu/events/PM_DISP_CLB_HELD_SB
+               /sys/devices/cpu/events/PM_VSU0_FMA_DOUBLE
+               /sys/devices/cpu/events/PM_FXU0_BUSY_FXU1_IDLE
+               /sys/devices/cpu/events/PM_IC_DEMAND_CYC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_SHR
+               /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_UST
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L3MISS
+               /sys/devices/cpu/events/PM_VSU_DENORM
+               /sys/devices/cpu/events/PM_MRK_LSU_PARTIAL_CDF
+               /sys/devices/cpu/events/PM_INST_FROM_L21_SHR
+               /sys/devices/cpu/events/PM_IC_PREF_WRITE
+               /sys/devices/cpu/events/PM_BR_PRED
+               /sys/devices/cpu/events/PM_INST_FROM_DMEM
+               /sys/devices/cpu/events/PM_IC_PREF_CANCEL_ALL
+               /sys/devices/cpu/events/PM_LSU_DC_PREF_STREAM_CONFIRM
+               /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_SRQ
+               /sys/devices/cpu/events/PM_MRK_FIN_STALL_CYC
+               /sys/devices/cpu/events/PM_L2_RCST_DISP_FAIL_OTHER
+               /sys/devices/cpu/events/PM_VSU1_DD_ISSUED
+               /sys/devices/cpu/events/PM_PTEG_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_DATA_FROM_L21_SHR
+               /sys/devices/cpu/events/PM_LSU0_NCLD
+               /sys/devices/cpu/events/PM_VSU1_4FLOP
+               /sys/devices/cpu/events/PM_VSU1_8FLOP
+               /sys/devices/cpu/events/PM_VSU_8FLOP
+               /sys/devices/cpu/events/PM_LSU_LMQ_SRQ_EMPTY_CYC
+               /sys/devices/cpu/events/PM_DTLB_MISS_64K
+               /sys/devices/cpu/events/PM_THRD_CONC_RUN_INST
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L2
+               /sys/devices/cpu/events/PM_PB_SYS_PUMP
+               /sys/devices/cpu/events/PM_VSU_FIN
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L31_MOD
+               /sys/devices/cpu/events/PM_THRD_PRIO_0_1_CYC
+               /sys/devices/cpu/events/PM_DERAT_MISS_64K
+               /sys/devices/cpu/events/PM_PMC2_REWIND
+               /sys/devices/cpu/events/PM_INST_FROM_L2
+               /sys/devices/cpu/events/PM_GRP_BR_MPRED_NONSPEC
+               /sys/devices/cpu/events/PM_INST_DISP
+               /sys/devices/cpu/events/PM_MEM0_RD_CANCEL_TOTAL
+               /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_CONFIRM
+               /sys/devices/cpu/events/PM_L1_DCACHE_RELOAD_VALID
+               /sys/devices/cpu/events/PM_VSU_SCALAR_DOUBLE_ISSUED
+               /sys/devices/cpu/events/PM_L3_PREF_HIT
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L31_MOD
+               /sys/devices/cpu/events/PM_MRK_FXU_FIN
+               /sys/devices/cpu/events/PM_PMC4_OVERFLOW
+               /sys/devices/cpu/events/PM_MRK_PTEG_FROM_L3
+               /sys/devices/cpu/events/PM_LSU0_LMQ_LHR_MERGE
+               /sys/devices/cpu/events/PM_BTAC_HIT
+               /sys/devices/cpu/events/PM_L3_RD_BUSY
+               /sys/devices/cpu/events/PM_LSU0_L1_SW_PREF
+               /sys/devices/cpu/events/PM_INST_FROM_L2MISS
+               /sys/devices/cpu/events/PM_LSU0_DC_PREF_STREAM_ALLOC
+               /sys/devices/cpu/events/PM_L2_ST
+               /sys/devices/cpu/events/PM_VSU0_DENORM
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_SHR
+               /sys/devices/cpu/events/PM_BR_PRED_CR_TA
+               /sys/devices/cpu/events/PM_VSU0_FCONV
+               /sys/devices/cpu/events/PM_MRK_LSU_FLUSH_ULD
+               /sys/devices/cpu/events/PM_BTAC_MISS
+               /sys/devices/cpu/events/PM_MRK_LD_MISS_EXPOSED_CYC_COUNT
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2
+               /sys/devices/cpu/events/PM_LSU_DCACHE_RELOAD_VALID
+               /sys/devices/cpu/events/PM_VSU_FMA
+               /sys/devices/cpu/events/PM_LSU0_FLUSH_SRQ
+               /sys/devices/cpu/events/PM_LSU1_L1_PREF
+               /sys/devices/cpu/events/PM_IOPS_CMPL
+               /sys/devices/cpu/events/PM_L2_SYS_PUMP
+               /sys/devices/cpu/events/PM_L2_RCLD_BUSY_RC_FULL
+               /sys/devices/cpu/events/PM_LSU_LMQ_S0_ALLOC
+               /sys/devices/cpu/events/PM_FLUSH_DISP_SYNC
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_DL2L3_MOD_CYC
+               /sys/devices/cpu/events/PM_L2_IC_INV
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L21_MOD_CYC
+               /sys/devices/cpu/events/PM_L3_PREF_LDST
+               /sys/devices/cpu/events/PM_LSU_SRQ_EMPTY_CYC
+               /sys/devices/cpu/events/PM_LSU_LMQ_S0_VALID
+               /sys/devices/cpu/events/PM_FLUSH_PARTIAL
+               /sys/devices/cpu/events/PM_VSU1_FMA_DOUBLE
+               /sys/devices/cpu/events/PM_1PLUS_PPC_DISP
+               /sys/devices/cpu/events/PM_DATA_FROM_L2MISS
+               /sys/devices/cpu/events/PM_SUSPENDED
+               /sys/devices/cpu/events/PM_VSU0_FMA
+               /sys/devices/cpu/events/PM_STCX_FAIL
+               /sys/devices/cpu/events/PM_VSU0_FSQRT_FDIV_DOUBLE
+               /sys/devices/cpu/events/PM_DC_PREF_DST
+               /sys/devices/cpu/events/PM_VSU1_SCAL_SINGLE_ISSUED
+               /sys/devices/cpu/events/PM_L3_HIT
+               /sys/devices/cpu/events/PM_L2_GLOB_GUESS_WRONG
+               /sys/devices/cpu/events/PM_MRK_DFU_FIN
+               /sys/devices/cpu/events/PM_INST_FROM_L1
+               /sys/devices/cpu/events/PM_IC_DEMAND_REQ
+               /sys/devices/cpu/events/PM_VSU1_FSQRT_FDIV_DOUBLE
+               /sys/devices/cpu/events/PM_VSU1_FMA
+               /sys/devices/cpu/events/PM_MRK_LD_MISS_L1
+               /sys/devices/cpu/events/PM_VSU0_2FLOP_DOUBLE
+               /sys/devices/cpu/events/PM_LSU_DC_PREF_STRIDED_STREAM_CONFIRM
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_L31_SHR
+               /sys/devices/cpu/events/PM_MRK_LSU_REJECT_ERAT_MISS
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_L2MISS
+               /sys/devices/cpu/events/PM_DATA_FROM_RL2L3_SHR
+               /sys/devices/cpu/events/PM_INST_FROM_PREF
+               /sys/devices/cpu/events/PM_VSU1_SQ
+               /sys/devices/cpu/events/PM_L2_LD_DISP
+               /sys/devices/cpu/events/PM_L2_DISP_ALL
+               /sys/devices/cpu/events/PM_THRD_GRP_CMPL_BOTH_CYC
+               /sys/devices/cpu/events/PM_VSU_FSQRT_FDIV_DOUBLE
+               /sys/devices/cpu/events/PM_INST_PTEG_FROM_DL2L3_SHR
+               /sys/devices/cpu/events/PM_VSU_1FLOP
+               /sys/devices/cpu/events/PM_HV_CYC
+               /sys/devices/cpu/events/PM_MRK_LSU_FIN
+               /sys/devices/cpu/events/PM_MRK_DATA_FROM_RL2L3_SHR
+               /sys/devices/cpu/events/PM_DTLB_MISS_16M
+               /sys/devices/cpu/events/PM_LSU1_LMQ_LHR_MERGE
+               /sys/devices/cpu/events/PM_IFU_FIN
+               /sys/devices/cpu/events/PM_1THRD_CON_RUN_INSTR
+               /sys/devices/cpu/events/PM_CMPLU_STALL_COUNT
+               /sys/devices/cpu/events/PM_MEM0_PB_RD_CL
+               /sys/devices/cpu/events/PM_THRD_1_RUN_CYC
+               /sys/devices/cpu/events/PM_THRD_2_CONC_RUN_INSTR
+               /sys/devices/cpu/events/PM_THRD_2_RUN_CYC
+               /sys/devices/cpu/events/PM_THRD_3_CONC_RUN_INST
+               /sys/devices/cpu/events/PM_THRD_3_RUN_CYC
+               /sys/devices/cpu/events/PM_THRD_4_CONC_RUN_INST
+               /sys/devices/cpu/events/PM_THRD_4_RUN_CYC
 
 Date:          2013/01/08
 
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7 b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_24x7
new file mode 100644 (file)
index 0000000..e78ee79
--- /dev/null
@@ -0,0 +1,23 @@
+What:          /sys/bus/event_source/devices/hv_24x7/interface/catalog
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               Provides access to the binary "24x7 catalog" provided by the
+               hypervisor on POWER7 and 8 systems. This catalog lists events
+               avaliable from the powerpc "hv_24x7" pmu. Its format is
+               documented here:
+               https://raw.githubusercontent.com/jmesmon/catalog-24x7/master/hv-24x7-catalog.h
+
+What:          /sys/bus/event_source/devices/hv_24x7/interface/catalog_length
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               A number equal to the length in bytes of the catalog. This is
+               also extractable from the provided binary "catalog" sysfs entry.
+
+What:          /sys/bus/event_source/devices/hv_24x7/interface/catalog_version
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               Exposes the "version" field of the 24x7 catalog. This is also
+               extractable from the provided binary "catalog" sysfs entry.
diff --git a/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci b/Documentation/ABI/testing/sysfs-bus-event_source-devices-hv_gpci
new file mode 100644 (file)
index 0000000..3fa58c2
--- /dev/null
@@ -0,0 +1,43 @@
+What:          /sys/bus/event_source/devices/hv_gpci/interface/collect_privileged
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               '0' if the hypervisor is configured to forbid access to event
+               counters being accumulated by other guests and to physical
+               domain event counters.
+               '1' if that access is allowed.
+
+What:          /sys/bus/event_source/devices/hv_gpci/interface/ga
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               0 or 1. Indicates whether we have access to "GA" events (listed
+               in arch/powerpc/perf/hv-gpci.h).
+
+What:          /sys/bus/event_source/devices/hv_gpci/interface/expanded
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               0 or 1. Indicates whether we have access to "EXPANDED" events (listed
+               in arch/powerpc/perf/hv-gpci.h).
+
+What:          /sys/bus/event_source/devices/hv_gpci/interface/lab
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               0 or 1. Indicates whether we have access to "LAB" events (listed
+               in arch/powerpc/perf/hv-gpci.h).
+
+What:          /sys/bus/event_source/devices/hv_gpci/interface/version
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               A number indicating the version of the gpci interface that the
+               hypervisor reports supporting.
+
+What:          /sys/bus/event_source/devices/hv_gpci/interface/kernel_version
+Date:          February 2014
+Contact:       Cody P Schafer <cody@linux.vnet.ibm.com>
+Description:
+               A number indicating the latest version of the gpci interface
+               that the kernel is aware of.
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/l2cache.txt b/Documentation/devicetree/bindings/powerpc/fsl/l2cache.txt
new file mode 100644 (file)
index 0000000..c41b218
--- /dev/null
@@ -0,0 +1,23 @@
+Freescale L2 Cache Controller
+
+L2 cache is present in Freescale's QorIQ and QorIQ Qonverge platforms.
+The cache bindings explained below are ePAPR compliant
+
+Required Properties:
+
+- compatible   : Should include "fsl,chip-l2-cache-controller" and "cache"
+                 where chip is the processor (bsc9132, npc8572 etc.)
+- reg          : Address and size of L2 cache controller registers
+- cache-size   : Size of the entire L2 cache
+- interrupts   : Error interrupt of L2 controller
+- cache-line-size : Size of L2 cache lines
+
+Example:
+
+       L2: l2-cache-controller@20000 {
+               compatible = "fsl,bsc9132-l2-cache-controller", "cache";
+               reg = <0x20000 0x1000>;
+               cache-line-size = <32>; // 32 bytes
+               cache-size = <0x40000>; // L2,256K
+               interrupts = <16 2 1 0>;
+       };
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mem-ctrlr.txt b/Documentation/devicetree/bindings/powerpc/fsl/mem-ctrlr.txt
new file mode 100644 (file)
index 0000000..f87856f
--- /dev/null
@@ -0,0 +1,27 @@
+Freescale DDR memory controller
+
+Properties:
+
+- compatible   : Should include "fsl,chip-memory-controller" where
+                 chip is the processor (bsc9132, mpc8572 etc.), or
+                 "fsl,qoriq-memory-controller".
+- reg          : Address and size of DDR controller registers
+- interrupts   : Error interrupt of DDR controller
+
+Example 1:
+
+       memory-controller@2000 {
+               compatible = "fsl,bsc9132-memory-controller";
+               reg = <0x2000 0x1000>;
+               interrupts = <16 2 1 8>;
+       };
+
+
+Example 2:
+
+       ddr1: memory-controller@8000 {
+               compatible = "fsl,qoriq-memory-controller-v4.7",
+                               "fsl,qoriq-memory-controller";
+               reg = <0x8000 0x1000>;
+               interrupts = <16 2 1 23>;
+       };
index bd5723f0b67ecd9f953019fbd2af3c850bbb0433..4779c029b6756536cd6df57424cfa9c4831c0d24 100644 (file)
@@ -8,7 +8,9 @@ and additions :
 Required properties :
  - compatible : Should be "fsl-usb2-mph" for multi port host USB
    controllers, or "fsl-usb2-dr" for dual role USB controllers
-   or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
+   or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121.
+   Wherever applicable, the IP version of the USB controller should
+   also be mentioned (for eg. fsl-usb2-dr-v2.2 for bsc9132).
  - phy_type : For multi port host USB controllers, should be one of
    "ulpi", or "serial". For dual role USB controllers, should be
    one of "ulpi", "utmi", "utmi_wide", or "serial".
index b99bbbc4c5ddd3c2f153919570929d9bedba150a..e2ed69f1c4302357bfb6ef9f174ca7993187d6a8 100644 (file)
@@ -5254,11 +5254,10 @@ F:      arch/powerpc/platforms/512x/
 F:     arch/powerpc/platforms/52xx/
 
 LINUX FOR POWERPC EMBEDDED PPC4XX
-M:     Josh Boyer <jwboyer@gmail.com>
+M:  Alistair Popple <alistair@popple.id.au>
 M:     Matt Porter <mporter@kernel.crashing.org>
 W:     http://www.penguinppc.org/
 L:     linuxppc-dev@lists.ozlabs.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git
 S:     Maintained
 F:     arch/powerpc/platforms/40x/
 F:     arch/powerpc/platforms/44x/
index b9fcecc706ab3eb072349eb07c4ad0439a8a5eac..05e532984c13212b47a87e04412a722e9e6d889a 100644 (file)
@@ -618,6 +618,15 @@ config CMDLINE
          some command-line options at build time by entering them here.  In
          most cases you will need to specify the root device here.
 
+config CMDLINE_FORCE
+       bool "Always use the default kernel command string"
+       depends on CMDLINE_BOOL
+       help
+         Always use the default kernel command string, even if the boot
+         loader passes other arguments to the kernel.
+         This is useful if you cannot or don't want to change the
+         command-line options your boot loader passes to the kernel.
+
 config EXTRA_TARGETS
        string "Additional default image types"
        help
index 90e9d95486603281684c9a06bdbb5029e06b0843..a1f8c7f1ec60138db045ae6b46b57bec62169538 100644 (file)
@@ -54,7 +54,7 @@ zlib       := inffast.c inflate.c inftrees.c
 zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h
 zliblinuxheader := zlib.h zconf.h zutil.h
 
-$(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \
+$(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o): \
        $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
 
 libfdt       := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
@@ -95,7 +95,7 @@ src-plat-$(CONFIG_FSL_SOC_BOOKE) += cuboot-85xx.c cuboot-85xx-cpm2.c
 src-plat-$(CONFIG_EMBEDDED6xx) += cuboot-pq2.c cuboot-mpc7448hpc2.c \
                                        cuboot-c2k.c gamecube-head.S \
                                        gamecube.c wii-head.S wii.c holly.c \
-                                       prpmc2800.c fixed-head.S mvme5100.c
+                                       fixed-head.S mvme5100.c
 src-plat-$(CONFIG_AMIGAONE) += cuboot-amigaone.c
 src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
 src-plat-$(CONFIG_EPAPR_BOOT) += epapr.c epapr-wrapper.c
@@ -204,7 +204,6 @@ image-$(CONFIG_PPC_CHRP)            += zImage.chrp
 image-$(CONFIG_PPC_EFIKA)              += zImage.chrp
 image-$(CONFIG_PPC_PMAC)               += zImage.pmac
 image-$(CONFIG_PPC_HOLLY)              += dtbImage.holly
-image-$(CONFIG_PPC_PRPMC2800)          += dtbImage.prpmc2800
 image-$(CONFIG_DEFAULT_UIMAGE)         += uImage
 image-$(CONFIG_EPAPR_BOOT)             += zImage.epapr
 
index 5a6615d0ade24717ed73a21fe8456bc420380a77..60566f9927be576de6797accfc578f6b1e5fd7ad 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,b4420-clockgen", "fsl,qoriq-clockgen-2.0";
+               ranges = <0x0 0xe1000 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-2.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2", "pll0-div4";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2", "pll1-div4";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-2.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
+                               <&pll1 0>, <&pll1 1>, <&pll1 2>;
+                       clock-names = "pll0", "pll0-div2", "pll0-div4",
+                               "pll1", "pll1-div2", "pll1-div4";
+                       clock-output-names = "cmux0";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index c6e451affb055958b3943378878d6dc4c4a59284..2419731c2c5443b35c1f6edde0f89808fc7bbef6 100644 (file)
                cpu0: PowerPC,e6500@0 {
                        device_type = "cpu";
                        reg = <0 1>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2>;
                };
                cpu1: PowerPC,e6500@2 {
                        device_type = "cpu";
                        reg = <2 3>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2>;
                };
        };
index 981397518fc6243919e78118944d8dda2f763f6b..cbc354b05117344342bab0d839749e19a0f2b832 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,b4860-clockgen", "fsl,qoriq-clockgen-2.0";
+               ranges = <0x0 0xe1000 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-2.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2", "pll0-div4";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2", "pll1-div4";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-2.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
+                               <&pll1 0>, <&pll1 1>, <&pll1 2>;
+                       clock-names = "pll0", "pll0-div2", "pll0-div4",
+                               "pll1", "pll1-div2", "pll1-div4";
+                       clock-output-names = "cmux0";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index 9bc26b14790061ea3793f7b3f4afa7c06efd09d3..142ac862cacfd2b1362ebf508ca9e11f9237fb3e 100644 (file)
                cpu0: PowerPC,e6500@0 {
                        device_type = "cpu";
                        reg = <0 1>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2>;
                };
                cpu1: PowerPC,e6500@2 {
                        device_type = "cpu";
                        reg = <2 3>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2>;
                };
                cpu2: PowerPC,e6500@4 {
                        device_type = "cpu";
                        reg = <4 5>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2>;
                };
                cpu3: PowerPC,e6500@6 {
                        device_type = "cpu";
                        reg = <6 7>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2>;
                };
        };
index dc6cc5afd189b6f1e66c200e994e75760229d2a3..e2987a33083cbbeb51b5d66984f2508e740759d7 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,p2041-clockgen", "fsl,qoriq-clockgen-1.0";
+               ranges = <0x0 0xe1000 0x1000>;
                reg = <0xe1000 0x1000>;
                clock-frequency = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-1.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux0";
+               };
+
+               mux1: mux1@20 {
+                       #clock-cells = <0>;
+                       reg = <0x20 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux1";
+               };
+
+               mux2: mux2@40 {
+                       #clock-cells = <0>;
+                       reg = <0x40 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+               };
+
+               mux3: mux3@60 {
+                       #clock-cells = <0>;
+                       reg = <0x60 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux3";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index 7a2697d04549535e74d5b78924c90e2bf193cef5..22f3b14517de83fc5f4c891d06eed37fb762cb68 100644 (file)
@@ -81,6 +81,7 @@
                cpu0: PowerPC,e500mc@0 {
                        device_type = "cpu";
                        reg = <0>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                next-level-cache = <&cpc>;
@@ -89,6 +90,7 @@
                cpu1: PowerPC,e500mc@1 {
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
                                next-level-cache = <&cpc>;
@@ -97,6 +99,7 @@
                cpu2: PowerPC,e500mc@2 {
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_2>;
                        L2_2: l2-cache {
                                next-level-cache = <&cpc>;
                cpu3: PowerPC,e500mc@3 {
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&mux3>;
                        next-level-cache = <&L2_3>;
                        L2_3: l2-cache {
                                next-level-cache = <&cpc>;
index 3fa1e22d544a51c76848c9113cdc5726b575c7e3..7af6d45fd998b6470a94e198855772e9d5313d5d 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,p3041-clockgen", "fsl,qoriq-clockgen-1.0";
+               ranges = <0x0 0xe1000 0x1000>;
                reg = <0xe1000 0x1000>;
                clock-frequency = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-1.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux0";
+               };
+
+               mux1: mux1@20 {
+                       #clock-cells = <0>;
+                       reg = <0x20 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux1";
+               };
+
+               mux2: mux2@40 {
+                       #clock-cells = <0>;
+                       reg = <0x40 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux2";
+               };
+
+               mux3: mux3@60 {
+                       #clock-cells = <0>;
+                       reg = <0x60 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux3";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index c9ca2c305cfecff64052e084d44b35af7ff02ce1..468e8be8ac6f82cc40c149fb50edab9baf5260d5 100644 (file)
@@ -82,6 +82,7 @@
                cpu0: PowerPC,e500mc@0 {
                        device_type = "cpu";
                        reg = <0>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                next-level-cache = <&cpc>;
@@ -90,6 +91,7 @@
                cpu1: PowerPC,e500mc@1 {
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
                                next-level-cache = <&cpc>;
                cpu2: PowerPC,e500mc@2 {
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_2>;
                        L2_2: l2-cache {
                                next-level-cache = <&cpc>;
                cpu3: PowerPC,e500mc@3 {
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&mux3>;
                        next-level-cache = <&L2_3>;
                        L2_3: l2-cache {
                                next-level-cache = <&cpc>;
index 34769a7eafea17cec138f0885feb8a476adf6d94..2415e1f1d3fafe6801020bbbf62d200bf8e47581 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,p4080-clockgen", "fsl,qoriq-clockgen-1.0";
+               ranges = <0x0 0xe1000 0x1000>;
                reg = <0xe1000 0x1000>;
                clock-frequency = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-1.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2";
+               };
+
+               pll2: pll2@840 {
+                       #clock-cells = <1>;
+                       reg = <0x840 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll2", "pll2-div2";
+               };
+
+               pll3: pll3@860 {
+                       #clock-cells = <1>;
+                       reg = <0x860 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll3", "pll3-div2";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux0";
+               };
+
+               mux1: mux1@20 {
+                       #clock-cells = <0>;
+                       reg = <0x20 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux1";
+               };
+
+               mux2: mux2@40 {
+                       #clock-cells = <0>;
+                       reg = <0x40 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux2";
+               };
+
+               mux3: mux3@60 {
+                       #clock-cells = <0>;
+                       reg = <0x60 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux3";
+               };
+
+               mux4: mux4@80 {
+                       #clock-cells = <0>;
+                       reg = <0x80 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
+                       clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
+                       clock-output-names = "cmux4";
+               };
+
+               mux5: mux5@a0 {
+                       #clock-cells = <0>;
+                       reg = <0xa0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
+                       clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
+                       clock-output-names = "cmux5";
+               };
+
+               mux6: mux6@c0 {
+                       #clock-cells = <0>;
+                       reg = <0xc0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
+                       clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
+                       clock-output-names = "cmux6";
+               };
+
+               mux7: mux7@e0 {
+                       #clock-cells = <0>;
+                       reg = <0xe0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll2 0>, <&pll2 1>, <&pll3 0>, <&pll3 1>;
+                       clock-names = "pll2", "pll2-div2", "pll3", "pll3-div2";
+                       clock-output-names = "cmux7";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index 493d9a056b5caceffbc58c80baf38a2fec8c2f25..0040b5a5379e2de22819988902e26b5e5f94dde2 100644 (file)
@@ -81,6 +81,7 @@
                cpu0: PowerPC,e500mc@0 {
                        device_type = "cpu";
                        reg = <0>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                next-level-cache = <&cpc>;
@@ -89,6 +90,7 @@
                cpu1: PowerPC,e500mc@1 {
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
                                next-level-cache = <&cpc>;
@@ -97,6 +99,7 @@
                cpu2: PowerPC,e500mc@2 {
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_2>;
                        L2_2: l2-cache {
                                next-level-cache = <&cpc>;
                cpu3: PowerPC,e500mc@3 {
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&mux3>;
                        next-level-cache = <&L2_3>;
                        L2_3: l2-cache {
                                next-level-cache = <&cpc>;
                cpu4: PowerPC,e500mc@4 {
                        device_type = "cpu";
                        reg = <4>;
+                       clocks = <&mux4>;
                        next-level-cache = <&L2_4>;
                        L2_4: l2-cache {
                                next-level-cache = <&cpc>;
                cpu5: PowerPC,e500mc@5 {
                        device_type = "cpu";
                        reg = <5>;
+                       clocks = <&mux5>;
                        next-level-cache = <&L2_5>;
                        L2_5: l2-cache {
                                next-level-cache = <&cpc>;
                cpu6: PowerPC,e500mc@6 {
                        device_type = "cpu";
                        reg = <6>;
+                       clocks = <&mux6>;
                        next-level-cache = <&L2_6>;
                        L2_6: l2-cache {
                                next-level-cache = <&cpc>;
                cpu7: PowerPC,e500mc@7 {
                        device_type = "cpu";
                        reg = <7>;
+                       clocks = <&mux7>;
                        next-level-cache = <&L2_7>;
                        L2_7: l2-cache {
                                next-level-cache = <&cpc>;
index bc3ae5a2252f451a4bdcc76ead0dff12fd5b553f..2985de4ad6bec72d0d28331e88558bf1c5cbd58d 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,p5020-clockgen", "fsl,qoriq-clockgen-1.0";
+               ranges = <0x0 0xe1000 0x1000>;
                reg = <0xe1000 0x1000>;
                clock-frequency = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-1.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux0";
+               };
+
+               mux1: mux1@20 {
+                       #clock-cells = <0>;
+                       reg = <0x20 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux1";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index 8df47fc45ab530c2523c3ae0968f61d5aa09c685..fe1a2e6613b49b8c116d65763e79f160e023b9e3 100644 (file)
@@ -88,6 +88,7 @@
                cpu0: PowerPC,e5500@0 {
                        device_type = "cpu";
                        reg = <0>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                next-level-cache = <&cpc>;
@@ -96,6 +97,7 @@
                cpu1: PowerPC,e5500@1 {
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
                                next-level-cache = <&cpc>;
index a91897f6af0989b92f8f8ed717b554c13514a044..546a899efe20eca6ec44bade2d2df2831e95d7f3 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0";
+               ranges = <0x0 0xe1000 0x1000>;
                reg = <0xe1000 0x1000>;
                clock-frequency = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-1.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-1.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux0";
+               };
+
+               mux1: mux1@20 {
+                       #clock-cells = <0>;
+                       reg = <0x20 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux1";
+               };
+
+               mux2: mux2@40 {
+                       #clock-cells = <0>;
+                       reg = <0x40 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux2";
+               };
+
+               mux3: mux3@60 {
+                       #clock-cells = <0>;
+                       reg = <0x60 0x4>;
+                       compatible = "fsl,qoriq-core-mux-1.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll1 0>, <&pll1 1>;
+                       clock-names = "pll0", "pll0-div2", "pll1", "pll1-div2";
+                       clock-output-names = "cmux3";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index 40ca943f5d1cac4e34a01413633dc640382edaec..3674686687cbfd24066b53debf34111ab63125c7 100644 (file)
@@ -81,6 +81,7 @@
                cpu0: PowerPC,e5500@0 {
                        device_type = "cpu";
                        reg = <0>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_0>;
                        L2_0: l2-cache {
                                next-level-cache = <&cpc>;
@@ -89,6 +90,7 @@
                cpu1: PowerPC,e5500@1 {
                        device_type = "cpu";
                        reg = <1>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_1>;
                        L2_1: l2-cache {
                                next-level-cache = <&cpc>;
@@ -97,6 +99,7 @@
                cpu2: PowerPC,e5500@2 {
                        device_type = "cpu";
                        reg = <2>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_2>;
                        L2_2: l2-cache {
                                next-level-cache = <&cpc>;
                cpu3: PowerPC,e5500@3 {
                        device_type = "cpu";
                        reg = <3>;
+                       clocks = <&mux3>;
                        next-level-cache = <&L2_3>;
                        L2_3: l2-cache {
                                next-level-cache = <&cpc>;
index 4143a9733cd01e0ad62d9d3d98902e7f414dd8f3..f99d74ff11b4f95cf3a312b1aa7645c6df6c24a9 100644 (file)
 
        clockgen: global-utilities@e1000 {
                compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0";
+               ranges = <0x0 0xe1000 0x1000>;
                reg = <0xe1000 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               sysclk: sysclk {
+                       #clock-cells = <0>;
+                       compatible = "fsl,qoriq-sysclk-2.0";
+                       clock-output-names = "sysclk";
+               };
+
+               pll0: pll0@800 {
+                       #clock-cells = <1>;
+                       reg = <0x800 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll0", "pll0-div2", "pll0-div4";
+               };
+
+               pll1: pll1@820 {
+                       #clock-cells = <1>;
+                       reg = <0x820 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll1", "pll1-div2", "pll1-div4";
+               };
+
+               pll2: pll2@840 {
+                       #clock-cells = <1>;
+                       reg = <0x840 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll2", "pll2-div2", "pll2-div4";
+               };
+
+               pll3: pll3@860 {
+                       #clock-cells = <1>;
+                       reg = <0x860 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll3", "pll3-div2", "pll3-div4";
+               };
+
+               pll4: pll4@880 {
+                       #clock-cells = <1>;
+                       reg = <0x880 0x4>;
+                       compatible = "fsl,qoriq-core-pll-2.0";
+                       clocks = <&sysclk>;
+                       clock-output-names = "pll4", "pll4-div2", "pll4-div4";
+               };
+
+               mux0: mux0@0 {
+                       #clock-cells = <0>;
+                       reg = <0x0 0x4>;
+                       compatible = "fsl,qoriq-core-mux-2.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
+                               <&pll1 0>, <&pll1 1>, <&pll1 2>,
+                               <&pll2 0>, <&pll2 1>, <&pll2 2>;
+                       clock-names = "pll0", "pll0-div2", "pll0-div4",
+                               "pll1", "pll1-div2", "pll1-div4",
+                               "pll2", "pll2-div2", "pll2-div4";
+                       clock-output-names = "cmux0";
+               };
+
+               mux1: mux1@20 {
+                       #clock-cells = <0>;
+                       reg = <0x20 0x4>;
+                       compatible = "fsl,qoriq-core-mux-2.0";
+                       clocks = <&pll0 0>, <&pll0 1>, <&pll0 2>,
+                               <&pll1 0>, <&pll1 1>, <&pll1 2>,
+                               <&pll2 0>, <&pll2 1>, <&pll2 2>;
+                       clock-names = "pll0", "pll0-div2", "pll0-div4",
+                               "pll1", "pll1-div2", "pll1-div4",
+                               "pll2", "pll2-div2", "pll2-div4";
+                       clock-output-names = "cmux1";
+               };
+
+               mux2: mux2@40 {
+                       #clock-cells = <0>;
+                       reg = <0x40 0x4>;
+                       compatible = "fsl,qoriq-core-mux-2.0";
+                       clocks = <&pll3 0>, <&pll3 1>, <&pll3 2>,
+                               <&pll4 0>, <&pll4 1>, <&pll4 2>;
+                       clock-names = "pll3", "pll3-div2", "pll3-div4",
+                               "pll4", "pll4-div2", "pll4-div4";
+                       clock-output-names = "cmux2";
+               };
        };
 
        rcpm: global-utilities@e2000 {
index a93c55a885601a098abc4187ac2b38d3f3d7bc8e..0b8ccc5b4a46575088acd599a01fd0aef3909d98 100644 (file)
                cpu0: PowerPC,e6500@0 {
                        device_type = "cpu";
                        reg = <0 1>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_1>;
                };
                cpu1: PowerPC,e6500@2 {
                        device_type = "cpu";
                        reg = <2 3>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_1>;
                };
                cpu2: PowerPC,e6500@4 {
                        device_type = "cpu";
                        reg = <4 5>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_1>;
                };
                cpu3: PowerPC,e6500@6 {
                        device_type = "cpu";
                        reg = <6 7>;
+                       clocks = <&mux0>;
                        next-level-cache = <&L2_1>;
                };
                cpu4: PowerPC,e6500@8 {
                        device_type = "cpu";
                        reg = <8 9>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_2>;
                };
                cpu5: PowerPC,e6500@10 {
                        device_type = "cpu";
                        reg = <10 11>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_2>;
                };
                cpu6: PowerPC,e6500@12 {
                        device_type = "cpu";
                        reg = <12 13>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_2>;
                };
                cpu7: PowerPC,e6500@14 {
                        device_type = "cpu";
                        reg = <14 15>;
+                       clocks = <&mux1>;
                        next-level-cache = <&L2_2>;
                };
                cpu8: PowerPC,e6500@16 {
                        device_type = "cpu";
                        reg = <16 17>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_3>;
                };
                cpu9: PowerPC,e6500@18 {
                        device_type = "cpu";
                        reg = <18 19>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_3>;
                };
                cpu10: PowerPC,e6500@20 {
                        device_type = "cpu";
                        reg = <20 21>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_3>;
                };
                cpu11: PowerPC,e6500@22 {
                        device_type = "cpu";
                        reg = <22 23>;
+                       clocks = <&mux2>;
                        next-level-cache = <&L2_3>;
                };
        };
index 63e81b010804f4e552dc14da69632211f2769403..97683f6a29361639f5b6e88efd11a0c69d5480dc 100644 (file)
                                                interrupts = <0x1 0x1 0 0>;
                                        };
                                };
+
+                               i2c@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0x2>;
+
+                                       ina220@40 {
+                                               compatible = "ti,ina220";
+                                               reg = <0x40>;
+                                               shunt-resistor = <1000>;
+                                       };
+
+                                       ina220@41 {
+                                               compatible = "ti,ina220";
+                                               reg = <0x41>;
+                                               shunt-resistor = <1000>;
+                                       };
+
+                                       ina220@44 {
+                                               compatible = "ti,ina220";
+                                               reg = <0x44>;
+                                               shunt-resistor = <1000>;
+                                       };
+
+                                       ina220@45 {
+                                               compatible = "ti,ina220";
+                                               reg = <0x45>;
+                                               shunt-resistor = <1000>;
+                                       };
+
+                                       ina220@46 {
+                                               compatible = "ti,ina220";
+                                               reg = <0x46>;
+                                               shunt-resistor = <1000>;
+                                       };
+
+                                       ina220@47 {
+                                               compatible = "ti,ina220";
+                                               reg = <0x47>;
+                                               shunt-resistor = <1000>;
+                                       };
+                               };
                        };
                };
 
index ed3bab72a8344b8713a8fc961032e795d4a7c554..69e06eeae6a661ac811134f06645a9b37642c689 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 17582a3420fbfeb599f9e8d4bb4be16e777bae9a..cf06d42f2c03d79e472dd67cd21b03b9d484776c 100644 (file)
@@ -29,7 +29,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index f2d4be936e08eed46970c5cb9f3b45387dad006b..5ff338f6443f063016e7936514ca9e6625ad9364 100644 (file)
@@ -32,7 +32,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 42b979355f9bbf2ce0efc992fc79a5f0f3d0aa9f..84505e3aa0fb2f12db78b968b936c980f847f13e 100644 (file)
@@ -29,7 +29,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index aa1a4cac3708baf18cd4ca346db95b56c707b3bb..0a19f4386ee9fe627a1e77c6a6adde32d9dc8dfe 100644 (file)
@@ -27,7 +27,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 329f9a3b892ec0501db87002647fdaa4888a06f7..44355c53cd3082bc5fd4cee881ef549c1ef11608 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 20c8d26d7fc043836cf0ff8b452ba74356617c76..ca7f1f32f2b2e113cbf00cc418907a5f04424ec0 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index d5be93e6e92d6e9477ad142228f9eede3f8e990e..7b8abd1b88b0619b6a40b31fca4c405020bed5f8 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index f9269fc4ffcc008b1eff7038c637d70fd8f36a29..31b58b0d52e26396944becbe8b098ba65009cedb 100644 (file)
@@ -28,7 +28,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 9be089038fd7ba602a529b21c4c521489c1222b3..faccaf65f394c949b651287810c4482ca2bde61d 100644 (file)
@@ -34,7 +34,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 82f73035a7ce8f8c520877eb1ae089174f8c665e..05782c145141fbd4524cc2f752706544b7f03061 100644 (file)
@@ -33,7 +33,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index ca00cf750d3e7bd9e90867cad7d29d30b03e10bf..49a1518a4e697a3475b2ce69ee98039f414155e0 100644 (file)
@@ -42,7 +42,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 109562c3c6be90124c2263e7acb61e55da861dc3..f1137972ed41299f0fa1e2ed7dc1f8a84a6fc2c6 100644 (file)
@@ -29,7 +29,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 21c33faf61a2deff1ec60aacc87f069e5f5a686f..4b91a44c4c32c64d2e4a2c233e515cdf407fe61c 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 48802811da76bf7605ece2c4ce28a7d674a8c4a3..b7113e114a14b3dec6efc7f4328fcc82a5509224 100644 (file)
@@ -34,7 +34,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index b7a653b626dbb67e14990278d1a5a0446626a872..9642d99b47f175adf82ecc65d2613fc8914a4e87 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 30de97f158a409b53d4883133c929e926435dbae..09e3075030bfe5aa166d2be339154af762b1eca5 100644 (file)
@@ -29,7 +29,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_CFI=y
index 105bc56f4b2b445a57970a77c583b48c56b8c200..551e50a0be5e9ea4d854416a96141c3466772df7 100644 (file)
@@ -34,7 +34,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_STANDALONE is not set
 # CONFIG_FIRMWARE_IN_KERNEL is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 0b88c7b30bb9a4a5697cc87fe8fd6486bfca6bf4..4f84a0b2fbf37ca340307ff33adabd029aa2ffe1 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_SYN_COOKIES=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 0d13ad7e44782fdf9adafa6f3a82231920048c98..c05310a913becb4921dae96fd83dbbc192885c74 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 430aa182fa1ceab8f53ca6af410ca39772095f3b..2401e255432953a1d4f44f003237467a15d4d51e 100644 (file)
@@ -44,7 +44,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 7af4c5bb7c63b30d23a058d885a26cbe40b179ee..21c841e0f4821f8b6ffd58c3d58739af42c242b3 100644 (file)
@@ -35,7 +35,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index d2762d9dcb8e969ba84bc8d2ecae30b14c5e8bdb..985f95c7280a95d728dd034233740341a675356a 100644 (file)
@@ -32,7 +32,6 @@ CONFIG_SYN_COOKIES=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
 CONFIG_MTD_OF_PARTS=y
index e4ad2e27551a096e8af773ec4fb9f231c5d64b03..0b73b7f9d1126926166f7e3917a2fb71e2861844 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_SYN_COOKIES=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 34ff5686be0833781ca864899efbb8dcbb05a658..97ac3b993cb68906f000aef833f663702e3baf04 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_SYN_COOKIES=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index 10b5c4cd0e72bb393148a8d6e63aa800dc7a823d..05710bbfd2ef3ed6d0af1efe9cbc1ba7832ba2ae 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_SYN_COOKIES=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 45925d701d2a10556692fa67cc7b9e6f80394ec4..0540d673a05231aaf3b86a2eaeaa4406314e7daa 100644 (file)
@@ -29,7 +29,6 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 6d6463fe06fc25dc7ac17d3fac7d5d19e9ef28fa..a3bcda67d2d9802e43eb5489f467ab61ae2f7d79 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 8f7c1061891ad6b0819659ea204573faa8fbcbb4..aee0d17a9551381c642a9f37ce21012e9ae8564d 100644 (file)
@@ -28,7 +28,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index a11337de8aa26be89880d879fd9dc2d20b10272f..e80bb9b21eacac7929b02569323ddc416095734f 100644 (file)
@@ -44,7 +44,6 @@ CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_PHYSMAP_OF=y
 
 CONFIG_I2C=y
index 77506b5d5a41db7408b311099f10c54c51478547..e5147488c00055eb7b8793f857573acf4ffdeb32 100644 (file)
@@ -32,7 +32,6 @@ CONFIG_CAN_RAW=y
 CONFIG_CAN_BCM=y
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index ddcb9f37fa1ff771dcb1f51c52dc54f89706721e..5a800e6e38e313d270083f8d5605ab76e3f21302 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 981abd6d4b57b31d13b31d5a0ecbaecdb18681a5..2d936697d69ed73547127334ab0d61dfa8932aad 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 37b3d7227cddfc635d92d53e2204141e14ef3b37..ce8a67e894737e42063e5d9d1716364095dcdad7 100644 (file)
@@ -34,7 +34,6 @@ CONFIG_SYN_COOKIES=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
index 3593b320c97c62962c17bb2400bec13a7084eb6d..a4e12971ccac8ce09a6d87bc4c24d0167b82ad4c 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index de413acc34d6d09d54071812cada37aa4fb3f488..341abe18a74deaf8a7c4206c5223fde41455aa2a 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_IPV6 is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 1cd6fcb368e95f5d26a6eae5db157796c94f21de..07bb81df27e065d2e3400987f2f515813b05c790 100644 (file)
@@ -65,7 +65,6 @@ CONFIG_ARPD=y
 CONFIG_IPV6=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
index f2f6734d5f768aa6b4b9fbfc07bb5356667383a5..e5a648115ada0c6396f65c12a1de19622ee95099 100644 (file)
@@ -70,7 +70,6 @@ CONFIG_NET_PKTGEN=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index be73219212b7b6e879d4deb6822908bd87ec268c..8317b6010ba6b288503ae2b2ccf6bea0833b31d4 100644 (file)
@@ -70,7 +70,6 @@ CONFIG_NET_PKTGEN=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index b3e2b1058f272c3428dc3f9881f7d2323d07a506..124d66f0282c8ef9cd1a222e49911beebaaf8cac 100644 (file)
@@ -123,7 +123,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index c09598b31de1bb6ded595721edf7e8cbb213ace9..bcbe747166899c0f63e25c6aafe3dee3708e55a5 100644 (file)
@@ -41,7 +41,6 @@ CONFIG_IP_PNP_RARP=y
 CONFIG_IPV6=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index 1a62baf855e9fcc222980d8a2afef59892c9cb56..1e151594c691585bb2948598587abac4d0118b30 100644 (file)
@@ -120,7 +120,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
index 671a8f960afa02b8d183a2c0eb069df9a791efc4..c69f61620908a44a30a6a2cf28db6c9b6b859be1 100644 (file)
@@ -149,7 +149,6 @@ CONFIG_BT_HCIVHCI=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=m
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLOCK=y
index 63508ddee11c899b7fd0aade515b9ee7e32bd9df..5c7fa19ae4ef1ebe60671890487f7292e87c7f34 100644 (file)
@@ -26,7 +26,6 @@ CONFIG_CORENET_GENERIC=y
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
 CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED=y
-CONFIG_FSL_IFC=y
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCI_MSI=y
 CONFIG_RAPIDIO=y
@@ -60,7 +59,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
index 8a874b99986768113bc946a440feb861d22eebd9..353435256f4ce308d3914a9c7a8c38d981d857f2 100644 (file)
@@ -59,7 +59,6 @@ CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 83d3550fdb5400b26f2508ef9e862346e1c004ae..19f0fbe5ba4b43e35f9e00bca14acacf2b79f343 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_HIGHMEM=y
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
 CONFIG_FORCE_MAX_ZONEORDER=12
-CONFIG_FSL_IFC=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
 CONFIG_RAPIDIO=y
@@ -82,7 +81,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
index 4b686294feb49592594f91c04abaea8377dca52d..062312e1fe1abd7b2912678f9e318f249811a8ed 100644 (file)
@@ -52,7 +52,6 @@ CONFIG_HIGHMEM=y
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
 CONFIG_FORCE_MAX_ZONEORDER=12
-CONFIG_FSL_IFC=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
 CONFIG_RAPIDIO=y
@@ -85,7 +84,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
index 1eb19ac45d09ac35172c7a57f1d046c71bc30401..52908c7897d922c18d53b31f85f4d126e726dd36 100644 (file)
@@ -33,7 +33,6 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 3b98d735434142bb9240a6a2d4906d0b882a3ab2..ccf66b9060a6036ce9eb6e6fd835d97ca1730c7a 100644 (file)
@@ -44,7 +44,6 @@ CONFIG_BRIDGE=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
index e015896b7e5cebacaf46bb713ab16e2fe2128747..f26b267eb71fa947db544f202e6cd55b581b1821 100644 (file)
@@ -73,74 +73,8 @@ CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_SCTP=m
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_SOCKET=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_BRIDGE=m
 CONFIG_BPF_JIT=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
index f627fda0895303061ee4fc199641fbc6a2a7272b..438e813dc9cb1c18cf4605f5d937135100d39530 100644 (file)
@@ -48,74 +48,8 @@ CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_SCTP=m
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_SOCKET=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_BRIDGE=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig
deleted file mode 100644 (file)
index cd80fb6..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-CONFIG_ALTIVEC=y
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_PMAC is not set
-CONFIG_EMBEDDED6xx=y
-CONFIG_PPC_PRPMC2800=y
-CONFIG_HIGHMEM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BINFMT_MISC=y
-CONFIG_SPARSE_IRQ=y
-# CONFIG_SECCOMP is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_PROC_DEVICETREE=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=131072
-CONFIG_IDE=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PDC202XX_NEW=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_SATA_MV=y
-CONFIG_MACINTOSH_DRIVERS=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
-CONFIG_E100=y
-CONFIG_8139TOO=y
-# CONFIG_8139TOO_PIO is not set
-CONFIG_E1000=y
-CONFIG_MV643XX_ETH=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_MPSC=y
-CONFIG_SERIAL_MPSC_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MV64XXX=y
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-CONFIG_HID_DRAGONRISE=y
-CONFIG_HID_GYRATION=y
-CONFIG_HID_TWINHAN=y
-CONFIG_HID_NTRIG=y
-CONFIG_HID_ORTEK=y
-CONFIG_HID_PANTHERLORD=y
-CONFIG_HID_PETALYNX=y
-CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
-CONFIG_HID_SUNPLUS=y
-CONFIG_HID_GREENASIA=y
-CONFIG_HID_SMARTJOYPLUS=y
-CONFIG_HID_TOPSEED=y
-CONFIG_HID_THRUSTMASTER=y
-CONFIG_THRUSTMASTER_FF=y
-CONFIG_HID_ZEROPLUS=y
-CONFIG_ZEROPLUS_FF=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_MON=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_MAX6900=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_INOTIFY=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_CRC_T10DIF=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
index e9a8b4e0a0f6309fb7a8a037d01615dc1018ffa1..9ea8342bd219b8851cbe209420b554f9f8128d15 100644 (file)
@@ -65,57 +65,8 @@ CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_UDPLITE=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_ULOG=m
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_BRIDGE=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -353,3 +304,5 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
index 62771e0adb7cf39d5dde893e43b280b5d07265ec..3c84f9d879800f47ada749fdad0628cfe7bd5be0 100644 (file)
@@ -67,57 +67,8 @@ CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CT_PROTO_UDPLITE=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_ULOG=m
+# CONFIG_NETFILTER_ADVANCED is not set
+CONFIG_BRIDGE=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
index ebb2a66c99d3b9b79d8ee05f2230215259e2a659..ba39c785445d435278f840771f4dfb5290ec03c3 100644 (file)
@@ -31,7 +31,6 @@ CONFIG_IP_PNP_DHCP=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index 4b6f8bf104e0687eb331c9c7d383855966ec5143..7fe277a7b42212abb1c8e60723fa375e1d82c931 100644 (file)
@@ -41,7 +41,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
 CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_OF_PARTS=y
 CONFIG_MTD_CHAR=y
index a613d2c82fd9e7cbb024a28f493c0be54748d7e0..b142b8e0ed9e26795215248c25aa90d45bf0704c 100644 (file)
@@ -8,7 +8,11 @@
 #include <linux/sched.h>
 
 #define COMPAT_USER_HZ         100
+#ifdef __BIG_ENDIAN__
 #define COMPAT_UTS_MACHINE     "ppc\0\0"
+#else
+#define COMPAT_UTS_MACHINE     "ppcle\0\0"
+#endif
 
 typedef u32            compat_size_t;
 typedef s32            compat_ssize_t;
index 617cc767c07681b109c5acd54f667cc3274956b5..bc2347774f0ad4ed111a5c98546fb763de6d8bbd 100644 (file)
@@ -189,6 +189,7 @@ extern const char *powerpc_base_platform;
 #define        CPU_FTR_HAS_PPR                 LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_DAWR                   LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_DABRX                  LONG_ASM_CONST(0x0800000000000000)
+#define CPU_FTR_PMAO_BUG               LONG_ASM_CONST(0x1000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -445,6 +446,7 @@ extern const char *powerpc_base_platform;
            CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
            CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
            CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
+#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -466,8 +468,8 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_POSSIBLE      \
            (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |        \
            CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 |       \
-           CPU_FTRS_POWER7 | CPU_FTRS_POWER8 | CPU_FTRS_CELL |         \
-           CPU_FTRS_PA6T | CPU_FTR_VSX)
+           CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 |      \
+           CPU_FTRS_CELL | CPU_FTRS_PA6T | CPU_FTR_VSX)
 #endif
 #else
 enum {
index 51fa43e536b917c08c5870525c9a81063c1448e2..a563d9afd179f3790332c453ebae0ee760df6196 100644 (file)
@@ -46,9 +46,8 @@
 #define EX_CR          (1 * 8)
 #define EX_R10         (2 * 8)
 #define EX_R11         (3 * 8)
-#define EX_R13         (4 * 8)
-#define EX_R14         (5 * 8)
-#define EX_R15         (6 * 8)
+#define EX_R14         (4 * 8)
+#define EX_R15         (5 * 8)
 
 /*
  * The TLB miss exception uses different slots.
@@ -173,16 +172,6 @@ exc_##label##_book3e:
        ld      r9,EX_TLB_R9(r12);                                          \
        ld      r8,EX_TLB_R8(r12);                                          \
        mtlr    r16;
-#define TLB_MISS_PROLOG_STATS_BOLTED                                               \
-       mflr    r10;                                                        \
-       std     r8,PACA_EXTLB+EX_TLB_R8(r13);                               \
-       std     r9,PACA_EXTLB+EX_TLB_R9(r13);                               \
-       std     r10,PACA_EXTLB+EX_TLB_LR(r13);
-#define TLB_MISS_RESTORE_STATS_BOLTED                                              \
-       ld      r16,PACA_EXTLB+EX_TLB_LR(r13);                              \
-       ld      r9,PACA_EXTLB+EX_TLB_R9(r13);                               \
-       ld      r8,PACA_EXTLB+EX_TLB_R8(r13);                               \
-       mtlr    r16;
 #define TLB_MISS_STATS_D(name)                                             \
        addi    r9,r13,MMSTAT_DSTATS+name;                                  \
        bl      .tlb_stat_inc;
index 66830618cc19b2f4b12a5b6cefa8d1663425187e..aeaa56cd9b5465100b00025c7a1da36b3d58e1c5 100644 (file)
@@ -146,6 +146,14 @@ BEGIN_FTR_SECTION_NESTED(943)                                              \
        mfspr   ra,spr;                                                 \
 END_FTR_SECTION_NESTED(ftr,ftr,943)
 
+/*
+ * Set an SPR from a register if the CPU has the given feature
+ */
+#define OPT_SET_SPR(ra, spr, ftr)                                      \
+BEGIN_FTR_SECTION_NESTED(943)                                          \
+       mtspr   spr,ra;                                                 \
+END_FTR_SECTION_NESTED(ftr,ftr,943)
+
 /*
  * Save a register to the PACA if the CPU has the given feature
  */
index d8b600b3f058bda7e0358931b885b8c5d4f30215..5dbbb29f5c3e554632dd4d361a96fd4a6051a012 100644 (file)
 /* Platform specific hcalls, used by KVM */
 #define H_RTAS                 0xf000
 
+/* "Platform specific hcalls", provided by PHYP */
+#define H_GET_24X7_CATALOG_PAGE        0xF078
+#define H_GET_24X7_DATA                0xF07C
+#define H_GET_PERF_COUNTER_INFO        0xF080
+
 #ifndef __ASSEMBLY__
 
 /**
index 3a79f53257125a4daf05e5546893eb8821606c3d..e5f048bbcb7c43569a0b0d9e8155b1f2732d4839 100644 (file)
  *   *(r8 + GPR11) = saved r11
  *
  * 64-bit host
- * Expected inputs (GEN/GDBELL/DBG/MC exception types):
+ * Expected inputs (GEN/GDBELL/DBG/CRIT/MC exception types):
  *  r10 = saved CR
  *  r13 = PACA_POINTER
  *  *(r13 + PACA_EX##type + EX_R10) = saved r10
  *  *(r13 + PACA_EX##type + EX_R11) = saved r11
  *  SPRN_SPRG_##type##_SCRATCH = saved r13
- *
-  * Expected inputs (CRIT exception type):
- *  r10 = saved CR
- *  r13 = PACA_POINTER
- *  *(r13 + PACA_EX##type + EX_R10) = saved r10
- *  *(r13 + PACA_EX##type + EX_R11) = saved r11
- *  *(r13 + PACA_EX##type + EX_R13) = saved r13
  *
  * Expected inputs (TLB exception type):
  *  r10 = saved CR
+ *  r12 = extlb pointer
  *  r13 = PACA_POINTER
- *  *(r13 + PACA_EX##type + EX_TLB_R10) = saved r10
- *  *(r13 + PACA_EX##type + EX_TLB_R11) = saved r11
- *  SPRN_SPRG_GEN_SCRATCH = saved r13
+ *  *(r12 + EX_TLB_R10) = saved r10
+ *  *(r12 + EX_TLB_R11) = saved r11
+ *  *(r12 + EX_TLB_R13) = saved r13
+ *  SPRN_SPRG_GEN_SCRATCH = saved r12
  *
  * Only the bolted version of TLB miss exception handlers is supported now.
  */
index ad3025d0880b1c709d073e9d42f55a71a9a8159a..5b6c03f1058f21c24a6402d05b8c19d6cd884983 100644 (file)
@@ -170,6 +170,9 @@ struct machdep_calls {
        int             (*system_reset_exception)(struct pt_regs *regs);
        int             (*machine_check_exception)(struct pt_regs *regs);
 
+       /* Called during machine check exception to retrive fixup address. */
+       bool            (*mce_check_early_recovery)(struct pt_regs *regs);
+
        /* Motherboard/chipset features. This is a kind of general purpose
         * hook used to control some machine specific features (like reset
         * lines, chip power control, etc...).
@@ -279,6 +282,10 @@ struct machdep_calls {
 #ifdef CONFIG_ARCH_RANDOM
        int (*get_random_long)(unsigned long *v);
 #endif
+
+#ifdef CONFIG_MEMORY_HOTREMOVE
+       int (*remove_memory)(u64, u64);
+#endif
 };
 
 extern void e500_idle(void);
index 8e99edf6d966d8129a7c1e3feef84334fba2b250..f97d8cb6bdf64fd8e147035d659b71016c33ecd0 100644 (file)
@@ -187,7 +187,8 @@ struct mce_error_info {
 #define MCE_EVENT_DONTRELEASE  false
 
 extern void save_mce_event(struct pt_regs *regs, long handled,
-                          struct mce_error_info *mce_err, uint64_t addr);
+                          struct mce_error_info *mce_err, uint64_t nip,
+                          uint64_t addr);
 extern int get_mce_event(struct machine_check_event *mce, bool release);
 extern void release_mce_event(void);
 extern void machine_check_queue_event(void);
index 89b785d1684673d0e00b7a75c132a345547f2e33..901dac6b6cb7f6bb6299c14b82158d5fc5cbcc39 100644 (file)
@@ -287,11 +287,14 @@ extern int mmu_linear_psize;
 extern int mmu_vmemmap_psize;
 
 struct tlb_core_data {
+       /*
+        * Per-core spinlock for e6500 TLB handlers (no tlbsrx.)
+        * Must be the first struct element.
+        */
+       u8 lock;
+
        /* For software way selection, as on Freescale TLB1 */
        u8 esel_next, esel_max, esel_first;
-
-       /* Per-core spinlock for e6500 TLB handlers (no tlbsrx.) */
-       u8 lock;
 };
 
 #ifdef CONFIG_PPC64
index ed82142a325111ca18ecbc5ad05ec5760cb03a87..ffafab037ba860b5eaada654528a8bb9332ee338 100644 (file)
@@ -83,6 +83,8 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_INTERNAL_ERROR    -11
 #define OPAL_BUSY_EVENT                -12
 #define OPAL_HARDWARE_FROZEN   -13
+#define OPAL_WRONG_STATE       -14
+#define OPAL_ASYNC_COMPLETION  -15
 
 /* API Tokens (in r0) */
 #define OPAL_CONSOLE_WRITE                     1
@@ -151,12 +153,26 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_LPC_READ                          67
 #define OPAL_LPC_WRITE                         68
 #define OPAL_RETURN_CPU                                69
+#define OPAL_ELOG_READ                         71
+#define OPAL_ELOG_WRITE                                72
+#define OPAL_ELOG_ACK                          73
+#define OPAL_ELOG_RESEND                       74
+#define OPAL_ELOG_SIZE                         75
 #define OPAL_FLASH_VALIDATE                    76
 #define OPAL_FLASH_MANAGE                      77
 #define OPAL_FLASH_UPDATE                      78
+#define OPAL_DUMP_INIT                         81
+#define OPAL_DUMP_INFO                         82
+#define OPAL_DUMP_READ                         83
+#define OPAL_DUMP_ACK                          84
 #define OPAL_GET_MSG                           85
 #define OPAL_CHECK_ASYNC_COMPLETION            86
 #define OPAL_SYNC_HOST_REBOOT                  87
+#define OPAL_SENSOR_READ                       88
+#define OPAL_GET_PARAM                         89
+#define OPAL_SET_PARAM                         90
+#define OPAL_DUMP_RESEND                       91
+#define OPAL_DUMP_INFO2                                94
 
 #ifndef __ASSEMBLY__
 
@@ -237,11 +253,14 @@ enum OpalPendingState {
        OPAL_EVENT_EPOW                 = 0x80,
        OPAL_EVENT_LED_STATUS           = 0x100,
        OPAL_EVENT_PCI_ERROR            = 0x200,
+       OPAL_EVENT_DUMP_AVAIL           = 0x400,
        OPAL_EVENT_MSG_PENDING          = 0x800,
 };
 
 enum OpalMessageType {
-       OPAL_MSG_ASYNC_COMP             = 0,
+       OPAL_MSG_ASYNC_COMP = 0,        /* params[0] = token, params[1] = rc,
+                                        * additional params function-specific
+                                        */
        OPAL_MSG_MEM_ERR,
        OPAL_MSG_EPOW,
        OPAL_MSG_SHUTDOWN,
@@ -394,6 +413,13 @@ enum OpalLPCAddressType {
        OPAL_LPC_FW     = 2,
 };
 
+/* System parameter permission */
+enum OpalSysparamPerm {
+       OPAL_SYSPARAM_READ      = 0x1,
+       OPAL_SYSPARAM_WRITE     = 0x2,
+       OPAL_SYSPARAM_RW        = (OPAL_SYSPARAM_READ | OPAL_SYSPARAM_WRITE),
+};
+
 struct opal_msg {
        uint32_t msg_type;
        uint32_t reserved;
@@ -823,16 +849,37 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
                       uint32_t addr, uint32_t data, uint32_t sz);
 int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
                      uint32_t addr, __be32 *data, uint32_t sz);
+
+int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id);
+int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type);
+int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
+int64_t opal_send_ack_elog(uint64_t log_id);
+void opal_resend_pending_logs(void);
+
 int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
 int64_t opal_manage_flash(uint8_t op);
 int64_t opal_update_flash(uint64_t blk_list);
+int64_t opal_dump_init(uint8_t dump_type);
+int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
+int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
+int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
+int64_t opal_dump_ack(uint32_t dump_id);
+int64_t opal_dump_resend_notification(void);
 
 int64_t opal_get_msg(uint64_t buffer, size_t size);
 int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
 int64_t opal_sync_host_reboot(void);
+int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
+               size_t length);
+int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
+               size_t length);
+int64_t opal_sensor_read(uint32_t sensor_hndl, int token,
+               uint32_t *sensor_data);
 
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
+extern int early_init_dt_scan_recoverable_ranges(unsigned long node,
+                                const char *uname, int depth, void *data);
 
 extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
 extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
@@ -853,6 +900,13 @@ extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val);
 extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
 extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
 
+extern int __opal_async_get_token(void);
+extern int opal_async_get_token_interruptible(void);
+extern int __opal_async_release_token(int token);
+extern int opal_async_release_token(int token);
+extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg);
+extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
+
 extern void hvc_opal_init_early(void);
 
 struct rtc_time;
@@ -861,8 +915,12 @@ extern void opal_get_rtc_time(struct rtc_time *tm);
 extern unsigned long opal_get_boot_time(void);
 extern void opal_nvram_init(void);
 extern void opal_flash_init(void);
+extern int opal_elog_init(void);
+extern void opal_platform_dump_init(void);
+extern void opal_sys_param_init(void);
 
 extern int opal_machine_check(struct pt_regs *regs);
+extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
 
 extern void opal_shutdown(void);
 
index 9c5dbc3833fbc65976ba17e60eec04f234f8e631..8e956a0b6e85ac4474b71373fee731bc7f5d6044 100644 (file)
@@ -116,8 +116,11 @@ struct paca_struct {
        /* Shared by all threads of a core -- points to tcd of first thread */
        struct tlb_core_data *tcd_ptr;
 
-       /* We can have up to 3 levels of reentrancy in the TLB miss handler */
-       u64 extlb[3][EX_TLB_SIZE / sizeof(u64)];
+       /*
+        * We can have up to 3 levels of reentrancy in the TLB miss handler,
+        * in each of four exception levels (normal, crit, mcheck, debug).
+        */
+       u64 extlb[12][EX_TLB_SIZE / sizeof(u64)];
        u64 exmc[8];            /* used for machine checks */
        u64 excrit[8];          /* used for crit interrupts */
        u64 exdbg[8];           /* used for debug interrupts */
@@ -146,7 +149,7 @@ struct paca_struct {
        u8 io_sync;                     /* writel() needs spin_unlock sync */
        u8 irq_work_pending;            /* IRQ_WORK interrupt while soft-disable */
        u8 nap_state_lost;              /* NV GPR values lost in power7_idle */
-       u64 sprg3;                      /* Saved user-visible sprg */
+       u64 sprg_vdso;                  /* Saved user-visible sprg */
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        u64 tm_scratch;                 /* TM scratch area for reclaim */
 #endif
index 3fd2f1b6f90617cf76b9e842e1093bc0db8d70ef..9ed737146dbb3cf5f2253697cbdc96ab8fb07077 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/device.h>
 #include <uapi/asm/perf_event.h>
 
+/* Update perf_event_print_debug() if this changes */
 #define MAX_HWEVENTS           8
 #define MAX_EVENT_ALTERNATIVES 8
 #define MAX_LIMITED_HWCOUNTERS 2
index 90c06ec6eff51d9863db7be38ea3c748f2c98e38..1a36b8ede41736f91b305eeb3b1f3c1ac225abcd 100644 (file)
 #define SPRN_SPRG3     0x113   /* Special Purpose Register General 3 */
 #define SPRN_USPRG3    0x103   /* SPRG3 userspace read */
 #define SPRN_SPRG4     0x114   /* Special Purpose Register General 4 */
+#define SPRN_USPRG4    0x104   /* SPRG4 userspace read */
 #define SPRN_SPRG5     0x115   /* Special Purpose Register General 5 */
+#define SPRN_USPRG5    0x105   /* SPRG5 userspace read */
 #define SPRN_SPRG6     0x116   /* Special Purpose Register General 6 */
+#define SPRN_USPRG6    0x106   /* SPRG6 userspace read */
 #define SPRN_SPRG7     0x117   /* Special Purpose Register General 7 */
+#define SPRN_USPRG7    0x107   /* SPRG7 userspace read */
 #define SPRN_SRR0      0x01A   /* Save/Restore Register 0 */
 #define SPRN_SRR1      0x01B   /* Save/Restore Register 1 */
 #define   SRR1_ISI_NOPT                0x40000000 /* ISI: Not found in hash */
 #define   MMCR0_PMXE   0x04000000UL /* performance monitor exception enable */
 #define   MMCR0_FCECE  0x02000000UL /* freeze ctrs on enabled cond or event */
 #define   MMCR0_TBEE   0x00400000UL /* time base exception enable */
+#define   MMCR0_BHRBA  0x00200000UL /* BHRB Access allowed in userspace */
 #define   MMCR0_EBE    0x00100000UL /* Event based branch enable */
 #define   MMCR0_PMCC   0x000c0000UL /* PMC control */
 #define   MMCR0_PMCC_U6        0x00080000UL /* PMC1-6 are R/W by user (PR) */
 #define   MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
 #define   MMCR0_PMCjCE 0x00004000UL /* PMCj count enable*/
 #define   MMCR0_TRIGGER        0x00002000UL /* TRIGGER enable */
+#define   MMCR0_PMAO_SYNC 0x00000800UL /* PMU interrupt is synchronous */
 #define   MMCR0_PMAO   0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
 #define   MMCR0_SHRFC  0x00000040UL /* SHRre freeze conditions between threads */
 #define   MMCR0_FC56   0x00000010UL /* freeze counters 5 and 6 */
 #define SPRN_EBBHR     804     /* Event based branch handler register */
 #define SPRN_EBBRR     805     /* Event based branch return register */
 #define SPRN_BESCR     806     /* Branch event status and control register */
+#define   BESCR_GE     0x8000000000000000ULL /* Global Enable */
 #define SPRN_WORT      895     /* Workload optimization register - thread */
 
 #define SPRN_PMC1      787
  * 64-bit embedded
  *     - SPRG0 generic exception scratch
  *     - SPRG2 TLB exception stack
- *     - SPRG3 critical exception scratch and
- *        CPU and NUMA node for VDSO getcpu (user visible)
+ *     - SPRG3 critical exception scratch (user visible, sorry!)
  *     - SPRG4 unused (user visible)
  *     - SPRG6 TLB miss scratch (user visible, sorry !)
- *     - SPRG7 critical exception scratch
+ *     - SPRG7 CPU and NUMA node for VDSO getcpu (user visible)
  *     - SPRG8 machine check exception scratch
  *     - SPRG9 debug exception scratch
  *
 #define SPRN_SPRG_SCRATCH0     SPRN_SPRG2
 #define SPRN_SPRG_HPACA                SPRN_HSPRG0
 #define SPRN_SPRG_HSCRATCH0    SPRN_HSPRG1
+#define SPRN_SPRG_VDSO_READ    SPRN_USPRG3
+#define SPRN_SPRG_VDSO_WRITE   SPRN_SPRG3
 
 #define GET_PACA(rX)                                   \
        BEGIN_FTR_SECTION_NESTED(66);                   \
 #define SPRN_SPRG_TLB_SCRATCH  SPRN_SPRG6
 #define SPRN_SPRG_GEN_SCRATCH  SPRN_SPRG0
 #define SPRN_SPRG_GDBELL_SCRATCH SPRN_SPRG_GEN_SCRATCH
+#define SPRN_SPRG_VDSO_READ    SPRN_USPRG7
+#define SPRN_SPRG_VDSO_WRITE   SPRN_SPRG7
 
 #define SET_PACA(rX)   mtspr   SPRN_SPRG_PACA,rX
 #define GET_PACA(rX)   mfspr   rX,SPRN_SPRG_PACA
 #define PVR_8560       0x80200000
 #define PVR_VER_E500V1 0x8020
 #define PVR_VER_E500V2 0x8021
+#define PVR_VER_E500MC 0x8023
+#define PVR_VER_E5500  0x8024
 #define PVR_VER_E6500  0x8040
 
 /*
index 9bd52c65e66f9800734b70fdf9f3d6b649c992ba..a0e1add01ef5804d00d105c5d3ba12e608be5f03 100644 (file)
@@ -283,6 +283,7 @@ extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
 
 #ifdef CONFIG_PPC_PSERIES
 extern int pseries_devicetree_update(s32 scope);
+extern void post_mobility_fixup(void);
 #endif
 
 #ifdef CONFIG_PPC_RTAS_DAEMON
index b5aacf72ae6f5db492a374c93ad2b505558e81c5..dba8140ebc20b8d425bafabe5a0edf57bea2e1bb 100644 (file)
@@ -253,7 +253,7 @@ int main(void)
        DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
        DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
        DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
-       DEFINE(PACA_SPRG3, offsetof(struct paca_struct, sprg3));
+       DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
 #endif /* CONFIG_PPC64 */
 
        /* RTAS */
index 2912b8787aa46b4b28b0e84a2e5c068afc2f5ea2..40198d50b4c24adb55da6db482d65098427b86b7 100644 (file)
@@ -756,7 +756,10 @@ void cacheinfo_cpu_online(unsigned int cpu_id)
        cacheinfo_sysfs_populate(cpu_id, cache);
 }
 
-#ifdef CONFIG_HOTPLUG_CPU /* functions needed for cpu offline */
+/* functions needed to remove cache entry for cpu offline or suspend/resume */
+
+#if (defined(CONFIG_PPC_PSERIES) && defined(CONFIG_SUSPEND)) || \
+    defined(CONFIG_HOTPLUG_CPU)
 
 static struct cache *cache_lookup_by_cpu(unsigned int cpu_id)
 {
@@ -843,4 +846,4 @@ void cacheinfo_cpu_offline(unsigned int cpu_id)
        if (cache)
                cache_cpu_clear(cache, cpu_id);
 }
-#endif /* CONFIG_HOTPLUG_CPU */
+#endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */
index 6c8dd5da4de5ea0b8b88196b773d2e39fca1c732..c1faade6506dd581e3baf2aebfd93c7972fbd6dc 100644 (file)
@@ -510,7 +510,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x004b0000,
                .cpu_name               = "POWER8E (raw)",
-               .cpu_features           = CPU_FTRS_POWER8,
+               .cpu_features           = CPU_FTRS_POWER8E,
                .cpu_user_features      = COMMON_USER_POWER8,
                .cpu_user_features2     = COMMON_USER2_POWER8,
                .mmu_features           = MMU_FTRS_POWER8,
index 063b65dd4f27a256106d34da4fda70c17859752f..c1bee3ce9d1fb63530bb886b04e456275279f050 100644 (file)
  *     special interrupts from within a non-standard level will probably
  *     blow you up
  */
-#define        SPECIAL_EXC_FRAME_SIZE  INT_FRAME_SIZE
+#define SPECIAL_EXC_SRR0       0
+#define SPECIAL_EXC_SRR1       1
+#define SPECIAL_EXC_SPRG_GEN   2
+#define SPECIAL_EXC_SPRG_TLB   3
+#define SPECIAL_EXC_MAS0       4
+#define SPECIAL_EXC_MAS1       5
+#define SPECIAL_EXC_MAS2       6
+#define SPECIAL_EXC_MAS3       7
+#define SPECIAL_EXC_MAS6       8
+#define SPECIAL_EXC_MAS7       9
+#define SPECIAL_EXC_MAS5       10      /* E.HV only */
+#define SPECIAL_EXC_MAS8       11      /* E.HV only */
+#define SPECIAL_EXC_IRQHAPPENED        12
+#define SPECIAL_EXC_DEAR       13
+#define SPECIAL_EXC_ESR                14
+#define SPECIAL_EXC_SOFTE      15
+#define SPECIAL_EXC_CSRR0      16
+#define SPECIAL_EXC_CSRR1      17
+/* must be even to keep 16-byte stack alignment */
+#define SPECIAL_EXC_END                18
+
+#define SPECIAL_EXC_FRAME_SIZE (INT_FRAME_SIZE + SPECIAL_EXC_END * 8)
+#define SPECIAL_EXC_FRAME_OFFS  (INT_FRAME_SIZE - 288)
+
+#define SPECIAL_EXC_STORE(reg, name) \
+       std     reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
+
+#define SPECIAL_EXC_LOAD(reg, name) \
+       ld      reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
+
+special_reg_save:
+       lbz     r9,PACAIRQHAPPENED(r13)
+       RECONCILE_IRQ_STATE(r3,r4)
+
+       /*
+        * We only need (or have stack space) to save this stuff if
+        * we interrupted the kernel.
+        */
+       ld      r3,_MSR(r1)
+       andi.   r3,r3,MSR_PR
+       bnelr
+
+       /* Copy info into temporary exception thread info */
+       ld      r11,PACAKSAVE(r13)
+       CURRENT_THREAD_INFO(r11, r11)
+       CURRENT_THREAD_INFO(r12, r1)
+       ld      r10,TI_FLAGS(r11)
+       std     r10,TI_FLAGS(r12)
+       ld      r10,TI_PREEMPT(r11)
+       std     r10,TI_PREEMPT(r12)
+       ld      r10,TI_TASK(r11)
+       std     r10,TI_TASK(r12)
+
+       /*
+        * Advance to the next TLB exception frame for handler
+        * types that don't do it automatically.
+        */
+       LOAD_REG_ADDR(r11,extlb_level_exc)
+       lwz     r12,0(r11)
+       mfspr   r10,SPRN_SPRG_TLB_EXFRAME
+       add     r10,r10,r12
+       mtspr   SPRN_SPRG_TLB_EXFRAME,r10
+
+       /*
+        * Save registers needed to allow nesting of certain exceptions
+        * (such as TLB misses) inside special exception levels
+        */
+       mfspr   r10,SPRN_SRR0
+       SPECIAL_EXC_STORE(r10,SRR0)
+       mfspr   r10,SPRN_SRR1
+       SPECIAL_EXC_STORE(r10,SRR1)
+       mfspr   r10,SPRN_SPRG_GEN_SCRATCH
+       SPECIAL_EXC_STORE(r10,SPRG_GEN)
+       mfspr   r10,SPRN_SPRG_TLB_SCRATCH
+       SPECIAL_EXC_STORE(r10,SPRG_TLB)
+       mfspr   r10,SPRN_MAS0
+       SPECIAL_EXC_STORE(r10,MAS0)
+       mfspr   r10,SPRN_MAS1
+       SPECIAL_EXC_STORE(r10,MAS1)
+       mfspr   r10,SPRN_MAS2
+       SPECIAL_EXC_STORE(r10,MAS2)
+       mfspr   r10,SPRN_MAS3
+       SPECIAL_EXC_STORE(r10,MAS3)
+       mfspr   r10,SPRN_MAS6
+       SPECIAL_EXC_STORE(r10,MAS6)
+       mfspr   r10,SPRN_MAS7
+       SPECIAL_EXC_STORE(r10,MAS7)
+BEGIN_FTR_SECTION
+       mfspr   r10,SPRN_MAS5
+       SPECIAL_EXC_STORE(r10,MAS5)
+       mfspr   r10,SPRN_MAS8
+       SPECIAL_EXC_STORE(r10,MAS8)
+
+       /* MAS5/8 could have inappropriate values if we interrupted KVM code */
+       li      r10,0
+       mtspr   SPRN_MAS5,r10
+       mtspr   SPRN_MAS8,r10
+END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
+       SPECIAL_EXC_STORE(r9,IRQHAPPENED)
+
+       mfspr   r10,SPRN_DEAR
+       SPECIAL_EXC_STORE(r10,DEAR)
+       mfspr   r10,SPRN_ESR
+       SPECIAL_EXC_STORE(r10,ESR)
+
+       lbz     r10,PACASOFTIRQEN(r13)
+       SPECIAL_EXC_STORE(r10,SOFTE)
+       ld      r10,_NIP(r1)
+       SPECIAL_EXC_STORE(r10,CSRR0)
+       ld      r10,_MSR(r1)
+       SPECIAL_EXC_STORE(r10,CSRR1)
+
+       blr
+
+ret_from_level_except:
+       ld      r3,_MSR(r1)
+       andi.   r3,r3,MSR_PR
+       beq     1f
+       b       ret_from_except
+1:
+
+       LOAD_REG_ADDR(r11,extlb_level_exc)
+       lwz     r12,0(r11)
+       mfspr   r10,SPRN_SPRG_TLB_EXFRAME
+       sub     r10,r10,r12
+       mtspr   SPRN_SPRG_TLB_EXFRAME,r10
+
+       /*
+        * It's possible that the special level exception interrupted a
+        * TLB miss handler, and inserted the same entry that the
+        * interrupted handler was about to insert.  On CPUs without TLB
+        * write conditional, this can result in a duplicate TLB entry.
+        * Wipe all non-bolted entries to be safe.
+        *
+        * Note that this doesn't protect against any TLB misses
+        * we may take accessing the stack from here to the end of
+        * the special level exception.  It's not clear how we can
+        * reasonably protect against that, but only CPUs with
+        * neither TLB write conditional nor bolted kernel memory
+        * are affected.  Do any such CPUs even exist?
+        */
+       PPC_TLBILX_ALL(0,R0)
+
+       REST_NVGPRS(r1)
+
+       SPECIAL_EXC_LOAD(r10,SRR0)
+       mtspr   SPRN_SRR0,r10
+       SPECIAL_EXC_LOAD(r10,SRR1)
+       mtspr   SPRN_SRR1,r10
+       SPECIAL_EXC_LOAD(r10,SPRG_GEN)
+       mtspr   SPRN_SPRG_GEN_SCRATCH,r10
+       SPECIAL_EXC_LOAD(r10,SPRG_TLB)
+       mtspr   SPRN_SPRG_TLB_SCRATCH,r10
+       SPECIAL_EXC_LOAD(r10,MAS0)
+       mtspr   SPRN_MAS0,r10
+       SPECIAL_EXC_LOAD(r10,MAS1)
+       mtspr   SPRN_MAS1,r10
+       SPECIAL_EXC_LOAD(r10,MAS2)
+       mtspr   SPRN_MAS2,r10
+       SPECIAL_EXC_LOAD(r10,MAS3)
+       mtspr   SPRN_MAS3,r10
+       SPECIAL_EXC_LOAD(r10,MAS6)
+       mtspr   SPRN_MAS6,r10
+       SPECIAL_EXC_LOAD(r10,MAS7)
+       mtspr   SPRN_MAS7,r10
+BEGIN_FTR_SECTION
+       SPECIAL_EXC_LOAD(r10,MAS5)
+       mtspr   SPRN_MAS5,r10
+       SPECIAL_EXC_LOAD(r10,MAS8)
+       mtspr   SPRN_MAS8,r10
+END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
+
+       lbz     r6,PACASOFTIRQEN(r13)
+       ld      r5,SOFTE(r1)
+
+       /* Interrupts had better not already be enabled... */
+       twnei   r6,0
+
+       cmpwi   cr0,r5,0
+       beq     1f
+
+       TRACE_ENABLE_INTS
+       stb     r5,PACASOFTIRQEN(r13)
+1:
+       /*
+        * Restore PACAIRQHAPPENED rather than setting it based on
+        * the return MSR[EE], since we could have interrupted
+        * __check_irq_replay() or other inconsistent transitory
+        * states that must remain that way.
+        */
+       SPECIAL_EXC_LOAD(r10,IRQHAPPENED)
+       stb     r10,PACAIRQHAPPENED(r13)
+
+       SPECIAL_EXC_LOAD(r10,DEAR)
+       mtspr   SPRN_DEAR,r10
+       SPECIAL_EXC_LOAD(r10,ESR)
+       mtspr   SPRN_ESR,r10
+
+       stdcx.  r0,0,r1         /* to clear the reservation */
+
+       REST_4GPRS(2, r1)
+       REST_4GPRS(6, r1)
+
+       ld      r10,_CTR(r1)
+       ld      r11,_XER(r1)
+       mtctr   r10
+       mtxer   r11
+
+       blr
+
+.macro ret_from_level srr0 srr1 paca_ex scratch
+       bl      ret_from_level_except
+
+       ld      r10,_LINK(r1)
+       ld      r11,_CCR(r1)
+       ld      r0,GPR13(r1)
+       mtlr    r10
+       mtcr    r11
+
+       ld      r10,GPR10(r1)
+       ld      r11,GPR11(r1)
+       ld      r12,GPR12(r1)
+       mtspr   \scratch,r0
+
+       std     r10,\paca_ex+EX_R10(r13);
+       std     r11,\paca_ex+EX_R11(r13);
+       ld      r10,_NIP(r1)
+       ld      r11,_MSR(r1)
+       ld      r0,GPR0(r1)
+       ld      r1,GPR1(r1)
+       mtspr   \srr0,r10
+       mtspr   \srr1,r11
+       ld      r10,\paca_ex+EX_R10(r13)
+       ld      r11,\paca_ex+EX_R11(r13)
+       mfspr   r13,\scratch
+.endm
+
+ret_from_crit_except:
+       ret_from_level SPRN_CSRR0 SPRN_CSRR1 PACA_EXCRIT SPRN_SPRG_CRIT_SCRATCH
+       rfci
+
+ret_from_mc_except:
+       ret_from_level SPRN_MCSRR0 SPRN_MCSRR1 PACA_EXMC SPRN_SPRG_MC_SCRATCH
+       rfmci
 
 /* Exception prolog code for all exceptions */
 #define EXCEPTION_PROLOG(n, intnum, type, addition)                        \
        mfspr   r13,SPRN_SPRG_PACA;     /* get PACA */                      \
        std     r10,PACA_EX##type+EX_R10(r13);                              \
        std     r11,PACA_EX##type+EX_R11(r13);                              \
-       PROLOG_STORE_RESTORE_SCRATCH_##type;                                \
        mfcr    r10;                    /* save CR */                       \
        mfspr   r11,SPRN_##type##_SRR1;/* what are we coming from */        \
        DO_KVM  intnum,SPRN_##type##_SRR1;    /* KVM hook */                \
 
 #define CRIT_SET_KSTACK                                                            \
        ld      r1,PACA_CRIT_STACK(r13);                                    \
-       subi    r1,r1,SPECIAL_EXC_FRAME_SIZE;
+       subi    r1,r1,SPECIAL_EXC_FRAME_SIZE
 #define SPRN_CRIT_SRR0 SPRN_CSRR0
 #define SPRN_CRIT_SRR1 SPRN_CSRR1
 
 #define DBG_SET_KSTACK                                                     \
        ld      r1,PACA_DBG_STACK(r13);                                     \
-       subi    r1,r1,SPECIAL_EXC_FRAME_SIZE;
+       subi    r1,r1,SPECIAL_EXC_FRAME_SIZE
 #define SPRN_DBG_SRR0  SPRN_DSRR0
 #define SPRN_DBG_SRR1  SPRN_DSRR1
 
 #define MC_SET_KSTACK                                                      \
        ld      r1,PACA_MC_STACK(r13);                                      \
-       subi    r1,r1,SPECIAL_EXC_FRAME_SIZE;
+       subi    r1,r1,SPECIAL_EXC_FRAME_SIZE
 #define SPRN_MC_SRR0   SPRN_MCSRR0
 #define SPRN_MC_SRR1   SPRN_MCSRR1
 
 #define GDBELL_EXCEPTION_PROLOG(n, intnum, addition)                       \
        EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
 
-/*
- * Store user-visible scratch in PACA exception slots and restore proper value
- */
-#define PROLOG_STORE_RESTORE_SCRATCH_GEN
-#define PROLOG_STORE_RESTORE_SCRATCH_GDBELL
-#define PROLOG_STORE_RESTORE_SCRATCH_DBG
-#define PROLOG_STORE_RESTORE_SCRATCH_MC
-
-#define PROLOG_STORE_RESTORE_SCRATCH_CRIT                                  \
-       mfspr   r10,SPRN_SPRG_CRIT_SCRATCH;     /* get r13 */               \
-       std     r10,PACA_EXCRIT+EX_R13(r13);                                \
-       ld      r11,PACA_SPRG3(r13);                                        \
-       mtspr   SPRN_SPRG_CRIT_SCRATCH,r11;
-
 /* Variants of the "addition" argument for the prolog
  */
 #define PROLOG_ADDITION_NONE_GEN(n)
        std     r15,PACA_EXMC+EX_R15(r13)
 
 
-/* Core exception code for all exceptions except TLB misses.
- * XXX: Needs to make SPRN_SPRG_GEN depend on exception type
- */
-#define EXCEPTION_COMMON(n, excf, ints)                                            \
+/* Core exception code for all exceptions except TLB misses. */
+#define EXCEPTION_COMMON_LVL(n, scratch, excf)                             \
 exc_##n##_common:                                                          \
        std     r0,GPR0(r1);            /* save r0 in stackframe */         \
        std     r2,GPR2(r1);            /* save r2 in stackframe */         \
@@ -163,7 +389,7 @@ exc_##n##_common:                                                       \
        ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */      \
 2:     ld      r3,excf+EX_R10(r13);    /* get back r10 */                  \
        ld      r4,excf+EX_R11(r13);    /* get back r11 */                  \
-       mfspr   r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */                 \
+       mfspr   r5,scratch;             /* get back r13 */                  \
        std     r12,GPR12(r1);          /* save r12 in stackframe */        \
        ld      r2,PACATOC(r13);        /* get kernel TOC into r2 */        \
        mflr    r6;                     /* save LR in stackframe */         \
@@ -187,24 +413,29 @@ exc_##n##_common:                                                     \
        std     r11,SOFTE(r1);          /* and save it to stackframe */     \
        std     r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */       \
        std     r3,_TRAP(r1);           /* set trap number              */  \
-       std     r0,RESULT(r1);          /* clear regs->result */            \
-       ints;
+       std     r0,RESULT(r1);          /* clear regs->result */
 
-/* Variants for the "ints" argument. This one does nothing when we want
- * to keep interrupts in their original state
- */
-#define INTS_KEEP
+#define EXCEPTION_COMMON(n) \
+       EXCEPTION_COMMON_LVL(n, SPRN_SPRG_GEN_SCRATCH, PACA_EXGEN)
+#define EXCEPTION_COMMON_CRIT(n) \
+       EXCEPTION_COMMON_LVL(n, SPRN_SPRG_CRIT_SCRATCH, PACA_EXCRIT)
+#define EXCEPTION_COMMON_MC(n) \
+       EXCEPTION_COMMON_LVL(n, SPRN_SPRG_MC_SCRATCH, PACA_EXMC)
+#define EXCEPTION_COMMON_DBG(n) \
+       EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)
 
-/* This second version is meant for exceptions that don't immediately
- * hard-enable. We set a bit in paca->irq_happened to ensure that
- * a subsequent call to arch_local_irq_restore() will properly
- * hard-enable and avoid the fast-path, and then reconcile irq state.
+/*
+ * This is meant for exceptions that don't immediately hard-enable.  We
+ * set a bit in paca->irq_happened to ensure that a subsequent call to
+ * arch_local_irq_restore() will properly hard-enable and avoid the
+ * fast-path, and then reconcile irq state.
  */
 #define INTS_DISABLE   RECONCILE_IRQ_STATE(r3,r4)
 
-/* This is called by exceptions that used INTS_KEEP (that did not touch
- * irq indicators in the PACA). This will restore MSR:EE to it's previous
- * value
+/*
+ * This is called by exceptions that don't use INTS_DISABLE (that did not
+ * touch irq indicators in the PACA).  This will restore MSR:EE to it's
+ * previous value
  *
  * XXX In the long run, we may want to open-code it in order to separate the
  *     load from the wrtee, thus limiting the latency caused by the dependency
@@ -262,7 +493,8 @@ exc_##n##_bad_stack:                                                            \
 #define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack)          \
        START_EXCEPTION(label);                                         \
        NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
-       EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE)             \
+       EXCEPTION_COMMON(trapnum)                                       \
+       INTS_DISABLE;                                                   \
        ack(r8);                                                        \
        CHECK_NAPPING();                                                \
        addi    r3,r1,STACK_FRAME_OVERHEAD;                             \
@@ -283,8 +515,8 @@ exception_marker:
        .balign 0x1000
        .globl interrupt_base_book3e
 interrupt_base_book3e:                                 /* fake trap */
-       EXCEPTION_STUB(0x000, machine_check)            /* 0x0200 */
-       EXCEPTION_STUB(0x020, critical_input)           /* 0x0580 */
+       EXCEPTION_STUB(0x000, machine_check)
+       EXCEPTION_STUB(0x020, critical_input)           /* 0x0100 */
        EXCEPTION_STUB(0x040, debug_crit)               /* 0x0d00 */
        EXCEPTION_STUB(0x060, data_storage)             /* 0x0300 */
        EXCEPTION_STUB(0x080, instruction_storage)      /* 0x0400 */
@@ -299,8 +531,8 @@ interrupt_base_book3e:                                      /* fake trap */
        EXCEPTION_STUB(0x1a0, watchdog)                 /* 0x09f0 */
        EXCEPTION_STUB(0x1c0, data_tlb_miss)
        EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
-       EXCEPTION_STUB(0x200, altivec_unavailable)      /* 0x0f20 */
-       EXCEPTION_STUB(0x220, altivec_assist)           /* 0x1700 */
+       EXCEPTION_STUB(0x200, altivec_unavailable)
+       EXCEPTION_STUB(0x220, altivec_assist)
        EXCEPTION_STUB(0x260, perfmon)
        EXCEPTION_STUB(0x280, doorbell)
        EXCEPTION_STUB(0x2a0, doorbell_crit)
@@ -317,25 +549,25 @@ interrupt_end_book3e:
        START_EXCEPTION(critical_input);
        CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL,
                              PROLOG_ADDITION_NONE)
-//     EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE)
-//     bl      special_reg_save_crit
-//     CHECK_NAPPING();
-//     addi    r3,r1,STACK_FRAME_OVERHEAD
-//     bl      .critical_exception
-//     b       ret_from_crit_except
-       b       .
+       EXCEPTION_COMMON_CRIT(0x100)
+       bl      .save_nvgprs
+       bl      special_reg_save
+       CHECK_NAPPING();
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unknown_exception
+       b       ret_from_crit_except
 
 /* Machine Check Interrupt */
        START_EXCEPTION(machine_check);
-       MC_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_MACHINE_CHECK,
+       MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK,
                            PROLOG_ADDITION_NONE)
-//     EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE)
-//     bl      special_reg_save_mc
-//     addi    r3,r1,STACK_FRAME_OVERHEAD
-//     CHECK_NAPPING();
-//     bl      .machine_check_exception
-//     b       ret_from_mc_except
-       b       .
+       EXCEPTION_COMMON_MC(0x000)
+       bl      .save_nvgprs
+       bl      special_reg_save
+       CHECK_NAPPING();
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .machine_check_exception
+       b       ret_from_mc_except
 
 /* Data Storage Interrupt */
        START_EXCEPTION(data_storage)
@@ -343,7 +575,8 @@ interrupt_end_book3e:
                                PROLOG_ADDITION_2REGS)
        mfspr   r14,SPRN_DEAR
        mfspr   r15,SPRN_ESR
-       EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_DISABLE)
+       EXCEPTION_COMMON(0x300)
+       INTS_DISABLE
        b       storage_fault_common
 
 /* Instruction Storage Interrupt */
@@ -352,7 +585,8 @@ interrupt_end_book3e:
                                PROLOG_ADDITION_2REGS)
        li      r15,0
        mr      r14,r10
-       EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_DISABLE)
+       EXCEPTION_COMMON(0x400)
+       INTS_DISABLE
        b       storage_fault_common
 
 /* External Input Interrupt */
@@ -365,7 +599,7 @@ interrupt_end_book3e:
                                PROLOG_ADDITION_2REGS)
        mfspr   r14,SPRN_DEAR
        mfspr   r15,SPRN_ESR
-       EXCEPTION_COMMON(0x600, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x600)
        b       alignment_more  /* no room, go out of line */
 
 /* Program Interrupt */
@@ -373,7 +607,8 @@ interrupt_end_book3e:
        NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM,
                                PROLOG_ADDITION_1REG)
        mfspr   r14,SPRN_ESR
-       EXCEPTION_COMMON(0x700, PACA_EXGEN, INTS_DISABLE)
+       EXCEPTION_COMMON(0x700)
+       INTS_DISABLE
        std     r14,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        ld      r14,PACA_EXGEN+EX_R14(r13)
@@ -386,7 +621,7 @@ interrupt_end_book3e:
        NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL,
                                PROLOG_ADDITION_NONE)
        /* we can probably do a shorter exception entry for that one... */
-       EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x800)
        ld      r12,_MSR(r1)
        andi.   r0,r12,MSR_PR;
        beq-    1f
@@ -403,7 +638,7 @@ interrupt_end_book3e:
        NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL,
                                PROLOG_ADDITION_NONE)
        /* we can probably do a shorter exception entry for that one... */
-       EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x200)
 #ifdef CONFIG_ALTIVEC
 BEGIN_FTR_SECTION
        ld      r12,_MSR(r1)
@@ -425,7 +660,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        NORMAL_EXCEPTION_PROLOG(0x220,
                                BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE)
+       EXCEPTION_COMMON(0x220)
+       INTS_DISABLE
        bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_ALTIVEC
@@ -450,13 +686,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        START_EXCEPTION(watchdog);
        CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG,
                              PROLOG_ADDITION_NONE)
-//     EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE)
-//     bl      special_reg_save_crit
-//     CHECK_NAPPING();
-//     addi    r3,r1,STACK_FRAME_OVERHEAD
-//     bl      .unknown_exception
-//     b       ret_from_crit_except
-       b       .
+       EXCEPTION_COMMON_CRIT(0x9f0)
+       bl      .save_nvgprs
+       bl      special_reg_save
+       CHECK_NAPPING();
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+#ifdef CONFIG_BOOKE_WDT
+       bl      .WatchdogException
+#else
+       bl      .unknown_exception
+#endif
+       b       ret_from_crit_except
 
 /* System Call Interrupt */
        START_EXCEPTION(system_call)
@@ -470,7 +710,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        START_EXCEPTION(ap_unavailable);
        NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_DISABLE)
+       EXCEPTION_COMMON(0xf20)
+       INTS_DISABLE
        bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .unknown_exception
@@ -513,7 +754,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        mtcr    r10
        ld      r10,PACA_EXCRIT+EX_R10(r13)     /* restore registers */
        ld      r11,PACA_EXCRIT+EX_R11(r13)
-       ld      r13,PACA_EXCRIT+EX_R13(r13)
+       mfspr   r13,SPRN_SPRG_CRIT_SCRATCH
        rfci
 
        /* Normal debug exception */
@@ -526,10 +767,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
        /* Now we mash up things to make it look like we are coming on a
         * normal exception
         */
-       ld      r15,PACA_EXCRIT+EX_R13(r13)
-       mtspr   SPRN_SPRG_GEN_SCRATCH,r15
        mfspr   r14,SPRN_DBSR
-       EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE)
+       EXCEPTION_COMMON_CRIT(0xd00)
        std     r14,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        mr      r4,r14
@@ -592,10 +831,9 @@ kernel_dbg_exc:
        /* Now we mash up things to make it look like we are coming on a
         * normal exception
         */
-       mfspr   r15,SPRN_SPRG_DBG_SCRATCH
-       mtspr   SPRN_SPRG_GEN_SCRATCH,r15
        mfspr   r14,SPRN_DBSR
-       EXCEPTION_COMMON(0xd08, PACA_EXDBG, INTS_DISABLE)
+       EXCEPTION_COMMON_DBG(0xd08)
+       INTS_DISABLE
        std     r14,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        mr      r4,r14
@@ -608,7 +846,8 @@ kernel_dbg_exc:
        START_EXCEPTION(perfmon);
        NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0x260, PACA_EXGEN, INTS_DISABLE)
+       EXCEPTION_COMMON(0x260)
+       INTS_DISABLE
        CHECK_NAPPING()
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .performance_monitor_exception
@@ -622,13 +861,13 @@ kernel_dbg_exc:
        START_EXCEPTION(doorbell_crit);
        CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL,
                              PROLOG_ADDITION_NONE)
-//     EXCEPTION_COMMON(0x2a0, PACA_EXCRIT, INTS_DISABLE)
-//     bl      special_reg_save_crit
-//     CHECK_NAPPING();
-//     addi    r3,r1,STACK_FRAME_OVERHEAD
-//     bl      .doorbell_critical_exception
-//     b       ret_from_crit_except
-       b       .
+       EXCEPTION_COMMON_CRIT(0x2a0)
+       bl      .save_nvgprs
+       bl      special_reg_save
+       CHECK_NAPPING();
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unknown_exception
+       b       ret_from_crit_except
 
 /*
  *     Guest doorbell interrupt
@@ -637,7 +876,7 @@ kernel_dbg_exc:
        START_EXCEPTION(guest_doorbell);
        GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0x2c0, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x2c0)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .save_nvgprs
        INTS_RESTORE_HARD
@@ -648,19 +887,19 @@ kernel_dbg_exc:
        START_EXCEPTION(guest_doorbell_crit);
        CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT,
                              PROLOG_ADDITION_NONE)
-//     EXCEPTION_COMMON(0x2e0, PACA_EXCRIT, INTS_DISABLE)
-//     bl      special_reg_save_crit
-//     CHECK_NAPPING();
-//     addi    r3,r1,STACK_FRAME_OVERHEAD
-//     bl      .guest_doorbell_critical_exception
-//     b       ret_from_crit_except
-       b       .
+       EXCEPTION_COMMON_CRIT(0x2e0)
+       bl      .save_nvgprs
+       bl      special_reg_save
+       CHECK_NAPPING();
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unknown_exception
+       b       ret_from_crit_except
 
 /* Hypervisor call */
        START_EXCEPTION(hypercall);
        NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0x310, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x310)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .save_nvgprs
        INTS_RESTORE_HARD
@@ -671,7 +910,7 @@ kernel_dbg_exc:
        START_EXCEPTION(ehpriv);
        NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0x320, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x320)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .save_nvgprs
        INTS_RESTORE_HARD
@@ -682,7 +921,7 @@ kernel_dbg_exc:
        START_EXCEPTION(lrat_error);
        NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR,
                                PROLOG_ADDITION_NONE)
-       EXCEPTION_COMMON(0x340, PACA_EXGEN, INTS_KEEP)
+       EXCEPTION_COMMON(0x340)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .save_nvgprs
        INTS_RESTORE_HARD
index 38d507306a111dc40f06028c90d5014e2fedd817..4c34c3c827ad5be65a4f59381c9f485086662fe9 100644 (file)
@@ -164,13 +164,18 @@ BEGIN_FTR_SECTION
         */
        mfspr   r13,SPRN_SRR1
        rlwinm. r13,r13,47-31,30,31
+       OPT_GET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
        beq     9f
 
+       mfspr   r13,SPRN_SRR1
+       rlwinm. r13,r13,47-31,30,31
        /* waking up from powersave (nap) state */
        cmpwi   cr1,r13,2
        /* Total loss of HV state is fatal. let's just stay stuck here */
+       OPT_GET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
        bgt     cr1,.
 9:
+       OPT_SET_SPR(r13, SPRN_CFAR, CPU_FTR_CFAR)
 END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 #endif /* CONFIG_PPC_P7_NAP */
        EXCEPTION_PROLOG_0(PACA_EXMC)
index cadef7e64e4245e816f0878c63ebab43855c15c2..a7fd4cb78b788e01a6545964572a4af44b28bc28 100644 (file)
@@ -70,7 +70,7 @@ static void mce_set_error_info(struct machine_check_event *mce,
  */
 void save_mce_event(struct pt_regs *regs, long handled,
                    struct mce_error_info *mce_err,
-                   uint64_t addr)
+                   uint64_t nip, uint64_t addr)
 {
        uint64_t srr1;
        int index = __get_cpu_var(mce_nest_count)++;
@@ -86,7 +86,7 @@ void save_mce_event(struct pt_regs *regs, long handled,
 
        /* Populate generic machine check info */
        mce->version = MCE_V1;
-       mce->srr0 = regs->nip;
+       mce->srr0 = nip;
        mce->srr1 = regs->msr;
        mce->gpr3 = regs->gpr[3];
        mce->in_use = 1;
index 27c93f41166f4216d5bd473e3e1aa397817c4cdb..aa9aff3d6ad3543fac861e06391fc067e7f91f55 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ptrace.h>
 #include <asm/mmu.h>
 #include <asm/mce.h>
+#include <asm/machdep.h>
 
 /* flush SLBs and reload */
 static void flush_and_reload_slb(void)
@@ -197,13 +198,32 @@ static void mce_get_derror_p7(struct mce_error_info *mce_err, uint64_t dsisr)
        }
 }
 
+static long mce_handle_ue_error(struct pt_regs *regs)
+{
+       long handled = 0;
+
+       /*
+        * On specific SCOM read via MMIO we may get a machine check
+        * exception with SRR0 pointing inside opal. If that is the
+        * case OPAL may have recovery address to re-read SCOM data in
+        * different way and hence we can recover from this MC.
+        */
+
+       if (ppc_md.mce_check_early_recovery) {
+               if (ppc_md.mce_check_early_recovery(regs))
+                       handled = 1;
+       }
+       return handled;
+}
+
 long __machine_check_early_realmode_p7(struct pt_regs *regs)
 {
-       uint64_t srr1, addr;
+       uint64_t srr1, nip, addr;
        long handled = 1;
        struct mce_error_info mce_error_info = { 0 };
 
        srr1 = regs->msr;
+       nip = regs->nip;
 
        /*
         * Handle memory errors depending whether this was a load/store or
@@ -221,7 +241,11 @@ long __machine_check_early_realmode_p7(struct pt_regs *regs)
                addr = regs->nip;
        }
 
-       save_mce_event(regs, handled, &mce_error_info, addr);
+       /* Handle UE error. */
+       if (mce_error_info.error_type == MCE_ERROR_TYPE_UE)
+               handled = mce_handle_ue_error(regs);
+
+       save_mce_event(regs, handled, &mce_error_info, nip, addr);
        return handled;
 }
 
@@ -263,11 +287,12 @@ static long mce_handle_derror_p8(uint64_t dsisr)
 
 long __machine_check_early_realmode_p8(struct pt_regs *regs)
 {
-       uint64_t srr1, addr;
+       uint64_t srr1, nip, addr;
        long handled = 1;
        struct mce_error_info mce_error_info = { 0 };
 
        srr1 = regs->msr;
+       nip = regs->nip;
 
        if (P7_SRR1_MC_LOADSTORE(srr1)) {
                handled = mce_handle_derror_p8(regs->dsisr);
@@ -279,6 +304,10 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs)
                addr = regs->nip;
        }
 
-       save_mce_event(regs, handled, &mce_error_info, addr);
+       /* Handle UE error. */
+       if (mce_error_info.error_type == MCE_ERROR_TYPE_UE)
+               handled = mce_handle_ue_error(regs);
+
+       save_mce_event(regs, handled, &mce_error_info, nip, addr);
        return handled;
 }
index f58c0d3aaeb497697aaa7ed75874ddee33146652..d711b7eb05aa30da72122c02ba3e6b80ef3c8ef8 100644 (file)
@@ -752,6 +752,11 @@ void __init early_init_devtree(void *params)
        spinning_secondaries = boot_cpu_count - 1;
 #endif
 
+#ifdef CONFIG_PPC_POWERNV
+       /* Scan and build the list of machine check recoverable ranges */
+       of_scan_flat_dt(early_init_dt_scan_recoverable_ranges, NULL);
+#endif
+
        DBG(" <- early_init_devtree()\n");
 }
 
index 4cf674d7d5ae184b14c0c4e08985dfe1ad4779a1..f386296ff3785cbf907e9311be50b87a046f45fd 100644 (file)
@@ -1013,12 +1013,13 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log,
        return NULL;
 }
 
+/* We assume to be passed big endian arguments */
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 {
        struct rtas_args args;
        unsigned long flags;
        char *buff_copy, *errbuf = NULL;
-       int nargs;
+       int nargs, nret, token;
        int rc;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -1027,10 +1028,13 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
        if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
                return -EFAULT;
 
-       nargs = args.nargs;
+       nargs = be32_to_cpu(args.nargs);
+       nret  = be32_to_cpu(args.nret);
+       token = be32_to_cpu(args.token);
+
        if (nargs > ARRAY_SIZE(args.args)
-           || args.nret > ARRAY_SIZE(args.args)
-           || nargs + args.nret > ARRAY_SIZE(args.args))
+           || nret > ARRAY_SIZE(args.args)
+           || nargs + nret > ARRAY_SIZE(args.args))
                return -EINVAL;
 
        /* Copy in args. */
@@ -1038,14 +1042,14 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
                           nargs * sizeof(rtas_arg_t)) != 0)
                return -EFAULT;
 
-       if (args.token == RTAS_UNKNOWN_SERVICE)
+       if (token == RTAS_UNKNOWN_SERVICE)
                return -EINVAL;
 
        args.rets = &args.args[nargs];
-       memset(args.rets, 0, args.nret * sizeof(rtas_arg_t));
+       memset(args.rets, 0, nret * sizeof(rtas_arg_t));
 
        /* Need to handle ibm,suspend_me call specially */
-       if (args.token == ibm_suspend_me_token) {
+       if (token == ibm_suspend_me_token) {
                rc = rtas_ibm_suspend_me(&args);
                if (rc)
                        return rc;
@@ -1062,7 +1066,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
 
        /* A -1 return code indicates that the last command couldn't
           be completed due to a hardware error. */
-       if (args.rets[0] == -1)
+       if (be32_to_cpu(args.rets[0]) == -1)
                errbuf = __fetch_rtas_last_error(buff_copy);
 
        unlock_rtas(flags);
@@ -1077,7 +1081,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
        /* Copy out args. */
        if (copy_to_user(uargs->args + nargs,
                         args.args + nargs,
-                        args.nret * sizeof(rtas_arg_t)) != 0)
+                        nret * sizeof(rtas_arg_t)) != 0)
                return -EFAULT;
 
        return 0;
index f5f11a7d30e5502637d58656b7c587b37001ea81..4933909cc5c001045b57f8fffef44c2a42478985 100644 (file)
@@ -102,6 +102,8 @@ static void setup_tlb_core_data(void)
 {
        int cpu;
 
+       BUILD_BUG_ON(offsetof(struct tlb_core_data, lock) != 0);
+
        for_each_possible_cpu(cpu) {
                int first = cpu_first_thread_sibling(cpu);
 
@@ -552,14 +554,20 @@ static void __init irqstack_early_init(void)
 static void __init exc_lvl_early_init(void)
 {
        unsigned int i;
+       unsigned long sp;
 
        for_each_possible_cpu(i) {
-               critirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
-               dbgirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
-               mcheckirq_ctx[i] = (struct thread_info *)
-                       __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+               sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+               critirq_ctx[i] = (struct thread_info *)__va(sp);
+               paca[i].crit_kstack = __va(sp + THREAD_SIZE);
+
+               sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+               dbgirq_ctx[i] = (struct thread_info *)__va(sp);
+               paca[i].dbg_kstack = __va(sp + THREAD_SIZE);
+
+               sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+               mcheckirq_ctx[i] = (struct thread_info *)__va(sp);
+               paca[i].mc_kstack = __va(sp + THREAD_SIZE);
        }
 
        if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC))
index 33cd7a0b8e730b1d22583ab304821a2d1d203cc2..df86f0ce2d360340593548c61e1394a652df3d90 100644 (file)
@@ -1379,8 +1379,9 @@ void facility_unavailable_exception(struct pt_regs *regs)
        if (!arch_irq_disabled_regs(regs))
                local_irq_enable();
 
-       pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n",
-              hv ? "Hypervisor " : "", facility, regs->nip, regs->msr);
+       pr_err_ratelimited(
+               "%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n",
+               hv ? "Hypervisor " : "", facility, regs->nip, regs->msr);
 
        if (user_mode(regs)) {
                _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
index 094e45c16a17032e36e33f3ef1fb5182fb4dd958..ce74c335a6a405b03e8400a72b74e1fc7227b56f 100644 (file)
@@ -715,8 +715,8 @@ int vdso_getcpu_init(void)
        unsigned long cpu, node, val;
 
        /*
-        * SPRG3 contains the CPU in the bottom 16 bits and the NUMA node in
-        * the next 16 bits. The VDSO uses this to implement getcpu().
+        * SPRG_VDSO contains the CPU in the bottom 16 bits and the NUMA node
+        * in the next 16 bits.  The VDSO uses this to implement getcpu().
         */
        cpu = get_cpu();
        WARN_ON_ONCE(cpu > 0xffff);
@@ -725,8 +725,8 @@ int vdso_getcpu_init(void)
        WARN_ON_ONCE(node > 0xffff);
 
        val = (cpu & 0xfff) | ((node & 0xffff) << 16);
-       mtspr(SPRN_SPRG3, val);
-       get_paca()->sprg3 = val;
+       mtspr(SPRN_SPRG_VDSO_WRITE, val);
+       get_paca()->sprg_vdso = val;
 
        put_cpu();
 
index 47afd08c90f7fd3f934beafb9398d106099e7f40..23eb9a9441bdad612481a7d1b2fcf12dd17a7ed3 100644 (file)
@@ -29,7 +29,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_getcpu)
   .cfi_startproc
-       mfspr   r5,SPRN_USPRG3
+       mfspr   r5,SPRN_SPRG_VDSO_READ
        cmpdi   cr0,r3,0
        cmpdi   cr1,r4,0
        clrlwi  r6,r5,16
index 47afd08c90f7fd3f934beafb9398d106099e7f40..23eb9a9441bdad612481a7d1b2fcf12dd17a7ed3 100644 (file)
@@ -29,7 +29,7 @@
  */
 V_FUNCTION_BEGIN(__kernel_getcpu)
   .cfi_startproc
-       mfspr   r5,SPRN_USPRG3
+       mfspr   r5,SPRN_SPRG_VDSO_READ
        cmpdi   cr0,r3,0
        cmpdi   cr1,r4,0
        clrlwi  r6,r5,16
index 826d8bd9e5223d94eccfe3639d980e323c78b189..904c66128faeb7d31a8463532929d187254da7ed 100644 (file)
@@ -1432,7 +1432,8 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
 
                /* needed to ensure proper operation of coherent allocations
                 * later, in case driver doesn't set it explicitly */
-               dma_coerce_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64));
+               viodev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+               viodev->dev.dma_mask = &viodev->dev.coherent_dma_mask;
        }
 
        /* register with generic device framework */
index 818dce344e82a0fa0a94fe7f21eefdb2483fbc68..53d647f8e7413bd9117d860b74b503fff8b136c7 100644 (file)
@@ -75,8 +75,8 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 
        /* Restore SPRG3 */
-       ld      r3,PACA_SPRG3(r13)
-       mtspr   SPRN_SPRG3,r3
+       ld      r3,PACA_SPRG_VDSO(r13)
+       mtspr   SPRN_SPRG_VDSO_WRITE,r3
 
        /* Reload the host's PMU registers */
        ld      r3, PACALPPACAPTR(r13)  /* is the host using the PMU? */
index f779450cb07c728681ede6d566ef85920117337e..3533c999194a3db8d835d570bd7f4d86bb494bbb 100644 (file)
@@ -153,8 +153,8 @@ kvm_start_lightweight:
         * Reload kernel SPRG3 value.
         * No need to save guest value as usermode can't modify SPRG3.
         */
-       ld      r3, PACA_SPRG3(r13)
-       mtspr   SPRN_SPRG3, r3
+       ld      r3, PACA_SPRG_VDSO(r13)
+       mtspr   SPRN_SPRG_VDSO_WRITE, r3
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
        /* R7 = vcpu */
index e4185f6b3309af4cf51d5990f766647c88e9a5a2..a1712b818a5f7ee0d6e9172c035a573ff2343fc9 100644 (file)
        stw     r10, VCPU_CR(r4)
        PPC_STL r11, VCPU_GPR(R4)(r4)
        PPC_STL r5, VCPU_GPR(R5)(r4)
-       .if \type == EX_CRIT
-       PPC_LL  r5, (\paca_ex + EX_R13)(r13)
-       .else
-       mfspr   r5, \scratch
-       .endif
        PPC_STL r6, VCPU_GPR(R6)(r4)
        PPC_STL r8, VCPU_GPR(R8)(r4)
        PPC_STL r9, VCPU_GPR(R9)(r4)
-       PPC_STL r5, VCPU_GPR(R13)(r4)
+       .if \type == EX_TLB
+       PPC_LL  r5, EX_TLB_R13(r12)
+       PPC_LL  r6, EX_TLB_R10(r12)
+       PPC_LL  r8, EX_TLB_R11(r12)
+       mfspr   r12, \scratch
+       .else
+       mfspr   r5, \scratch
        PPC_LL  r6, (\paca_ex + \ex_r10)(r13)
        PPC_LL  r8, (\paca_ex + \ex_r11)(r13)
+       .endif
+       PPC_STL r5, VCPU_GPR(R13)(r4)
        PPC_STL r3, VCPU_GPR(R3)(r4)
        PPC_STL r7, VCPU_GPR(R7)(r4)
        PPC_STL r12, VCPU_GPR(R12)(r4)
@@ -435,10 +438,16 @@ _GLOBAL(kvmppc_resume_host)
        PPC_STL r5, VCPU_LR(r4)
        mfspr   r7, SPRN_SPRG5
        stw     r3, VCPU_VRSAVE(r4)
+#ifdef CONFIG_64BIT
+       PPC_LL  r3, PACA_SPRG_VDSO(r13)
+#endif
        PPC_STD(r6, VCPU_SHARED_SPRG4, r11)
        mfspr   r8, SPRN_SPRG6
        PPC_STD(r7, VCPU_SHARED_SPRG5, r11)
        mfspr   r9, SPRN_SPRG7
+#ifdef CONFIG_64BIT
+       mtspr   SPRN_SPRG_VDSO_WRITE, r3
+#endif
        PPC_STD(r8, VCPU_SHARED_SPRG6, r11)
        mfxer   r3
        PPC_STD(r9, VCPU_SHARED_SPRG7, r11)
index d2bbbc8d7dc0b045aab751d79264a2f4f959fe61..72ad055168a333ed31ebd5c0c014ff00f6c7436a 100644 (file)
@@ -14,7 +14,9 @@ _GLOBAL(memcpy)
 BEGIN_FTR_SECTION
        std     r3,48(r1)       /* save destination pointer for return value */
 FTR_SECTION_ELSE
+#ifndef SELFTEST
        b       memcpy_power7
+#endif
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
        PPC_MTOCRF(0x01,r5)
        cmpldi  cr1,r5,16
index 4b5cd5c2594d9b5ca507bc80751f6d1003fde4d6..2c8e90f5789e4a72feb2e5a019a63a9e1dded518 100644 (file)
@@ -139,9 +139,14 @@ int arch_remove_memory(u64 start, u64 size)
        unsigned long start_pfn = start >> PAGE_SHIFT;
        unsigned long nr_pages = size >> PAGE_SHIFT;
        struct zone *zone;
+       int ret;
 
        zone = page_zone(pfn_to_page(start_pfn));
-       return __remove_pages(zone, start_pfn, nr_pages);
+       ret = __remove_pages(zone, start_pfn, nr_pages);
+       if (!ret && (ppc_md.remove_memory))
+               ret = ppc_md.remove_memory(start, size);
+
+       return ret;
 }
 #endif
 #endif /* CONFIG_MEMORY_HOTPLUG */
index 62bf5e8e78daaaf5051fb6e5727bfd99be81a088..f6ce1f111f5b143fb338274fb90e704013d47648 100644 (file)
@@ -647,6 +647,11 @@ void pmdp_splitting_flush(struct vm_area_struct *vma,
                if (old & _PAGE_HASHPTE)
                        hpte_do_hugepage_flush(vma->vm_mm, address, pmdp);
        }
+       /*
+        * This ensures that generic code that rely on IRQ disabling
+        * to prevent a parallel THP split work as expected.
+        */
+       kick_all_cpus_sync();
 }
 
 /*
index c95eb323e9ae5ac8e07feb28c024127266e405a8..356e8b41fb09d8e41e5fa36391238fbfa4353831 100644 (file)
  *                                                                    *
  **********************************************************************/
 
+/*
+ * Note that, unlike non-bolted handlers, TLB_EXFRAME is not
+ * modified by the TLB miss handlers themselves, since the TLB miss
+ * handler code will not itself cause a recursive TLB miss.
+ *
+ * TLB_EXFRAME will be modified when crit/mc/debug exceptions are
+ * entered/exited.
+ */
 .macro tlb_prolog_bolted intnum addr
-       mtspr   SPRN_SPRG_GEN_SCRATCH,r13
+       mtspr   SPRN_SPRG_GEN_SCRATCH,r12
+       mfspr   r12,SPRN_SPRG_TLB_EXFRAME
+       std     r13,EX_TLB_R13(r12)
+       std     r10,EX_TLB_R10(r12)
        mfspr   r13,SPRN_SPRG_PACA
-       std     r10,PACA_EXTLB+EX_TLB_R10(r13)
+
        mfcr    r10
-       std     r11,PACA_EXTLB+EX_TLB_R11(r13)
+       std     r11,EX_TLB_R11(r12)
 #ifdef CONFIG_KVM_BOOKE_HV
 BEGIN_FTR_SECTION
        mfspr   r11, SPRN_SRR1
 END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 #endif
        DO_KVM  \intnum, SPRN_SRR1
-       std     r16,PACA_EXTLB+EX_TLB_R16(r13)
+       std     r16,EX_TLB_R16(r12)
        mfspr   r16,\addr               /* get faulting address */
-       std     r14,PACA_EXTLB+EX_TLB_R14(r13)
+       std     r14,EX_TLB_R14(r12)
        ld      r14,PACAPGD(r13)
-       std     r15,PACA_EXTLB+EX_TLB_R15(r13)
-       std     r10,PACA_EXTLB+EX_TLB_CR(r13)
-       TLB_MISS_PROLOG_STATS_BOLTED
+       std     r15,EX_TLB_R15(r12)
+       std     r10,EX_TLB_CR(r12)
+       TLB_MISS_PROLOG_STATS
 .endm
 
 .macro tlb_epilog_bolted
-       ld      r14,PACA_EXTLB+EX_TLB_CR(r13)
-       ld      r10,PACA_EXTLB+EX_TLB_R10(r13)
-       ld      r11,PACA_EXTLB+EX_TLB_R11(r13)
+       ld      r14,EX_TLB_CR(r12)
+       ld      r10,EX_TLB_R10(r12)
+       ld      r11,EX_TLB_R11(r12)
+       ld      r13,EX_TLB_R13(r12)
        mtcr    r14
-       ld      r14,PACA_EXTLB+EX_TLB_R14(r13)
-       ld      r15,PACA_EXTLB+EX_TLB_R15(r13)
-       TLB_MISS_RESTORE_STATS_BOLTED
-       ld      r16,PACA_EXTLB+EX_TLB_R16(r13)
-       mfspr   r13,SPRN_SPRG_GEN_SCRATCH
+       ld      r14,EX_TLB_R14(r12)
+       ld      r15,EX_TLB_R15(r12)
+       TLB_MISS_RESTORE_STATS
+       ld      r16,EX_TLB_R16(r12)
+       mfspr   r12,SPRN_SPRG_GEN_SCRATCH
 .endm
 
 /* Data TLB miss */
@@ -284,7 +296,7 @@ itlb_miss_fault_bolted:
  * r14 = page table base
  * r13 = PACA
  * r11 = tlb_per_core ptr
- * r10 = crap (free to use)
+ * r10 = cpu number
  */
 tlb_miss_common_e6500:
        /*
@@ -293,15 +305,18 @@ tlb_miss_common_e6500:
         *
         * MAS6:IND should be already set based on MAS4
         */
-       addi    r10,r11,TCD_LOCK
-1:     lbarx   r15,0,r10
+1:     lbarx   r15,0,r11
+       lhz     r10,PACAPACAINDEX(r13)
        cmpdi   r15,0
+       cmpdi   cr1,r15,1       /* set cr1.eq = 0 for non-recursive */
        bne     2f
-       li      r15,1
-       stbcx.  r15,0,r10
+       stbcx.  r10,0,r11
        bne     1b
+3:
        .subsection 1
-2:     lbz     r15,0(r10)
+2:     cmpd    cr1,r15,r10     /* recursive lock due to mcheck/crit/etc? */
+       beq     cr1,3b          /* unlock will happen if cr1.eq = 0 */
+       lbz     r15,0(r11)
        cmpdi   r15,0
        bne     2b
        b       1b
@@ -379,9 +394,11 @@ tlb_miss_common_e6500:
 
 tlb_miss_done_e6500:
        .macro  tlb_unlock_e6500
+       beq     cr1,1f          /* no unlock if lock was recursively grabbed */
        li      r15,0
        isync
-       stb     r15,TCD_LOCK(r11)
+       stb     r15,0(r11)
+1:
        .endm
 
        tlb_unlock_e6500
@@ -1091,7 +1108,8 @@ tlb_load_linear:
        ld      r11,PACATOC(r13)
        ld      r11,linear_map_top@got(r11)
        ld      r10,0(r11)
-       cmpld   cr0,r10,r16
+       tovirt(10,10)
+       cmpld   cr0,r16,r10
        bge     tlb_load_linear_fault
 
        /* MAS1 need whole new setup. */
index b37a58e1c92da8bfa9092828f6d3a92126da29d9..ae3d5b799b9004f3089176c90a22b4dd8e76c84a 100644 (file)
@@ -144,6 +144,15 @@ int mmu_vmemmap_psize;             /* Page size used for the virtual mem map */
 int book3e_htw_mode;           /* HW tablewalk?  Value is PPC_HTW_* */
 unsigned long linear_map_top;  /* Top of linear mapping */
 
+
+/*
+ * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
+ * exceptions.  This is used for bolted and e6500 TLB miss handlers which
+ * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
+ * this is set to zero.
+ */
+int extlb_level_exc;
+
 #endif /* CONFIG_PPC64 */
 
 #ifdef CONFIG_PPC_FSL_BOOK3E
@@ -559,6 +568,7 @@ static void setup_mmu_htw(void)
                break;
 #ifdef CONFIG_PPC_FSL_BOOK3E
        case PPC_HTW_E6500:
+               extlb_level_exc = EX_TLB_SIZE;
                patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
                patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
                break;
@@ -652,6 +662,7 @@ static void __early_init_mmu(int boot_cpu)
                memblock_enforce_memory_limit(linear_map_top);
 
                if (book3e_htw_mode == PPC_HTW_NONE) {
+                       extlb_level_exc = EX_TLB_SIZE;
                        patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
                        patch_exception(0x1e0,
                                exc_instruction_tlb_miss_bolted_book3e);
index 60d71eea919c7f2e64b8d74e6732e4883fa3f61b..f9c083a5652a4c2a99f6b13778d6f84feed9072e 100644 (file)
@@ -11,5 +11,7 @@ obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
 obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
 obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o
 
+obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o
+
 obj-$(CONFIG_PPC64)            += $(obj64-y)
 obj-$(CONFIG_PPC32)            += $(obj32-y)
index 67cf22083f4c2cfd6175c91ce416efb68ae1a6e6..4520c9356b5473bdf5ae880d214bb4076cee2c3d 100644 (file)
@@ -78,6 +78,7 @@ static unsigned int freeze_events_kernel = MMCR0_FCS;
 #define MMCR0_FC56             0
 #define MMCR0_PMAO             0
 #define MMCR0_EBE              0
+#define MMCR0_BHRBA            0
 #define MMCR0_PMCC             0
 #define MMCR0_PMCC_U6          0
 
@@ -120,6 +121,7 @@ static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
 static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
 void power_pmu_flush_branch_stack(void) {}
 static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
+static void pmao_restore_workaround(bool ebb) { }
 #endif /* CONFIG_PPC32 */
 
 static bool regs_use_siar(struct pt_regs *regs)
@@ -502,8 +504,11 @@ static int ebb_event_check(struct perf_event *event)
                if (!leader->attr.pinned || !leader->attr.exclusive)
                        return -EINVAL;
 
-               if (event->attr.inherit || event->attr.sample_period ||
-                   event->attr.enable_on_exec || event->attr.freq)
+               if (event->attr.freq ||
+                   event->attr.inherit ||
+                   event->attr.sample_type ||
+                   event->attr.sample_period ||
+                   event->attr.enable_on_exec)
                        return -EINVAL;
        }
 
@@ -542,13 +547,21 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
        if (!ebb)
                goto out;
 
-       /* Enable EBB and read/write to all 6 PMCs for userspace */
-       mmcr0 |= MMCR0_EBE | MMCR0_PMCC_U6;
+       /* Enable EBB and read/write to all 6 PMCs and BHRB for userspace */
+       mmcr0 |= MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC_U6;
 
-       /* Add any bits from the user reg, FC or PMAO */
+       /*
+        * Add any bits from the user MMCR0, FC or PMAO. This is compatible
+        * with pmao_restore_workaround() because we may add PMAO but we never
+        * clear it here.
+        */
        mmcr0 |= current->thread.mmcr0;
 
-       /* Be careful not to set PMXE if userspace had it cleared */
+       /*
+        * Be careful not to set PMXE if userspace had it cleared. This is also
+        * compatible with pmao_restore_workaround() because it has already
+        * cleared PMXE and we leave PMAO alone.
+        */
        if (!(current->thread.mmcr0 & MMCR0_PMXE))
                mmcr0 &= ~MMCR0_PMXE;
 
@@ -559,13 +572,94 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
 out:
        return mmcr0;
 }
-#endif /* CONFIG_PPC64 */
-
-static void perf_event_interrupt(struct pt_regs *regs);
 
-void perf_event_print_debug(void)
+static void pmao_restore_workaround(bool ebb)
 {
+       unsigned pmcs[6];
+
+       if (!cpu_has_feature(CPU_FTR_PMAO_BUG))
+               return;
+
+       /*
+        * On POWER8E there is a hardware defect which affects the PMU context
+        * switch logic, ie. power_pmu_disable/enable().
+        *
+        * When a counter overflows PMXE is cleared and FC/PMAO is set in MMCR0
+        * by the hardware. Sometime later the actual PMU exception is
+        * delivered.
+        *
+        * If we context switch, or simply disable/enable, the PMU prior to the
+        * exception arriving, the exception will be lost when we clear PMAO.
+        *
+        * When we reenable the PMU, we will write the saved MMCR0 with PMAO
+        * set, and this _should_ generate an exception. However because of the
+        * defect no exception is generated when we write PMAO, and we get
+        * stuck with no counters counting but no exception delivered.
+        *
+        * The workaround is to detect this case and tweak the hardware to
+        * create another pending PMU exception.
+        *
+        * We do that by setting up PMC6 (cycles) for an imminent overflow and
+        * enabling the PMU. That causes a new exception to be generated in the
+        * chip, but we don't take it yet because we have interrupts hard
+        * disabled. We then write back the PMU state as we want it to be seen
+        * by the exception handler. When we reenable interrupts the exception
+        * handler will be called and see the correct state.
+        *
+        * The logic is the same for EBB, except that the exception is gated by
+        * us having interrupts hard disabled as well as the fact that we are
+        * not in userspace. The exception is finally delivered when we return
+        * to userspace.
+        */
+
+       /* Only if PMAO is set and PMAO_SYNC is clear */
+       if ((current->thread.mmcr0 & (MMCR0_PMAO | MMCR0_PMAO_SYNC)) != MMCR0_PMAO)
+               return;
+
+       /* If we're doing EBB, only if BESCR[GE] is set */
+       if (ebb && !(current->thread.bescr & BESCR_GE))
+               return;
+
+       /*
+        * We are already soft-disabled in power_pmu_enable(). We need to hard
+        * enable to actually prevent the PMU exception from firing.
+        */
+       hard_irq_disable();
+
+       /*
+        * This is a bit gross, but we know we're on POWER8E and have 6 PMCs.
+        * Using read/write_pmc() in a for loop adds 12 function calls and
+        * almost doubles our code size.
+        */
+       pmcs[0] = mfspr(SPRN_PMC1);
+       pmcs[1] = mfspr(SPRN_PMC2);
+       pmcs[2] = mfspr(SPRN_PMC3);
+       pmcs[3] = mfspr(SPRN_PMC4);
+       pmcs[4] = mfspr(SPRN_PMC5);
+       pmcs[5] = mfspr(SPRN_PMC6);
+
+       /* Ensure all freeze bits are unset */
+       mtspr(SPRN_MMCR2, 0);
+
+       /* Set up PMC6 to overflow in one cycle */
+       mtspr(SPRN_PMC6, 0x7FFFFFFE);
+
+       /* Enable exceptions and unfreeze PMC6 */
+       mtspr(SPRN_MMCR0, MMCR0_PMXE | MMCR0_PMCjCE | MMCR0_PMAO);
+
+       /* Now we need to refreeze and restore the PMCs */
+       mtspr(SPRN_MMCR0, MMCR0_FC | MMCR0_PMAO);
+
+       mtspr(SPRN_PMC1, pmcs[0]);
+       mtspr(SPRN_PMC2, pmcs[1]);
+       mtspr(SPRN_PMC3, pmcs[2]);
+       mtspr(SPRN_PMC4, pmcs[3]);
+       mtspr(SPRN_PMC5, pmcs[4]);
+       mtspr(SPRN_PMC6, pmcs[5]);
 }
+#endif /* CONFIG_PPC64 */
+
+static void perf_event_interrupt(struct pt_regs *regs);
 
 /*
  * Read one performance monitor counter (PMC).
@@ -645,6 +739,57 @@ static void write_pmc(int idx, unsigned long val)
        }
 }
 
+/* Called from sysrq_handle_showregs() */
+void perf_event_print_debug(void)
+{
+       unsigned long sdar, sier, flags;
+       u32 pmcs[MAX_HWEVENTS];
+       int i;
+
+       if (!ppmu->n_counter)
+               return;
+
+       local_irq_save(flags);
+
+       pr_info("CPU: %d PMU registers, ppmu = %s n_counters = %d",
+                smp_processor_id(), ppmu->name, ppmu->n_counter);
+
+       for (i = 0; i < ppmu->n_counter; i++)
+               pmcs[i] = read_pmc(i + 1);
+
+       for (; i < MAX_HWEVENTS; i++)
+               pmcs[i] = 0xdeadbeef;
+
+       pr_info("PMC1:  %08x PMC2: %08x PMC3: %08x PMC4: %08x\n",
+                pmcs[0], pmcs[1], pmcs[2], pmcs[3]);
+
+       if (ppmu->n_counter > 4)
+               pr_info("PMC5:  %08x PMC6: %08x PMC7: %08x PMC8: %08x\n",
+                        pmcs[4], pmcs[5], pmcs[6], pmcs[7]);
+
+       pr_info("MMCR0: %016lx MMCR1: %016lx MMCRA: %016lx\n",
+               mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCRA));
+
+       sdar = sier = 0;
+#ifdef CONFIG_PPC64
+       sdar = mfspr(SPRN_SDAR);
+
+       if (ppmu->flags & PPMU_HAS_SIER)
+               sier = mfspr(SPRN_SIER);
+
+       if (ppmu->flags & PPMU_EBB) {
+               pr_info("MMCR2: %016lx EBBHR: %016lx\n",
+                       mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
+               pr_info("EBBRR: %016lx BESCR: %016lx\n",
+                       mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR));
+       }
+#endif
+       pr_info("SIAR:  %016lx SDAR:  %016lx SIER:  %016lx\n",
+               mfspr(SPRN_SIAR), sdar, sier);
+
+       local_irq_restore(flags);
+}
+
 /*
  * Check if a set of events can all go on the PMU at once.
  * If they can't, this will look at alternative codes for the events
@@ -973,11 +1118,12 @@ static void power_pmu_disable(struct pmu *pmu)
                }
 
                /*
-                * Set the 'freeze counters' bit, clear EBE/PMCC/PMAO/FC56.
+                * Set the 'freeze counters' bit, clear EBE/BHRBA/PMCC/PMAO/FC56
                 */
                val  = mmcr0 = mfspr(SPRN_MMCR0);
                val |= MMCR0_FC;
-               val &= ~(MMCR0_EBE | MMCR0_PMCC | MMCR0_PMAO | MMCR0_FC56);
+               val &= ~(MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC | MMCR0_PMAO |
+                        MMCR0_FC56);
 
                /*
                 * The barrier is to make sure the mtspr has been
@@ -1144,6 +1290,8 @@ static void power_pmu_enable(struct pmu *pmu)
        cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
 
  out_enable:
+       pmao_restore_workaround(ebb);
+
        mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
 
        mb();
diff --git a/arch/powerpc/perf/hv-24x7-catalog.h b/arch/powerpc/perf/hv-24x7-catalog.h
new file mode 100644 (file)
index 0000000..21b19dd
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_
+#define LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_
+
+#include <linux/types.h>
+
+/* From document "24x7 Event and Group Catalog Formats Proposal" v0.15 */
+
+struct hv_24x7_catalog_page_0 {
+#define HV_24X7_CATALOG_MAGIC 0x32347837 /* "24x7" in ASCII */
+       __be32 magic;
+       __be32 length; /* In 4096 byte pages */
+       __be64 version; /* XXX: arbitrary? what's the meaning/useage/purpose? */
+       __u8 build_time_stamp[16]; /* "YYYYMMDDHHMMSS\0\0" */
+       __u8 reserved2[32];
+       __be16 schema_data_offs; /* in 4096 byte pages */
+       __be16 schema_data_len;  /* in 4096 byte pages */
+       __be16 schema_entry_count;
+       __u8 reserved3[2];
+       __be16 event_data_offs;
+       __be16 event_data_len;
+       __be16 event_entry_count;
+       __u8 reserved4[2];
+       __be16 group_data_offs; /* in 4096 byte pages */
+       __be16 group_data_len;  /* in 4096 byte pages */
+       __be16 group_entry_count;
+       __u8 reserved5[2];
+       __be16 formula_data_offs; /* in 4096 byte pages */
+       __be16 formula_data_len;  /* in 4096 byte pages */
+       __be16 formula_entry_count;
+       __u8 reserved6[2];
+} __packed;
+
+#endif
diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
new file mode 100644 (file)
index 0000000..297c910
--- /dev/null
@@ -0,0 +1,510 @@
+/*
+ * Hypervisor supplied "24x7" performance counter support
+ *
+ * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
+ * Copyright 2014 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "hv-24x7: " fmt
+
+#include <linux/perf_event.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/io.h>
+
+#include "hv-24x7.h"
+#include "hv-24x7-catalog.h"
+#include "hv-common.h"
+
+/*
+ * TODO: Merging events:
+ * - Think of the hcall as an interface to a 4d array of counters:
+ *   - x = domains
+ *   - y = indexes in the domain (core, chip, vcpu, node, etc)
+ *   - z = offset into the counter space
+ *   - w = lpars (guest vms, "logical partitions")
+ * - A single request is: x,y,y_last,z,z_last,w,w_last
+ *   - this means we can retrieve a rectangle of counters in y,z for a single x.
+ *
+ * - Things to consider (ignoring w):
+ *   - input  cost_per_request = 16
+ *   - output cost_per_result(ys,zs)  = 8 + 8 * ys + ys * zs
+ *   - limited number of requests per hcall (must fit into 4K bytes)
+ *     - 4k = 16 [buffer header] - 16 [request size] * request_count
+ *     - 255 requests per hcall
+ *   - sometimes it will be more efficient to read extra data and discard
+ */
+
+/*
+ * Example usage:
+ *  perf stat -e 'hv_24x7/domain=2,offset=8,starting_index=0,lpar=0xffffffff/'
+ */
+
+/* u3 0-6, one of HV_24X7_PERF_DOMAIN */
+EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
+/* u16 */
+EVENT_DEFINE_RANGE_FORMAT(starting_index, config, 16, 31);
+/* u32, see "data_offset" */
+EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63);
+/* u16 */
+EVENT_DEFINE_RANGE_FORMAT(lpar, config1, 0, 15);
+
+EVENT_DEFINE_RANGE(reserved1, config,   4, 15);
+EVENT_DEFINE_RANGE(reserved2, config1, 16, 63);
+EVENT_DEFINE_RANGE(reserved3, config2,  0, 63);
+
+static struct attribute *format_attrs[] = {
+       &format_attr_domain.attr,
+       &format_attr_offset.attr,
+       &format_attr_starting_index.attr,
+       &format_attr_lpar.attr,
+       NULL,
+};
+
+static struct attribute_group format_group = {
+       .name = "format",
+       .attrs = format_attrs,
+};
+
+static struct kmem_cache *hv_page_cache;
+
+/*
+ * read_offset_data - copy data from one buffer to another while treating the
+ *                    source buffer as a small view on the total avaliable
+ *                    source data.
+ *
+ * @dest: buffer to copy into
+ * @dest_len: length of @dest in bytes
+ * @requested_offset: the offset within the source data we want. Must be > 0
+ * @src: buffer to copy data from
+ * @src_len: length of @src in bytes
+ * @source_offset: the offset in the sorce data that (src,src_len) refers to.
+ *                 Must be > 0
+ *
+ * returns the number of bytes copied.
+ *
+ * The following ascii art shows the various buffer possitioning we need to
+ * handle, assigns some arbitrary varibles to points on the buffer, and then
+ * shows how we fiddle with those values to get things we care about (copy
+ * start in src and copy len)
+ *
+ * s = @src buffer
+ * d = @dest buffer
+ * '.' areas in d are written to.
+ *
+ *                       u
+ *   x         w        v  z
+ * d           |.........|
+ * s |----------------------|
+ *
+ *                      u
+ *   x         w       z     v
+ * d           |........------|
+ * s |------------------|
+ *
+ *   x         w        u,z,v
+ * d           |........|
+ * s |------------------|
+ *
+ *   x,w                u,v,z
+ * d |..................|
+ * s |------------------|
+ *
+ *   x        u
+ *   w        v                z
+ * d |........|
+ * s |------------------|
+ *
+ *   x      z   w      v
+ * d            |------|
+ * s |------|
+ *
+ * x = source_offset
+ * w = requested_offset
+ * z = source_offset + src_len
+ * v = requested_offset + dest_len
+ *
+ * w_offset_in_s = w - x = requested_offset - source_offset
+ * z_offset_in_s = z - x = src_len
+ * v_offset_in_s = v - x = request_offset + dest_len - src_len
+ */
+static ssize_t read_offset_data(void *dest, size_t dest_len,
+                               loff_t requested_offset, void *src,
+                               size_t src_len, loff_t source_offset)
+{
+       size_t w_offset_in_s = requested_offset - source_offset;
+       size_t z_offset_in_s = src_len;
+       size_t v_offset_in_s = requested_offset + dest_len - src_len;
+       size_t u_offset_in_s = min(z_offset_in_s, v_offset_in_s);
+       size_t copy_len = u_offset_in_s - w_offset_in_s;
+
+       if (requested_offset < 0 || source_offset < 0)
+               return -EINVAL;
+
+       if (z_offset_in_s <= w_offset_in_s)
+               return 0;
+
+       memcpy(dest, src + w_offset_in_s, copy_len);
+       return copy_len;
+}
+
+static unsigned long h_get_24x7_catalog_page(char page[static 4096],
+                                            u32 version, u32 index)
+{
+       WARN_ON(!IS_ALIGNED((unsigned long)page, 4096));
+       return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE,
+                       virt_to_phys(page),
+                       version,
+                       index);
+}
+
+static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
+                           struct bin_attribute *bin_attr, char *buf,
+                           loff_t offset, size_t count)
+{
+       unsigned long hret;
+       ssize_t ret = 0;
+       size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
+       loff_t page_offset = 0;
+       uint32_t catalog_version_num = 0;
+       void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
+       struct hv_24x7_catalog_page_0 *page_0 = page;
+       if (!page)
+               return -ENOMEM;
+
+       hret = h_get_24x7_catalog_page(page, 0, 0);
+       if (hret) {
+               ret = -EIO;
+               goto e_free;
+       }
+
+       catalog_version_num = be32_to_cpu(page_0->version);
+       catalog_page_len = be32_to_cpu(page_0->length);
+       catalog_len = catalog_page_len * 4096;
+
+       page_offset = offset / 4096;
+       page_count  = count  / 4096;
+
+       if (page_offset >= catalog_page_len)
+               goto e_free;
+
+       if (page_offset != 0) {
+               hret = h_get_24x7_catalog_page(page, catalog_version_num,
+                                              page_offset);
+               if (hret) {
+                       ret = -EIO;
+                       goto e_free;
+               }
+       }
+
+       ret = read_offset_data(buf, count, offset,
+                               page, 4096, page_offset * 4096);
+e_free:
+       if (hret)
+               pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n",
+                               catalog_version_num, page_offset, hret);
+       kfree(page);
+
+       pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n",
+                       offset, page_offset, count, page_count, catalog_len,
+                       catalog_page_len, ret);
+
+       return ret;
+}
+
+#define PAGE_0_ATTR(_name, _fmt, _expr)                                \
+static ssize_t _name##_show(struct device *dev,                        \
+                           struct device_attribute *dev_attr,  \
+                           char *buf)                          \
+{                                                              \
+       unsigned long hret;                                     \
+       ssize_t ret = 0;                                        \
+       void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); \
+       struct hv_24x7_catalog_page_0 *page_0 = page;           \
+       if (!page)                                              \
+               return -ENOMEM;                                 \
+       hret = h_get_24x7_catalog_page(page, 0, 0);             \
+       if (hret) {                                             \
+               ret = -EIO;                                     \
+               goto e_free;                                    \
+       }                                                       \
+       ret = sprintf(buf, _fmt, _expr);                        \
+e_free:                                                                \
+       kfree(page);                                            \
+       return ret;                                             \
+}                                                              \
+static DEVICE_ATTR_RO(_name)
+
+PAGE_0_ATTR(catalog_version, "%lld\n",
+               (unsigned long long)be32_to_cpu(page_0->version));
+PAGE_0_ATTR(catalog_len, "%lld\n",
+               (unsigned long long)be32_to_cpu(page_0->length) * 4096);
+static BIN_ATTR_RO(catalog, 0/* real length varies */);
+
+static struct bin_attribute *if_bin_attrs[] = {
+       &bin_attr_catalog,
+       NULL,
+};
+
+static struct attribute *if_attrs[] = {
+       &dev_attr_catalog_len.attr,
+       &dev_attr_catalog_version.attr,
+       NULL,
+};
+
+static struct attribute_group if_group = {
+       .name = "interface",
+       .bin_attrs = if_bin_attrs,
+       .attrs = if_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+       &format_group,
+       &if_group,
+       NULL,
+};
+
+static bool is_physical_domain(int domain)
+{
+       return  domain == HV_24X7_PERF_DOMAIN_PHYSICAL_CHIP ||
+               domain == HV_24X7_PERF_DOMAIN_PHYSICAL_CORE;
+}
+
+static unsigned long single_24x7_request(u8 domain, u32 offset, u16 ix,
+                                        u16 lpar, u64 *res,
+                                        bool success_expected)
+{
+       unsigned long ret;
+
+       /*
+        * request_buffer and result_buffer are not required to be 4k aligned,
+        * but are not allowed to cross any 4k boundary. Aligning them to 4k is
+        * the simplest way to ensure that.
+        */
+       struct reqb {
+               struct hv_24x7_request_buffer buf;
+               struct hv_24x7_request req;
+       } __packed __aligned(4096) request_buffer = {
+               .buf = {
+                       .interface_version = HV_24X7_IF_VERSION_CURRENT,
+                       .num_requests = 1,
+               },
+               .req = {
+                       .performance_domain = domain,
+                       .data_size = cpu_to_be16(8),
+                       .data_offset = cpu_to_be32(offset),
+                       .starting_lpar_ix = cpu_to_be16(lpar),
+                       .max_num_lpars = cpu_to_be16(1),
+                       .starting_ix = cpu_to_be16(ix),
+                       .max_ix = cpu_to_be16(1),
+               }
+       };
+
+       struct resb {
+               struct hv_24x7_data_result_buffer buf;
+               struct hv_24x7_result res;
+               struct hv_24x7_result_element elem;
+               __be64 result;
+       } __packed __aligned(4096) result_buffer = {};
+
+       ret = plpar_hcall_norets(H_GET_24X7_DATA,
+                       virt_to_phys(&request_buffer), sizeof(request_buffer),
+                       virt_to_phys(&result_buffer),  sizeof(result_buffer));
+
+       if (ret) {
+               if (success_expected)
+                       pr_err_ratelimited("hcall failed: %d %#x %#x %d => 0x%lx (%ld) detail=0x%x failing ix=%x\n",
+                                       domain, offset, ix, lpar,
+                                       ret, ret,
+                                       result_buffer.buf.detailed_rc,
+                                       result_buffer.buf.failing_request_ix);
+               return ret;
+       }
+
+       *res = be64_to_cpu(result_buffer.result);
+       return ret;
+}
+
+static unsigned long event_24x7_request(struct perf_event *event, u64 *res,
+               bool success_expected)
+{
+       return single_24x7_request(event_get_domain(event),
+                               event_get_offset(event),
+                               event_get_starting_index(event),
+                               event_get_lpar(event),
+                               res,
+                               success_expected);
+}
+
+static int h_24x7_event_init(struct perf_event *event)
+{
+       struct hv_perf_caps caps;
+       unsigned domain;
+       unsigned long hret;
+       u64 ct;
+
+       /* Not our event */
+       if (event->attr.type != event->pmu->type)
+               return -ENOENT;
+
+       /* Unused areas must be 0 */
+       if (event_get_reserved1(event) ||
+           event_get_reserved2(event) ||
+           event_get_reserved3(event)) {
+               pr_devel("reserved set when forbidden 0x%llx(0x%llx) 0x%llx(0x%llx) 0x%llx(0x%llx)\n",
+                               event->attr.config,
+                               event_get_reserved1(event),
+                               event->attr.config1,
+                               event_get_reserved2(event),
+                               event->attr.config2,
+                               event_get_reserved3(event));
+               return -EINVAL;
+       }
+
+       /* unsupported modes and filters */
+       if (event->attr.exclude_user   ||
+           event->attr.exclude_kernel ||
+           event->attr.exclude_hv     ||
+           event->attr.exclude_idle   ||
+           event->attr.exclude_host   ||
+           event->attr.exclude_guest  ||
+           is_sampling_event(event)) /* no sampling */
+               return -EINVAL;
+
+       /* no branch sampling */
+       if (has_branch_stack(event))
+               return -EOPNOTSUPP;
+
+       /* offset must be 8 byte aligned */
+       if (event_get_offset(event) % 8) {
+               pr_devel("bad alignment\n");
+               return -EINVAL;
+       }
+
+       /* Domains above 6 are invalid */
+       domain = event_get_domain(event);
+       if (domain > 6) {
+               pr_devel("invalid domain %d\n", domain);
+               return -EINVAL;
+       }
+
+       hret = hv_perf_caps_get(&caps);
+       if (hret) {
+               pr_devel("could not get capabilities: rc=%ld\n", hret);
+               return -EIO;
+       }
+
+       /* PHYSICAL domains & other lpars require extra capabilities */
+       if (!caps.collect_privileged && (is_physical_domain(domain) ||
+               (event_get_lpar(event) != event_get_lpar_max()))) {
+               pr_devel("hv permisions disallow: is_physical_domain:%d, lpar=0x%llx\n",
+                               is_physical_domain(domain),
+                               event_get_lpar(event));
+               return -EACCES;
+       }
+
+       /* see if the event complains */
+       if (event_24x7_request(event, &ct, false)) {
+               pr_devel("test hcall failed\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static u64 h_24x7_get_value(struct perf_event *event)
+{
+       unsigned long ret;
+       u64 ct;
+       ret = event_24x7_request(event, &ct, true);
+       if (ret)
+               /* We checked this in event init, shouldn't fail here... */
+               return 0;
+
+       return ct;
+}
+
+static void h_24x7_event_update(struct perf_event *event)
+{
+       s64 prev;
+       u64 now;
+       now = h_24x7_get_value(event);
+       prev = local64_xchg(&event->hw.prev_count, now);
+       local64_add(now - prev, &event->count);
+}
+
+static void h_24x7_event_start(struct perf_event *event, int flags)
+{
+       if (flags & PERF_EF_RELOAD)
+               local64_set(&event->hw.prev_count, h_24x7_get_value(event));
+}
+
+static void h_24x7_event_stop(struct perf_event *event, int flags)
+{
+       h_24x7_event_update(event);
+}
+
+static int h_24x7_event_add(struct perf_event *event, int flags)
+{
+       if (flags & PERF_EF_START)
+               h_24x7_event_start(event, flags);
+
+       return 0;
+}
+
+static int h_24x7_event_idx(struct perf_event *event)
+{
+       return 0;
+}
+
+static struct pmu h_24x7_pmu = {
+       .task_ctx_nr = perf_invalid_context,
+
+       .name = "hv_24x7",
+       .attr_groups = attr_groups,
+       .event_init  = h_24x7_event_init,
+       .add         = h_24x7_event_add,
+       .del         = h_24x7_event_stop,
+       .start       = h_24x7_event_start,
+       .stop        = h_24x7_event_stop,
+       .read        = h_24x7_event_update,
+       .event_idx   = h_24x7_event_idx,
+};
+
+static int hv_24x7_init(void)
+{
+       int r;
+       unsigned long hret;
+       struct hv_perf_caps caps;
+
+       if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+               pr_info("not a virtualized system, not enabling\n");
+               return -ENODEV;
+       }
+
+       hret = hv_perf_caps_get(&caps);
+       if (hret) {
+               pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
+                               hret);
+               return -ENODEV;
+       }
+
+       hv_page_cache = kmem_cache_create("hv-page-4096", 4096, 4096, 0, NULL);
+       if (!hv_page_cache)
+               return -ENOMEM;
+
+       r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1);
+       if (r)
+               return r;
+
+       return 0;
+}
+
+device_initcall(hv_24x7_init);
diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h
new file mode 100644 (file)
index 0000000..720ebce
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef LINUX_POWERPC_PERF_HV_24X7_H_
+#define LINUX_POWERPC_PERF_HV_24X7_H_
+
+#include <linux/types.h>
+
+struct hv_24x7_request {
+       /* PHYSICAL domains require enabling via phyp/hmc. */
+#define HV_24X7_PERF_DOMAIN_PHYSICAL_CHIP 0x01
+#define HV_24X7_PERF_DOMAIN_PHYSICAL_CORE 0x02
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_CORE   0x03
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_CHIP   0x04
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_HOME_NODE   0x05
+#define HV_24X7_PERF_DOMAIN_VIRTUAL_PROCESSOR_REMOTE_NODE 0x06
+       __u8 performance_domain;
+       __u8 reserved[0x1];
+
+       /* bytes to read starting at @data_offset. must be a multiple of 8 */
+       __be16 data_size;
+
+       /*
+        * byte offset within the perf domain to read from. must be 8 byte
+        * aligned
+        */
+       __be32 data_offset;
+
+       /*
+        * only valid for VIRTUAL_PROCESSOR domains, ignored for others.
+        * -1 means "current partition only"
+        *  Enabling via phyp/hmc required for non-"-1" values. 0 forbidden
+        *  unless requestor is 0.
+        */
+       __be16 starting_lpar_ix;
+
+       /*
+        * Ignored when @starting_lpar_ix == -1
+        * Ignored when @performance_domain is not VIRTUAL_PROCESSOR_*
+        * -1 means "infinite" or all
+        */
+       __be16 max_num_lpars;
+
+       /* chip, core, or virtual processor based on @performance_domain */
+       __be16 starting_ix;
+       __be16 max_ix;
+} __packed;
+
+struct hv_24x7_request_buffer {
+       /* 0 - ? */
+       /* 1 - ? */
+#define HV_24X7_IF_VERSION_CURRENT 0x01
+       __u8 interface_version;
+       __u8 num_requests;
+       __u8 reserved[0xE];
+       struct hv_24x7_request requests[];
+} __packed;
+
+struct hv_24x7_result_element {
+       __be16 lpar_ix;
+
+       /*
+        * represents the core, chip, or virtual processor based on the
+        * request's @performance_domain
+        */
+       __be16 domain_ix;
+
+       /* -1 if @performance_domain does not refer to a virtual processor */
+       __be32 lpar_cfg_instance_id;
+
+       /* size = @result_element_data_size of cointaining result. */
+       __u8 element_data[];
+} __packed;
+
+struct hv_24x7_result {
+       __u8 result_ix;
+
+       /*
+        * 0 = not all result elements fit into the buffer, additional requests
+        *     required
+        * 1 = all result elements were returned
+        */
+       __u8 results_complete;
+       __be16 num_elements_returned;
+
+       /* This is a copy of @data_size from the coresponding hv_24x7_request */
+       __be16 result_element_data_size;
+       __u8 reserved[0x2];
+
+       /* WARNING: only valid for first result element due to variable sizes
+        *          of result elements */
+       /* struct hv_24x7_result_element[@num_elements_returned] */
+       struct hv_24x7_result_element elements[];
+} __packed;
+
+struct hv_24x7_data_result_buffer {
+       /* See versioning for request buffer */
+       __u8 interface_version;
+
+       __u8 num_results;
+       __u8 reserved[0x1];
+       __u8 failing_request_ix;
+       __be32 detailed_rc;
+       __be64 cec_cfg_instance_id;
+       __be64 catalog_version_num;
+       __u8 reserved2[0x8];
+       /* WARNING: only valid for the first result due to variable sizes of
+        *          results */
+       struct hv_24x7_result results[]; /* [@num_results] */
+} __packed;
+
+#endif
diff --git a/arch/powerpc/perf/hv-common.c b/arch/powerpc/perf/hv-common.c
new file mode 100644 (file)
index 0000000..47e02b3
--- /dev/null
@@ -0,0 +1,39 @@
+#include <asm/io.h>
+#include <asm/hvcall.h>
+
+#include "hv-gpci.h"
+#include "hv-common.h"
+
+unsigned long hv_perf_caps_get(struct hv_perf_caps *caps)
+{
+       unsigned long r;
+       struct p {
+               struct hv_get_perf_counter_info_params params;
+               struct cv_system_performance_capabilities caps;
+       } __packed __aligned(sizeof(uint64_t));
+
+       struct p arg = {
+               .params = {
+                       .counter_request = cpu_to_be32(
+                                       CIR_SYSTEM_PERFORMANCE_CAPABILITIES),
+                       .starting_index = cpu_to_be32(-1),
+                       .counter_info_version_in = 0,
+               }
+       };
+
+       r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
+                              virt_to_phys(&arg), sizeof(arg));
+
+       if (r)
+               return r;
+
+       pr_devel("capability_mask: 0x%x\n", arg.caps.capability_mask);
+
+       caps->version = arg.params.counter_info_version_out;
+       caps->collect_privileged = !!arg.caps.perf_collect_privileged;
+       caps->ga = !!(arg.caps.capability_mask & CV_CM_GA);
+       caps->expanded = !!(arg.caps.capability_mask & CV_CM_EXPANDED);
+       caps->lab = !!(arg.caps.capability_mask & CV_CM_LAB);
+
+       return r;
+}
diff --git a/arch/powerpc/perf/hv-common.h b/arch/powerpc/perf/hv-common.h
new file mode 100644 (file)
index 0000000..5d79cec
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef LINUX_POWERPC_PERF_HV_COMMON_H_
+#define LINUX_POWERPC_PERF_HV_COMMON_H_
+
+#include <linux/perf_event.h>
+#include <linux/types.h>
+
+struct hv_perf_caps {
+       u16 version;
+       u16 collect_privileged:1,
+           ga:1,
+           expanded:1,
+           lab:1,
+           unused:12;
+};
+
+unsigned long hv_perf_caps_get(struct hv_perf_caps *caps);
+
+
+#define EVENT_DEFINE_RANGE_FORMAT(name, attr_var, bit_start, bit_end)  \
+PMU_FORMAT_ATTR(name, #attr_var ":" #bit_start "-" #bit_end);          \
+EVENT_DEFINE_RANGE(name, attr_var, bit_start, bit_end)
+
+#define EVENT_DEFINE_RANGE(name, attr_var, bit_start, bit_end) \
+static u64 event_get_##name##_max(void)                                        \
+{                                                                      \
+       BUILD_BUG_ON((bit_start > bit_end)                              \
+                   || (bit_end >= (sizeof(1ull) * 8)));                \
+       return (((1ull << (bit_end - bit_start)) - 1) << 1) + 1;        \
+}                                                                      \
+static u64 event_get_##name(struct perf_event *event)                  \
+{                                                                      \
+       return (event->attr.attr_var >> (bit_start)) &                  \
+               event_get_##name##_max();                               \
+}
+
+#endif
diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
new file mode 100644 (file)
index 0000000..278ba7b
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Hypervisor supplied "gpci" ("get performance counter info") performance
+ * counter support
+ *
+ * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
+ * Copyright 2014 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "hv-gpci: " fmt
+
+#include <linux/init.h>
+#include <linux/perf_event.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/io.h>
+
+#include "hv-gpci.h"
+#include "hv-common.h"
+
+/*
+ * Example usage:
+ *  perf stat -e 'hv_gpci/counter_info_version=3,offset=0,length=8,
+ *               secondary_index=0,starting_index=0xffffffff,request=0x10/' ...
+ */
+
+/* u32 */
+EVENT_DEFINE_RANGE_FORMAT(request, config, 0, 31);
+/* u32 */
+EVENT_DEFINE_RANGE_FORMAT(starting_index, config, 32, 63);
+/* u16 */
+EVENT_DEFINE_RANGE_FORMAT(secondary_index, config1, 0, 15);
+/* u8 */
+EVENT_DEFINE_RANGE_FORMAT(counter_info_version, config1, 16, 23);
+/* u8, bytes of data (1-8) */
+EVENT_DEFINE_RANGE_FORMAT(length, config1, 24, 31);
+/* u32, byte offset */
+EVENT_DEFINE_RANGE_FORMAT(offset, config1, 32, 63);
+
+static struct attribute *format_attrs[] = {
+       &format_attr_request.attr,
+       &format_attr_starting_index.attr,
+       &format_attr_secondary_index.attr,
+       &format_attr_counter_info_version.attr,
+
+       &format_attr_offset.attr,
+       &format_attr_length.attr,
+       NULL,
+};
+
+static struct attribute_group format_group = {
+       .name = "format",
+       .attrs = format_attrs,
+};
+
+#define HV_CAPS_ATTR(_name, _format)                           \
+static ssize_t _name##_show(struct device *dev,                        \
+                           struct device_attribute *attr,      \
+                           char *page)                         \
+{                                                              \
+       struct hv_perf_caps caps;                               \
+       unsigned long hret = hv_perf_caps_get(&caps);           \
+       if (hret)                                               \
+               return -EIO;                                    \
+                                                               \
+       return sprintf(page, _format, caps._name);              \
+}                                                              \
+static struct device_attribute hv_caps_attr_##_name = __ATTR_RO(_name)
+
+static ssize_t kernel_version_show(struct device *dev,
+                                  struct device_attribute *attr,
+                                  char *page)
+{
+       return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT);
+}
+
+DEVICE_ATTR_RO(kernel_version);
+HV_CAPS_ATTR(version, "0x%x\n");
+HV_CAPS_ATTR(ga, "%d\n");
+HV_CAPS_ATTR(expanded, "%d\n");
+HV_CAPS_ATTR(lab, "%d\n");
+HV_CAPS_ATTR(collect_privileged, "%d\n");
+
+static struct attribute *interface_attrs[] = {
+       &dev_attr_kernel_version.attr,
+       &hv_caps_attr_version.attr,
+       &hv_caps_attr_ga.attr,
+       &hv_caps_attr_expanded.attr,
+       &hv_caps_attr_lab.attr,
+       &hv_caps_attr_collect_privileged.attr,
+       NULL,
+};
+
+static struct attribute_group interface_group = {
+       .name = "interface",
+       .attrs = interface_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+       &format_group,
+       &interface_group,
+       NULL,
+};
+
+#define GPCI_MAX_DATA_BYTES \
+       (1024 - sizeof(struct hv_get_perf_counter_info_params))
+
+static unsigned long single_gpci_request(u32 req, u32 starting_index,
+               u16 secondary_index, u8 version_in, u32 offset, u8 length,
+               u64 *value)
+{
+       unsigned long ret;
+       size_t i;
+       u64 count;
+
+       struct {
+               struct hv_get_perf_counter_info_params params;
+               uint8_t bytes[GPCI_MAX_DATA_BYTES];
+       } __packed __aligned(sizeof(uint64_t)) arg = {
+               .params = {
+                       .counter_request = cpu_to_be32(req),
+                       .starting_index = cpu_to_be32(starting_index),
+                       .secondary_index = cpu_to_be16(secondary_index),
+                       .counter_info_version_in = version_in,
+               }
+       };
+
+       ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
+                       virt_to_phys(&arg), sizeof(arg));
+       if (ret) {
+               pr_devel("hcall failed: 0x%lx\n", ret);
+               return ret;
+       }
+
+       /*
+        * we verify offset and length are within the zeroed buffer at event
+        * init.
+        */
+       count = 0;
+       for (i = offset; i < offset + length; i++)
+               count |= arg.bytes[i] << (i - offset);
+
+       *value = count;
+       return ret;
+}
+
+static u64 h_gpci_get_value(struct perf_event *event)
+{
+       u64 count;
+       unsigned long ret = single_gpci_request(event_get_request(event),
+                                       event_get_starting_index(event),
+                                       event_get_secondary_index(event),
+                                       event_get_counter_info_version(event),
+                                       event_get_offset(event),
+                                       event_get_length(event),
+                                       &count);
+       if (ret)
+               return 0;
+       return count;
+}
+
+static void h_gpci_event_update(struct perf_event *event)
+{
+       s64 prev;
+       u64 now = h_gpci_get_value(event);
+       prev = local64_xchg(&event->hw.prev_count, now);
+       local64_add(now - prev, &event->count);
+}
+
+static void h_gpci_event_start(struct perf_event *event, int flags)
+{
+       local64_set(&event->hw.prev_count, h_gpci_get_value(event));
+}
+
+static void h_gpci_event_stop(struct perf_event *event, int flags)
+{
+       h_gpci_event_update(event);
+}
+
+static int h_gpci_event_add(struct perf_event *event, int flags)
+{
+       if (flags & PERF_EF_START)
+               h_gpci_event_start(event, flags);
+
+       return 0;
+}
+
+static int h_gpci_event_init(struct perf_event *event)
+{
+       u64 count;
+       u8 length;
+
+       /* Not our event */
+       if (event->attr.type != event->pmu->type)
+               return -ENOENT;
+
+       /* config2 is unused */
+       if (event->attr.config2) {
+               pr_devel("config2 set when reserved\n");
+               return -EINVAL;
+       }
+
+       /* unsupported modes and filters */
+       if (event->attr.exclude_user   ||
+           event->attr.exclude_kernel ||
+           event->attr.exclude_hv     ||
+           event->attr.exclude_idle   ||
+           event->attr.exclude_host   ||
+           event->attr.exclude_guest  ||
+           is_sampling_event(event)) /* no sampling */
+               return -EINVAL;
+
+       /* no branch sampling */
+       if (has_branch_stack(event))
+               return -EOPNOTSUPP;
+
+       length = event_get_length(event);
+       if (length < 1 || length > 8) {
+               pr_devel("length invalid\n");
+               return -EINVAL;
+       }
+
+       /* last byte within the buffer? */
+       if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) {
+               pr_devel("request outside of buffer: %zu > %zu\n",
+                               (size_t)event_get_offset(event) + length,
+                               GPCI_MAX_DATA_BYTES);
+               return -EINVAL;
+       }
+
+       /* check if the request works... */
+       if (single_gpci_request(event_get_request(event),
+                               event_get_starting_index(event),
+                               event_get_secondary_index(event),
+                               event_get_counter_info_version(event),
+                               event_get_offset(event),
+                               length,
+                               &count)) {
+               pr_devel("gpci hcall failed\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int h_gpci_event_idx(struct perf_event *event)
+{
+       return 0;
+}
+
+static struct pmu h_gpci_pmu = {
+       .task_ctx_nr = perf_invalid_context,
+
+       .name = "hv_gpci",
+       .attr_groups = attr_groups,
+       .event_init  = h_gpci_event_init,
+       .add         = h_gpci_event_add,
+       .del         = h_gpci_event_stop,
+       .start       = h_gpci_event_start,
+       .stop        = h_gpci_event_stop,
+       .read        = h_gpci_event_update,
+       .event_idx   = h_gpci_event_idx,
+};
+
+static int hv_gpci_init(void)
+{
+       int r;
+       unsigned long hret;
+       struct hv_perf_caps caps;
+
+       if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+               pr_info("not a virtualized system, not enabling\n");
+               return -ENODEV;
+       }
+
+       hret = hv_perf_caps_get(&caps);
+       if (hret) {
+               pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
+                               hret);
+               return -ENODEV;
+       }
+
+       r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
+       if (r)
+               return r;
+
+       return 0;
+}
+
+device_initcall(hv_gpci_init);
diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h
new file mode 100644 (file)
index 0000000..b25f460
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef LINUX_POWERPC_PERF_HV_GPCI_H_
+#define LINUX_POWERPC_PERF_HV_GPCI_H_
+
+#include <linux/types.h>
+
+/* From the document "H_GetPerformanceCounterInfo Interface" v1.07 */
+
+/* H_GET_PERF_COUNTER_INFO argument */
+struct hv_get_perf_counter_info_params {
+       __be32 counter_request; /* I */
+       __be32 starting_index;  /* IO */
+       __be16 secondary_index; /* IO */
+       __be16 returned_values; /* O */
+       __be32 detail_rc; /* O, only needed when called via *_norets() */
+
+       /*
+        * O, size each of counter_value element in bytes, only set for version
+        * >= 0x3
+        */
+       __be16 cv_element_size;
+
+       /* I, 0 (zero) for versions < 0x3 */
+       __u8 counter_info_version_in;
+
+       /* O, 0 (zero) if version < 0x3. Must be set to 0 when making hcall */
+       __u8 counter_info_version_out;
+       __u8 reserved[0xC];
+       __u8 counter_value[];
+} __packed;
+
+/*
+ * counter info version => fw version/reference (spec version)
+ *
+ * 8 => power8 (1.07)
+ * [7 is skipped by spec 1.07]
+ * 6 => TLBIE (1.07)
+ * 5 => v7r7m0.phyp (1.05)
+ * [4 skipped]
+ * 3 => v7r6m0.phyp (?)
+ * [1,2 skipped]
+ * 0 => v7r{2,3,4}m0.phyp (?)
+ */
+#define COUNTER_INFO_VERSION_CURRENT 0x8
+
+/*
+ * These determine the counter_value[] layout and the meaning of starting_index
+ * and secondary_index.
+ *
+ * Unless otherwise noted, @secondary_index is unused and ignored.
+ */
+enum counter_info_requests {
+
+       /* GENERAL */
+
+       /* @starting_index: must be -1 (to refer to the current partition)
+        */
+       CIR_SYSTEM_PERFORMANCE_CAPABILITIES = 0X40,
+};
+
+struct cv_system_performance_capabilities {
+       /* If != 0, allowed to collect data from other partitions */
+       __u8 perf_collect_privileged;
+
+       /* These following are only valid if counter_info_version >= 0x3 */
+#define CV_CM_GA       (1 << 7)
+#define CV_CM_EXPANDED (1 << 6)
+#define CV_CM_LAB      (1 << 5)
+       /* remaining bits are reserved */
+       __u8 capability_mask;
+       __u8 reserved[0xE];
+} __packed;
+
+#endif
index 687790a2c0b8dd57025a86a0092277b3b2abda09..64f13d9260a691526caa6fe374a37565b0027d09 100644 (file)
@@ -546,3 +546,13 @@ EVENT(PM_MRK_DATA_FROM_RL2L3_SHR,             0x1d04c)
 EVENT(PM_DTLB_MISS_16M,                       0x4c05e)
 EVENT(PM_LSU1_LMQ_LHR_MERGE,                  0x0d09a)
 EVENT(PM_IFU_FIN,                             0x40066)
+EVENT(PM_1THRD_CON_RUN_INSTR,                 0x30062)
+EVENT(PM_CMPLU_STALL_COUNT,                   0x4000B)
+EVENT(PM_MEM0_PB_RD_CL,                       0x30083)
+EVENT(PM_THRD_1_RUN_CYC,                      0x10060)
+EVENT(PM_THRD_2_CONC_RUN_INSTR,               0x40062)
+EVENT(PM_THRD_2_RUN_CYC,                      0x20060)
+EVENT(PM_THRD_3_CONC_RUN_INST,                0x10062)
+EVENT(PM_THRD_3_RUN_CYC,                      0x30060)
+EVENT(PM_THRD_4_CONC_RUN_INST,                0x20062)
+EVENT(PM_THRD_4_RUN_CYC,                      0x40060)
index 96cee20dcd34ec2cf33f6d836d4f4fd49b7848c6..fe2763b6e039cfc5773ba8255731a3f7d7228d78 100644 (file)
@@ -10,6 +10,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt)    "power8-pmu: " fmt
+
 #include <linux/kernel.h>
 #include <linux/perf_event.h>
 #include <asm/firmware.h>
  *
  *        60        56        52        48        44        40        36        32
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
- *   |                                 [      thresh_cmp     ]   [  thresh_ctl   ]
- *   |                                                                   |
- *   *- EBB (Linux)                      thresh start/stop OR FAB match -*
+ *   | | [ ]                           [      thresh_cmp     ]   [  thresh_ctl   ]
+ *   | |  |                                                              |
+ *   | |  *- IFM (Linux)                 thresh start/stop OR FAB match -*
+ *   | *- BHRB (Linux)
+ *   *- EBB (Linux)
  *
  *        28        24        20        16        12         8         4         0
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
  *     MMCRA[63]    = 1                (SAMPLE_ENABLE)
  *     MMCRA[57:59] = sample[0:2]      (RAND_SAMP_ELIG)
 Â *    MMCRA[61:62] = sample[3:4]      (RAND_SAMP_MODE)
+ *
+ * if EBB and BHRB:
+ *     MMCRA[32:33] = IFM
  *
  */
 
 #define EVENT_EBB_MASK         1ull
+#define EVENT_EBB_SHIFT                PERF_EVENT_CONFIG_EBB_SHIFT
+#define EVENT_BHRB_MASK                1ull
+#define EVENT_BHRB_SHIFT       62
+#define EVENT_WANTS_BHRB       (EVENT_BHRB_MASK << EVENT_BHRB_SHIFT)
+#define EVENT_IFM_MASK         3ull
+#define EVENT_IFM_SHIFT                60
 #define EVENT_THR_CMP_SHIFT    40      /* Threshold CMP value */
 #define EVENT_THR_CMP_MASK     0x3ff
 #define EVENT_THR_CTL_SHIFT    32      /* Threshold control value (start/stop) */
 #define EVENT_IS_MARKED                (EVENT_MARKED_MASK << EVENT_MARKED_SHIFT)
 #define EVENT_PSEL_MASK                0xff    /* PMCxSEL value */
 
+/* Bits defined by Linux */
+#define EVENT_LINUX_MASK       \
+       ((EVENT_EBB_MASK  << EVENT_EBB_SHIFT)                   |       \
+        (EVENT_BHRB_MASK << EVENT_BHRB_SHIFT)                  |       \
+        (EVENT_IFM_MASK  << EVENT_IFM_SHIFT))
+
 #define EVENT_VALID_MASK       \
        ((EVENT_THRESH_MASK    << EVENT_THRESH_SHIFT)           |       \
         (EVENT_SAMPLE_MASK    << EVENT_SAMPLE_SHIFT)           |       \
         (EVENT_UNIT_MASK      << EVENT_UNIT_SHIFT)             |       \
         (EVENT_COMBINE_MASK   << EVENT_COMBINE_SHIFT)          |       \
         (EVENT_MARKED_MASK    << EVENT_MARKED_SHIFT)           |       \
-        (EVENT_EBB_MASK       << PERF_EVENT_CONFIG_EBB_SHIFT)  |       \
+         EVENT_LINUX_MASK                                      |       \
          EVENT_PSEL_MASK)
 
 /* MMCRA IFM bits - POWER8 */
  *
  *        28        24        20        16        12         8         4         0
  * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - |
- *                   |   [ ]   [  sample ]   [     ]   [6] [5]   [4] [3]   [2] [1]
- *              EBB -*    |                     |
- *                        |                     |      Count of events for each PMC.
- *      L1 I/D qualifier -*                     |        p1, p2, p3, p4, p5, p6.
+ *               [ ] |   [ ]   [  sample ]   [     ]   [6] [5]   [4] [3]   [2] [1]
+ *                |  |    |                     |
+ *      BHRB IFM -*  |    |                     |      Count of events for each PMC.
+ *              EBB -*    |                     |        p1, p2, p3, p4, p5, p6.
+ *      L1 I/D qualifier -*                     |
  *                     nc - number of counters -*
  *
  * The PMC fields P1..P6, and NC, are adder fields. As we accumulate constraints
 #define CNST_EBB_VAL(v)                (((v) & EVENT_EBB_MASK) << 24)
 #define CNST_EBB_MASK          CNST_EBB_VAL(EVENT_EBB_MASK)
 
+#define CNST_IFM_VAL(v)                (((v) & EVENT_IFM_MASK) << 25)
+#define CNST_IFM_MASK          CNST_IFM_VAL(EVENT_IFM_MASK)
+
 #define CNST_L1_QUAL_VAL(v)    (((v) & 3) << 22)
 #define CNST_L1_QUAL_MASK      CNST_L1_QUAL_VAL(3)
 
 #define MMCRA_THR_SEL_SHIFT            16
 #define MMCRA_THR_CMP_SHIFT            32
 #define MMCRA_SDAR_MODE_TLB            (1ull << 42)
+#define MMCRA_IFM_SHIFT                        30
 
 
 static inline bool event_is_fab_match(u64 event)
@@ -265,20 +289,22 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
        pmc   = (event >> EVENT_PMC_SHIFT)        & EVENT_PMC_MASK;
        unit  = (event >> EVENT_UNIT_SHIFT)       & EVENT_UNIT_MASK;
        cache = (event >> EVENT_CACHE_SEL_SHIFT)  & EVENT_CACHE_SEL_MASK;
-       ebb   = (event >> PERF_EVENT_CONFIG_EBB_SHIFT) & EVENT_EBB_MASK;
-
-       /* Clear the EBB bit in the event, so event checks work below */
-       event &= ~(EVENT_EBB_MASK << PERF_EVENT_CONFIG_EBB_SHIFT);
+       ebb   = (event >> EVENT_EBB_SHIFT)        & EVENT_EBB_MASK;
 
        if (pmc) {
+               u64 base_event;
+
                if (pmc > 6)
                        return -1;
 
-               mask  |= CNST_PMC_MASK(pmc);
-               value |= CNST_PMC_VAL(pmc);
+               /* Ignore Linux defined bits when checking event below */
+               base_event = event & ~EVENT_LINUX_MASK;
 
-               if (pmc >= 5 && event != 0x500fa && event != 0x600f4)
+               if (pmc >= 5 && base_event != 0x500fa && base_event != 0x600f4)
                        return -1;
+
+               mask  |= CNST_PMC_MASK(pmc);
+               value |= CNST_PMC_VAL(pmc);
        }
 
        if (pmc <= 4) {
@@ -299,9 +325,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
                 * HV writable, and there is no API for guest kernels to modify
                 * it. The solution is for the hypervisor to initialise the
                 * field to zeroes, and for us to only ever allow events that
-                * have a cache selector of zero.
+                * have a cache selector of zero. The bank selector (bit 3) is
+                * irrelevant, as long as the rest of the value is 0.
                 */
-               if (cache)
+               if (cache & 0x7)
                        return -1;
 
        } else if (event & EVENT_IS_L1) {
@@ -342,6 +369,15 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long
                /* EBB events must specify the PMC */
                return -1;
 
+       if (event & EVENT_WANTS_BHRB) {
+               if (!ebb)
+                       /* Only EBB events can request BHRB */
+                       return -1;
+
+               mask  |= CNST_IFM_MASK;
+               value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT);
+       }
+
        /*
         * All events must agree on EBB, either all request it or none.
         * EBB events are pinned & exclusive, so this should never actually
@@ -431,6 +467,11 @@ static int power8_compute_mmcr(u64 event[], int n_ev,
                        mmcra |= val << MMCRA_THR_CMP_SHIFT;
                }
 
+               if (event[i] & EVENT_WANTS_BHRB) {
+                       val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK;
+                       mmcra |= val << MMCRA_IFM_SHIFT;
+               }
+
                hwc[i] = pmc - 1;
        }
 
@@ -774,6 +815,9 @@ static int __init init_power8_pmu(void)
        /* Tell userspace that EBB is supported */
        cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
 
+       if (cpu_has_feature(CPU_FTR_PMAO_BUG))
+               pr_info("PMAO restore workaround active.\n");
+
        return 0;
 }
 early_initcall(init_power8_pmu);
index 213d5b8158270058cc41ed6513a8d55d7028baf0..84476b646005aab57db2447ad0f711595bf3d0bf 100644 (file)
@@ -68,6 +68,7 @@ define_machine(c293_pcie) {
        .init_IRQ               = c293_pcie_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index 3b085c7ee539bc23fbcaf0e38ebaa7752a8e05d3..b564b5e23f7c315d9fb88e2d0c7f5374f9aa24e8 100644 (file)
@@ -107,6 +107,12 @@ void __init mpc85xx_qe_init(void)
        qe_reset();
        of_node_put(np);
 
+}
+
+void __init mpc85xx_qe_par_io_init(void)
+{
+       struct device_node *np;
+
        np = of_find_node_by_name(NULL, "par_io");
        if (np) {
                struct device_node *ucc;
index fbd871e6975464d5df532402c956213ad5b9c055..8e4b1e1a49113cb17b6bf394d743a57bce9e9113 100644 (file)
 #include <asm/udbg.h>
 #include <asm/mpic.h>
 #include <asm/ehv_pic.h>
+#include <asm/qe_ic.h>
 
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include "smp.h"
+#include "mpc85xx.h"
 
 void __init corenet_gen_pic_init(void)
 {
@@ -38,6 +40,8 @@ void __init corenet_gen_pic_init(void)
        unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
                MPIC_NO_RESET;
 
+       struct device_node *np;
+
        if (ppc_md.get_irq == mpic_get_coreint_irq)
                flags |= MPIC_ENABLE_COREINT;
 
@@ -45,6 +49,13 @@ void __init corenet_gen_pic_init(void)
        BUG_ON(mpic == NULL);
 
        mpic_init(mpic);
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
+       if (np) {
+               qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
+                               qe_ic_cascade_high_mpic);
+               of_node_put(np);
+       }
 }
 
 /*
@@ -57,6 +68,8 @@ void __init corenet_gen_setup_arch(void)
        swiotlb_detect_4g();
 
        pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
+
+       mpc85xx_qe_init();
 }
 
 static const struct of_device_id of_device_ids[] = {
@@ -81,6 +94,9 @@ static const struct of_device_id of_device_ids[] = {
        {
                .compatible     = "fsl,qoriq-pcie-v3.0",
        },
+       {
+               .compatible     = "fsl,qe",
+       },
        /* The following two are for the Freescale hypervisor */
        {
                .name           = "hypervisor",
@@ -163,6 +179,7 @@ define_machine(corenet_generic) {
        .init_IRQ               = corenet_gen_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_coreint_irq,
        .restart                = fsl_rstcr_restart,
index e6285ae6f4239d5e12ada123c937c272964f4e67..11790e074c8a6afd6d513d89617ed25f6771240a 100644 (file)
@@ -215,6 +215,7 @@ define_machine(ge_imp3a) {
        .show_cpuinfo           = ge_imp3a_show_cpuinfo,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index 15ce4b55f117896b2f96cd3dd0bab994a8310613..a378ba3519e9fdb6a830a3e89d0364048e278196 100644 (file)
@@ -76,6 +76,7 @@ define_machine(mpc8536_ds) {
        .init_IRQ               = mpc8536_ds_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index fc51dd4092e5d10d88620f10c07434072e612b63..39056f6befeba8ef5cbeb025ed1cf13adce7ee4d 100644 (file)
@@ -10,8 +10,10 @@ static inline void __init mpc85xx_cpm2_pic_init(void) {}
 
 #ifdef CONFIG_QUICC_ENGINE
 extern void mpc85xx_qe_init(void);
+extern void mpc85xx_qe_par_io_init(void);
 #else
 static inline void __init mpc85xx_qe_init(void) {}
+static inline void __init mpc85xx_qe_par_io_init(void) {}
 #endif
 
 #endif
index 7a31a0e1df2987b0bf33bd33c90b971676c57f5e..b0753e2220862cb1585fefa23aee64889390b4d3 100644 (file)
@@ -385,6 +385,7 @@ define_machine(mpc85xx_cds) {
 #ifdef CONFIG_PCI
        .restart        = mpc85xx_cds_restart,
        .pcibios_fixup_bus      = mpc85xx_cds_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #else
        .restart        = fsl_rstcr_restart,
 #endif
index 9ebb91ed96a332e1683ec364f3e7ba2a5e0cd982..ffdf02121a7cb9ecf51d888cf26126a621faa4c4 100644 (file)
@@ -209,6 +209,7 @@ define_machine(mpc8544_ds) {
        .init_IRQ               = mpc85xx_ds_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -223,6 +224,7 @@ define_machine(mpc8572_ds) {
        .init_IRQ               = mpc85xx_ds_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -237,6 +239,7 @@ define_machine(p2020_ds) {
        .init_IRQ               = mpc85xx_ds_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index 34f3c5eb3bee77dcf584b9742a241ee9d99cc310..a392e94a07fadb48413d4f284d62c8a277427a68 100644 (file)
@@ -239,6 +239,7 @@ static void __init mpc85xx_mds_qe_init(void)
        struct device_node *np;
 
        mpc85xx_qe_init();
+       mpc85xx_qe_par_io_init();
        mpc85xx_mds_reset_ucc_phys();
 
        if (machine_is(p1021_mds)) {
@@ -391,6 +392,7 @@ define_machine(mpc8568_mds) {
        .progress       = udbg_progress,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
@@ -412,6 +414,7 @@ define_machine(mpc8569_mds) {
        .progress       = udbg_progress,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
@@ -434,6 +437,7 @@ define_machine(p1021_mds) {
        .progress       = udbg_progress,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
index e15bdd18fdb2f2571312a6cfad74ee5ee741bbd9..e358bed66d014781056f9af672b5171310d5c2f8 100644 (file)
@@ -86,10 +86,6 @@ void __init mpc85xx_rdb_pic_init(void)
  */
 static void __init mpc85xx_rdb_setup_arch(void)
 {
-#ifdef CONFIG_QUICC_ENGINE
-       struct device_node *np;
-#endif
-
        if (ppc_md.progress)
                ppc_md.progress("mpc85xx_rdb_setup_arch()", 0);
 
@@ -99,8 +95,10 @@ static void __init mpc85xx_rdb_setup_arch(void)
 
 #ifdef CONFIG_QUICC_ENGINE
        mpc85xx_qe_init();
+       mpc85xx_qe_par_io_init();
 #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
        if (machine_is(p1025_rdb)) {
+               struct device_node *np;
 
                struct ccsr_guts __iomem *guts;
 
@@ -233,6 +231,7 @@ define_machine(p2020_rdb) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -247,6 +246,7 @@ define_machine(p1020_rdb) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -261,6 +261,7 @@ define_machine(p1021_rdb_pc) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -275,6 +276,7 @@ define_machine(p2020_rdb_pc) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -289,6 +291,7 @@ define_machine(p1025_rdb) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -303,6 +306,7 @@ define_machine(p1020_mbg_pc) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -317,6 +321,7 @@ define_machine(p1020_utm_pc) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -331,6 +336,7 @@ define_machine(p1020_rdb_pc) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -345,6 +351,7 @@ define_machine(p1020_rdb_pd) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -359,6 +366,7 @@ define_machine(p1024_rdb) {
        .init_IRQ               = mpc85xx_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index d6a3dd3114945676eb89fa4e3e3d91a34a0b1c6c..ad1a3d438a9ee65eb705fe107fdd7283a017d18b 100644 (file)
@@ -78,6 +78,7 @@ define_machine(p1010_rdb) {
        .init_IRQ               = p1010_rdb_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index e611e79f23ce68053d0c4190adf2b2104862e6a9..6ac986d3f8a39984ae8308a092191831c796e21b 100644 (file)
@@ -567,6 +567,7 @@ define_machine(p1022_ds) {
        .init_IRQ               = p1022_ds_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index 8c9297112b30d65ddbe8cf6ef8473ded29d74cf8..7a180f0308d55ad316a74c39083515fb92322326 100644 (file)
@@ -147,6 +147,7 @@ define_machine(p1022_rdk) {
        .init_IRQ               = p1022_rdk_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index 2ae9d490c3d940954ac2a805ca14764b5c5bf4d8..0e614007acfb36e7f6fdad6fb139dc2f0ff5e96b 100644 (file)
@@ -126,6 +126,7 @@ define_machine(p1023_rds) {
        .progress               = udbg_progress,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
 
@@ -140,5 +141,6 @@ define_machine(p1023_rdb) {
        .progress               = udbg_progress,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
 };
index 5cefc5a9a144fa682a69c4499f5ca3802b7a1c6b..7f26732935496381f92446600f30262dccb4215a 100644 (file)
@@ -66,6 +66,7 @@ define_machine(qemu_e500) {
        .init_IRQ               = qemu_e500_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_coreint_irq,
        .restart                = fsl_rstcr_restart,
index f62121825914d952add0d638adfc470551e6e0da..b07214666d65f70a9cf2015bf5dd6264631e6795 100644 (file)
@@ -135,6 +135,7 @@ define_machine(sbc8548) {
        .restart        = fsl_rstcr_restart,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .calibrate_decr = generic_calibrate_decr,
        .progress       = udbg_progress,
index c25ff10f05ee14a4a3f97ec83a620d35f1449738..1eadb6d0dc6406acbe24a5b946fb4a62b104b83e 100644 (file)
@@ -77,6 +77,7 @@ static void __init twr_p1025_setup_arch(void)
 
 #ifdef CONFIG_QUICC_ENGINE
        mpc85xx_qe_init();
+       mpc85xx_qe_par_io_init();
 
 #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE)
        if (machine_is(twr_p1025)) {
index dcbf7e42dce79100881ac66ea4ab93e9a8b5571c..1a9c1085855fea67a08da7f18a3e42793183ff94 100644 (file)
@@ -170,6 +170,7 @@ define_machine(xes_mpc8572) {
        .init_IRQ               = xes_mpc85xx_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -184,6 +185,7 @@ define_machine(xes_mpc8548) {
        .init_IRQ               = xes_mpc85xx_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
@@ -198,6 +200,7 @@ define_machine(xes_mpc8540) {
        .init_IRQ               = xes_mpc85xx_pic_init,
 #ifdef CONFIG_PCI
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+       .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 #endif
        .get_irq                = mpic_get_irq,
        .restart                = fsl_rstcr_restart,
index 6d3c7a9fd047a5de571a733d11aa31bd48cd82bd..2a7024d8d8b1333f646bce95738d83b6e9ba0999 100644 (file)
@@ -34,7 +34,6 @@ config MPC7448HPC2
        select TSI108_BRIDGE
        select DEFAULT_UIMAGE
        select PPC_UDBG_16550
-       select TSI108_BRIDGE
        help
          Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
          platform
@@ -44,19 +43,10 @@ config PPC_HOLLY
        depends on EMBEDDED6xx
        select TSI108_BRIDGE
        select PPC_UDBG_16550
-       select TSI108_BRIDGE
        help
          Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval
          Board with TSI108/9 bridge (Hickory/Holly)
 
-config PPC_PRPMC2800
-       bool "Motorola-PrPMC2800"
-       depends on EMBEDDED6xx
-       select MV64X60
-       select NOT_COHERENT_CACHE
-       help
-         This option enables support for the Motorola PrPMC2800 board
-
 config PPC_C2K
        bool "SBS/GEFanuc C2K board"
        depends on EMBEDDED6xx
index cdd48d402b93eba2633ff5854eb4bf8723e47cbb..f126a2a0998170c118c7d17d9e6bfc36989233d7 100644 (file)
@@ -5,7 +5,6 @@ obj-$(CONFIG_MPC7448HPC2)       += mpc7448_hpc2.o
 obj-$(CONFIG_LINKSTATION)      += linkstation.o ls_uart.o
 obj-$(CONFIG_STORCENTER)       += storcenter.o
 obj-$(CONFIG_PPC_HOLLY)                += holly.o
-obj-$(CONFIG_PPC_PRPMC2800)    += prpmc2800.o
 obj-$(CONFIG_PPC_C2K)          += c2k.o
 obj-$(CONFIG_USBGECKO_UDBG)    += usbgecko_udbg.o
 obj-$(CONFIG_GAMECUBE_COMMON)  += flipper-pic.o
diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
deleted file mode 100644 (file)
index d455f08..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Board setup routines for the Motorola PrPMC2800
- *
- * Author: Dale Farnsworth <dale@farnsworth.org>
- *
- * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/seq_file.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/time.h>
-
-#include <mm/mmu_decl.h>
-
-#include <sysdev/mv64x60.h>
-
-#define MV64x60_MPP_CNTL_0     0x0000
-#define MV64x60_MPP_CNTL_2     0x0008
-
-#define MV64x60_GPP_IO_CNTL    0x0000
-#define MV64x60_GPP_LEVEL_CNTL 0x0010
-#define MV64x60_GPP_VALUE_SET  0x0018
-
-#define PLATFORM_NAME_MAX      32
-
-static char prpmc2800_platform_name[PLATFORM_NAME_MAX];
-
-static void __iomem *mv64x60_mpp_reg_base;
-static void __iomem *mv64x60_gpp_reg_base;
-
-static void __init prpmc2800_setup_arch(void)
-{
-       struct device_node *np;
-       phys_addr_t paddr;
-       const unsigned int *reg;
-
-       /*
-        * ioremap mpp and gpp registers in case they are later
-        * needed by prpmc2800_reset_board().
-        */
-       np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
-       reg = of_get_property(np, "reg", NULL);
-       paddr = of_translate_address(np, reg);
-       of_node_put(np);
-       mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
-
-       np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
-       reg = of_get_property(np, "reg", NULL);
-       paddr = of_translate_address(np, reg);
-       of_node_put(np);
-       mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
-
-#ifdef CONFIG_PCI
-       mv64x60_pci_init();
-#endif
-
-       printk("Motorola %s\n", prpmc2800_platform_name);
-}
-
-static void prpmc2800_reset_board(void)
-{
-       u32 temp;
-
-       local_irq_disable();
-
-       temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
-       temp &= 0xFFFF0FFF;
-       out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
-
-       temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
-       temp |= 0x00000004;
-       out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
-
-       temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
-       temp |= 0x00000004;
-       out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
-
-       temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
-       temp &= 0xFFFF0FFF;
-       out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
-
-       temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
-       temp |= 0x00080000;
-       out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
-
-       temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
-       temp |= 0x00080000;
-       out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
-
-       out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
-}
-
-static void prpmc2800_restart(char *cmd)
-{
-       volatile ulong i = 10000000;
-
-       prpmc2800_reset_board();
-
-       while (i-- > 0);
-       panic("restart failed\n");
-}
-
-#ifdef CONFIG_NOT_COHERENT_CACHE
-#define PPRPM2800_COHERENCY_SETTING "off"
-#else
-#define PPRPM2800_COHERENCY_SETTING "on"
-#endif
-
-void prpmc2800_show_cpuinfo(struct seq_file *m)
-{
-       seq_printf(m, "Vendor\t\t: Motorola\n");
-       seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
-}
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init prpmc2800_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-       unsigned long len = PLATFORM_NAME_MAX;
-       void *m;
-
-       if (!of_flat_dt_is_compatible(root, "motorola,PrPMC2800"))
-               return 0;
-
-       /* Update ppc_md.name with name from dt */
-       m = of_get_flat_dt_prop(root, "model", &len);
-       if (m)
-               strncpy(prpmc2800_platform_name, m,
-                       min((int)len, PLATFORM_NAME_MAX - 1));
-
-       _set_L2CR(_get_L2CR() | L2CR_L2E);
-       return 1;
-}
-
-define_machine(prpmc2800){
-       .name                   = prpmc2800_platform_name,
-       .probe                  = prpmc2800_probe,
-       .setup_arch             = prpmc2800_setup_arch,
-       .init_early             = mv64x60_init_early,
-       .show_cpuinfo           = prpmc2800_show_cpuinfo,
-       .init_IRQ               = mv64x60_init_irq,
-       .get_irq                = mv64x60_get_irq,
-       .restart                = prpmc2800_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-};
index 8d767fde5a6ac32484bf106698d8c43e1292cd73..f324ea0995033c9197ace32b35a4b50768b7a3ce 100644 (file)
@@ -1,6 +1,6 @@
-obj-y                  += setup.o opal-takeover.o opal-wrappers.o opal.o
+obj-y                  += setup.o opal-takeover.o opal-wrappers.o opal.o opal-async.o
 obj-y                  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
-obj-y                  += rng.o
+obj-y                  += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
 
 obj-$(CONFIG_SMP)      += smp.o
 obj-$(CONFIG_PCI)      += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c
new file mode 100644 (file)
index 0000000..cd0c135
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * PowerNV OPAL asynchronous completion interfaces
+ *
+ * Copyright 2013 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/gfp.h>
+#include <linux/of.h>
+#include <asm/opal.h>
+
+#define N_ASYNC_COMPLETIONS    64
+
+static DECLARE_BITMAP(opal_async_complete_map, N_ASYNC_COMPLETIONS) = {~0UL};
+static DECLARE_BITMAP(opal_async_token_map, N_ASYNC_COMPLETIONS);
+static DECLARE_WAIT_QUEUE_HEAD(opal_async_wait);
+static DEFINE_SPINLOCK(opal_async_comp_lock);
+static struct semaphore opal_async_sem;
+static struct opal_msg *opal_async_responses;
+static unsigned int opal_max_async_tokens;
+
+int __opal_async_get_token(void)
+{
+       unsigned long flags;
+       int token;
+
+       spin_lock_irqsave(&opal_async_comp_lock, flags);
+       token = find_first_bit(opal_async_complete_map, opal_max_async_tokens);
+       if (token >= opal_max_async_tokens) {
+               token = -EBUSY;
+               goto out;
+       }
+
+       if (__test_and_set_bit(token, opal_async_token_map)) {
+               token = -EBUSY;
+               goto out;
+       }
+
+       __clear_bit(token, opal_async_complete_map);
+
+out:
+       spin_unlock_irqrestore(&opal_async_comp_lock, flags);
+       return token;
+}
+
+int opal_async_get_token_interruptible(void)
+{
+       int token;
+
+       /* Wait until a token is available */
+       if (down_interruptible(&opal_async_sem))
+               return -ERESTARTSYS;
+
+       token = __opal_async_get_token();
+       if (token < 0)
+               up(&opal_async_sem);
+
+       return token;
+}
+
+int __opal_async_release_token(int token)
+{
+       unsigned long flags;
+
+       if (token < 0 || token >= opal_max_async_tokens) {
+               pr_err("%s: Passed token is out of range, token %d\n",
+                               __func__, token);
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&opal_async_comp_lock, flags);
+       __set_bit(token, opal_async_complete_map);
+       __clear_bit(token, opal_async_token_map);
+       spin_unlock_irqrestore(&opal_async_comp_lock, flags);
+
+       return 0;
+}
+
+int opal_async_release_token(int token)
+{
+       int ret;
+
+       ret = __opal_async_release_token(token);
+       if (ret)
+               return ret;
+
+       up(&opal_async_sem);
+
+       return 0;
+}
+
+int opal_async_wait_response(uint64_t token, struct opal_msg *msg)
+{
+       if (token >= opal_max_async_tokens) {
+               pr_err("%s: Invalid token passed\n", __func__);
+               return -EINVAL;
+       }
+
+       if (!msg) {
+               pr_err("%s: Invalid message pointer passed\n", __func__);
+               return -EINVAL;
+       }
+
+       wait_event(opal_async_wait, test_bit(token, opal_async_complete_map));
+       memcpy(msg, &opal_async_responses[token], sizeof(*msg));
+
+       return 0;
+}
+
+static int opal_async_comp_event(struct notifier_block *nb,
+               unsigned long msg_type, void *msg)
+{
+       struct opal_msg *comp_msg = msg;
+       unsigned long flags;
+
+       if (msg_type != OPAL_MSG_ASYNC_COMP)
+               return 0;
+
+       memcpy(&opal_async_responses[comp_msg->params[0]], comp_msg,
+                       sizeof(*comp_msg));
+       spin_lock_irqsave(&opal_async_comp_lock, flags);
+       __set_bit(comp_msg->params[0], opal_async_complete_map);
+       spin_unlock_irqrestore(&opal_async_comp_lock, flags);
+
+       wake_up(&opal_async_wait);
+
+       return 0;
+}
+
+static struct notifier_block opal_async_comp_nb = {
+               .notifier_call  = opal_async_comp_event,
+               .next           = NULL,
+               .priority       = 0,
+};
+
+static int __init opal_async_comp_init(void)
+{
+       struct device_node *opal_node;
+       const __be32 *async;
+       int err;
+
+       opal_node = of_find_node_by_path("/ibm,opal");
+       if (!opal_node) {
+               pr_err("%s: Opal node not found\n", __func__);
+               err = -ENOENT;
+               goto out;
+       }
+
+       async = of_get_property(opal_node, "opal-msg-async-num", NULL);
+       if (!async) {
+               pr_err("%s: %s has no opal-msg-async-num\n",
+                               __func__, opal_node->full_name);
+               err = -ENOENT;
+               goto out_opal_node;
+       }
+
+       opal_max_async_tokens = be32_to_cpup(async);
+       if (opal_max_async_tokens > N_ASYNC_COMPLETIONS)
+               opal_max_async_tokens = N_ASYNC_COMPLETIONS;
+
+       err = opal_message_notifier_register(OPAL_MSG_ASYNC_COMP,
+                       &opal_async_comp_nb);
+       if (err) {
+               pr_err("%s: Can't register OPAL event notifier (%d)\n",
+                               __func__, err);
+               goto out_opal_node;
+       }
+
+       opal_async_responses = kzalloc(
+                       sizeof(*opal_async_responses) * opal_max_async_tokens,
+                       GFP_KERNEL);
+       if (!opal_async_responses) {
+               pr_err("%s: Out of memory, failed to do asynchronous "
+                               "completion init\n", __func__);
+               err = -ENOMEM;
+               goto out_opal_node;
+       }
+
+       /* Initialize to 1 less than the maximum tokens available, as we may
+        * require to pop one during emergency through synchronous call to
+        * __opal_async_get_token()
+        */
+       sema_init(&opal_async_sem, opal_max_async_tokens - 1);
+
+out_opal_node:
+       of_node_put(opal_node);
+out:
+       return err;
+}
+subsys_initcall(opal_async_comp_init);
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
new file mode 100644 (file)
index 0000000..0c767c5
--- /dev/null
@@ -0,0 +1,525 @@
+/*
+ * PowerNV OPAL Dump Interface
+ *
+ * Copyright 2013,2014 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kobject.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/delay.h>
+
+#include <asm/opal.h>
+
+#define DUMP_TYPE_FSP  0x01
+
+struct dump_obj {
+       struct kobject  kobj;
+       struct bin_attribute dump_attr;
+       uint32_t        id;  /* becomes object name */
+       uint32_t        type;
+       uint32_t        size;
+       char            *buffer;
+};
+#define to_dump_obj(x) container_of(x, struct dump_obj, kobj)
+
+struct dump_attribute {
+       struct attribute attr;
+       ssize_t (*show)(struct dump_obj *dump, struct dump_attribute *attr,
+                       char *buf);
+       ssize_t (*store)(struct dump_obj *dump, struct dump_attribute *attr,
+                        const char *buf, size_t count);
+};
+#define to_dump_attr(x) container_of(x, struct dump_attribute, attr)
+
+static ssize_t dump_id_show(struct dump_obj *dump_obj,
+                           struct dump_attribute *attr,
+                           char *buf)
+{
+       return sprintf(buf, "0x%x\n", dump_obj->id);
+}
+
+static const char* dump_type_to_string(uint32_t type)
+{
+       switch (type) {
+       case 0x01: return "SP Dump";
+       case 0x02: return "System/Platform Dump";
+       case 0x03: return "SMA Dump";
+       default: return "unknown";
+       }
+}
+
+static ssize_t dump_type_show(struct dump_obj *dump_obj,
+                             struct dump_attribute *attr,
+                             char *buf)
+{
+       
+       return sprintf(buf, "0x%x %s\n", dump_obj->type,
+                      dump_type_to_string(dump_obj->type));
+}
+
+static ssize_t dump_ack_show(struct dump_obj *dump_obj,
+                            struct dump_attribute *attr,
+                            char *buf)
+{
+       return sprintf(buf, "ack - acknowledge dump\n");
+}
+
+/*
+ * Send acknowledgement to OPAL
+ */
+static int64_t dump_send_ack(uint32_t dump_id)
+{
+       int rc;
+
+       rc = opal_dump_ack(dump_id);
+       if (rc)
+               pr_warn("%s: Failed to send ack to Dump ID 0x%x (%d)\n",
+                       __func__, dump_id, rc);
+       return rc;
+}
+
+static void delay_release_kobj(void *kobj)
+{
+       kobject_put((struct kobject *)kobj);
+}
+
+static ssize_t dump_ack_store(struct dump_obj *dump_obj,
+                             struct dump_attribute *attr,
+                             const char *buf,
+                             size_t count)
+{
+       dump_send_ack(dump_obj->id);
+       sysfs_schedule_callback(&dump_obj->kobj, delay_release_kobj,
+                               &dump_obj->kobj, THIS_MODULE);
+       return count;
+}
+
+/* Attributes of a dump
+ * The binary attribute of the dump itself is dynamic
+ * due to the dynamic size of the dump
+ */
+static struct dump_attribute id_attribute =
+       __ATTR(id, 0666, dump_id_show, NULL);
+static struct dump_attribute type_attribute =
+       __ATTR(type, 0666, dump_type_show, NULL);
+static struct dump_attribute ack_attribute =
+       __ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store);
+
+static ssize_t init_dump_show(struct dump_obj *dump_obj,
+                             struct dump_attribute *attr,
+                             char *buf)
+{
+       return sprintf(buf, "1 - initiate dump\n");
+}
+
+static int64_t dump_fips_init(uint8_t type)
+{
+       int rc;
+
+       rc = opal_dump_init(type);
+       if (rc)
+               pr_warn("%s: Failed to initiate FipS dump (%d)\n",
+                       __func__, rc);
+       return rc;
+}
+
+static ssize_t init_dump_store(struct dump_obj *dump_obj,
+                              struct dump_attribute *attr,
+                              const char *buf,
+                              size_t count)
+{
+       dump_fips_init(DUMP_TYPE_FSP);
+       pr_info("%s: Initiated FSP dump\n", __func__);
+       return count;
+}
+
+static struct dump_attribute initiate_attribute =
+       __ATTR(initiate_dump, 0600, init_dump_show, init_dump_store);
+
+static struct attribute *initiate_attrs[] = {
+       &initiate_attribute.attr,
+       NULL,
+};
+
+static struct attribute_group initiate_attr_group = {
+       .attrs = initiate_attrs,
+};
+
+static struct kset *dump_kset;
+
+static ssize_t dump_attr_show(struct kobject *kobj,
+                             struct attribute *attr,
+                             char *buf)
+{
+       struct dump_attribute *attribute;
+       struct dump_obj *dump;
+
+       attribute = to_dump_attr(attr);
+       dump = to_dump_obj(kobj);
+
+       if (!attribute->show)
+               return -EIO;
+
+       return attribute->show(dump, attribute, buf);
+}
+
+static ssize_t dump_attr_store(struct kobject *kobj,
+                              struct attribute *attr,
+                              const char *buf, size_t len)
+{
+       struct dump_attribute *attribute;
+       struct dump_obj *dump;
+
+       attribute = to_dump_attr(attr);
+       dump = to_dump_obj(kobj);
+
+       if (!attribute->store)
+               return -EIO;
+
+       return attribute->store(dump, attribute, buf, len);
+}
+
+static const struct sysfs_ops dump_sysfs_ops = {
+       .show = dump_attr_show,
+       .store = dump_attr_store,
+};
+
+static void dump_release(struct kobject *kobj)
+{
+       struct dump_obj *dump;
+
+       dump = to_dump_obj(kobj);
+       vfree(dump->buffer);
+       kfree(dump);
+}
+
+static struct attribute *dump_default_attrs[] = {
+       &id_attribute.attr,
+       &type_attribute.attr,
+       &ack_attribute.attr,
+       NULL,
+};
+
+static struct kobj_type dump_ktype = {
+       .sysfs_ops = &dump_sysfs_ops,
+       .release = &dump_release,
+       .default_attrs = dump_default_attrs,
+};
+
+static void free_dump_sg_list(struct opal_sg_list *list)
+{
+       struct opal_sg_list *sg1;
+       while (list) {
+               sg1 = list->next;
+               kfree(list);
+               list = sg1;
+       }
+       list = NULL;
+}
+
+static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump)
+{
+       struct opal_sg_list *sg1, *list = NULL;
+       void *addr;
+       int64_t size;
+
+       addr = dump->buffer;
+       size = dump->size;
+
+       sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!sg1)
+               goto nomem;
+
+       list = sg1;
+       sg1->num_entries = 0;
+       while (size > 0) {
+               /* Translate virtual address to physical address */
+               sg1->entry[sg1->num_entries].data =
+                       (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
+
+               if (size > PAGE_SIZE)
+                       sg1->entry[sg1->num_entries].length = PAGE_SIZE;
+               else
+                       sg1->entry[sg1->num_entries].length = size;
+
+               sg1->num_entries++;
+               if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
+                       sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
+                       if (!sg1->next)
+                               goto nomem;
+
+                       sg1 = sg1->next;
+                       sg1->num_entries = 0;
+               }
+               addr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+       return list;
+
+nomem:
+       pr_err("%s : Failed to allocate memory\n", __func__);
+       free_dump_sg_list(list);
+       return NULL;
+}
+
+static void sglist_to_phy_addr(struct opal_sg_list *list)
+{
+       struct opal_sg_list *sg, *next;
+
+       for (sg = list; sg; sg = next) {
+               next = sg->next;
+               /* Don't translate NULL pointer for last entry */
+               if (sg->next)
+                       sg->next = (struct opal_sg_list *)__pa(sg->next);
+               else
+                       sg->next = NULL;
+
+               /* Convert num_entries to length */
+               sg->num_entries =
+                       sg->num_entries * sizeof(struct opal_sg_entry) + 16;
+       }
+}
+
+static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
+{
+       int rc;
+       *type = 0xffffffff;
+
+       rc = opal_dump_info2(id, size, type);
+
+       if (rc == OPAL_PARAMETER)
+               rc = opal_dump_info(id, size);
+
+       if (rc)
+               pr_warn("%s: Failed to get dump info (%d)\n",
+                       __func__, rc);
+       return rc;
+}
+
+static int64_t dump_read_data(struct dump_obj *dump)
+{
+       struct opal_sg_list *list;
+       uint64_t addr;
+       int64_t rc;
+
+       /* Allocate memory */
+       dump->buffer = vzalloc(PAGE_ALIGN(dump->size));
+       if (!dump->buffer) {
+               pr_err("%s : Failed to allocate memory\n", __func__);
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* Generate SG list */
+       list = dump_data_to_sglist(dump);
+       if (!list) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* Translate sg list addr to real address */
+       sglist_to_phy_addr(list);
+
+       /* First entry address */
+       addr = __pa(list);
+
+       /* Fetch data */
+       rc = OPAL_BUSY_EVENT;
+       while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
+               rc = opal_dump_read(dump->id, addr);
+               if (rc == OPAL_BUSY_EVENT) {
+                       opal_poll_events(NULL);
+                       msleep(20);
+               }
+       }
+
+       if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL)
+               pr_warn("%s: Extract dump failed for ID 0x%x\n",
+                       __func__, dump->id);
+
+       /* Free SG list */
+       free_dump_sg_list(list);
+
+out:
+       return rc;
+}
+
+static ssize_t dump_attr_read(struct file *filep, struct kobject *kobj,
+                             struct bin_attribute *bin_attr,
+                             char *buffer, loff_t pos, size_t count)
+{
+       ssize_t rc;
+
+       struct dump_obj *dump = to_dump_obj(kobj);
+
+       if (!dump->buffer) {
+               rc = dump_read_data(dump);
+
+               if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL) {
+                       vfree(dump->buffer);
+                       dump->buffer = NULL;
+
+                       return -EIO;
+               }
+               if (rc == OPAL_PARTIAL) {
+                       /* On a partial read, we just return EIO
+                        * and rely on userspace to ask us to try
+                        * again.
+                        */
+                       pr_info("%s: Platform dump partially read.ID = 0x%x\n",
+                               __func__, dump->id);
+                       return -EIO;
+               }
+       }
+
+       memcpy(buffer, dump->buffer + pos, count);
+
+       /* You may think we could free the dump buffer now and retrieve
+        * it again later if needed, but due to current firmware limitation,
+        * that's not the case. So, once read into userspace once,
+        * we keep the dump around until it's acknowledged by userspace.
+        */
+
+       return count;
+}
+
+static struct dump_obj *create_dump_obj(uint32_t id, size_t size,
+                                       uint32_t type)
+{
+       struct dump_obj *dump;
+       int rc;
+
+       dump = kzalloc(sizeof(*dump), GFP_KERNEL);
+       if (!dump)
+               return NULL;
+
+       dump->kobj.kset = dump_kset;
+
+       kobject_init(&dump->kobj, &dump_ktype);
+
+       sysfs_bin_attr_init(&dump->dump_attr);
+
+       dump->dump_attr.attr.name = "dump";
+       dump->dump_attr.attr.mode = 0400;
+       dump->dump_attr.size = size;
+       dump->dump_attr.read = dump_attr_read;
+
+       dump->id = id;
+       dump->size = size;
+       dump->type = type;
+
+       rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id);
+       if (rc) {
+               kobject_put(&dump->kobj);
+               return NULL;
+       }
+
+       rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr);
+       if (rc) {
+               kobject_put(&dump->kobj);
+               return NULL;
+       }
+
+       pr_info("%s: New platform dump. ID = 0x%x Size %u\n",
+               __func__, dump->id, dump->size);
+
+       kobject_uevent(&dump->kobj, KOBJ_ADD);
+
+       return dump;
+}
+
+static int process_dump(void)
+{
+       int rc;
+       uint32_t dump_id, dump_size, dump_type;
+       struct dump_obj *dump;
+       char name[22];
+
+       rc = dump_read_info(&dump_id, &dump_size, &dump_type);
+       if (rc != OPAL_SUCCESS)
+               return rc;
+
+       sprintf(name, "0x%x-0x%x", dump_type, dump_id);
+
+       /* we may get notified twice, let's handle
+        * that gracefully and not create two conflicting
+        * entries.
+        */
+       if (kset_find_obj(dump_kset, name))
+               return 0;
+
+       dump = create_dump_obj(dump_id, dump_size, dump_type);
+       if (!dump)
+               return -1;
+
+       return 0;
+}
+
+static void dump_work_fn(struct work_struct *work)
+{
+       process_dump();
+}
+
+static DECLARE_WORK(dump_work, dump_work_fn);
+
+static void schedule_process_dump(void)
+{
+       schedule_work(&dump_work);
+}
+
+/*
+ * New dump available notification
+ *
+ * Once we get notification, we add sysfs entries for it.
+ * We only fetch the dump on demand, and create sysfs asynchronously.
+ */
+static int dump_event(struct notifier_block *nb,
+                     unsigned long events, void *change)
+{
+       if (events & OPAL_EVENT_DUMP_AVAIL)
+               schedule_process_dump();
+
+       return 0;
+}
+
+static struct notifier_block dump_nb = {
+       .notifier_call  = dump_event,
+       .next           = NULL,
+       .priority       = 0
+};
+
+void __init opal_platform_dump_init(void)
+{
+       int rc;
+
+       dump_kset = kset_create_and_add("dump", NULL, opal_kobj);
+       if (!dump_kset) {
+               pr_warn("%s: Failed to create dump kset\n", __func__);
+               return;
+       }
+
+       rc = sysfs_create_group(&dump_kset->kobj, &initiate_attr_group);
+       if (rc) {
+               pr_warn("%s: Failed to create initiate dump attr group\n",
+                       __func__);
+               kobject_put(&dump_kset->kobj);
+               return;
+       }
+
+       rc = opal_notifier_register(&dump_nb);
+       if (rc) {
+               pr_warn("%s: Can't register OPAL event notifier (%d)\n",
+                       __func__, rc);
+               return;
+       }
+
+       opal_dump_resend_notification();
+}
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
new file mode 100644 (file)
index 0000000..1d7355b
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * Error log support on PowerNV.
+ *
+ * Copyright 2013,2014 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <linux/fcntl.h>
+#include <linux/kobject.h>
+#include <asm/uaccess.h>
+#include <asm/opal.h>
+
+struct elog_obj {
+       struct kobject kobj;
+       struct bin_attribute raw_attr;
+       uint64_t id;
+       uint64_t type;
+       size_t size;
+       char *buffer;
+};
+#define to_elog_obj(x) container_of(x, struct elog_obj, kobj)
+
+struct elog_attribute {
+       struct attribute attr;
+       ssize_t (*show)(struct elog_obj *elog, struct elog_attribute *attr,
+                       char *buf);
+       ssize_t (*store)(struct elog_obj *elog, struct elog_attribute *attr,
+                        const char *buf, size_t count);
+};
+#define to_elog_attr(x) container_of(x, struct elog_attribute, attr)
+
+static ssize_t elog_id_show(struct elog_obj *elog_obj,
+                           struct elog_attribute *attr,
+                           char *buf)
+{
+       return sprintf(buf, "0x%llx\n", elog_obj->id);
+}
+
+static const char *elog_type_to_string(uint64_t type)
+{
+       switch (type) {
+       case 0: return "PEL";
+       default: return "unknown";
+       }
+}
+
+static ssize_t elog_type_show(struct elog_obj *elog_obj,
+                             struct elog_attribute *attr,
+                             char *buf)
+{
+       return sprintf(buf, "0x%llx %s\n",
+                      elog_obj->type,
+                      elog_type_to_string(elog_obj->type));
+}
+
+static ssize_t elog_ack_show(struct elog_obj *elog_obj,
+                            struct elog_attribute *attr,
+                            char *buf)
+{
+       return sprintf(buf, "ack - acknowledge log message\n");
+}
+
+static void delay_release_kobj(void *kobj)
+{
+       kobject_put((struct kobject *)kobj);
+}
+
+static ssize_t elog_ack_store(struct elog_obj *elog_obj,
+                             struct elog_attribute *attr,
+                             const char *buf,
+                             size_t count)
+{
+       opal_send_ack_elog(elog_obj->id);
+       sysfs_schedule_callback(&elog_obj->kobj, delay_release_kobj,
+                               &elog_obj->kobj, THIS_MODULE);
+       return count;
+}
+
+static struct elog_attribute id_attribute =
+       __ATTR(id, 0666, elog_id_show, NULL);
+static struct elog_attribute type_attribute =
+       __ATTR(type, 0666, elog_type_show, NULL);
+static struct elog_attribute ack_attribute =
+       __ATTR(acknowledge, 0660, elog_ack_show, elog_ack_store);
+
+static struct kset *elog_kset;
+
+static ssize_t elog_attr_show(struct kobject *kobj,
+                             struct attribute *attr,
+                             char *buf)
+{
+       struct elog_attribute *attribute;
+       struct elog_obj *elog;
+
+       attribute = to_elog_attr(attr);
+       elog = to_elog_obj(kobj);
+
+       if (!attribute->show)
+               return -EIO;
+
+       return attribute->show(elog, attribute, buf);
+}
+
+static ssize_t elog_attr_store(struct kobject *kobj,
+                              struct attribute *attr,
+                              const char *buf, size_t len)
+{
+       struct elog_attribute *attribute;
+       struct elog_obj *elog;
+
+       attribute = to_elog_attr(attr);
+       elog = to_elog_obj(kobj);
+
+       if (!attribute->store)
+               return -EIO;
+
+       return attribute->store(elog, attribute, buf, len);
+}
+
+static const struct sysfs_ops elog_sysfs_ops = {
+       .show = elog_attr_show,
+       .store = elog_attr_store,
+};
+
+static void elog_release(struct kobject *kobj)
+{
+       struct elog_obj *elog;
+
+       elog = to_elog_obj(kobj);
+       kfree(elog->buffer);
+       kfree(elog);
+}
+
+static struct attribute *elog_default_attrs[] = {
+       &id_attribute.attr,
+       &type_attribute.attr,
+       &ack_attribute.attr,
+       NULL,
+};
+
+static struct kobj_type elog_ktype = {
+       .sysfs_ops = &elog_sysfs_ops,
+       .release = &elog_release,
+       .default_attrs = elog_default_attrs,
+};
+
+/* Maximum size of a single log on FSP is 16KB */
+#define OPAL_MAX_ERRLOG_SIZE   16384
+
+static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj,
+                            struct bin_attribute *bin_attr,
+                            char *buffer, loff_t pos, size_t count)
+{
+       int opal_rc;
+
+       struct elog_obj *elog = to_elog_obj(kobj);
+
+       /* We may have had an error reading before, so let's retry */
+       if (!elog->buffer) {
+               elog->buffer = kzalloc(elog->size, GFP_KERNEL);
+               if (!elog->buffer)
+                       return -EIO;
+
+               opal_rc = opal_read_elog(__pa(elog->buffer),
+                                        elog->size, elog->id);
+               if (opal_rc != OPAL_SUCCESS) {
+                       pr_err("ELOG: log read failed for log-id=%llx\n",
+                              elog->id);
+                       kfree(elog->buffer);
+                       elog->buffer = NULL;
+                       return -EIO;
+               }
+       }
+
+       memcpy(buffer, elog->buffer + pos, count);
+
+       return count;
+}
+
+static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
+{
+       struct elog_obj *elog;
+       int rc;
+
+       elog = kzalloc(sizeof(*elog), GFP_KERNEL);
+       if (!elog)
+               return NULL;
+
+       elog->kobj.kset = elog_kset;
+
+       kobject_init(&elog->kobj, &elog_ktype);
+
+       sysfs_bin_attr_init(&elog->raw_attr);
+
+       elog->raw_attr.attr.name = "raw";
+       elog->raw_attr.attr.mode = 0400;
+       elog->raw_attr.size = size;
+       elog->raw_attr.read = raw_attr_read;
+
+       elog->id = id;
+       elog->size = size;
+       elog->type = type;
+
+       elog->buffer = kzalloc(elog->size, GFP_KERNEL);
+
+       if (elog->buffer) {
+               rc = opal_read_elog(__pa(elog->buffer),
+                                        elog->size, elog->id);
+               if (rc != OPAL_SUCCESS) {
+                       pr_err("ELOG: log read failed for log-id=%llx\n",
+                              elog->id);
+                       kfree(elog->buffer);
+                       elog->buffer = NULL;
+               }
+       }
+
+       rc = kobject_add(&elog->kobj, NULL, "0x%llx", id);
+       if (rc) {
+               kobject_put(&elog->kobj);
+               return NULL;
+       }
+
+       rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr);
+       if (rc) {
+               kobject_put(&elog->kobj);
+               return NULL;
+       }
+
+       kobject_uevent(&elog->kobj, KOBJ_ADD);
+
+       return elog;
+}
+
+static void elog_work_fn(struct work_struct *work)
+{
+       size_t elog_size;
+       uint64_t log_id;
+       uint64_t elog_type;
+       int rc;
+       char name[2+16+1];
+
+       rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
+       if (rc != OPAL_SUCCESS) {
+               pr_err("ELOG: Opal log read failed\n");
+               return;
+       }
+
+       BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);
+
+       if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
+               elog_size  =  OPAL_MAX_ERRLOG_SIZE;
+
+       sprintf(name, "0x%llx", log_id);
+
+       /* we may get notified twice, let's handle
+        * that gracefully and not create two conflicting
+        * entries.
+        */
+       if (kset_find_obj(elog_kset, name))
+               return;
+
+       create_elog_obj(log_id, elog_size, elog_type);
+}
+
+static DECLARE_WORK(elog_work, elog_work_fn);
+
+static int elog_event(struct notifier_block *nb,
+                               unsigned long events, void *change)
+{
+       /* check for error log event */
+       if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
+               schedule_work(&elog_work);
+       return 0;
+}
+
+static struct notifier_block elog_nb = {
+       .notifier_call  = elog_event,
+       .next           = NULL,
+       .priority       = 0
+};
+
+int __init opal_elog_init(void)
+{
+       int rc = 0;
+
+       elog_kset = kset_create_and_add("elog", NULL, opal_kobj);
+       if (!elog_kset) {
+               pr_warn("%s: failed to create elog kset\n", __func__);
+               return -1;
+       }
+
+       rc = opal_notifier_register(&elog_nb);
+       if (rc) {
+               pr_err("%s: Can't register OPAL event notifier (%d)\n",
+               __func__, rc);
+               return rc;
+       }
+
+       /* We are now ready to pull error logs from opal. */
+       opal_resend_pending_logs();
+
+       return 0;
+}
diff --git a/arch/powerpc/platforms/powernv/opal-sensor.c b/arch/powerpc/platforms/powernv/opal-sensor.c
new file mode 100644 (file)
index 0000000..663cc9c
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * PowerNV sensor code
+ *
+ * Copyright (C) 2013 IBM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <asm/opal.h>
+
+static DEFINE_MUTEX(opal_sensor_mutex);
+
+/*
+ * This will return sensor information to driver based on the requested sensor
+ * handle. A handle is an opaque id for the powernv, read by the driver from the
+ * device tree..
+ */
+int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data)
+{
+       int ret, token;
+       struct opal_msg msg;
+
+       token = opal_async_get_token_interruptible();
+       if (token < 0) {
+               pr_err("%s: Couldn't get the token, returning\n", __func__);
+               ret = token;
+               goto out;
+       }
+
+       mutex_lock(&opal_sensor_mutex);
+       ret = opal_sensor_read(sensor_hndl, token, sensor_data);
+       if (ret != OPAL_ASYNC_COMPLETION)
+               goto out_token;
+
+       ret = opal_async_wait_response(token, &msg);
+       if (ret) {
+               pr_err("%s: Failed to wait for the async response, %d\n",
+                               __func__, ret);
+               goto out_token;
+       }
+
+       ret = msg.params[1];
+
+out_token:
+       mutex_unlock(&opal_sensor_mutex);
+       opal_async_release_token(token);
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(opal_get_sensor_data);
diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c
new file mode 100644 (file)
index 0000000..0bd249a
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * PowerNV system parameter code
+ *
+ * Copyright (C) 2013 IBM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/kobject.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/gfp.h>
+#include <linux/stat.h>
+#include <asm/opal.h>
+
+#define MAX_PARAM_DATA_LEN     64
+
+static DEFINE_MUTEX(opal_sysparam_mutex);
+static struct kobject *sysparam_kobj;
+static void *param_data_buf;
+
+struct param_attr {
+       struct list_head list;
+       u32 param_id;
+       u32 param_size;
+       struct kobj_attribute kobj_attr;
+};
+
+static int opal_get_sys_param(u32 param_id, u32 length, void *buffer)
+{
+       struct opal_msg msg;
+       int ret, token;
+
+       token = opal_async_get_token_interruptible();
+       if (token < 0) {
+               if (token != -ERESTARTSYS)
+                       pr_err("%s: Couldn't get the token, returning\n",
+                                       __func__);
+               ret = token;
+               goto out;
+       }
+
+       ret = opal_get_param(token, param_id, (u64)buffer, length);
+       if (ret != OPAL_ASYNC_COMPLETION)
+               goto out_token;
+
+       ret = opal_async_wait_response(token, &msg);
+       if (ret) {
+               pr_err("%s: Failed to wait for the async response, %d\n",
+                               __func__, ret);
+               goto out_token;
+       }
+
+       ret = msg.params[1];
+
+out_token:
+       opal_async_release_token(token);
+out:
+       return ret;
+}
+
+static int opal_set_sys_param(u32 param_id, u32 length, void *buffer)
+{
+       struct opal_msg msg;
+       int ret, token;
+
+       token = opal_async_get_token_interruptible();
+       if (token < 0) {
+               if (token != -ERESTARTSYS)
+                       pr_err("%s: Couldn't get the token, returning\n",
+                                       __func__);
+               ret = token;
+               goto out;
+       }
+
+       ret = opal_set_param(token, param_id, (u64)buffer, length);
+
+       if (ret != OPAL_ASYNC_COMPLETION)
+               goto out_token;
+
+       ret = opal_async_wait_response(token, &msg);
+       if (ret) {
+               pr_err("%s: Failed to wait for the async response, %d\n",
+                               __func__, ret);
+               goto out_token;
+       }
+
+       ret = msg.params[1];
+
+out_token:
+       opal_async_release_token(token);
+out:
+       return ret;
+}
+
+static ssize_t sys_param_show(struct kobject *kobj,
+               struct kobj_attribute *kobj_attr, char *buf)
+{
+       struct param_attr *attr = container_of(kobj_attr, struct param_attr,
+                       kobj_attr);
+       int ret;
+
+       mutex_lock(&opal_sysparam_mutex);
+       ret = opal_get_sys_param(attr->param_id, attr->param_size,
+                       param_data_buf);
+       if (ret)
+               goto out;
+
+       memcpy(buf, param_data_buf, attr->param_size);
+
+out:
+       mutex_unlock(&opal_sysparam_mutex);
+       return ret ? ret : attr->param_size;
+}
+
+static ssize_t sys_param_store(struct kobject *kobj,
+               struct kobj_attribute *kobj_attr, const char *buf, size_t count)
+{
+       struct param_attr *attr = container_of(kobj_attr, struct param_attr,
+                       kobj_attr);
+       int ret;
+
+       mutex_lock(&opal_sysparam_mutex);
+       memcpy(param_data_buf, buf, count);
+       ret = opal_set_sys_param(attr->param_id, attr->param_size,
+                       param_data_buf);
+       mutex_unlock(&opal_sysparam_mutex);
+       return ret ? ret : count;
+}
+
+void __init opal_sys_param_init(void)
+{
+       struct device_node *sysparam;
+       struct param_attr *attr;
+       u32 *id, *size;
+       int count, i;
+       u8 *perm;
+
+       if (!opal_kobj) {
+               pr_warn("SYSPARAM: opal kobject is not available\n");
+               goto out;
+       }
+
+       sysparam_kobj = kobject_create_and_add("sysparams", opal_kobj);
+       if (!sysparam_kobj) {
+               pr_err("SYSPARAM: Failed to create sysparam kobject\n");
+               goto out;
+       }
+
+       /* Allocate big enough buffer for any get/set transactions */
+       param_data_buf = kzalloc(MAX_PARAM_DATA_LEN, GFP_KERNEL);
+       if (!param_data_buf) {
+               pr_err("SYSPARAM: Failed to allocate memory for param data "
+                               "buf\n");
+               goto out_kobj_put;
+       }
+
+       sysparam = of_find_node_by_path("/ibm,opal/sysparams");
+       if (!sysparam) {
+               pr_err("SYSPARAM: Opal sysparam node not found\n");
+               goto out_param_buf;
+       }
+
+       if (!of_device_is_compatible(sysparam, "ibm,opal-sysparams")) {
+               pr_err("SYSPARAM: Opal sysparam node not compatible\n");
+               goto out_node_put;
+       }
+
+       /* Number of parameters exposed through DT */
+       count = of_property_count_strings(sysparam, "param-name");
+       if (count < 0) {
+               pr_err("SYSPARAM: No string found of property param-name in "
+                               "the node %s\n", sysparam->name);
+               goto out_node_put;
+       }
+
+       id = kzalloc(sizeof(*id) * count, GFP_KERNEL);
+       if (!id) {
+               pr_err("SYSPARAM: Failed to allocate memory to read parameter "
+                               "id\n");
+               goto out_node_put;
+       }
+
+       size = kzalloc(sizeof(*size) * count, GFP_KERNEL);
+       if (!size) {
+               pr_err("SYSPARAM: Failed to allocate memory to read parameter "
+                               "size\n");
+               goto out_free_id;
+       }
+
+       perm = kzalloc(sizeof(*perm) * count, GFP_KERNEL);
+       if (!perm) {
+               pr_err("SYSPARAM: Failed to allocate memory to read supported "
+                               "action on the parameter");
+               goto out_free_size;
+       }
+
+       if (of_property_read_u32_array(sysparam, "param-id", id, count)) {
+               pr_err("SYSPARAM: Missing property param-id in the DT\n");
+               goto out_free_perm;
+       }
+
+       if (of_property_read_u32_array(sysparam, "param-len", size, count)) {
+               pr_err("SYSPARAM: Missing propery param-len in the DT\n");
+               goto out_free_perm;
+       }
+
+
+       if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) {
+               pr_err("SYSPARAM: Missing propery param-perm in the DT\n");
+               goto out_free_perm;
+       }
+
+       attr = kzalloc(sizeof(*attr) * count, GFP_KERNEL);
+       if (!attr) {
+               pr_err("SYSPARAM: Failed to allocate memory for parameter "
+                               "attributes\n");
+               goto out_free_perm;
+       }
+
+       /* For each of the parameters, populate the parameter attributes */
+       for (i = 0; i < count; i++) {
+               sysfs_attr_init(&attr[i].kobj_attr.attr);
+               attr[i].param_id = id[i];
+               attr[i].param_size = size[i];
+               if (of_property_read_string_index(sysparam, "param-name", i,
+                               &attr[i].kobj_attr.attr.name))
+                       continue;
+
+               /* If the parameter is read-only or read-write */
+               switch (perm[i] & 3) {
+               case OPAL_SYSPARAM_READ:
+                       attr[i].kobj_attr.attr.mode = S_IRUGO;
+                       break;
+               case OPAL_SYSPARAM_WRITE:
+                       attr[i].kobj_attr.attr.mode = S_IWUGO;
+                       break;
+               case OPAL_SYSPARAM_RW:
+                       attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUGO;
+                       break;
+               default:
+                       break;
+               }
+
+               attr[i].kobj_attr.show = sys_param_show;
+               attr[i].kobj_attr.store = sys_param_store;
+
+               if (sysfs_create_file(sysparam_kobj, &attr[i].kobj_attr.attr)) {
+                       pr_err("SYSPARAM: Failed to create sysfs file %s\n",
+                                       attr[i].kobj_attr.attr.name);
+                       goto out_free_attr;
+               }
+       }
+
+       kfree(perm);
+       kfree(size);
+       kfree(id);
+       of_node_put(sysparam);
+       return;
+
+out_free_attr:
+       kfree(attr);
+out_free_perm:
+       kfree(perm);
+out_free_size:
+       kfree(size);
+out_free_id:
+       kfree(id);
+out_node_put:
+       of_node_put(sysparam);
+out_param_buf:
+       kfree(param_data_buf);
+out_kobj_put:
+       kobject_put(sysparam_kobj);
+out:
+       return;
+}
index 3e8829c40fbbfc436adb206fb297b82ea7385e89..75c89df8d71e95b130dc827e036f25330cc1d6ad 100644 (file)
@@ -123,9 +123,23 @@ OPAL_CALL(opal_xscom_write,                        OPAL_XSCOM_WRITE);
 OPAL_CALL(opal_lpc_read,                       OPAL_LPC_READ);
 OPAL_CALL(opal_lpc_write,                      OPAL_LPC_WRITE);
 OPAL_CALL(opal_return_cpu,                     OPAL_RETURN_CPU);
+OPAL_CALL(opal_read_elog,                      OPAL_ELOG_READ);
+OPAL_CALL(opal_send_ack_elog,                  OPAL_ELOG_ACK);
+OPAL_CALL(opal_get_elog_size,                  OPAL_ELOG_SIZE);
+OPAL_CALL(opal_resend_pending_logs,            OPAL_ELOG_RESEND);
+OPAL_CALL(opal_write_elog,                     OPAL_ELOG_WRITE);
 OPAL_CALL(opal_validate_flash,                 OPAL_FLASH_VALIDATE);
 OPAL_CALL(opal_manage_flash,                   OPAL_FLASH_MANAGE);
 OPAL_CALL(opal_update_flash,                   OPAL_FLASH_UPDATE);
+OPAL_CALL(opal_dump_init,                      OPAL_DUMP_INIT);
+OPAL_CALL(opal_dump_info,                      OPAL_DUMP_INFO);
+OPAL_CALL(opal_dump_info2,                     OPAL_DUMP_INFO2);
+OPAL_CALL(opal_dump_read,                      OPAL_DUMP_READ);
+OPAL_CALL(opal_dump_ack,                       OPAL_DUMP_ACK);
 OPAL_CALL(opal_get_msg,                                OPAL_GET_MSG);
 OPAL_CALL(opal_check_completion,               OPAL_CHECK_ASYNC_COMPLETION);
+OPAL_CALL(opal_dump_resend_notification,       OPAL_DUMP_RESEND);
 OPAL_CALL(opal_sync_host_reboot,               OPAL_SYNC_HOST_REBOOT);
+OPAL_CALL(opal_sensor_read,                    OPAL_SENSOR_READ);
+OPAL_CALL(opal_get_param,                      OPAL_GET_PARAM);
+OPAL_CALL(opal_set_param,                      OPAL_SET_PARAM);
index 65499adaecff2a1e2367612ece5e051028e38634..e92f2f67640f7db39e18d78ccbb08d6ad12eed7e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/kobject.h>
 #include <linux/delay.h>
+#include <linux/memblock.h>
 #include <asm/opal.h>
 #include <asm/firmware.h>
 #include <asm/mce.h>
@@ -33,8 +34,18 @@ struct kobject *opal_kobj;
 struct opal {
        u64 base;
        u64 entry;
+       u64 size;
 } opal;
 
+struct mcheck_recoverable_range {
+       u64 start_addr;
+       u64 end_addr;
+       u64 recover_addr;
+};
+
+static struct mcheck_recoverable_range *mc_recoverable_range;
+static int mc_recoverable_range_len;
+
 static struct device_node *opal_node;
 static DEFINE_SPINLOCK(opal_write_lock);
 extern u64 opal_mc_secondary_handler[];
@@ -49,25 +60,29 @@ static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
 int __init early_init_dt_scan_opal(unsigned long node,
                                   const char *uname, int depth, void *data)
 {
-       const void *basep, *entryp;
-       unsigned long basesz, entrysz;
+       const void *basep, *entryp, *sizep;
+       unsigned long basesz, entrysz, runtimesz;
 
        if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
                return 0;
 
        basep  = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
        entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
+       sizep = of_get_flat_dt_prop(node, "opal-runtime-size", &runtimesz);
 
-       if (!basep || !entryp)
+       if (!basep || !entryp || !sizep)
                return 1;
 
        opal.base = of_read_number(basep, basesz/4);
        opal.entry = of_read_number(entryp, entrysz/4);
+       opal.size = of_read_number(sizep, runtimesz/4);
 
        pr_debug("OPAL Base  = 0x%llx (basep=%p basesz=%ld)\n",
                 opal.base, basep, basesz);
        pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n",
                 opal.entry, entryp, entrysz);
+       pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%ld)\n",
+                opal.size, sizep, runtimesz);
 
        powerpc_firmware_features |= FW_FEATURE_OPAL;
        if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
@@ -84,6 +99,53 @@ int __init early_init_dt_scan_opal(unsigned long node,
        return 1;
 }
 
+int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
+                                  const char *uname, int depth, void *data)
+{
+       unsigned long i, size;
+       const __be32 *prop;
+
+       if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
+               return 0;
+
+       prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &size);
+
+       if (!prop)
+               return 1;
+
+       pr_debug("Found machine check recoverable ranges.\n");
+
+       /*
+        * Allocate a buffer to hold the MC recoverable ranges. We would be
+        * accessing them in real mode, hence it needs to be within
+        * RMO region.
+        */
+       mc_recoverable_range =__va(memblock_alloc_base(size, __alignof__(u64),
+                                                       ppc64_rma_size));
+       memset(mc_recoverable_range, 0, size);
+
+       /*
+        * Each recoverable address entry is an (start address,len,
+        * recover address) pair, * 2 cells each, totalling 4 cells per entry.
+        */
+       for (i = 0; i < size / (sizeof(*prop) * 5); i++) {
+               mc_recoverable_range[i].start_addr =
+                                       of_read_number(prop + (i * 5) + 0, 2);
+               mc_recoverable_range[i].end_addr =
+                                       mc_recoverable_range[i].start_addr +
+                                       of_read_number(prop + (i * 5) + 2, 1);
+               mc_recoverable_range[i].recover_addr =
+                                       of_read_number(prop + (i * 5) + 3, 2);
+
+               pr_debug("Machine check recoverable range: %llx..%llx: %llx\n",
+                               mc_recoverable_range[i].start_addr,
+                               mc_recoverable_range[i].end_addr,
+                               mc_recoverable_range[i].recover_addr);
+       }
+       mc_recoverable_range_len = i;
+       return 1;
+}
+
 static int __init opal_register_exception_handlers(void)
 {
 #ifdef __BIG_ENDIAN__
@@ -401,6 +463,38 @@ int opal_machine_check(struct pt_regs *regs)
        return 0;
 }
 
+static uint64_t find_recovery_address(uint64_t nip)
+{
+       int i;
+
+       for (i = 0; i < mc_recoverable_range_len; i++)
+               if ((nip >= mc_recoverable_range[i].start_addr) &&
+                   (nip < mc_recoverable_range[i].end_addr))
+                   return mc_recoverable_range[i].recover_addr;
+       return 0;
+}
+
+bool opal_mce_check_early_recovery(struct pt_regs *regs)
+{
+       uint64_t recover_addr = 0;
+
+       if (!opal.base || !opal.size)
+               goto out;
+
+       if ((regs->nip >= opal.base) &&
+                       (regs->nip <= (opal.base + opal.size)))
+               recover_addr = find_recovery_address(regs->nip);
+
+       /*
+        * Setup regs->nip to rfi into fixup address.
+        */
+       if (recover_addr)
+               regs->nip = recover_addr;
+
+out:
+       return !!recover_addr;
+}
+
 static irqreturn_t opal_interrupt(int irq, void *data)
 {
        __be64 events;
@@ -472,8 +566,14 @@ static int __init opal_init(void)
        /* Create "opal" kobject under /sys/firmware */
        rc = opal_sysfs_init();
        if (rc == 0) {
+               /* Setup error log interface */
+               rc = opal_elog_init();
                /* Setup code update interface */
                opal_flash_init();
+               /* Setup platform dump extract interface */
+               opal_platform_dump_init();
+               /* Setup system parameters interface */
+               opal_sys_param_init();
        }
 
        return 0;
index 81a7a0a79be75e0c8035baa992a6a674546c94eb..61cf8fa9c61b50489009b94c99c993fffaddde28 100644 (file)
@@ -187,6 +187,7 @@ static void __init pnv_setup_machdep_opal(void)
        ppc_md.power_off = pnv_power_off;
        ppc_md.halt = pnv_halt;
        ppc_md.machine_check_exception = opal_machine_check;
+       ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
 }
 
 #ifdef CONFIG_PPC_POWERNV_RTAS
index 80b1d57c306a997e9b3c0a2933efa00ed1ac946e..2cb8b776c84a5660e5ef225cc004fbdcc9109f96 100644 (file)
@@ -111,6 +111,18 @@ config CMM
          will be reused for other LPARs. The interface allows firmware to
          balance memory across many LPARs.
 
+config HV_PERF_CTRS
+       bool "Hypervisor supplied PMU events (24x7 & GPCI)"
+       default y
+       depends on PERF_EVENTS && PPC_PSERIES
+       help
+         Enable access to hypervisor supplied counters in perf. Currently,
+         this enables code that uses the hcall GetPerfCounterInfo and 24x7
+         interfaces to retrieve counters. GPCI exists on Power 6 and later
+         systems. 24x7 is available on Power 8 systems.
+
+          If unsure, select Y.
+
 config DTL
        bool "Dispatch Trace Log"
        depends on PPC_SPLPAR && DEBUG_FS
index 0ea99e3d4815733a74b8098864f3594839ed97eb..9b8e05078a63e73a2993cc89890793353a45f9ea 100644 (file)
@@ -420,4 +420,4 @@ static int __init pseries_cpu_hotplug_init(void)
 
        return 0;
 }
-arch_initcall(pseries_cpu_hotplug_init);
+machine_arch_initcall(pseries, pseries_cpu_hotplug_init);
index 9590dbb756f2e1cafc6eb02f216b075f5db6087f..573b488fc48b8a9b79674806d27599993c96b362 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/memblock.h>
 #include <linux/vmalloc.h>
 #include <linux/memory.h>
+#include <linux/memory_hotplug.h>
 
 #include <asm/firmware.h>
 #include <asm/machdep.h>
@@ -75,13 +76,27 @@ unsigned long memory_block_size_bytes(void)
 }
 
 #ifdef CONFIG_MEMORY_HOTREMOVE
-static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
+static int pseries_remove_memory(u64 start, u64 size)
 {
-       unsigned long start, start_pfn;
-       struct zone *zone;
        int ret;
-       unsigned long section;
-       unsigned long sections_to_remove;
+
+       /* Remove htab bolted mappings for this section of memory */
+       start = (unsigned long)__va(start);
+       ret = remove_section_mapping(start, start + size);
+
+       /* Ensure all vmalloc mappings are flushed in case they also
+        * hit that section of memory
+        */
+       vm_unmap_aliases();
+
+       return ret;
+}
+
+static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
+{
+       unsigned long block_sz, start_pfn;
+       int sections_per_block;
+       int i, nid;
 
        start_pfn = base >> PAGE_SHIFT;
 
@@ -90,45 +105,21 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
                return 0;
        }
 
-       zone = page_zone(pfn_to_page(start_pfn));
+       block_sz = memory_block_size_bytes();
+       sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
+       nid = memory_add_physaddr_to_nid(base);
 
-       /*
-        * Remove section mappings and sysfs entries for the
-        * section of the memory we are removing.
-        *
-        * NOTE: Ideally, this should be done in generic code like
-        * remove_memory(). But remove_memory() gets called by writing
-        * to sysfs "state" file and we can't remove sysfs entries
-        * while writing to it. So we have to defer it to here.
-        */
-       sections_to_remove = (memblock_size >> PAGE_SHIFT) / PAGES_PER_SECTION;
-       for (section = 0; section < sections_to_remove; section++) {
-               unsigned long pfn = start_pfn + section * PAGES_PER_SECTION;
-               ret = __remove_pages(zone, pfn, PAGES_PER_SECTION);
-               if (ret)
-                       return ret;
+       for (i = 0; i < sections_per_block; i++) {
+               remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE);
+               base += MIN_MEMORY_BLOCK_SIZE;
        }
 
-       /*
-        * Update memory regions for memory remove
-        */
+       /* Update memory regions for memory remove */
        memblock_remove(base, memblock_size);
-
-       /*
-        * Remove htab bolted mappings for this section of memory
-        */
-       start = (unsigned long)__va(base);
-       ret = remove_section_mapping(start, start + memblock_size);
-
-       /* Ensure all vmalloc mappings are flushed in case they also
-        * hit that section of memory
-        */
-       vm_unmap_aliases();
-
-       return ret;
+       return 0;
 }
 
-static int pseries_remove_memory(struct device_node *np)
+static int pseries_remove_mem_node(struct device_node *np)
 {
        const char *type;
        const unsigned int *regs;
@@ -153,8 +144,8 @@ static int pseries_remove_memory(struct device_node *np)
        base = *(unsigned long *)regs;
        lmb_size = regs[3];
 
-       ret = pseries_remove_memblock(base, lmb_size);
-       return ret;
+       pseries_remove_memblock(base, lmb_size);
+       return 0;
 }
 #else
 static inline int pseries_remove_memblock(unsigned long base,
@@ -162,13 +153,13 @@ static inline int pseries_remove_memblock(unsigned long base,
 {
        return -EOPNOTSUPP;
 }
-static inline int pseries_remove_memory(struct device_node *np)
+static inline int pseries_remove_mem_node(struct device_node *np)
 {
        return -EOPNOTSUPP;
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
-static int pseries_add_memory(struct device_node *np)
+static int pseries_add_mem_node(struct device_node *np)
 {
        const char *type;
        const unsigned int *regs;
@@ -254,10 +245,10 @@ static int pseries_memory_notifier(struct notifier_block *nb,
 
        switch (action) {
        case OF_RECONFIG_ATTACH_NODE:
-               err = pseries_add_memory(node);
+               err = pseries_add_mem_node(node);
                break;
        case OF_RECONFIG_DETACH_NODE:
-               err = pseries_remove_memory(node);
+               err = pseries_remove_mem_node(node);
                break;
        case OF_RECONFIG_UPDATE_PROPERTY:
                pr = (struct of_prop_reconfig *)node;
@@ -277,6 +268,10 @@ static int __init pseries_memory_hotplug_init(void)
        if (firmware_has_feature(FW_FEATURE_LPAR))
                of_reconfig_notifier_register(&pseries_mem_nb);
 
+#ifdef CONFIG_MEMORY_HOTREMOVE
+       ppc_md.remove_memory = pseries_remove_memory;
+#endif
+
        return 0;
 }
 machine_device_initcall(pseries, pseries_memory_hotplug_init);
index cde4e0a095ae25bb208ff5d11c30c22c733f783f..bde7ebad3949c941c31fd7b6df67ba4bb15ee32c 100644 (file)
@@ -290,13 +290,6 @@ void post_mobility_fixup(void)
        int rc;
        int activate_fw_token;
 
-       rc = pseries_devicetree_update(MIGRATION_SCOPE);
-       if (rc) {
-               printk(KERN_ERR "Initial post-mobility device tree update "
-                      "failed: %d\n", rc);
-               return;
-       }
-
        activate_fw_token = rtas_token("ibm,activate-firmware");
        if (activate_fw_token == RTAS_UNKNOWN_SERVICE) {
                printk(KERN_ERR "Could not make post-mobility "
@@ -304,16 +297,17 @@ void post_mobility_fixup(void)
                return;
        }
 
-       rc = rtas_call(activate_fw_token, 0, 1, NULL);
-       if (!rc) {
-               rc = pseries_devicetree_update(MIGRATION_SCOPE);
-               if (rc)
-                       printk(KERN_ERR "Secondary post-mobility device tree "
-                              "update failed: %d\n", rc);
-       } else {
+       do {
+               rc = rtas_call(activate_fw_token, 0, 1, NULL);
+       } while (rtas_busy_delay(rc));
+
+       if (rc)
                printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
-               return;
-       }
+
+       rc = pseries_devicetree_update(MIGRATION_SCOPE);
+       if (rc)
+               printk(KERN_ERR "Post-mobility device tree update "
+                       "failed: %d\n", rc);
 
        return;
 }
index 16a255255d3003c64ce8d517fe90bf8b9109552b..b87b97849d4c4d6e95295a519cec8f6e335d6e2e 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/mmu.h>
 #include <asm/rtas.h>
 #include <asm/topology.h>
+#include "../../kernel/cacheinfo.h"
 
 static u64 stream_id;
 static struct device suspend_dev;
@@ -78,6 +79,23 @@ static int pseries_suspend_cpu(void)
        return 0;
 }
 
+/**
+ * pseries_suspend_enable_irqs
+ *
+ * Post suspend configuration updates
+ *
+ **/
+static void pseries_suspend_enable_irqs(void)
+{
+       /*
+        * Update configuration which can be modified based on device tree
+        * changes during resume.
+        */
+       cacheinfo_cpu_offline(smp_processor_id());
+       post_mobility_fixup();
+       cacheinfo_cpu_online(smp_processor_id());
+}
+
 /**
  * pseries_suspend_enter - Final phase of hibernation
  *
@@ -174,7 +192,30 @@ out:
        return rc;
 }
 
-static DEVICE_ATTR(hibernate, S_IWUSR, NULL, store_hibernate);
+#define USER_DT_UPDATE 0
+#define KERN_DT_UPDATE 1
+
+/**
+ * show_hibernate - Report device tree update responsibilty
+ * @dev:               subsys root device
+ * @attr:              device attribute struct
+ * @buf:               buffer
+ *
+ * Report whether a device tree update is performed by the kernel after a
+ * resume, or if drmgr must coordinate the update from user space.
+ *
+ * Return value:
+ *     0 if drmgr is to initiate update, and 1 otherwise
+ **/
+static ssize_t show_hibernate(struct device *dev,
+                             struct device_attribute *attr,
+                             char *buf)
+{
+       return sprintf(buf, "%d\n", KERN_DT_UPDATE);
+}
+
+static DEVICE_ATTR(hibernate, S_IWUSR | S_IRUGO,
+                  show_hibernate, store_hibernate);
 
 static struct bus_type suspend_subsys = {
        .name = "power",
@@ -235,6 +276,7 @@ static int __init pseries_suspend_init(void)
                return rc;
 
        ppc_md.suspend_disable_cpu = pseries_suspend_cpu;
+       ppc_md.suspend_enable_irqs = pseries_suspend_enable_irqs;
        suspend_set_ops(&pseries_suspend_ops);
        return 0;
 }
index a625dcf26b2b7c53374883980d9f45e1881098ff..3f415e252ea54fc34e8dee84ea7de1b56fd54ec1 100644 (file)
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/bootmem.h>
 #include <linux/memblock.h>
 #include <linux/log2.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
 #include <linux/uaccess.h>
 
 #include <asm/io.h>
@@ -868,6 +871,14 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose)
 
                pci_bus_read_config_dword(hose->bus,
                        PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+
+               /*
+                * For PEXCSRBAR, bit 3-0 indicate prefetchable and
+                * address type. So when getting base address, these
+                * bits should be masked
+                */
+               base &= PCI_BASE_ADDRESS_MEM_MASK;
+
                return base;
        }
 #endif
@@ -1086,55 +1097,171 @@ void fsl_pci_assign_primary(void)
        }
 }
 
-static int fsl_pci_probe(struct platform_device *pdev)
+#ifdef CONFIG_PM_SLEEP
+static irqreturn_t fsl_pci_pme_handle(int irq, void *dev_id)
 {
-       int ret;
-       struct device_node *node;
+       struct pci_controller *hose = dev_id;
+       struct ccsr_pci __iomem *pci = hose->private_data;
+       u32 dr;
 
-       node = pdev->dev.of_node;
-       ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+       dr = in_be32(&pci->pex_pme_mes_dr);
+       if (!dr)
+               return IRQ_NONE;
 
-       mpc85xx_pci_err_probe(pdev);
+       out_be32(&pci->pex_pme_mes_dr, dr);
 
-       return 0;
+       return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_PM
-static int fsl_pci_resume(struct device *dev)
+static int fsl_pci_pme_probe(struct pci_controller *hose)
 {
-       struct pci_controller *hose;
-       struct resource pci_rsrc;
+       struct ccsr_pci __iomem *pci;
+       struct pci_dev *dev;
+       int pme_irq;
+       int res;
+       u16 pms;
 
-       hose = pci_find_hose_for_OF_device(dev->of_node);
-       if (!hose)
-               return -ENODEV;
+       /* Get hose's pci_dev */
+       dev = list_first_entry(&hose->bus->devices, typeof(*dev), bus_list);
+
+       /* PME Disable */
+       pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
+       pms &= ~PCI_PM_CTRL_PME_ENABLE;
+       pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
+
+       pme_irq = irq_of_parse_and_map(hose->dn, 0);
+       if (!pme_irq) {
+               dev_err(&dev->dev, "Failed to map PME interrupt.\n");
+
+               return -ENXIO;
+       }
+
+       res = devm_request_irq(hose->parent, pme_irq,
+                       fsl_pci_pme_handle,
+                       IRQF_SHARED,
+                       "[PCI] PME", hose);
+       if (res < 0) {
+               dev_err(&dev->dev, "Unable to requiest irq %d for PME\n", pme_irq);
+               irq_dispose_mapping(pme_irq);
 
-       if (of_address_to_resource(dev->of_node, 0, &pci_rsrc)) {
-               dev_err(dev, "Get pci register base failed.");
                return -ENODEV;
        }
 
-       setup_pci_atmu(hose);
+       pci = hose->private_data;
+
+       /* Enable PTOD, ENL23D & EXL23D */
+       out_be32(&pci->pex_pme_mes_disr, 0);
+       setbits32(&pci->pex_pme_mes_disr,
+                 PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
+
+       out_be32(&pci->pex_pme_mes_ier, 0);
+       setbits32(&pci->pex_pme_mes_ier,
+                 PME_DISR_EN_PTOD | PME_DISR_EN_ENL23D | PME_DISR_EN_EXL23D);
+
+       /* PME Enable */
+       pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pms);
+       pms |= PCI_PM_CTRL_PME_ENABLE;
+       pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pms);
 
        return 0;
 }
 
-static const struct dev_pm_ops pci_pm_ops = {
-       .resume = fsl_pci_resume,
-};
+static void send_pme_turnoff_message(struct pci_controller *hose)
+{
+       struct ccsr_pci __iomem *pci = hose->private_data;
+       u32 dr;
+       int i;
 
-#define PCI_PM_OPS (&pci_pm_ops)
+       /* Send PME_Turn_Off Message Request */
+       setbits32(&pci->pex_pmcr, PEX_PMCR_PTOMR);
 
-#else
+       /* Wait trun off done */
+       for (i = 0; i < 150; i++) {
+               dr = in_be32(&pci->pex_pme_mes_dr);
+               if (dr) {
+                       out_be32(&pci->pex_pme_mes_dr, dr);
+                       break;
+               }
+
+               udelay(1000);
+       }
+}
+
+static void fsl_pci_syscore_do_suspend(struct pci_controller *hose)
+{
+       send_pme_turnoff_message(hose);
+}
+
+static int fsl_pci_syscore_suspend(void)
+{
+       struct pci_controller *hose, *tmp;
 
-#define PCI_PM_OPS NULL
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+               fsl_pci_syscore_do_suspend(hose);
 
+       return 0;
+}
+
+static void fsl_pci_syscore_do_resume(struct pci_controller *hose)
+{
+       struct ccsr_pci __iomem *pci = hose->private_data;
+       u32 dr;
+       int i;
+
+       /* Send Exit L2 State Message */
+       setbits32(&pci->pex_pmcr, PEX_PMCR_EXL2S);
+
+       /* Wait exit done */
+       for (i = 0; i < 150; i++) {
+               dr = in_be32(&pci->pex_pme_mes_dr);
+               if (dr) {
+                       out_be32(&pci->pex_pme_mes_dr, dr);
+                       break;
+               }
+
+               udelay(1000);
+       }
+
+       setup_pci_atmu(hose);
+}
+
+static void fsl_pci_syscore_resume(void)
+{
+       struct pci_controller *hose, *tmp;
+
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+               fsl_pci_syscore_do_resume(hose);
+}
+
+static struct syscore_ops pci_syscore_pm_ops = {
+       .suspend = fsl_pci_syscore_suspend,
+       .resume = fsl_pci_syscore_resume,
+};
 #endif
 
+void fsl_pcibios_fixup_phb(struct pci_controller *phb)
+{
+#ifdef CONFIG_PM_SLEEP
+       fsl_pci_pme_probe(phb);
+#endif
+}
+
+static int fsl_pci_probe(struct platform_device *pdev)
+{
+       struct device_node *node;
+       int ret;
+
+       node = pdev->dev.of_node;
+       ret = fsl_add_bridge(pdev, fsl_pci_primary == node);
+
+       mpc85xx_pci_err_probe(pdev);
+
+       return 0;
+}
+
 static struct platform_driver fsl_pci_driver = {
        .driver = {
                .name = "fsl-pci",
-               .pm = PCI_PM_OPS,
                .of_match_table = pci_ids,
        },
        .probe = fsl_pci_probe,
@@ -1142,6 +1269,9 @@ static struct platform_driver fsl_pci_driver = {
 
 static int __init fsl_pci_init(void)
 {
+#ifdef CONFIG_PM_SLEEP
+       register_syscore_ops(&pci_syscore_pm_ops);
+#endif
        return platform_driver_register(&fsl_pci_driver);
 }
 arch_initcall(fsl_pci_init);
index 8d455df584711c84c004468be1656fd4b55e36eb..c1cec771d5eae2f7f81381782dbff1193d21db46 100644 (file)
@@ -32,6 +32,13 @@ struct platform_device;
 #define PIWAR_WRITE_SNOOP      0x00005000
 #define PIWAR_SZ_MASK          0x0000003f
 
+#define PEX_PMCR_PTOMR         0x1
+#define PEX_PMCR_EXL2S         0x2
+
+#define PME_DISR_EN_PTOD       0x00008000
+#define PME_DISR_EN_ENL23D     0x00002000
+#define PME_DISR_EN_EXL23D     0x00001000
+
 /* PCI/PCI Express outbound window reg */
 struct pci_outbound_window_regs {
        __be32  potar;  /* 0x.0 - Outbound translation address register */
@@ -111,6 +118,7 @@ struct ccsr_pci {
 
 extern int fsl_add_bridge(struct platform_device *pdev, int is_primary);
 extern void fsl_pcibios_fixup_bus(struct pci_bus *bus);
+extern void fsl_pcibios_fixup_phb(struct pci_controller *phb);
 extern int mpc83xx_add_bridge(struct device_node *dev);
 u64 fsl_pci_immrbar_base(struct pci_controller *hose);
 
index b07909850f77151b393f73a30bac727a79ea9921..08504e75b2c731acd259ec5b317d97c1cdac8e12 100644 (file)
@@ -171,7 +171,11 @@ extern void xmon_leave(void);
 #define REG            "%.8lx"
 #endif
 
+#ifdef __LITTLE_ENDIAN__
+#define GETWORD(v)     (((v)[3] << 24) + ((v)[2] << 16) + ((v)[1] << 8) + (v)[0])
+#else
 #define GETWORD(v)     (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+#endif
 
 #define isxdigit(c)    (('0' <= (c) && (c) <= '9') \
                         || ('a' <= (c) && (c) <= 'f') \
index f288b60a87be5ca0a24399ae11f2d565338f12a3..b53d87958710bcfa40d06d078e4e60e77f450672 100644 (file)
@@ -554,6 +554,14 @@ config SENSORS_IBMPEX
          This driver can also be built as a module.  If so, the module
          will be called ibmpex.
 
+config SENSORS_IBMPOWERNV
+       tristate "IBM PowerNv Platform temperature/power/fan sensor"
+       depends on PPC_POWERNV
+       default y
+       help
+         If you say yes here you get support for the temperature/fan/power
+         sensors on your platform.
+
 config SENSORS_IIO_HWMON
        tristate "Hwmon driver that uses channels specified via iio maps"
        depends on IIO
index c48f9873ac7367034a584d7e3aa5ad0231be9ffe..199c401bf8d9f11743c7e0a4bedcfd1f2928ea52 100644 (file)
@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
 obj-$(CONFIG_SENSORS_I5K_AMB)  += i5k_amb.o
 obj-$(CONFIG_SENSORS_IBMAEM)   += ibmaem.o
 obj-$(CONFIG_SENSORS_IBMPEX)   += ibmpex.o
+obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
 obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
 obj-$(CONFIG_SENSORS_INA209)   += ina209.o
 obj-$(CONFIG_SENSORS_INA2XX)   += ina2xx.o
diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c
new file mode 100644 (file)
index 0000000..b7b1297
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+ * hwmon driver for temperature/power/fan on IBM PowerNV platform
+ * Copyright (C) 2013 IBM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <asm/opal.h>
+#include <linux/err.h>
+
+MODULE_DESCRIPTION("IBM PowerNV Platform power/temp/fan sensor hwmon module");
+MODULE_LICENSE("GPL");
+
+#define MAX_ATTR_LENGTH                32
+
+/* Device tree sensor name prefixes. The device tree has the names in the
+ * format "cooling-fan#2-faulted" where the "cooling-fan" is the sensor type,
+ * 2 is the sensor count, and "faulted" is the sensor data attribute type.
+ */
+#define DT_FAULT_ATTR_SUFFIX           "faulted"
+#define DT_DATA_ATTR_SUFFIX            "data"
+#define DT_THRESHOLD_ATTR_SUFFIX       "thrs"
+
+enum sensors {
+       FAN,
+       TEMPERATURE,
+       POWERSUPPLY,
+       POWER,
+       MAX_SENSOR_TYPE,
+};
+
+enum attributes {
+       INPUT,
+       MINIMUM,
+       MAXIMUM,
+       FAULT,
+       MAX_ATTR_TYPES
+};
+
+static struct sensor_name {
+       char *name;
+       char *compaible;
+} sensor_names[] = {
+               {"fan-sensor", "ibm,opal-sensor-cooling-fan"},
+               {"amb-temp-sensor", "ibm,opal-sensor-amb-temp"},
+               {"power-sensor", "ibm,opal-sensor-power-supply"},
+               {"power", "ibm,opal-sensor-power"}
+};
+
+static const char * const attribute_type_table[] = {
+       "input",
+       "min",
+       "max",
+       "fault",
+       NULL
+};
+
+struct pdev_entry {
+       struct list_head list;
+       struct platform_device *pdev;
+       enum sensors type;
+};
+
+static LIST_HEAD(pdev_list);
+
+/* The sensors are categorised on type.
+ *
+ * The sensors of same type are categorised under a common platform device.
+ * So, The pdev is shared by all sensors of same type.
+ * Ex : temp1_input, temp1_max, temp2_input,temp2_max all share same platform
+ * device.
+ *
+ * "sensor_data" is the Platform device specific data.
+ * There is one hwmon_device instance for all the sensors of same type.
+ * This also holds the list of all sensors with same type but different
+ * attribute and index.
+ */
+struct sensor_specific_data {
+       u32 sensor_id; /* The hex value as in the device tree */
+       u32 sensor_index; /* The sensor instance index */
+       struct sensor_device_attribute sd_attr;
+       enum attributes attr_type;
+       char attr_name[64];
+};
+
+struct sensor_data {
+       struct device *hwmon_dev;
+       struct list_head sensor_list;
+       struct device_attribute name_attr;
+};
+
+struct  sensor_entry {
+       struct list_head list;
+       struct sensor_specific_data *sensor_data;
+};
+
+static struct platform_device *powernv_sensor_get_pdev(enum sensors type)
+{
+       struct pdev_entry *p;
+       list_for_each_entry(p, &pdev_list, list)
+               if (p->type == type)
+                       return p->pdev;
+
+       return NULL;
+}
+
+static struct sensor_specific_data *powernv_sensor_get_sensor_data(
+                                       struct sensor_data *pdata,
+                                       int index, enum attributes attr_type)
+{
+       struct sensor_entry *p;
+       list_for_each_entry(p, &pdata->sensor_list, list)
+               if ((p->sensor_data->sensor_index == index) &&
+                   (attr_type == p->sensor_data->attr_type))
+                       return p->sensor_data;
+
+       return NULL;
+}
+
+static ssize_t show_name(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+
+       return sprintf(buf, "%s\n", pdev->name);
+}
+
+/* Note: Data from the sensors for each sensor type needs to be converted to
+ * the dimension appropriate.
+ */
+static ssize_t show_sensor(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       struct sensor_device_attribute *sd_attr = to_sensor_dev_attr(devattr);
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sensor_data *pdata = platform_get_drvdata(pdev);
+       struct sensor_specific_data *tdata = NULL;
+       enum sensors sensor_type = pdev->id;
+       u32 x = -1;
+       int ret;
+
+       if (sd_attr && sd_attr->dev_attr.attr.name) {
+               char *pos = strchr(sd_attr->dev_attr.attr.name, '_');
+               int i;
+
+               for (i = 0; i < MAX_ATTR_TYPES; i++) {
+                       if (strcmp(pos+1, attribute_type_table[i]) == 0) {
+                               tdata = powernv_sensor_get_sensor_data(pdata,
+                                               sd_attr->index, i);
+                               break;
+                       }
+               }
+       }
+
+       if (tdata) {
+               ret = opal_get_sensor_data(tdata->sensor_id, &x);
+               if (ret)
+                       x = -1;
+       }
+
+       if (sensor_type == TEMPERATURE && x > 0) {
+               /* Temperature comes in Degrees and convert it to
+                * milli-degrees.
+                */
+               x = x*1000;
+       } else if (sensor_type == POWER && x > 0) {
+               /* Power value comes in watts, convert to micro-watts */
+               x = x * 1000000;
+       }
+
+       return sprintf(buf, "%d\n", x);
+}
+
+static u32 get_sensor_index_from_name(const char *name)
+{
+       char *hash_position = strchr(name, '#');
+       u32 index = 0, copy_length;
+       char newbuf[8];
+
+       if (hash_position) {
+               copy_length = strchr(hash_position, '-') - hash_position - 1;
+               if (copy_length < sizeof(newbuf)) {
+                       strncpy(newbuf, hash_position + 1, copy_length);
+                       sscanf(newbuf, "%d", &index);
+               }
+       }
+
+       return index;
+}
+
+static inline void get_sensor_suffix_from_name(const char *name, char *suffix)
+{
+       char *dash_position = strrchr(name, '-');
+       if (dash_position)
+               strncpy(suffix, dash_position+1, MAX_ATTR_LENGTH);
+       else
+               strcpy(suffix,"");
+}
+
+static int get_sensor_attr_properties(const char *sensor_name,
+               enum sensors sensor_type, enum attributes *attr_type,
+               u32 *sensor_index)
+{
+       char suffix[MAX_ATTR_LENGTH];
+
+       *attr_type = MAX_ATTR_TYPES;
+       *sensor_index = get_sensor_index_from_name(sensor_name);
+       if (*sensor_index == 0)
+               return -EINVAL;
+
+       get_sensor_suffix_from_name(sensor_name, suffix);
+       if (strcmp(suffix, "") == 0)
+               return -EINVAL;
+
+       if (strcmp(suffix, DT_FAULT_ATTR_SUFFIX) == 0)
+               *attr_type = FAULT;
+       else if (strcmp(suffix, DT_DATA_ATTR_SUFFIX) == 0)
+               *attr_type = INPUT;
+       else if ((sensor_type == TEMPERATURE) &&
+                       (strcmp(suffix, DT_THRESHOLD_ATTR_SUFFIX) == 0))
+               *attr_type = MAXIMUM;
+       else if ((sensor_type == FAN) &&
+                       (strcmp(suffix, DT_THRESHOLD_ATTR_SUFFIX) == 0))
+               *attr_type = MINIMUM;
+       else
+               return -ENOENT;
+
+       if (((sensor_type == FAN) && ((*attr_type == INPUT) ||
+                                   (*attr_type == MINIMUM)))
+           || ((sensor_type == TEMPERATURE) && ((*attr_type == INPUT) ||
+                                                (*attr_type == MAXIMUM)))
+           || ((sensor_type == POWER) && ((*attr_type == INPUT))))
+               return 0;
+
+       return -ENOENT;
+}
+
+static int create_sensor_attr(struct sensor_specific_data *tdata,
+               struct device *dev, enum sensors sensor_type,
+               enum attributes attr_type)
+{
+       int err = 0;
+       char temp_file_prefix[50];
+       static const char *const file_name_format = "%s%d_%s";
+
+       tdata->attr_type = attr_type;
+
+       if (sensor_type == FAN)
+               strcpy(temp_file_prefix, "fan");
+       else if (sensor_type == TEMPERATURE)
+               strcpy(temp_file_prefix, "temp");
+       else if (sensor_type == POWERSUPPLY)
+               strcpy(temp_file_prefix, "powersupply");
+       else if (sensor_type == POWER)
+               strcpy(temp_file_prefix, "power");
+
+       snprintf(tdata->attr_name, sizeof(tdata->attr_name), file_name_format,
+                temp_file_prefix, tdata->sensor_index,
+                attribute_type_table[tdata->attr_type]);
+
+       sysfs_attr_init(&tdata->sd_attr.dev_attr.attr);
+       tdata->sd_attr.dev_attr.attr.name = tdata->attr_name;
+       tdata->sd_attr.dev_attr.attr.mode = S_IRUGO;
+       tdata->sd_attr.dev_attr.show = show_sensor;
+
+       tdata->sd_attr.index = tdata->sensor_index;
+       err = device_create_file(dev, &tdata->sd_attr.dev_attr);
+
+       return err;
+}
+
+static int create_name_attr(struct sensor_data *pdata,
+                               struct device *dev)
+{
+       sysfs_attr_init(&pdata->name_attr.attr);
+       pdata->name_attr.attr.name = "name";
+       pdata->name_attr.attr.mode = S_IRUGO;
+       pdata->name_attr.show = show_name;
+       return device_create_file(dev, &pdata->name_attr);
+}
+
+static int create_platform_device(enum sensors sensor_type,
+                                       struct platform_device **pdev)
+{
+       struct pdev_entry *pdev_entry = NULL;
+       int err;
+
+       *pdev = platform_device_alloc(sensor_names[sensor_type].name,
+                       sensor_type);
+       if (!*pdev) {
+               pr_err("Device allocation failed\n");
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
+       if (!pdev_entry) {
+               pr_err("Device allocation failed\n");
+               err = -ENOMEM;
+               goto exit_device_put;
+       }
+
+       err = platform_device_add(*pdev);
+       if (err) {
+               pr_err("Device addition failed (%d)\n", err);
+               goto exit_device_free;
+       }
+
+       pdev_entry->pdev = *pdev;
+       pdev_entry->type = (*pdev)->id;
+
+       list_add_tail(&pdev_entry->list, &pdev_list);
+
+       return 0;
+exit_device_free:
+       kfree(pdev_entry);
+exit_device_put:
+       platform_device_put(*pdev);
+exit:
+       return err;
+}
+
+static int create_sensor_data(struct platform_device *pdev)
+{
+       struct sensor_data *pdata = NULL;
+       int err = 0;
+
+       pdata = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
+       if (!pdata) {
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       err = create_name_attr(pdata, &pdev->dev);
+       if (err)
+               goto exit_free;
+
+       pdata->hwmon_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(pdata->hwmon_dev)) {
+               err = PTR_ERR(pdata->hwmon_dev);
+               dev_err(&pdev->dev, "Class registration failed (%d)\n",
+                       err);
+               goto exit_name;
+       }
+
+       INIT_LIST_HEAD(&pdata->sensor_list);
+       platform_set_drvdata(pdev, pdata);
+
+       return 0;
+
+exit_name:
+       device_remove_file(&pdev->dev, &pdata->name_attr);
+exit_free:
+       kfree(pdata);
+exit:
+       return err;
+}
+
+static void delete_sensor_attr(struct sensor_data *pdata)
+{
+       struct sensor_entry *s, *l;
+
+       list_for_each_entry_safe(s, l, &pdata->sensor_list, list) {
+               struct sensor_specific_data *tdata = s->sensor_data;
+                       kfree(tdata);
+                       list_del(&s->list);
+                       kfree(s);
+               }
+}
+
+static int powernv_sensor_init(u32 sensor_id, const struct device_node *np,
+               enum sensors sensor_type, enum attributes attr_type,
+               u32 sensor_index)
+{
+       struct platform_device *pdev = powernv_sensor_get_pdev(sensor_type);
+       struct sensor_specific_data *tdata;
+       struct sensor_entry *sensor_entry;
+       struct sensor_data *pdata;
+       int err = 0;
+
+       if (!pdev) {
+               err = create_platform_device(sensor_type, &pdev);
+               if (err)
+                       goto exit;
+
+               err = create_sensor_data(pdev);
+               if (err)
+                       goto exit;
+       }
+
+       pdata = platform_get_drvdata(pdev);
+       if (!pdata) {
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       tdata = kzalloc(sizeof(struct sensor_specific_data), GFP_KERNEL);
+       if (!tdata) {
+               err = -ENOMEM;
+               goto exit;
+       }
+
+       tdata->sensor_id = sensor_id;
+       tdata->sensor_index = sensor_index;
+
+       err = create_sensor_attr(tdata, &pdev->dev, sensor_type, attr_type);
+       if (err)
+               goto exit_free;
+
+       sensor_entry = kzalloc(sizeof(struct sensor_entry), GFP_KERNEL);
+       if (!sensor_entry) {
+               err = -ENOMEM;
+               goto exit_attr;
+       }
+
+       sensor_entry->sensor_data = tdata;
+
+       list_add_tail(&sensor_entry->list, &pdata->sensor_list);
+
+       return 0;
+exit_attr:
+       device_remove_file(&pdev->dev, &tdata->sd_attr.dev_attr);
+exit_free:
+       kfree(tdata);
+exit:
+       return err;
+}
+
+static void delete_unregister_sensors(void)
+{
+       struct pdev_entry *p, *n;
+
+       list_for_each_entry_safe(p, n, &pdev_list, list) {
+               struct sensor_data *pdata = platform_get_drvdata(p->pdev);
+                       if (pdata) {
+                               delete_sensor_attr(pdata);
+
+                               hwmon_device_unregister(pdata->hwmon_dev);
+                               kfree(pdata);
+                       }
+               platform_device_unregister(p->pdev);
+               list_del(&p->list);
+               kfree(p);
+       }
+}
+
+static int __init powernv_hwmon_init(void)
+{
+       struct device_node *opal, *np = NULL;
+       enum attributes attr_type;
+       enum sensors type;
+       const u32 *sensor_id;
+       u32 sensor_index;
+       int err;
+
+       opal = of_find_node_by_path("/ibm,opal/sensors");
+       if (!opal) {
+               pr_err("%s: Opal 'sensors' node not found\n", __func__);
+               return -ENXIO;
+       }
+
+       for_each_child_of_node(opal, np) {
+               if (np->name == NULL)
+                       continue;
+
+               for (type = 0; type < MAX_SENSOR_TYPE; type++)
+                       if (of_device_is_compatible(np,
+                                       sensor_names[type].compaible))
+                               break;
+
+               if (type == MAX_SENSOR_TYPE)
+                       continue;
+
+               if (get_sensor_attr_properties(np->name, type, &attr_type,
+                               &sensor_index))
+                       continue;
+
+               sensor_id = of_get_property(np, "sensor-id", NULL);
+               if (!sensor_id) {
+                       pr_info("%s: %s doesn't have sensor-id\n", __func__,
+                                       np->name);
+                       continue;
+               }
+
+               err = powernv_sensor_init(*sensor_id, np, type, attr_type,
+                               sensor_index);
+               if (err) {
+                       of_node_put(opal);
+                       goto exit;
+               }
+       }
+       of_node_put(opal);
+
+       return 0;
+exit:
+       delete_unregister_sensors();
+       return err;
+
+}
+
+static void powernv_hwmon_exit(void)
+{
+       delete_unregister_sensors();
+}
+
+module_init(powernv_hwmon_init);
+module_exit(powernv_hwmon_exit);
index 04a50498f2576f8019488e118c49d4b7092f0fc4..9e9c56758a0897ab5c7e7b0dfc14ac690e1bb043 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #ifdef CONFIG_PPC
 #include <asm/prom.h>
 #include <asm/machdep.h>
@@ -193,8 +193,7 @@ static int adb_scan_bus(void)
                                        break;
 
                                noMovement = 0;
-                       }
-                       else {
+                       } else {
                                /*
                                 * No devices left at address i; move the
                                 * one(s) we moved to `highFree' back to i.
@@ -263,7 +262,7 @@ adb_reset_bus(void)
 /*
  * notify clients before sleep
  */
-static int adb_suspend(struct platform_device *dev, pm_message_t state)
+static int __adb_suspend(struct platform_device *dev, pm_message_t state)
 {
        adb_got_sleep = 1;
        /* We need to get a lock on the probe thread */
@@ -276,10 +275,25 @@ static int adb_suspend(struct platform_device *dev, pm_message_t state)
        return 0;
 }
 
+static int adb_suspend(struct device *dev)
+{
+       return __adb_suspend(to_platform_device(dev), PMSG_SUSPEND);
+}
+
+static int adb_freeze(struct device *dev)
+{
+       return __adb_suspend(to_platform_device(dev), PMSG_FREEZE);
+}
+
+static int adb_poweroff(struct device *dev)
+{
+       return __adb_suspend(to_platform_device(dev), PMSG_HIBERNATE);
+}
+
 /*
  * reset bus after sleep
  */
-static int adb_resume(struct platform_device *dev)
+static int __adb_resume(struct platform_device *dev)
 {
        adb_got_sleep = 0;
        up(&adb_probe_mutex);
@@ -287,6 +301,11 @@ static int adb_resume(struct platform_device *dev)
 
        return 0;
 }
+
+static int adb_resume(struct device *dev)
+{
+       return __adb_resume(to_platform_device(dev));
+}
 #endif /* CONFIG_PM */
 
 static int __init adb_init(void)
@@ -502,7 +521,7 @@ void
 adb_input(unsigned char *buf, int nb, int autopoll)
 {
        int i, id;
-       static int dump_adb_input = 0;
+       static int dump_adb_input;
        unsigned long flags;
        
        void (*handler)(unsigned char *, int, int);
@@ -624,8 +643,7 @@ do_adb_query(struct adb_request *req)
 {
        int     ret = -EINVAL;
 
-       switch(req->data[1])
-       {
+       switch(req->data[1]) {
        case ADB_QUERY_GETDEVINFO:
                if (req->nbytes < 3)
                        break;
@@ -697,7 +715,7 @@ static ssize_t adb_read(struct file *file, char __user *buf,
        int ret = 0;
        struct adbdev_state *state = file->private_data;
        struct adb_request *req;
-       DECLARE_WAITQUEUE(wait,current);
+       DECLARE_WAITQUEUE(wait, current);
        unsigned long flags;
 
        if (count < 2)
@@ -794,8 +812,8 @@ static ssize_t adb_write(struct file *file, const char __user *buf,
        }
        /* Special case for ADB_BUSRESET request, all others are sent to
           the controller */
-       else if ((req->data[0] == ADB_PACKET)&&(count > 1)
-               &&(req->data[1] == ADB_BUSRESET)) {
+       else if ((req->data[0] == ADB_PACKET) && (count > 1)
+               && (req->data[1] == ADB_BUSRESET)) {
                ret = do_adb_reset_bus();
                up(&adb_probe_mutex);
                atomic_dec(&state->n_pending);
@@ -831,14 +849,25 @@ static const struct file_operations adb_fops = {
        .release        = adb_release,
 };
 
+#ifdef CONFIG_PM
+static const struct dev_pm_ops adb_dev_pm_ops = {
+       .suspend = adb_suspend,
+       .resume = adb_resume,
+       /* Hibernate hooks */
+       .freeze = adb_freeze,
+       .thaw = adb_resume,
+       .poweroff = adb_poweroff,
+       .restore = adb_resume,
+};
+#endif
+
 static struct platform_driver adb_pfdrv = {
        .driver = {
                .name = "adb",
-       },
 #ifdef CONFIG_PM
-       .suspend = adb_suspend,
-       .resume = adb_resume,
+               .pm = &adb_dev_pm_ops,
 #endif
+       },
 };
 
 static struct platform_device adb_pfdev = {
index f1b8d555080e8c562ea1cb886b42c77f8c8b0c1f..a8dbceb32914a0e834a8c6b8ae394898c213e527 100644 (file)
@@ -138,14 +138,6 @@ static void __booke_wdt_enable(void *data)
        val &= ~WDTP_MASK;
        val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
 
-#ifdef CONFIG_PPC_BOOK3E_64
-       /*
-        * Crit ints are currently broken on PPC64 Book-E, so
-        * just disable them for now.
-        */
-       val &= ~TCR_WIE;
-#endif
-
        mtspr(SPRN_TCR, val);
 }
 
index bd24ae5aaeab052894d2c998754ec150084c9bba..316194f26ff4ab3131c6b29f939ef2209626f208 100644 (file)
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
 
 export CC CFLAGS
 
-TARGETS = pmu
+TARGETS = pmu copyloops
 
 endif
 
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile
new file mode 100644 (file)
index 0000000..6f2d3be
--- /dev/null
@@ -0,0 +1,29 @@
+# The loops are all 64-bit code
+CFLAGS += -m64
+CFLAGS += -I$(CURDIR)
+CFLAGS += -D SELFTEST
+
+# Use our CFLAGS for the implicit .S rule
+ASFLAGS = $(CFLAGS)
+
+PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7
+EXTRA_SOURCES := validate.c ../harness.c
+
+all: $(PROGS)
+
+copyuser_64:     CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base
+copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7
+memcpy_64:       CPPFLAGS += -D COPY_LOOP=test_memcpy
+memcpy_power7:   CPPFLAGS += -D COPY_LOOP=test_memcpy_power7
+
+$(PROGS): $(EXTRA_SOURCES)
+
+run_tests: all
+       @-for PROG in $(PROGS); do \
+               ./$$PROG; \
+       done;
+
+clean:
+       rm -f $(PROGS) *.o
+
+.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
new file mode 100644 (file)
index 0000000..ccd9c84
--- /dev/null
@@ -0,0 +1,86 @@
+#include <ppc-asm.h>
+
+#define CONFIG_ALTIVEC
+
+#define r1     1
+
+#define vr0     0
+#define vr1     1
+#define vr2     2
+#define vr3     3
+#define vr4     4
+#define vr5     5
+#define vr6     6
+#define vr7     7
+#define vr8     8
+#define vr9     9
+#define vr10    10
+#define vr11    11
+#define vr12    12
+#define vr13    13
+#define vr14    14
+#define vr15    15
+#define vr16    16
+#define vr17    17
+#define vr18    18
+#define vr19    19
+#define vr20    20
+#define vr21    21
+#define vr22    22
+#define vr23    23
+#define vr24    24
+#define vr25    25
+#define vr26    26
+#define vr27    27
+#define vr28    28
+#define vr29    29
+#define vr30    30
+#define vr31    31
+
+#define R14 r14
+#define R15 r15
+#define R16 r16
+#define R17 r17
+#define R18 r18
+#define R19 r19
+#define R20 r20
+#define R21 r21
+#define R22 r22
+
+#define STACKFRAMESIZE 256
+#define STK_PARAM(i)   (48 + ((i)-3)*8)
+#define STK_REG(i)     (112 + ((i)-14)*8)
+
+#define _GLOBAL(A) FUNC_START(test_ ## A)
+
+#define PPC_MTOCRF(A, B)       mtocrf A, B
+
+FUNC_START(enter_vmx_usercopy)
+       li      r3,1
+       blr
+
+FUNC_START(exit_vmx_usercopy)
+       li      r3,0
+       blr
+
+FUNC_START(enter_vmx_copy)
+       li      r3,1
+       blr
+
+FUNC_START(exit_vmx_copy)
+       blr
+
+FUNC_START(memcpy_power7)
+       blr
+
+FUNC_START(__copy_tofrom_user_power7)
+       blr
+
+FUNC_START(__copy_tofrom_user_base)
+       blr
+
+#define BEGIN_FTR_SECTION
+#define FTR_SECTION_ELSE
+#define ALT_FTR_SECTION_END_IFCLR(x)
+#define ALT_FTR_SECTION_END(x, y)
+#define END_FTR_SECTION_IFCLR(x)
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/processor.h b/tools/testing/selftests/powerpc/copyloops/asm/processor.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/testing/selftests/powerpc/copyloops/copyuser_64.S b/tools/testing/selftests/powerpc/copyloops/copyuser_64.S
new file mode 120000 (symlink)
index 0000000..f1c418a
--- /dev/null
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/copyuser_64.S
\ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S b/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S
new file mode 120000 (symlink)
index 0000000..4786895
--- /dev/null
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/copyuser_power7.S
\ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_64.S b/tools/testing/selftests/powerpc/copyloops/memcpy_64.S
new file mode 120000 (symlink)
index 0000000..cce33fb
--- /dev/null
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/memcpy_64.S
\ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S b/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
new file mode 120000 (symlink)
index 0000000..0d6fbfa
--- /dev/null
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/memcpy_power7.S
\ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/copyloops/validate.c b/tools/testing/selftests/powerpc/copyloops/validate.c
new file mode 100644 (file)
index 0000000..1750ff5
--- /dev/null
@@ -0,0 +1,99 @@
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "../utils.h"
+
+#define MAX_LEN 8192
+#define MAX_OFFSET 16
+#define MIN_REDZONE 128
+#define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE)
+#define POISON 0xa5
+
+unsigned long COPY_LOOP(void *to, const void *from, unsigned long size);
+
+static void do_one(char *src, char *dst, unsigned long src_off,
+                  unsigned long dst_off, unsigned long len, void *redzone,
+                  void *fill)
+{
+       char *srcp, *dstp;
+       unsigned long ret;
+       unsigned long i;
+
+       srcp = src + MIN_REDZONE + src_off;
+       dstp = dst + MIN_REDZONE + dst_off;
+
+       memset(src, POISON, BUFLEN);
+       memset(dst, POISON, BUFLEN);
+       memcpy(srcp, fill, len);
+
+       ret = COPY_LOOP(dstp, srcp, len);
+       if (ret && ret != (unsigned long)dstp) {
+               printf("(%p,%p,%ld) returned %ld\n", dstp, srcp, len, ret);
+               abort();
+       }
+
+       if (memcmp(dstp, srcp, len)) {
+               printf("(%p,%p,%ld) miscompare\n", dstp, srcp, len);
+               printf("src: ");
+               for (i = 0; i < len; i++)
+                       printf("%02x ", srcp[i]);
+               printf("\ndst: ");
+               for (i = 0; i < len; i++)
+                       printf("%02x ", dstp[i]);
+               printf("\n");
+               abort();
+       }
+
+       if (memcmp(dst, redzone, dstp - dst)) {
+               printf("(%p,%p,%ld) redzone before corrupted\n",
+                      dstp, srcp, len);
+               abort();
+       }
+
+       if (memcmp(dstp+len, redzone, dst+BUFLEN-(dstp+len))) {
+               printf("(%p,%p,%ld) redzone after corrupted\n",
+                      dstp, srcp, len);
+               abort();
+       }
+}
+
+int test_copy_loop(void)
+{
+       char *src, *dst, *redzone, *fill;
+       unsigned long len, src_off, dst_off;
+       unsigned long i;
+
+       src = memalign(BUFLEN, BUFLEN);
+       dst = memalign(BUFLEN, BUFLEN);
+       redzone = malloc(BUFLEN);
+       fill = malloc(BUFLEN);
+
+       if (!src || !dst || !redzone || !fill) {
+               fprintf(stderr, "malloc failed\n");
+               exit(1);
+       }
+
+       memset(redzone, POISON, BUFLEN);
+
+       /* Fill with sequential bytes */
+       for (i = 0; i < BUFLEN; i++)
+               fill[i] = i & 0xff;
+
+       for (len = 1; len < MAX_LEN; len++) {
+               for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
+                       for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
+                               do_one(src, dst, src_off, dst_off, len,
+                                      redzone, fill);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int main(void)
+{
+       return test_harness(test_copy_loop, str(COPY_LOOP));
+}
index 5851c4b0f55362e9f2cab9b480c6ebd3b4d0ef30..0de064406dabf5d7589f9cc094f133e12b1798a1 100644 (file)
@@ -31,4 +31,7 @@ do {                                                          \
        }                                                       \
 } while (0)
 
+#define _str(s) #s
+#define str(s) _str(s)
+
 #endif /* _SELFTESTS_POWERPC_UTILS_H */