Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL] arm64 patches for 3.14-rc1
From: Catalin Marinas @ 2014-01-20 17:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Linus,

Please pull the arm64 patches below. Thanks.


The following changes since commit 319e2e3f63c348a9b66db4667efa73178e18b17d:

  Linux 3.13-rc4 (2013-12-15 12:31:33 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-upstream

for you to fetch changes up to 883c057367014d20a14b5054e4eb0d81ce3bea5c:

  arm64: fix typo in entry.S (2014-01-13 13:55:13 +0000)

----------------------------------------------------------------
- CPU suspend support on top of PSCI (firmware Power State Coordination
  Interface)
- Jump label support
- CMA can now be enabled on arm64
- HWCAP bits for crypto and CRC32 extensions
- Optimised percpu using tpidr_el1 register
- Code cleanup

----------------------------------------------------------------
Ard Biesheuvel (1):
      arm64: drop redundant macros from read_cpuid()

Catalin Marinas (1):
      Merge tag 'arm64-suspend' of git://linux-arm.org/linux-2.6-lp into upstream

Geoff Levand (1):
      arm64: Remove unused __data_loc variable

Jiang Liu (7):
      arm64: introduce basic aarch64 instruction decoding helpers
      arm64: introduce interfaces to hotpatch kernel and module code
      arm64: move encode_insn_immediate() from module.c to insn.c
      arm64: introduce aarch64_insn_gen_{nop|branch_imm}() helper functions
      arm64, jump label: detect %c support for ARM64
      arm64, jump label: optimize jump label implementation
      jump_label: use defined macros instead of hard-coding for better readability

Konstantin Khlebnikov (2):
      ARM64: check stack pointer in get_wchan
      ARM64: fix framepointer check in unwind_frame

Laura Abbott (3):
      arm64: Correct virt_addr_valid
      arm64: Warn on NULL device structure for dma APIs
      arm64: Enable CMA

Liviu Dudau (1):
      arm64: Remove outdated comment

Lorenzo Pieralisi (13):
      arm64: kernel: add MPIDR_EL1 accessors macros
      arm64: kernel: build MPIDR_EL1 hash function data structure
      arm64: kernel: suspend/resume registers save/restore
      arm64: kernel: cpu_{suspend/resume} implementation
      arm64: kernel: implement fpsimd CPU PM notifier
      arm: kvm: implement CPU PM notifier
      arm64: kernel: refactor code to install/uninstall breakpoints
      arm64: kernel: implement HW breakpoints CPU PM notifier
      arm64: enable generic clockevent broadcast
      arm64: kernel: add CPU idle call
      arm64: kernel: add PM build infrastructure
      arm64: add CPU power management menu/entries
      arm64: kernel: restore HW breakpoint registers in cpu_suspend

Mark Brown (1):
      arm64: dts: Reduce size of virtio block device for foundation model

Mark Hambleton (2):
      arm64: dts: Add a virtio disk to the RTSM motherboard
      arm64: cmpxchg: update macros to prevent warnings

Mark Rutland (1):
      arm64: vmlinux.lds.S: drop redundant .comment

Neil Zhang (1):
      arm64: fix typo in entry.S

Sandeepa Prabhu (1):
      arm64: support single-step and breakpoint handler hooks

Steve Capper (1):
      arm64: Add hwcaps for crypto and CRC32 extensions.

Vinayak Kale (2):
      genirq: Add an accessor for IRQ_PER_CPU flag
      arm64: perf: add support for percpu pmu interrupt

Will Deacon (5):
      arm64: percpu: implement optimised pcpu access using tpidr_el1
      arm64: use generic strnlen_user and strncpy_from_user functions
      arm64: futex: ensure .fixup entries are sufficiently aligned
      arm64: dcache: select DCACHE_WORD_ACCESS for little-endian CPUs
      arm64: kconfig: select HAVE_EFFICIENT_UNALIGNED_ACCESS

 arch/arm/kvm/arm.c                           |  30 +++
 arch/arm64/Kconfig                           |  27 +++
 arch/arm64/boot/dts/foundation-v8.dts        |   2 +-
 arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi |   6 +
 arch/arm64/include/asm/Kbuild                |   1 -
 arch/arm64/include/asm/cmpxchg.h             |  28 ++-
 arch/arm64/include/asm/cpu_ops.h             |   6 +
 arch/arm64/include/asm/cputype.h             |  28 +--
 arch/arm64/include/asm/debug-monitors.h      |  21 ++
 arch/arm64/include/asm/dma-contiguous.h      |  29 +++
 arch/arm64/include/asm/futex.h               |   1 +
 arch/arm64/include/asm/hardirq.h             |   2 +-
 arch/arm64/include/asm/insn.h                | 108 ++++++++++
 arch/arm64/include/asm/jump_label.h          |  52 +++++
 arch/arm64/include/asm/memory.h              |   3 +-
 arch/arm64/include/asm/percpu.h              |  41 ++++
 arch/arm64/include/asm/proc-fns.h            |   3 +
 arch/arm64/include/asm/smp_plat.h            |  13 ++
 arch/arm64/include/asm/suspend.h             |  27 +++
 arch/arm64/include/asm/uaccess.h             |  25 +--
 arch/arm64/include/asm/word-at-a-time.h      |  94 +++++++++
 arch/arm64/include/uapi/asm/hwcap.h          |   6 +-
 arch/arm64/kernel/Makefile                   |   4 +-
 arch/arm64/kernel/arm64ksyms.c               |   5 +-
 arch/arm64/kernel/asm-offsets.c              |  11 +
 arch/arm64/kernel/debug-monitors.c           |  88 +++++++-
 arch/arm64/kernel/entry.S                    |   4 +-
 arch/arm64/kernel/fpsimd.c                   |  36 ++++
 arch/arm64/kernel/head.S                     |  10 -
 arch/arm64/kernel/hw_breakpoint.c            | 203 ++++++++++++------
 arch/arm64/kernel/insn.c                     | 304 +++++++++++++++++++++++++++
 arch/arm64/kernel/jump_label.c               |  58 +++++
 arch/arm64/kernel/module.c                   | 157 +++++---------
 arch/arm64/kernel/perf_event.c               | 108 +++++++---
 arch/arm64/kernel/process.c                  |  14 +-
 arch/arm64/kernel/setup.c                    | 122 ++++++++++-
 arch/arm64/kernel/sleep.S                    | 184 ++++++++++++++++
 arch/arm64/kernel/smp.c                      |  23 +-
 arch/arm64/kernel/stacktrace.c               |   2 +-
 arch/arm64/kernel/suspend.c                  | 132 ++++++++++++
 arch/arm64/kernel/vmlinux.lds.S              |   3 -
 arch/arm64/lib/Makefile                      |   8 +-
 arch/arm64/lib/strncpy_from_user.S           |  50 -----
 arch/arm64/lib/strnlen_user.S                |  47 -----
 arch/arm64/mm/dma-mapping.c                  |  35 ++-
 arch/arm64/mm/init.c                         |   3 +
 arch/arm64/mm/proc.S                         |  69 ++++++
 include/linux/irqdesc.h                      |   8 +
 include/linux/jump_label.h                   |  19 +-
 scripts/gcc-goto.sh                          |   2 +-
 50 files changed, 1859 insertions(+), 403 deletions(-)
 create mode 100644 arch/arm64/include/asm/dma-contiguous.h
 create mode 100644 arch/arm64/include/asm/insn.h
 create mode 100644 arch/arm64/include/asm/jump_label.h
 create mode 100644 arch/arm64/include/asm/percpu.h
 create mode 100644 arch/arm64/include/asm/suspend.h
 create mode 100644 arch/arm64/include/asm/word-at-a-time.h
 create mode 100644 arch/arm64/kernel/insn.c
 create mode 100644 arch/arm64/kernel/jump_label.c
 create mode 100644 arch/arm64/kernel/sleep.S
 create mode 100644 arch/arm64/kernel/suspend.c
 delete mode 100644 arch/arm64/lib/strncpy_from_user.S
 delete mode 100644 arch/arm64/lib/strnlen_user.S

-- 
Catalin

^ permalink raw reply

* [PATCH RFC v2 2/2] Documentation: arm: define DT C-states bindings
From: Lorenzo Pieralisi @ 2014-01-20 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390240079-6495-1-git-send-email-lorenzo.pieralisi@arm.com>

ARM based platforms implement a variety of power management schemes that
allow processors to enter at run-time low-power states, aka C-states
in ACPI jargon. The parameters defining these C-states vary on a per-platform
basis forcing the OS to hardcode the state parameters in platform
specific static tables whose size grows as the number of platforms supported
in the kernel increases and hampers device drivers standardization.

Therefore, this patch aims at standardizing C-state device tree bindings for
ARM platforms. Bindings define C-state parameters inclusive of entry methods
and state latencies, to allow operating systems to retrieve the
configuration entries from the device tree and initialize the related
power management drivers, paving the way for common code in the kernel
to deal with power states and removing the need for static data in current
and previous kernel versions.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/c-states.txt | 774 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/cpus.txt     |  10 +
 2 files changed, 784 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/c-states.txt

diff --git a/Documentation/devicetree/bindings/arm/c-states.txt b/Documentation/devicetree/bindings/arm/c-states.txt
new file mode 100644
index 0000000..0b5617b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/c-states.txt
@@ -0,0 +1,774 @@
+==========================================
+ARM C-states binding description
+==========================================
+
+==========================================
+1 - Introduction
+==========================================
+
+ARM systems contain HW capable of managing power consumption dynamically,
+where cores can be put in different low-power states (ranging from simple
+wfi to power gating) according to OSPM policies. Borrowing concepts
+from the ACPI specification[1], the CPU states representing the range of
+dynamic states that a processor can enter at run-time, aka C-state, can be
+specified through device tree bindings representing the parameters required to
+enter/exit specific C-states on a given processor.
+
+The state an ARM CPU can be put into is loosely identified by one of the
+following operating modes:
+
+- Running:
+	 # Processor core is executing instructions
+
+- Wait for Interrupt:
+	# An ARM processor enters wait for interrupt (WFI) low power
+	  state by executing a wfi instruction. When a processor enters
+	  wfi state it disables most of the clocks while keeping the processor
+	  powered up. This state is standard on all ARM processors and it is
+	  defined as C1 in the remainder of this document.
+
+- Dormant:
+	# Dormant mode is entered by executing wfi instructions and by sending
+	  platform specific commands to the platform power controller (coupled
+	  with processor specific SW/HW control sequences).
+	  In dormant mode, most of the processor control and debug logic is
+	  powered up but cache RAM can be put in retention state, providing
+	  additional power savings.
+
+- Sleep:
+	# Sleep mode is entered by executing the wfi instruction and by sending
+	  platform specific commands to the platform power controller (coupled
+	  with processor specific SW/HW control sequences). In sleep mode, a
+	  processor and its caches are shutdown, the entire processor state is
+	  lost.
+
+Building on top of the previous processor modes, ARM platforms implement power
+management schemes that allow an OS PM implementation to put the processor in
+different CPU states (C-states). C-states parameters (eg latency) are
+platform specific and need to be characterized with bindings that provide the
+required information to OSPM code so that it can build the required tables and
+use them at runtime.
+
+The device tree binding definition for ARM C-states is the subject of this
+document.
+
+===========================================
+2 - cpu-power-states node
+===========================================
+
+ARM processor C-states are defined within the cpu-power-states node, which is
+a direct child of the cpus node and provides a container where the processor
+states, defined as device tree nodes, are listed.
+
+- cpu-power-states node
+
+	Usage: Optional - On ARM systems, is a container of processor C-state
+			  nodes. If the system does not provide CPU power
+			  management capabilities or the processor just
+			  supports WFI (C1 state) a cpu-power-states node is
+			  not required.
+
+	Description: cpu-power-states node is a container node, where its
+		     subnodes describe the CPU low-power C-states.
+
+	Node name must be "cpu-power-states".
+
+	The cpu-power-states node's parent node must be cpus node.
+
+	The cpu-power-states node's child nodes can be:
+
+	- one or more state nodes
+
+	Any other configuration is considered invalid.
+
+The nodes describing the C-states (state) can only be defined within the
+cpu-power-states node.
+
+Any other configuration is consider invalid and therefore must be ignored.
+
+===========================================
+2 - state node
+===========================================
+
+A state node represents a C-state description and must be defined as follows:
+
+- state node
+
+	Description: must be child of either the cpu-power-states node or
+		     a state node.
+
+	The state node name shall be "stateN", where N = {0, 1, ...} is
+	the node number; state nodes which are siblings within a single common
+	parent node must be given a unique and sequential N value, starting
+	from 0.
+
+	A state node can contain state child nodes. Child nodes inherit
+	properties from the parent state nodes that work as state
+	properties aggregators (ie contain properties valid on all state
+	nodes children).
+
+	A state node defines the following properties (either explicitly
+	or by inheriting them from a parent node):
+
+	- compatible
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Must be "arm,cpu-power-state".
+
+	- index
+		Usage: Required
+		Value type: <u32>
+		Definition: It represents C-state index, starting from 2 (index
+			    0 represents the processor state "running" and
+			    index 1 represents processor mode "WFI"; indexes 0
+			    and 1 are standard ARM states that need not be
+			    described).
+
+	- power-domain
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: List of phandle and power domain specifiers
+			    as defined by bindings of power controller
+			    specified by the phandle [3]. It represents the
+			    power domains associated with the C-state. The
+			    power domains list can be used by OSPM to
+			    retrieve the devices belonging to the power
+			    domains and carry out corresponding actions to
+			    preserve functionality across power cycles
+			    (ie context save/restore, cache flushing).
+
+	- entry-method
+		Usage: Required
+		Value type: <stringlist>
+		Definition: Describes the method by which a CPU enters the
+			    C-state. This property is required and must be one
+			    of:
+
+			    - "psci"
+			      ARM Standard firmware interface
+
+			    - "[vendor],[method]"
+			      An implementation dependent string with
+			      format "vendor,method", where vendor is a string
+			      denoting the name of the manufacturer and
+			      method is a string specifying the mechanism
+			      used to enter the C-state.
+
+	- psci-power-state
+		Usage: Required if entry-method property value is set to
+		       "psci".
+		Value type: <u32>
+		Definition: power_state parameter to pass to the PSCI
+			    suspend call to enter the C-state.
+
+	- latency
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: List of u32 values representing worst case latency
+			    in microseconds required to enter and exit the
+			    C-state, one value per OPP [2]. The list should
+			    be specified in the same order as the operating
+			    points property list of the cpu this state is
+			    valid on.
+			    If no OPP bindings are present, the latency value
+			    is associated with the current OPP of CPUs in the
+			    system.
+
+	- min-residency
+		Usage: Required
+		Value type: <prop-encoded-array>
+		Definition: List of u32 values representing time in
+			    microseconds required for the CPU to be in
+			    the C-state to make up for the dynamic power
+			    consumed to enter/exit the C-state in order to
+			    break even in terms of power consumption compared
+			    to C1 state (wfi), one value per-OPP [2].
+			    This parameter depends on the operating conditions
+			    (HW state) and must assume worst case scenario.
+			    The list should be specified in the same order as
+			    the operating points property list of the cpu this
+			    state is valid on.
+			    If no OPP bindings are present the min-residency
+			    value is associated with the current OPP of CPUs
+			    in the system.
+
+===========================================
+3 - Examples
+===========================================
+
+Example 1 (ARM 64-bit, 16-cpu system, two clusters of clusters):
+
+pd_clusters: power-domain-clusters at 80002000 {
+	compatible = "arm,power-controller";
+	reg = <0x0 0x80002000 0x0 0x1000>;
+	#power-domain-cells = <1>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	pd_cores: power-domain-cores at 80000000 {
+		compatible = "arm,power-controller";
+		reg = <0x0 0x80000000 0x0 0x1000>;
+		#power-domain-cells = <1>;
+	};
+};
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <2>;
+
+	cpu-power-states {
+
+		state0 {
+			compatible = "arm,cpu-power-state";
+			index = <2>;
+			entry-method = "psci";
+			psci-power-state = <0x1010000>;
+			latency = <400>;
+			min-residency = <300>;
+			STATE0_0: state0 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 0>;
+			};
+			STATE0_1: state1 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 1>;
+			};
+			STATE0_2: state2 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 2>;
+			};
+			STATE0_3: state3 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 3>;
+			};
+			STATE0_4: state4 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 4>;
+			};
+			STATE0_5: state5 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 5>;
+			};
+			STATE0_6: state6 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 6>;
+			};
+			STATE0_7: state7 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 7>;
+			};
+		};
+
+		state1 {
+			compatible = "arm,cpu-power-state";
+			index = <2>;
+			entry-method = "psci";
+			psci-power-state = <0x1010000>;
+			latency = <400>;
+			min-residency = <500>;
+			STATE1_0: state0 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 8>;
+			};
+			STATE1_1: state1 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 9>;
+			};
+			STATE1_2: state2 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 10>;
+			};
+			STATE1_3: state3 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 11>;
+			};
+			STATE1_4: state4 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 12>;
+			};
+			STATE1_5: state5 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 13>;
+			};
+			STATE1_6: state6 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 14>;
+			};
+			STATE1_7: state7 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 15>;
+			};
+		};
+
+		STATE2: state2 {
+			compatible = "arm,cpu-power-state";
+			index = <3>;
+			entry-method = "psci";
+			psci-power-state = <0x3010000>;
+			latency = <1000>;
+			min-residency = <2500>;
+			power-domain = <&pd_clusters 0>;
+		};
+
+		STATE3: state3 {
+			compatible = "arm,cpu-power-state";
+			index = <3>;
+			entry-method = "psci";
+			psci-power-state = <0x3010000>;
+			latency = <4500>;
+			min-residency = <6500>;
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x0>;
+		enable-method = "psci";
+		next-level-cache = <&L1_0>;
+		cpu-power-states = <&STATE0_0 &STATE2>;
+		L1_0: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 0>;
+		};
+		L2_0: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 0>;
+		};
+	};
+
+	CPU1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x1>;
+		enable-method = "psci";
+		next-level-cache = <&L1_1>;
+		cpu-power-states = <&STATE0_1 &STATE2>;
+		L1_1: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 1>;
+		};
+	};
+
+	CPU2: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_2>;
+		cpu-power-states = <&STATE0_2 &STATE2>;
+		L1_2: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 2>;
+		};
+	};
+
+	CPU3: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_3>;
+		cpu-power-states = <&STATE0_3 &STATE2>;
+		L1_3: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 3>;
+		};
+	};
+
+	CPU4: cpu at 10000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10000>;
+		enable-method = "psci";
+		next-level-cache = <&L1_4>;
+		cpu-power-states = <&STATE0_4 &STATE2>;
+		L1_4: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 4>;
+		};
+	};
+
+	CPU5: cpu at 10001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10001>;
+		enable-method = "psci";
+		next-level-cache = <&L1_5>;
+		cpu-power-states = <&STATE0_5 &STATE2>;
+		L1_5: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 5>;
+		};
+	};
+
+	CPU6: cpu at 10100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_6>;
+		cpu-power-states = <&STATE0_6 &STATE2>;
+		L1_6: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 6>;
+		};
+	};
+
+	CPU7: cpu at 10101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x0 0x10101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_7>;
+		cpu-power-states = <&STATE0_7 &STATE2>;
+		L1_7: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 7>;
+		};
+	};
+
+	CPU8: cpu at 100000000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x0>;
+		enable-method = "psci";
+		next-level-cache = <&L1_8>;
+		cpu-power-states = <&STATE1_0 &STATE3>;
+		L1_8: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 8>;
+		};
+		L2_1: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU9: cpu at 100000001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x1>;
+		enable-method = "psci";
+		next-level-cache = <&L1_9>;
+		cpu-power-states = <&STATE1_1 &STATE3>;
+		L1_9: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 9>;
+		};
+	};
+
+	CPU10: cpu at 100000100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_10>;
+		cpu-power-states = <&STATE1_2 &STATE3>;
+		L1_10: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 10>;
+		};
+	};
+
+	CPU11: cpu at 100000101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_11>;
+		cpu-power-states = <&STATE1_3 &STATE3>;
+		L1_11: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 11>;
+		};
+	};
+
+	CPU12: cpu at 100010000 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10000>;
+		enable-method = "psci";
+		next-level-cache = <&L1_12>;
+		cpu-power-states = <&STATE1_4 &STATE3>;
+		L1_12: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 12>;
+		};
+	};
+
+	CPU13: cpu at 100010001 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10001>;
+		enable-method = "psci";
+		next-level-cache = <&L1_13>;
+		cpu-power-states = <&STATE1_5 &STATE3>;
+		L1_13: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 13>;
+		};
+	};
+
+	CPU14: cpu at 100010100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10100>;
+		enable-method = "psci";
+		next-level-cache = <&L1_14>;
+		cpu-power-states = <&STATE1_6 &STATE3>;
+		L1_14: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 14>;
+		};
+	};
+
+	CPU15: cpu at 100010101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x1 0x10101>;
+		enable-method = "psci";
+		next-level-cache = <&L1_15>;
+		cpu-power-states = <&STATE1_7 &STATE3>;
+		L1_15: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 15>;
+		};
+	};
+};
+
+Example 2 (ARM 32-bit, 8-cpu system, two clusters):
+
+pd_clusters: power-domain-clusters at 80002000 {
+	compatible = "arm,power-controller";
+	reg = <0x80002000 0x1000>;
+	#power-domain-cells = <1>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	pd_cores: power-domain-cores at 80000000 {
+		compatible = "arm,power-controller";
+		reg = <0x80000000 0x1000>;
+		#power-domain-cells = <1>;
+	};
+};
+
+cpus {
+	#size-cells = <0>;
+	#address-cells = <1>;
+
+	cpu-power-states {
+
+		state0 {
+			compatible = "arm,cpu-power-state";
+			index = <2>;
+			entry-method = "psci";
+			psci-power-state = <0x1010000>;
+			latency = <400>;
+			min-residency = <300>;
+			STATE0_0: state0 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 0>;
+			};
+			STATE0_1: state1 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 1>;
+			};
+			STATE0_2: state2 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 2>;
+			};
+			STATE0_3: state3 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 3>;
+			};
+		};
+
+		state1 {
+			compatible = "arm,cpu-power-state";
+			index = <2>;
+			entry-method = "psci";
+			psci-power-state = <0x1010000>;
+			latency = <400>;
+			min-residency = <500>;
+			STATE1_0: state0 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 4>;
+			};
+			STATE1_1: state1 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 5>;
+			};
+			STATE1_2: state2 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 6>;
+			};
+			STATE1_3: state3 {
+				compatible = "arm,cpu-power-state";
+				power-domain = <&pd_cores 7>;
+			};
+		};
+
+		STATE2: state2 {
+			compatible = "arm,cpu-power-state";
+			index = <3>;
+			entry-method = "psci";
+			psci-power-state = <0x3010000>;
+			latency = <1000>;
+			min-residency = <1500>;
+			power-domain = <&pd_clusters 0>;
+		};
+
+		STATE3: state3 {
+			compatible = "arm,cpu-power-state";
+			index = <3>;
+			entry-method = "psci";
+			psci-power-state = <0x3010000>;
+			latency = <4500>;
+			min-residency = <6500>;
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x0>;
+		next-level-cache = <&L1_0>;
+		cpu-power-states = <&STATE0_0 &STATE2>;
+		L1_0: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 0>;
+		};
+		L2_0: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 0>;
+		};
+	};
+
+	CPU1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x1>;
+		next-level-cache = <&L1_1>;
+		cpu-power-states = <&STATE0_1 &STATE2>;
+		L1_1: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 1>;
+		};
+	};
+
+	CPU2: cpu at 2 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x2>;
+		next-level-cache = <&L1_2>;
+		cpu-power-states = <&STATE0_2 &STATE2>;
+		L1_2: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 2>;
+		};
+	};
+
+	CPU3: cpu at 3 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a15";
+		reg = <0x3>;
+		next-level-cache = <&L1_3>;
+		cpu-power-states = <&STATE0_3 &STATE2>;
+		L1_3: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_0>;
+			power-domain = <&pd_cores 3>;
+		};
+	};
+
+	CPU4: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x100>;
+		next-level-cache = <&L1_4>;
+		cpu-power-states = <&STATE1_0 &STATE3>;
+		L1_4: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 4>;
+		};
+		L2_1: l2-cache {
+			compatible = "arm,arch-cache";
+			power-domain = <&pd_clusters 1>;
+		};
+	};
+
+	CPU5: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x101>;
+		next-level-cache = <&L1_5>;
+		cpu-power-states = <&STATE1_1 &STATE3>;
+		L1_5: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 5>;
+		};
+	};
+
+	CPU6: cpu at 102 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x102>;
+		next-level-cache = <&L1_6>;
+		cpu-power-states = <&STATE1_2 &STATE3>;
+		L1_6: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 6>;
+		};
+	};
+
+	CPU7: cpu at 103 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a7";
+		reg = <0x103>;
+		next-level-cache = <&L1_7>;
+		cpu-power-states = <&STATE1_3 &STATE3>;
+		L1_7: l1-cache {
+			compatible = "arm,arch-cache";
+			next-level-cache = <&L2_1>;
+			power-domain = <&pd_cores 7>;
+		};
+	};
+};
+
+===========================================
+4 - References
+===========================================
+
+[1] ACPI v5.0 specification
+    http://www.acpi.info/spec50.htm
+
+[2] ARM Linux kernel documentation - OPP bindings
+    Documentation/devicetree/bindings/power/opp.txt
+
+[3] ARM Linux Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 9130435..a3c9193 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -191,6 +191,13 @@ nodes to be present and contain the properties described below.
 			  property identifying a 64-bit zero-initialised
 			  memory location.
 
+	- cpu-power-states
+		Usage: Optional
+		Value type: <prop-encoded-array>
+		Definition:
+			# List of phandles to cpu power state nodes supported
+			  by this cpu [1].
+
 Example 1 (dual-cluster big.LITTLE system 32-bit):
 
 	cpus {
@@ -382,3 +389,6 @@ cpus {
 		cpu-release-addr = <0 0x20000000>;
 	};
 };
+
+[1] ARM Linux kernel documentation - C-state bindings
+    Documentation/devicetree/bindings/arm/c-states.txt
-- 
1.8.4

^ permalink raw reply related

* [PATCH RFC v2 1/2] Documentation: arm: add cache DT bindings
From: Lorenzo Pieralisi @ 2014-01-20 17:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390240079-6495-1-git-send-email-lorenzo.pieralisi@arm.com>

On ARM systems the cache topology cannot be probed at runtime, in
particular, it is impossible to probe which CPUs share a given cache
level. Power management software requires this knowledge to implement
optimized power down sequences, hence this patch adds a document that
defines the DT cache bindings for ARM systems. The bindings are compliant
with ePAPR (PowerPC bindings), even though most of the cache nodes
properties requirements are overriden, because caches geometry for
architected caches is probeable on ARM systems. This patch also adds
properties that are specific to ARM architected caches to the existing ones
defined in the ePAPR v1.1, as bindings extensions.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
---
 Documentation/devicetree/bindings/arm/cache.txt | 187 ++++++++++++++++++++++++
 1 file changed, 187 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/cache.txt

diff --git a/Documentation/devicetree/bindings/arm/cache.txt b/Documentation/devicetree/bindings/arm/cache.txt
new file mode 100644
index 0000000..b27cedf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cache.txt
@@ -0,0 +1,187 @@
+==========================================
+ARM processors cache binding description
+==========================================
+
+Device tree bindings for ARM processor caches adhere to the cache bindings
+described in [3], in section 3.8 for multi-level and shared caches.
+On ARM based systems most of the cache properties related to cache
+geometry are probeable in HW, hence, unless otherwise stated, the properties
+defined in ePAPR for multi-level and shared caches are to be considered
+optional by default.
+
+On ARM, caches are either architected (directly controlled by the processor
+through coprocessor instructions and tightly coupled with the processor
+implementation) or unarchitected (controlled through a memory mapped
+interface, implemented as a stand-alone IP external to the processor
+implementation).
+
+This document provides the device tree bindings for ARM architected caches.
+
+- ARM architected cache node
+
+	Description: must be a direct child of the cpu node. A system
+		     can contain multiple architected cache nodes per cpu node,
+		     linked through the next-level-cache phandle. The
+		     next-level-cache property in the cpu node points to
+		     the first level of architected cache for the CPU.
+		     The next-level-cache property in architected cache nodes
+		     points to the respective next level of caching in the
+		     hierarchy. An architected cache node with an empty or
+		     missing next-level-cache property represents the last
+		     architected cache level for the CPU.
+		     On ARM v7 and v8 architectures, the order in which cache
+		     nodes are linked through the next-level-cache phandle must
+		     follow the ordering specified in the processors CLIDR (v7)
+		     and CLIDR_EL1 (v8) registers, as described in [1][2],
+		     implying that a cache node pointed at by a
+		     next-level-cache phandle must correspond to a level
+		     defined in CLIDR (v7) and CLIDR_EL1 (v8) greater than the
+		     one the cache node containing the next-level-cache
+		     phandle corresponds to.
+
+	Since on ARM most of the cache properties are probeable in HW the
+	properties described in [3] - section 3.8 multi-level and shared
+	caches - shall be considered optional, with the following properties
+	updates, specific for the ARM architected cache node.
+
+	- compatible
+		Usage: Required
+		Value type: <string>
+		Definition: value shall be "arm,arch-cache".
+
+	- interrupts
+		Usage: Optional
+		Value type: See definition
+		Definition: standard device tree property [3] that defines
+			    the interrupt line associated with the cache.
+			    The property can be accompanied by an
+			    interrupt-names property, as described in [4].
+
+	- power-domain
+		Usage: Optional
+		Value type: phandle
+		Definition: A phandle and power domain specifier as defined by
+			    bindings of power controller specified by the
+			    phandle [5].
+
+Example(dual-cluster big.LITTLE system 32-bit)
+
+	cpus {
+		#size-cells = <0>;
+		#address-cells = <1>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x0>;
+			next-level-cache = <&L1_0>;
+
+			L1_0: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+
+			L2_0: l2-cache {
+				compatible = "arm,arch-cache";
+			};
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x1>;
+			next-level-cache = <&L1_1>;
+
+			L1_1: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x2>;
+			next-level-cache = <&L1_2>;
+
+			L1_2: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <0x3>;
+			next-level-cache = <&L1_3>;
+
+			L1_3: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_0>;
+			};
+		};
+
+		cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			next-level-cache = <&L1_4>;
+
+			L1_4: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+
+			L2_1: l2-cache {
+				compatible = "arm,arch-cache";
+			};
+		};
+
+		cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			next-level-cache = <&L1_5>;
+
+			L1_5: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+
+		cpu at 102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x102>;
+			next-level-cache = <&L1_6>;
+
+			L1_6: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+
+		cpu at 103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x103>;
+			next-level-cache = <&L1_7>;
+
+			L1_7: l1-cache {
+				compatible = "arm,arch-cache";
+				next-level-cache = <&L2_1>;
+			};
+		};
+	};
+
+[1] ARMv7-AR Reference Manual
+    http://infocenter.arm.com/help/index.jsp
+[2] ARMv8-A Reference Manual
+    http://infocenter.arm.com/help/index.jsp
+[3] ePAPR standard
+    https://www.power.org/documentation/epapr-version-1-1/
+[4] Kernel documentation - resource property bindings
+    Documentation/devicetree/bindings/resource-names.txt
+[5] Kernel documentation - power domain bindings
+    Documentation/devicetree/bindings/power/power_domain.txt
-- 
1.8.4

^ permalink raw reply related

* [PATCH RFC v2 0/2] ARM: defining power states DT bindings
From: Lorenzo Pieralisi @ 2014-01-20 17:47 UTC (permalink / raw)
  To: linux-arm-kernel

This is v2 of a previous posting:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-December/215544.html

This patchset depends on the following bindings to be approved and augmented
to cater for hierarchical power domains in DT:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-January/224928.html

Changes in v2:

- Updated cache bindings according to review
- Added power domain phandle to cache bindings
- Added power domains to C-states bindings
- Removed useless reg property from C-states bindings
- Removed cpu-map references from C-states bindings
- Added dependency on OPP in C-states parameters
- Added C-state state hierarchy

ARM based systems embed power management HW that allows SW to enter
low-power states according to run-time criteria based on parameters (eg
power state entry/exit latency) that define how a power state has to be
managed and its respective properties. ARM partners implement HW power
management schemes through custom HW, with power controllers and relative
control mechanisms differing on both HW implementations and the way SW can
control them. This differentiation forces PM software in the kernel to cope
with states differences in power management drivers, which cause code
fragmentation and duplication of functionality.

Most of the power control scheme HW parameters are not probeable on ARM
platforms from a SW point of view, hence, in order to tackle the drivers
fragmentation problem, this patch series defines device tree bindings to
describe power states parameters on ARM platforms.

Device tree bindings for power states also require the introduction of device
tree bindings for processor caches, since power states entry/exit require
SW cache maintainance; in some ARM systems, where firmware does not
support power down interfaces, cache maintainance must be carried out in the
OS power management layer, which then requires a description of the cache
topology through device tree nodes.

The power states on ARM are described as "C-states" in this patchset,
borrowing the nomenclature from ACPI power states bindings which have by now
been widely adopted on both x86 and ARM world as power states names.

C-states device tree standardization shares most of the concepts and
definitions with the ongoing ACPI ARM C-state bindings proposal so that
both standards can contain a coherent set of parameters, simplifying the
way SW will have to handle the respective device drivers.

Lorenzo Pieralisi (2):
  Documentation: arm: add cache DT bindings
  Documentation: arm: define DT C-states bindings

 Documentation/devicetree/bindings/arm/c-states.txt | 774 +++++++++++++++++++++
 Documentation/devicetree/bindings/arm/cache.txt    | 187 +++++
 Documentation/devicetree/bindings/arm/cpus.txt     |  10 +
 3 files changed, 971 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/c-states.txt
 create mode 100644 Documentation/devicetree/bindings/arm/cache.txt

-- 
1.8.4

^ permalink raw reply

* [PATCH v2 0/5] arm64: advertise availability of CRC and crypto instructions
From: Nicolas Pitre @ 2014-01-20 17:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140120173838.GD29971@arm.com>

On Mon, 20 Jan 2014, Catalin Marinas wrote:

> On Mon, Dec 23, 2013 at 02:06:27PM +0000, Ard Biesheuvel wrote:
> > This series is a followup to the patch that was recently merged by Catalin that
> > allocates hwcaps bits for CRC and Crypto Extensions instructions so userland can
> > discover whether the current CPU has any of those capabilities.
> > 
> > Patch #1 enables ARM support for the ELF_HWCAP2/AT_HWCAP2 ELF auxv entry that
> > was recently added to the kernel and glibc (2.18). It extends the feature bit
> > space to 64 bits (on 32-bit architectures)
> > 
> > Patch #2 adds generic support for ELF_HWCAP2/AT_HWCAP2 to the 32-bit ELF compat
> > mode for 64-bit architectures.
> > 
> > Patch #3 adds support for ELF_HWCAP2/AT_HWCAP2 to arm64's 32-bit ELF compat mode
> > 
> > Patch #4 allocates the HWCAP2 bits in the arch/arm tree. This is necessary
> > because 32-bit ARM binaries can execute both under ARM and under arm64 kernels,
> > so there should be agreement about the meaning of feature bits, even if the ARM
> > kernel has no support yet for ARMv8 32-bit only hardware (such as ARMv8-R).
> 
> It looks a bit strange to start filling HWCAP2 before HWCAP is full but
> I guess we want to preserve some future extensions in HWCAP for older
> glibc.

How could older glibc possibly care about future extensions?


Nicolas

^ permalink raw reply

* [PATCH v2 5/5] arm64: advertise ARMv8 extensions to 32-bit compat ELF binaries
From: Catalin Marinas @ 2014-01-20 17:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1387807592-26375-6-git-send-email-ard.biesheuvel@linaro.org>

On Mon, Dec 23, 2013 at 02:06:32PM +0000, Ard Biesheuvel wrote:
> This adds support for advertising the presence of ARMv8 Crypto
> Extensions in the Aarch32 execution state to 32-bit ELF binaries
> running in 32-bit compat mode under the arm64 kernel.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

(for both arm64 patches in case they go in via a different route;
otherwise I'll take the arm64 patches if Russell is ok with merging the
arm ones)

^ permalink raw reply

* [PATCH v2 4/5] ARM: introduce HWCAP2 feature bits for ARMv8 Crypto Extensions
From: Catalin Marinas @ 2014-01-20 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1387807592-26375-5-git-send-email-ard.biesheuvel@linaro.org>

On Mon, Dec 23, 2013 at 02:06:31PM +0000, Ard Biesheuvel wrote:
> This allocates feature bits 0-4 in HWCAP2 for the crypto and CRC
> extensions introduced in ARMv8.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH v2 2/5] binfmt_elf: add ELF_HWCAP2 to compat auxv entries
From: Catalin Marinas @ 2014-01-20 17:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1387807592-26375-3-git-send-email-ard.biesheuvel@linaro.org>

On Mon, Dec 23, 2013 at 02:06:29PM +0000, Ard Biesheuvel wrote:
> Add ELF_HWCAP2 to the set of auxv entries that is passed to
> a 32-bit ELF program running in 32-bit compat mode under a
> 64-bit kernel.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH v2 1/5] ARM: add support for AT_HWCAP2 ELF auxv entry
From: Catalin Marinas @ 2014-01-20 17:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1387807592-26375-2-git-send-email-ard.biesheuvel@linaro.org>

On Mon, Dec 23, 2013 at 02:06:28PM +0000, Ard Biesheuvel wrote:
> This enables AT_HWCAP2 for ARM. The generic support for this
> new ELF auxv entry was added in commit 2171364d1a9 (powerpc:
> Add HWCAP2 aux entry)
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

^ permalink raw reply

* [PATCH v2 0/5] arm64: advertise availability of CRC and crypto instructions
From: Catalin Marinas @ 2014-01-20 17:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1387807592-26375-1-git-send-email-ard.biesheuvel@linaro.org>

On Mon, Dec 23, 2013 at 02:06:27PM +0000, Ard Biesheuvel wrote:
> This series is a followup to the patch that was recently merged by Catalin that
> allocates hwcaps bits for CRC and Crypto Extensions instructions so userland can
> discover whether the current CPU has any of those capabilities.
> 
> Patch #1 enables ARM support for the ELF_HWCAP2/AT_HWCAP2 ELF auxv entry that
> was recently added to the kernel and glibc (2.18). It extends the feature bit
> space to 64 bits (on 32-bit architectures)
> 
> Patch #2 adds generic support for ELF_HWCAP2/AT_HWCAP2 to the 32-bit ELF compat
> mode for 64-bit architectures.
> 
> Patch #3 adds support for ELF_HWCAP2/AT_HWCAP2 to arm64's 32-bit ELF compat mode
> 
> Patch #4 allocates the HWCAP2 bits in the arch/arm tree. This is necessary
> because 32-bit ARM binaries can execute both under ARM and under arm64 kernels,
> so there should be agreement about the meaning of feature bits, even if the ARM
> kernel has no support yet for ARMv8 32-bit only hardware (such as ARMv8-R).

It looks a bit strange to start filling HWCAP2 before HWCAP is full but
I guess we want to preserve some future extensions in HWCAP for older
glibc.

-- 
Catalin

^ permalink raw reply

* [PATCHv13 00/40] ARM: TI SoC clock DT conversion
From: Nishanth Menon @ 2014-01-20 17:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52D9D6C6.2000700@ti.com>

On 01/17/2014 07:20 PM, Nishanth Menon wrote:
[...]
> I am running a defconfig set check on next-20140117 and will do one
> with next-20140118 once that is ready for comparison results
> 
baseline next-20140120
modified as follows:
multi_v7_defconfig - added CONFIG_SOC_DRA7XX
omap2plus_defconfig - added CONFIG_SOC_AM43XX
few patches for legacy boot platforms added in.

next-20140120-omap2plus_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s2vfJ5w6Na
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s21IdtacuB
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s2zrGqzI8r
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s21RLq4EzM
 5: am43xx-epos:  Boot PASS: http://slexy.org/raw/s21msOh70k
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s2MyM1kbTJ
 7: BeagleBone-Black:  Boot PASS: http://slexy.org/raw/s2KmkjEQU5
 8:      crane: No Image built - Missing platform support?:
* Pending merge from Benoit's tree
 9:       dra7:  Boot PASS: http://slexy.org/raw/s20GK8ZSrL
10:        ldp:  Boot FAIL: http://slexy.org/raw/s20I1vJEY6
* Known issue on my setup :( - debug pending.
11: PandaBoard-ES:  Boot PASS: http://slexy.org/raw/s2SVGtHlwx
12:    sdp2430:  Boot PASS: http://slexy.org/raw/s214WyGCco
13:    sdp3430:  Boot PASS: http://slexy.org/raw/s21fPHXoOB
14:    sdp4430:  Boot PASS: http://slexy.org/raw/s20v0UJubl
15: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s2jPgymund
TOTAL = 15 boards, Booted Boards = 13, No Boot boards = 2

next-20140120-multi_v7_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s2DcNIdR1p
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s2NWkEQIct
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s21rOVU9L3
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s2xRLmJ9EW
 5: am43xx-epos:  Boot PASS: http://slexy.org/raw/s21487l9Tw
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s2198moPea
 7: BeagleBone-Black:  Boot PASS: http://slexy.org/raw/s20wdS9zgf
 8:      crane: No Image built - Missing platform support?:
* pending merge from Benoit's tree
 9:       dra7:  Boot PASS: http://slexy.org/raw/s21Vr0foZS
10:        ldp:  Boot PASS: http://slexy.org/raw/s21PKycvVx
11: PandaBoard-ES:  Boot FAIL: http://slexy.org/raw/s20M5bdzFq
* kevin already reported this for CPU_IDLE enable
12:    sdp2430:  v6 platform - wont boot
13:    sdp3430:  Boot PASS: http://slexy.org/raw/s2pmLQItJb
14:    sdp4430:  Boot PASS: http://slexy.org/raw/s21FYwSVZz
15: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s21O7xuAJp
TOTAL = 15 boards, Booted Boards = 12, No Boot boards = 3

next-20140120-multi_v7_defconfig + CONFIG_ARM_LPAE=y
 1: am335x-evm:  Boot FAIL: http://slexy.org/raw/s21YHQrdtf
 2:  am335x-sk:  Boot FAIL: http://slexy.org/raw/s20buoWhQw
 3: am3517-evm:  Boot FAIL: http://slexy.org/raw/s2VfH3LYFf
 4:  am37x-evm:  Boot FAIL: http://slexy.org/raw/s20Q4s7tjA
 5: am43xx-epos:  Boot FAIL: http://slexy.org/raw/s2tMG0ABLi
 6: BeagleBoard-XM:  Boot FAIL: http://slexy.org/raw/s20INrphLO
 7: BeagleBone-Black:  Boot FAIL: http://slexy.org/raw/s2ZKx9lyGc
 8:      crane: No Image built - Missing platform support?:
 9:       dra7:  Boot PASS: http://slexy.org/raw/s21EV3vV4E
10:        ldp:  Boot FAIL: http://slexy.org/raw/s21aQ1vXWH
11: PandaBoard-ES:  Boot FAIL: http://slexy.org/raw/s20JMBxQUc
12:    sdp2430:  v6 platform - wont boot
13:    sdp3430:  Boot FAIL: http://slexy.org/raw/s20Itj0uX4
14:    sdp4430:  Boot FAIL: http://slexy.org/raw/s2BEPG9pjN
15: OMAP5432uEVM:  Boot PASS: http://slexy.org/raw/s20bOKUZev
TOTAL = 15 boards, Booted Boards = 2, No Boot boards = 13


in comparison  with previous next tag:
multi_v7_defconfig - added CONFIG_SOC_DRA7XX
omap2plus_defconfig - added CONFIG_SOC_AM43XX
few patches for legacy boot platforms added in.

next-20140117-omap2plus_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s2x6c41m1Q
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s24IkMtLwV
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s20ahoA1JR
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s2hzZbe5fq
 5: am43xx-epos:  Boot FAIL: http://slexy.org/raw/s20875oeoW
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s20luzJWbj
 7: BeagleBone-Black:  Boot PASS: http://slexy.org/raw/s2Z1YQqX1A
 8:      crane: No Image built - Missing platform support?:
 9:       dra7:  Boot FAIL: http://slexy.org/raw/s2137kLALM
10:        ldp:  Boot FAIL: http://slexy.org/raw/s21S66NNnp
11: PandaBoard-ES:  Boot PASS: http://slexy.org/raw/s20XyDcifE
12:    sdp2430:  Boot PASS: http://slexy.org/raw/s234d7bWzB
13:    sdp3430:  Boot PASS: http://slexy.org/raw/s250xvaBxy
14:    sdp4430:  Boot PASS: http://slexy.org/raw/s2g3As3XlA
15: OMAP5432uEVM:  Boot FAIL: http://slexy.org/raw/s21hOhWY4E
TOTAL = 15 boards, Booted Boards = 10, No Boot boards = 5

next-20140117-multi_v7_defconfig
 1: am335x-evm:  Boot PASS: http://slexy.org/raw/s2M6DZp8D2
 2:  am335x-sk:  Boot PASS: http://slexy.org/raw/s21WdeG7QL
 3: am3517-evm:  Boot PASS: http://slexy.org/raw/s2PanhpCqK
 4:  am37x-evm:  Boot PASS: http://slexy.org/raw/s20nI7GNQS
 5: am43xx-epos:  Boot FAIL: http://slexy.org/raw/s2FFQpMN21
 6: BeagleBoard-XM:  Boot PASS: http://slexy.org/raw/s2hy4PnWL6
 7: BeagleBone-Black:  Boot PASS: http://slexy.org/raw/s21tx10epo
 8:      crane: No Image built - Missing platform support?:
 9:       dra7:  Boot FAIL: http://slexy.org/raw/s20itoFBdS
10:        ldp:  Boot PASS: http://slexy.org/raw/s213Un5KQW
11: PandaBoard-ES:  Boot FAIL: http://slexy.org/raw/s20B5kDMwg
12:    sdp2430:  Boot FAIL: http://slexy.org/raw/s21ZvpGpmK
13:    sdp3430:  Boot PASS: http://slexy.org/raw/s20Ne0P2oX
14:    sdp4430:  Boot PASS: http://slexy.org/raw/s215lq0bvl
15: OMAP5432uEVM:  Boot FAIL: http://slexy.org/raw/s2cUSAGe5h
TOTAL = 15 boards, Booted Boards = 9, No Boot boards = 6

next-20140117-multi_v7_defconfig + CONFIG_ARM_LPAE=y
 1: am335x-evm:  Boot FAIL: http://slexy.org/raw/s208rBie8T
 2:  am335x-sk:  Boot FAIL: http://slexy.org/raw/s2176U7Dph
 3: am3517-evm:  Boot FAIL: http://slexy.org/raw/s216noNiRN
 4:  am37x-evm:  Boot FAIL: http://slexy.org/raw/s21iF5KAJz
 5: am43xx-epos:  Boot FAIL: http://slexy.org/raw/s2lTTWBTzz
 6: BeagleBoard-XM:  Boot FAIL: http://slexy.org/raw/s20rHgs9kq
 7: BeagleBone-Black:  Boot FAIL: http://slexy.org/raw/s2yp7IWdE1
 8:      crane: No Image built - Missing platform support?:
 9:       dra7:  Boot FAIL: http://slexy.org/raw/s2GgOR9BzT
10:        ldp:  Boot FAIL: http://slexy.org/raw/s2u2OKWLpI
11: PandaBoard-ES:  Boot FAIL: http://slexy.org/raw/s2t3PluNV5
12:    sdp2430:  Boot FAIL: http://slexy.org/raw/s2biJ1CVJf
13:    sdp3430:  Boot FAIL: http://slexy.org/raw/s2K3G0fji6
14:    sdp4430:  Boot FAIL: http://slexy.org/raw/s2162mQFOS
15: OMAP5432uEVM:  Boot FAIL: http://slexy.org/raw/s2WbE4HU6Q
TOTAL = 15 boards, Booted Boards = 0, No Boot boards = 15


-- 
Regards,
Nishanth Menon

^ permalink raw reply

* [PATCH RFC 04/10] base: power: Add generic OF-based power domain look-up
From: Tomasz Figa @ 2014-01-20 17:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140116163409.GD25540@e102568-lin.cambridge.arm.com>

Hi Lorenzo,

On 16.01.2014 17:34, Lorenzo Pieralisi wrote:
> Hi Tomasz,
>
> thank you for posting this series. I would like to use the DT bindings
> for power domains in the bindings for C-states on ARM:
>
> http://comments.gmane.org/gmane.linux.power-management.general/41012
>
> and in particular link a given C-state to a given power domain so that the
> kernel will have a way to actually check what devices are lost upon C-state
> entry (and for devices I also mean CPU peripheral like PMUs, GIC CPU IF,
> caches and possibly cpus, all of them already represented with DT nodes).
>
> I have a remark:
>
> -  Can we group device nodes under a single power-domain-parent so that
>     all devices defined under that parent won't have to re-define a
>     power-domain property (a property like interrupt-parent, so to speak)
>
> What do you think ?

Hmm, I can see potential benefits of such construct on platforms with 
clear hierarchy of devices, but to make sure I'm getting it correctly, 
is the following what you have in mind?

soc-domain-x at 12340000 {
	compatible = "...";
	reg = <...>;
	power-domain-parent = <&power_domains DOMAIN_X>;

	device at 1000 {
		compatible = "...";
		// inherits power-domain = <&power_domains DOMAIN_X>
	};

	device at 2000 {
		compatible = "...";
		// inherits power-domain = <&power_domains DOMAIN_X>
	};
};

Best regards,
Tomasz

^ permalink raw reply

* New randconfig build failure: rx51 asoc / gpiolib
From: Mark Brown @ 2014-01-20 17:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140117131257.GB15937@n2100.arm.linux.org.uk>

On Fri, Jan 17, 2014 at 01:12:58PM +0000, Russell King - ARM Linux wrote:
> Last night's omap randconfig found this.  This has only appeared in the
> builds in the last few days, so it's a new regression for the changes
> queued up for merge window:

Really?  The relevant change is quite old...  it is possible some other
thing removed a select though so gpiolib can now be unset.

> which is caused by "struct snd_soc_jack_gpio" not being defined.  For
> some reason, this structure is defined in sound/soc.h, but is
> conditionalised upon CONFIG_GPIOLIB.

> This means either the dependencies on SND_OMAP_SOC_RX51 are incorrect
> (they don't include a dependency on GPIOLIB) or ASoC is wrong to make
> the definitions conditional upon GPIOLIB.

I'd add the dependency here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140120/e6087ac6/attachment.sig>

^ permalink raw reply

* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Russell King - ARM Linux @ 2014-01-20 17:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOMZO5AfSe_c7gfee0BcZso8ZYg=PaTDwfsXwzpEcM1554VQ6Q@mail.gmail.com>

On Mon, Jan 20, 2014 at 03:03:50PM -0200, Fabio Estevam wrote:
> On Mon, Jan 20, 2014 at 2:48 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> 
> > So far so good.  Now, what about this external oscillator which has its
> > own separate power control.  My immediate thought is that this can be
> > specified via card_ext_clock - I would simply need to declare a fixed-rate
> > clock with either a regulator (power switch) controlled via a gpio (which
> > would probably be closer to the hardware) or a gpio as an enable... ah,
> > that requires me to write a common clock driver for that bit since this
> > is currently not modelled by CCF...
> 
> Isn't this covered by the gpios property of fixed-clock?
> 
> We do the following to enable the 26MHz codec clock in
> imx51-babbage.dts via GPIO4_26:
> 
>         clk_26M: codec_clock {
>             compatible = "fixed-clock";
>             reg=<0>;
>             #clock-cells = <0>;
>             clock-frequency = <26000000>;
>             gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
>         };

Not as far as I can see.  fixed-clock appears to have two properies:

	clock-frequency
	clock-output-names

and nothing else.  See of_fixed_clk_setup in drivers/clk/clk-fixed-rate.c.
You'll also find that the documentation in this file says this about it:

 * DOC: basic fixed-rate clock that cannot gate
 *
 * Traits of this clock:
 * prepare - clk_(un)prepare only ensures parents are prepared
 * enable - clk_enable only ensures parents are enabled
 * rate - rate is always a fixed value.  No clk_set_rate support
 * parent - fixed parent.  No clk_set_parent support

So, I think the bit which you quote from imx51-babbage.dts is wishful
thinking on the part of the author of the DT file, rather than actually
being implemented in any way by the kernel DT support.

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH] ARM64: perf: support dwarf unwinding in compat mode
From: Jean Pihet @ 2014-01-20 17:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140117100723.GB16003@mudshark.cambridge.arm.com>

Hi Will,

Here is an updated version of the change, which uses compat_sp at only
one place.
The drawback is that compat_user_mode is checked when calling
compat_user_stack_pointer, which seems unnecessary. Unfortunately the
check is not optimized out by the complier as I could check with
objdump -S.

What do you think?

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index fda2704..e71f81f 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -228,7 +228,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }

-#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
+#define compat_user_stack_pointer() (user_stack_pointer(current_pt_regs()))

 static inline void __user *arch_compat_alloc_user_space(long len)
 {
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index fbb0020..86d5b54 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -133,7 +133,7 @@ struct pt_regs {
        (!((regs)->pstate & PSR_F_BIT))

 #define user_stack_pointer(regs) \
-       ((regs)->sp)
+       (!compat_user_mode(regs)) ? ((regs)->sp) : ((regs)->compat_sp)

 /*
  * Are the current registers suitable for user mode? (used to maintain



Regards,
Jean

On 17 January 2014 11:07, Will Deacon <will.deacon@arm.com> wrote:
> On Fri, Jan 17, 2014 at 09:00:09AM +0000, Jean Pihet wrote:
>> On 16 January 2014 14:47, Jean Pihet <jean.pihet@linaro.org> wrote:
>> >> So the simplest thing would be to make compat_user_stack_pointer expand to
>> >> user_stack_pointer(current_pt_regs()) on arm64 and merge that in with your
>> >> original patch fixing user_stack_pointer.
>>
>> I see 2 issues in your proposal:
>>
>> 1) user_stack_pointer(regs) calls compat_user_stack_pointer if
>> compat_user_mode(regs)) and compat_user_stack_pointer expands to
>> user_stack_pointer. I see a circular dependency in the macros.
>
> Not today it doesn't, so you just need to avoid writing the circular
> dependency and instead make user_stack_pointer access (regs)->compat_sp
> instead.
>
>> 2) current_pt_regs() returns the current task regs although perf
>> passes a regs struct that had been recorded previously.
>
> Yes, but compat_user_stack_pointer doesn't take a regs paramater anyway, so
> there's no change in behaviour here.
>
> Will

^ permalink raw reply related

* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Fabio Estevam @ 2014-01-20 17:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140120164859.GF15937@n2100.arm.linux.org.uk>

On Mon, Jan 20, 2014 at 2:48 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:

> So far so good.  Now, what about this external oscillator which has its
> own separate power control.  My immediate thought is that this can be
> specified via card_ext_clock - I would simply need to declare a fixed-rate
> clock with either a regulator (power switch) controlled via a gpio (which
> would probably be closer to the hardware) or a gpio as an enable... ah,
> that requires me to write a common clock driver for that bit since this
> is currently not modelled by CCF...

Isn't this covered by the gpios property of fixed-clock?

We do the following to enable the 26MHz codec clock in
imx51-babbage.dts via GPIO4_26:

        clk_26M: codec_clock {
            compatible = "fixed-clock";
            reg=<0>;
            #clock-cells = <0>;
            clock-frequency = <26000000>;
            gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
        };

Regards,

Fabio Estevam

^ permalink raw reply

* [PATCH v2 00/16] ARM: support for ICP DAS LP-8x4x (with dts)
From: Daniel Mack @ 2014-01-20 16:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236763.25903.12.camel@host5.omatika.ru>

On 01/20/2014 05:52 PM, Sergei Ianovich wrote:
> On Mon, 2014-01-20 at 17:20 +0100, Daniel Mack wrote:
>> On 01/20/2014 05:08 PM, Sergei Ianovich wrote:
>>> It's over a month now. Is anything wrong?
>> No, I'm busy, that's all.
> 
> Thanks for reply.
> 
>> That said, the current situation is
>>
>> a) we need someone to have a look at the performance regression of the
>> MMC file system layer that you reported. I couldn't find a PXA-based
>> board yet with a MMC slot soldered on it. But as you apparently have
>> such hardware, I'd really appreciate your help here. Could you do some
>> measurements and see whether you see major differences in packet size or
>> timings?
> 
> I have the hardware with MMC, but none of the other devices. Could you
> give some pointer where to start? How would you do measurements?

Please check whether the DMA engine transfers data in chunks of
comparable size in both cases. Also, take time stamps when the packet is
submitted, and calculate the delta when the transfer returns. See if any
significant time gap contributes to the regression you see.

After all, it's still quite possible that the DMA driver has performance
bottlenecks. We need to find the code where so much more time is spent
with the new implementation.

> It would be nice to have updated patches. Most interesting is whether
> the new DMA still works as expected for other devices.

I'll allocate a time slot for that :)

> Apart from that, would mind if my series is landed with a workaround
> (Patch v3 7/21). I hope you understand it doesn't feel good to depend on
> something with no development activity.

I understand, but that shouldn't keep you you from maintaining a patch
stack out-of-tree until things are in shape enough to go mainline.


Thanks for you help,
Daniel

^ permalink raw reply

* [PATCH v2 00/16] ARM: support for ICP DAS LP-8x4x (with dts)
From: Sergei Ianovich @ 2014-01-20 16:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52DD4CDE.7020705@gmail.com>

On Mon, 2014-01-20 at 17:20 +0100, Daniel Mack wrote:
> On 01/20/2014 05:08 PM, Sergei Ianovich wrote:
> > It's over a month now. Is anything wrong?
> No, I'm busy, that's all.

Thanks for reply.

> That said, the current situation is
> 
> a) we need someone to have a look at the performance regression of the
> MMC file system layer that you reported. I couldn't find a PXA-based
> board yet with a MMC slot soldered on it. But as you apparently have
> such hardware, I'd really appreciate your help here. Could you do some
> measurements and see whether you see major differences in packet size or
> timings?

I have the hardware with MMC, but none of the other devices. Could you
give some pointer where to start? How would you do measurements?

(...)

> So please, if you have any spare time, have a look at the MMC
> regressions and see if you can contribute anything. I'll hope to find
> some time to rebase my patches on top of 3.13 very soon, so we have a
> new base to work on.

It would be nice to have updated patches. Most interesting is whether
the new DMA still works as expected for other devices.

Apart from that, would mind if my series is landed with a workaround
(Patch v3 7/21). I hope you understand it doesn't feel good to depend on
something with no development activity.

^ permalink raw reply

* [PATCH 1/3] mmc: add support for power-on sequencing through DT
From: Russell King - ARM Linux @ 2014-01-20 16:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390190215-22700-2-git-send-email-olof@lixom.net>

On Sun, Jan 19, 2014 at 07:56:53PM -0800, Olof Johansson wrote:
> diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
> index 458b57f..962e0ee 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc.txt
> @@ -5,6 +5,8 @@ these definitions.
>  Interpreted by the OF core:
>  - reg: Registers location and length.
>  - interrupts: Interrupts used by the MMC controller.
> +- clocks: Clocks needed for the host controller, if any.
> +- clock-names: Goes with clocks above.
>  
>  Card detection:
>  If no property below is supplied, host native card detect is used.
> @@ -30,6 +32,15 @@ Optional properties:
>  - cap-sdio-irq: enable SDIO IRQ signalling on this interface
>  - full-pwr-cycle: full power cycle of the card is supported
>  
> +Card power and reset control:
> +The following properties can be specified for cases where the MMC
> +peripheral needs additional reset, regulator and clock lines. It is for
> +example common for WiFi/BT adapters to have these separate from the main
> +MMC bus:
> +  - card-reset-gpios: Specify GPIOs for card reset (reset active low)
> +  - card-external-vcc-supply: Regulator to drive (independent) card VCC
> +  - clock with name "card_ext_clock": External clock provided to the card
> +

This looks good.  I can connect the wifi/bt power control to a regulator,
and give that as the card-external-vcc-supply property.  I can specify
the WIFI/BT resets for card-reset-gpios.

So far so good.  Now, what about this external oscillator which has its
own separate power control.  My immediate thought is that this can be
specified via card_ext_clock - I would simply need to declare a fixed-rate
clock with either a regulator (power switch) controlled via a gpio (which
would probably be closer to the hardware) or a gpio as an enable... ah,
that requires me to write a common clock driver for that bit since this
is currently not modelled by CCF...

-- 
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up.  Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".

^ permalink raw reply

* [PATCH RFC v4 10/10] ahci_imx: Port to library-ised ahci_platform
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236303-22538-1-git-send-email-hdegoede@redhat.com>

This avoids the ugliness of creating a nested platform device from probe.

Note untested, I've ordered a wandboard to be able to test these changes.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../devicetree/bindings/ata/ahci-platform.txt      |   8 +-
 drivers/ata/ahci_imx.c                             | 199 ++++++++-------------
 2 files changed, 80 insertions(+), 127 deletions(-)

diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index f036e786..ee3a127 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -5,8 +5,8 @@ Each SATA controller should have its own node.
 
 Required properties:
 - compatible        : compatible list, one of "snps,spear-ahci",
-                      "snps,exynos5440-ahci", "ibm,476gtr-ahci", or
-                      "allwinner,sun4i-a10-ahci"
+                      "snps,exynos5440-ahci", "ibm,476gtr-ahci",
+                      "allwinner,sun4i-a10-ahci" or "fsl,imx6q-ahci"
 - interrupts        : <interrupt mapping for SATA IRQ>
 - reg               : <registers mapping>
 
@@ -18,6 +18,10 @@ Optional properties:
 allwinner,sun4i-a10-ahci required properties:
 - clocks            : index 0 must point to the sata_ref clk, 1 to the ahb clk
 
+fsl,imx6q-ahci required properties:
+- clocks            : index 0 must point to the sataf clk, 1 to the sata_ref
+		      clk and 2 to the ahb clk
+
 Examples:
         sata at ffe08000 {
 		compatible = "snps,spear-ahci";
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
index 49fa0ca..3454b18 100644
--- a/drivers/ata/ahci_imx.c
+++ b/drivers/ata/ahci_imx.c
@@ -34,10 +34,14 @@ enum {
 	HOST_TIMER1MS = 0xe0,			/* Timer 1-ms */
 };
 
+enum {
+	CLK_SATA,
+	CLK_SATA_REF,
+	CLK_AHB
+};
+
 struct imx_ahci_priv {
 	struct platform_device *ahci_pdev;
-	struct clk *sata_ref_clk;
-	struct clk *ahb_clk;
 	struct regmap *gpr;
 	bool no_device;
 	bool first_time;
@@ -47,6 +51,8 @@ static int ahci_imx_hotplug;
 module_param_named(hotplug, ahci_imx_hotplug, int, 0644);
 MODULE_PARM_DESC(hotplug, "AHCI IMX hot-plug support (0=Don't support, 1=support)");
 
+static void ahci_imx_host_stop(struct ata_host *host);
+
 static void ahci_imx_error_handler(struct ata_port *ap)
 {
 	u32 reg_val;
@@ -54,7 +60,7 @@ static void ahci_imx_error_handler(struct ata_port *ap)
 	struct ata_host *host = dev_get_drvdata(ap->dev);
 	struct ahci_host_priv *hpriv = host->private_data;
 	void __iomem *mmio = hpriv->mmio;
-	struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent);
+	struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 
 	ahci_error_handler(ap);
 
@@ -75,12 +81,13 @@ static void ahci_imx_error_handler(struct ata_port *ap)
 	regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
 			IMX6Q_GPR13_SATA_MPLL_CLK_EN,
 			!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
-	clk_disable_unprepare(imxpriv->sata_ref_clk);
+	ahci_platform_disable_clks(hpriv);
 	imxpriv->no_device = true;
 }
 
 static struct ata_port_operations ahci_imx_ops = {
-	.inherits	= &ahci_platform_ops,
+	.inherits	= &ahci_ops,
+	.host_stop	= ahci_imx_host_stop,
 	.error_handler	= ahci_imx_error_handler,
 };
 
@@ -91,23 +98,38 @@ static const struct ata_port_info ahci_imx_port_info = {
 	.port_ops	= &ahci_imx_ops,
 };
 
-static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv)
+static int imx_ahci_probe(struct platform_device *pdev)
 {
-	int ret = 0;
+	struct device *dev = &pdev->dev;
+	struct ahci_host_priv *hpriv;
+	struct imx_ahci_priv *imxpriv;
 	unsigned int reg_val;
-	struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent);
+	int rc;
+
+	imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
+	if (!imxpriv)
+		return -ENOMEM;
+
+	hpriv = ahci_platform_get_resources(pdev);
+	if (IS_ERR(hpriv))
+		return PTR_ERR(hpriv);
+	if (!hpriv->clks[CLK_AHB]) {
+		dev_err(dev, "no ahb clk, need sata, sata_ref and ahb clks\n");
+		rc = -ENOENT;
+		goto put_resources;
+	}
+	hpriv->plat_data = imxpriv;
+
+	rc = ahci_platform_enable_resources(hpriv);
+	if (rc)
+		goto put_resources;
 
 	imxpriv->gpr =
 		syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
 	if (IS_ERR(imxpriv->gpr)) {
 		dev_err(dev, "failed to find fsl,imx6q-iomux-gpr regmap\n");
-		return PTR_ERR(imxpriv->gpr);
-	}
-
-	ret = clk_prepare_enable(imxpriv->sata_ref_clk);
-	if (ret < 0) {
-		dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret);
-		return ret;
+		rc = PTR_ERR(imxpriv->gpr);
+		goto disable_resources;
 	}
 
 	/*
@@ -156,24 +178,45 @@ static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv)
 		writel(reg_val, hpriv->mmio + HOST_PORTS_IMPL);
 	}
 
-	reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000;
+	reg_val = clk_get_rate(hpriv->clks[CLK_AHB]) / 1000;
 	writel(reg_val, hpriv->mmio + HOST_TIMER1MS);
 
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0);
+	if (rc)
+		goto disable_resources;
+
 	return 0;
+
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
+put_resources:
+	ahci_platform_put_resources(hpriv);
+	return rc;
 }
 
-static void imx6q_sata_exit(struct device *dev)
+static void ahci_imx_host_stop(struct ata_host *host)
 {
-	struct imx_ahci_priv *imxpriv =  dev_get_drvdata(dev->parent);
+	struct ahci_host_priv *hpriv = host->private_data;
+	struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 
-	regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN,
+	if (!imxpriv->no_device) {
+		regmap_update_bits(imxpriv->gpr, 0x34,
+			IMX6Q_GPR13_SATA_MPLL_CLK_EN,
 			!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
-	clk_disable_unprepare(imxpriv->sata_ref_clk);
+		ahci_platform_disable_clks(hpriv);
+	}
 }
 
 static int imx_ahci_suspend(struct device *dev)
 {
-	struct imx_ahci_priv *imxpriv =  dev_get_drvdata(dev->parent);
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	struct imx_ahci_priv *imxpriv = hpriv->plat_data;
+	int rc;
+
+	rc = ahci_platform_suspend_host(dev);
+	if (rc)
+		return rc;
 
 	/*
 	 * If no_device is set, The CLKs had been gated off in the
@@ -183,7 +226,7 @@ static int imx_ahci_suspend(struct device *dev)
 		regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13,
 				IMX6Q_GPR13_SATA_MPLL_CLK_EN,
 				!IMX6Q_GPR13_SATA_MPLL_CLK_EN);
-		clk_disable_unprepare(imxpriv->sata_ref_clk);
+		ahci_platform_disable_clks(hpriv);
 	}
 
 	return 0;
@@ -191,11 +234,13 @@ static int imx_ahci_suspend(struct device *dev)
 
 static int imx_ahci_resume(struct device *dev)
 {
-	struct imx_ahci_priv *imxpriv =  dev_get_drvdata(dev->parent);
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	struct imx_ahci_priv *imxpriv = hpriv->plat_data;
 	int ret;
 
 	if (!imxpriv->no_device) {
-		ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+		ret = ahci_platform_enable_clks(hpriv);
 		if (ret < 0) {
 			dev_err(dev, "pre-enable sata_ref clock err:%d\n", ret);
 			return ret;
@@ -207,123 +252,27 @@ static int imx_ahci_resume(struct device *dev)
 		usleep_range(1000, 2000);
 	}
 
-	return 0;
+	return ahci_platform_resume_host(dev);
 }
 
-static struct ahci_platform_data imx6q_sata_pdata = {
-	.init = imx6q_sata_init,
-	.exit = imx6q_sata_exit,
-	.ata_port_info = &ahci_imx_port_info,
-	.suspend = imx_ahci_suspend,
-	.resume = imx_ahci_resume,
-};
+static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume);
 
 static const struct of_device_id imx_ahci_of_match[] = {
-	{ .compatible = "fsl,imx6q-ahci", .data = &imx6q_sata_pdata},
+	{ .compatible = "fsl,imx6q-ahci", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, imx_ahci_of_match);
 
-static int imx_ahci_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct resource *mem, *irq, res[2];
-	const struct of_device_id *of_id;
-	const struct ahci_platform_data *pdata = NULL;
-	struct imx_ahci_priv *imxpriv;
-	struct device *ahci_dev;
-	struct platform_device *ahci_pdev;
-	int ret;
-
-	imxpriv = devm_kzalloc(dev, sizeof(*imxpriv), GFP_KERNEL);
-	if (!imxpriv) {
-		dev_err(dev, "can't alloc ahci_host_priv\n");
-		return -ENOMEM;
-	}
-
-	ahci_pdev = platform_device_alloc("ahci", -1);
-	if (!ahci_pdev)
-		return -ENODEV;
-
-	ahci_dev = &ahci_pdev->dev;
-	ahci_dev->parent = dev;
-
-	imxpriv->no_device = false;
-	imxpriv->first_time = true;
-	imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
-	if (IS_ERR(imxpriv->ahb_clk)) {
-		dev_err(dev, "can't get ahb clock.\n");
-		ret = PTR_ERR(imxpriv->ahb_clk);
-		goto err_out;
-	}
-
-	imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
-	if (IS_ERR(imxpriv->sata_ref_clk)) {
-		dev_err(dev, "can't get sata_ref clock.\n");
-		ret = PTR_ERR(imxpriv->sata_ref_clk);
-		goto err_out;
-	}
-
-	imxpriv->ahci_pdev = ahci_pdev;
-	platform_set_drvdata(pdev, imxpriv);
-
-	of_id = of_match_device(imx_ahci_of_match, dev);
-	if (of_id) {
-		pdata = of_id->data;
-	} else {
-		ret = -EINVAL;
-		goto err_out;
-	}
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!mem || !irq) {
-		dev_err(dev, "no mmio/irq resource\n");
-		ret = -ENOMEM;
-		goto err_out;
-	}
-
-	res[0] = *mem;
-	res[1] = *irq;
-
-	ahci_dev->coherent_dma_mask = DMA_BIT_MASK(32);
-	ahci_dev->dma_mask = &ahci_dev->coherent_dma_mask;
-	ahci_dev->of_node = dev->of_node;
-
-	ret = platform_device_add_resources(ahci_pdev, res, 2);
-	if (ret)
-		goto err_out;
-
-	ret = platform_device_add_data(ahci_pdev, pdata, sizeof(*pdata));
-	if (ret)
-		goto err_out;
-
-	ret = platform_device_add(ahci_pdev);
-	if (ret) {
-err_out:
-		platform_device_put(ahci_pdev);
-		return ret;
-	}
-
-	return 0;
-}
-
-static int imx_ahci_remove(struct platform_device *pdev)
-{
-	struct imx_ahci_priv *imxpriv = platform_get_drvdata(pdev);
-	struct platform_device *ahci_pdev = imxpriv->ahci_pdev;
-
-	platform_device_unregister(ahci_pdev);
-	return 0;
-}
 
 static struct platform_driver imx_ahci_driver = {
 	.probe = imx_ahci_probe,
-	.remove = imx_ahci_remove,
+	.remove = ata_platform_remove_one,
 	.driver = {
 		.name = "ahci-imx",
 		.owner = THIS_MODULE,
 		.of_match_table = imx_ahci_of_match,
+		.pm = &ahci_imx_pm_ops,
 	},
 };
 module_platform_driver(imx_ahci_driver);
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH RFC v4 09/10] ARM: sunxi: Add support for Allwinner SUNXi SoCs sata to ahci_platform
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236303-22538-1-git-send-email-hdegoede@redhat.com>

From: Olliver Schinagl <oliver@schinagl.nl>

This patch adds support for the ahci sata controler found on Allwinner A10
and A20 SoCs to the ahci_platform driver.

Orignally written by Olliver Schinagl using the approach of having a platform
device which probe method creates a new child platform device which gets
driven by ahci_platform.c, as done by ahci_imx.c .

Refactored by Hans de Goede to add most of the non sunxi specific functionality
to ahci_platform.c and use a platform_data pointer from of_device_id for the
sunxi specific bits.

Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../devicetree/bindings/ata/ahci-platform.txt      |  18 +-
 drivers/ata/Kconfig                                |   9 +
 drivers/ata/Makefile                               |   1 +
 drivers/ata/ahci_sunxi.c                           | 242 +++++++++++++++++++++
 4 files changed, 267 insertions(+), 3 deletions(-)
 create mode 100644 drivers/ata/ahci_sunxi.c

diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 1ac807f..f036e786 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -4,7 +4,9 @@ SATA nodes are defined to describe on-chip Serial ATA controllers.
 Each SATA controller should have its own node.
 
 Required properties:
-- compatible        : compatible list, contains "snps,spear-ahci"
+- compatible        : compatible list, one of "snps,spear-ahci",
+                      "snps,exynos5440-ahci", "ibm,476gtr-ahci", or
+                      "allwinner,sun4i-a10-ahci"
 - interrupts        : <interrupt mapping for SATA IRQ>
 - reg               : <registers mapping>
 
@@ -13,10 +15,20 @@ Optional properties:
 - clocks            : a list of phandle + clock specifier pairs
 - target-supply     : regulator for SATA target power
 
-Example:
+allwinner,sun4i-a10-ahci required properties:
+- clocks            : index 0 must point to the sata_ref clk, 1 to the ahb clk
+
+Examples:
         sata at ffe08000 {
 		compatible = "snps,spear-ahci";
 		reg = <0xffe08000 0x1000>;
 		interrupts = <115>;
-
         };
+
+	sata: ahci at 01c18000 {
+		compatible = "allwinner,sun4i-a10-ahci";
+		reg = <0x01c18000 0x1000>;
+		interrupts = <56>;
+		clocks = <&pll6 0>, <&ahb_gates 25>;
+		target-supply = <&reg_ahci_5v>;
+	};
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 4e73772..cc67cc0 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -106,6 +106,15 @@ config AHCI_IMX
 
 	  If unsure, say N.
 
+config AHCI_SUNXI
+	tristate "Allwinner sunxi AHCI SATA support"
+	depends on ARCH_SUNXI && SATA_AHCI_PLATFORM
+	help
+	  This option enables support for the Allwinner sunxi SoC's
+	  onboard AHCI SATA.
+
+	  If unsure, say N.
+
 config SATA_FSL
 	tristate "Freescale 3.0Gbps SATA support"
 	depends on FSL_SOC
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 46518c6..246050b 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SATA_SIL24)	+= sata_sil24.o
 obj-$(CONFIG_SATA_DWC)		+= sata_dwc_460ex.o
 obj-$(CONFIG_SATA_HIGHBANK)	+= sata_highbank.o libahci.o
 obj-$(CONFIG_AHCI_IMX)		+= ahci_imx.o
+obj-$(CONFIG_AHCI_SUNXI)	+= ahci_sunxi.o
 
 # SFF w/ custom DMA
 obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
new file mode 100644
index 0000000..b3f4463
--- /dev/null
+++ b/drivers/ata/ahci_sunxi.c
@@ -0,0 +1,242 @@
+/*
+ * Allwinner sunxi AHCI SATA platform driver
+ * Copyright 2013 Olliver Schinagl <oliver@schinagl.nl>
+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
+ *
+ * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
+ * Based on code from Allwinner Technology Co., Ltd. <www.allwinnertech.com>,
+ * Daniel Wang <danielwang@allwinnertech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#include <linux/ahci_platform.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include "ahci.h"
+
+#define AHCI_BISTAFR 0x00a0
+#define AHCI_BISTCR 0x00a4
+#define AHCI_BISTFCTR 0x00a8
+#define AHCI_BISTSR 0x00ac
+#define AHCI_BISTDECR 0x00b0
+#define AHCI_DIAGNR0 0x00b4
+#define AHCI_DIAGNR1 0x00b8
+#define AHCI_OOBR 0x00bc
+#define AHCI_PHYCS0R 0x00c0
+#define AHCI_PHYCS1R 0x00c4
+#define AHCI_PHYCS2R 0x00c8
+#define AHCI_TIMER1MS 0x00e0
+#define AHCI_GPARAM1R 0x00e8
+#define AHCI_GPARAM2R 0x00ec
+#define AHCI_PPARAMR 0x00f0
+#define AHCI_TESTR 0x00f4
+#define AHCI_VERSIONR 0x00f8
+#define AHCI_IDR 0x00fc
+#define AHCI_RWCR 0x00fc
+#define AHCI_P0DMACR 0x0170
+#define AHCI_P0PHYCR 0x0178
+#define AHCI_P0PHYSR 0x017c
+
+static void sunxi_clrbits(void __iomem *reg, u32 clr_val)
+{
+	u32 reg_val;
+
+	reg_val = readl(reg);
+	reg_val &= ~(clr_val);
+	writel(reg_val, reg);
+}
+
+static void sunxi_setbits(void __iomem *reg, u32 set_val)
+{
+	u32 reg_val;
+
+	reg_val = readl(reg);
+	reg_val |= set_val;
+	writel(reg_val, reg);
+}
+
+static void sunxi_clrsetbits(void __iomem *reg, u32 clr_val, u32 set_val)
+{
+	u32 reg_val;
+
+	reg_val = readl(reg);
+	reg_val &= ~(clr_val);
+	reg_val |= set_val;
+	writel(reg_val, reg);
+}
+
+static u32 sunxi_getbits(void __iomem *reg, u8 mask, u8 shift)
+{
+	return (readl(reg) >> shift) & mask;
+}
+
+static int ahci_sunxi_phy_init(struct device *dev, void __iomem *reg_base)
+{
+	u32 reg_val;
+	int timeout;
+
+	/* This magic is from the original code */
+	writel(0, reg_base + AHCI_RWCR);
+	mdelay(5);
+
+	sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(19));
+	sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+			 (0x7 << 24),
+			 (0x5 << 24) | BIT(23) | BIT(18));
+	sunxi_clrsetbits(reg_base + AHCI_PHYCS1R,
+			 (0x3 << 16) | (0x1f << 8) | (0x3 << 6),
+			 (0x2 << 16) | (0x6 << 8) | (0x2 << 6));
+	sunxi_setbits(reg_base + AHCI_PHYCS1R, BIT(28) | BIT(15));
+	sunxi_clrbits(reg_base + AHCI_PHYCS1R, BIT(19));
+	sunxi_clrsetbits(reg_base + AHCI_PHYCS0R,
+			 (0x7 << 20), (0x3 << 20));
+	sunxi_clrsetbits(reg_base + AHCI_PHYCS2R,
+			 (0x1f << 5), (0x19 << 5));
+	mdelay(5);
+
+	sunxi_setbits(reg_base + AHCI_PHYCS0R, (0x1 << 19));
+
+	timeout = 0x100000;
+	do {
+		reg_val = sunxi_getbits(reg_base + AHCI_PHYCS0R, 0x7, 28);
+	} while (--timeout && (reg_val != 0x2));
+	if (!timeout) {
+		dev_err(dev, "PHY power up failed.\n");
+		return -EIO;
+	}
+
+	sunxi_setbits(reg_base + AHCI_PHYCS2R, (0x1 << 24));
+
+	timeout = 0x100000;
+	do {
+		reg_val = sunxi_getbits(reg_base + AHCI_PHYCS2R, 0x1, 24);
+	} while (--timeout && reg_val);
+	if (!timeout) {
+		dev_err(dev, "PHY calibration failed.\n");
+		return -EIO;
+	}
+	mdelay(15);
+
+	writel(0x7, reg_base + AHCI_RWCR);
+
+	return 0;
+}
+
+static void ahci_sunxi_start_engine(struct ata_port *ap)
+{
+	void __iomem *port_mmio = ahci_port_base(ap);
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+
+	/* Setup DMA before DMA start */
+	sunxi_clrsetbits(hpriv->mmio + AHCI_P0DMACR, 0x0000ff00, 0x00004400);
+
+	/* Start DMA */
+	sunxi_setbits(port_mmio + PORT_CMD, PORT_CMD_START);
+}
+
+static const struct ata_port_info ahci_sunxi_port_info = {
+	AHCI_HFLAGS(AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
+			  AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ),
+	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NCQ,
+	.pio_mask	= ATA_PIO4,
+	.udma_mask	= ATA_UDMA6,
+	.port_ops	= &ahci_platform_ops,
+};
+
+static int ahci_sunxi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ahci_host_priv *hpriv;
+	int rc;
+
+	hpriv = ahci_platform_get_resources(pdev);
+	if (IS_ERR(hpriv))
+		return PTR_ERR(hpriv);
+
+	hpriv->start_engine = ahci_sunxi_start_engine;
+
+	rc = ahci_platform_enable_resources(hpriv);
+	if (rc)
+		goto put_resources;
+
+	rc = ahci_sunxi_phy_init(dev, hpriv->mmio);
+	if (rc)
+		goto disable_resources;
+
+	rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info, 0, 0);
+	if (rc)
+		goto disable_resources;
+
+	return 0;
+
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
+put_resources:
+	ahci_platform_put_resources(hpriv);
+	return rc;
+}
+
+#ifdef CONFIG_PM_SLEEP
+int ahci_sunxi_resume(struct device *dev)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	int rc;
+
+	rc = ahci_platform_enable_resources(hpriv);
+	if (rc)
+		return rc;
+
+	rc = ahci_sunxi_phy_init(dev, hpriv->mmio);
+	if (rc)
+		goto disable_resources;
+
+	rc = ahci_platform_resume_host(dev);
+	if (rc)
+		goto disable_resources;
+
+	return 0;
+
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
+	return rc;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend,
+			 ahci_sunxi_resume);
+
+static const struct of_device_id ahci_sunxi_of_match[] = {
+	{ .compatible = "allwinner,sun4i-a10-ahci", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match);
+
+static struct platform_driver ahci_sunxi_driver = {
+	.probe = ahci_sunxi_probe,
+	.remove = ata_platform_remove_one,
+	.driver = {
+		.name = "ahci-sunxi",
+		.owner = THIS_MODULE,
+		.of_match_table = ahci_sunxi_of_match,
+		.pm = &ahci_sunxi_pm_ops,
+	},
+};
+module_platform_driver(ahci_sunxi_driver);
+
+MODULE_DESCRIPTION("Allwinner sunxi AHCI SATA driver");
+MODULE_AUTHOR("Olliver Schinagl <oliver@schinagl.nl>");
+MODULE_LICENSE("GPL");
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH RFC v4 08/10] ahci-platform: "Library-ise" suspend / resume functionality
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236303-22538-1-git-send-email-hdegoede@redhat.com>

Split suspend / resume code into host suspend / resume functionality and
resource enable / disabling phases, and export the new suspend_ / resume_host
functions.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/ata/ahci_platform.c   | 55 +++++++++++++++++++++++++++++++------------
 include/linux/ahci_platform.h |  7 ++++++
 2 files changed, 47 insertions(+), 15 deletions(-)

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index b260ebe..ba93930 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -353,14 +353,12 @@ static void ahci_host_stop(struct ata_host *host)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int ahci_suspend(struct device *dev)
+int ahci_platform_suspend_host(struct device *dev)
 {
-	struct ahci_platform_data *pdata = dev_get_platdata(dev);
 	struct ata_host *host = dev_get_drvdata(dev);
 	struct ahci_host_priv *hpriv = host->private_data;
 	void __iomem *mmio = hpriv->mmio;
 	u32 ctl;
-	int rc;
 
 	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
 		dev_err(dev, "firmware update required for suspend/resume\n");
@@ -377,7 +375,37 @@ static int ahci_suspend(struct device *dev)
 	writel(ctl, mmio + HOST_CTL);
 	readl(mmio + HOST_CTL); /* flush */
 
-	rc = ata_host_suspend(host, PMSG_SUSPEND);
+	return ata_host_suspend(host, PMSG_SUSPEND);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_suspend_host);
+
+int ahci_platform_resume_host(struct device *dev)
+{
+	struct ata_host *host = dev_get_drvdata(dev);
+	int rc;
+
+	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
+		rc = ahci_reset_controller(host);
+		if (rc)
+			return rc;
+
+		ahci_init_controller(host);
+	}
+
+	ata_host_resume(host);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_resume_host);
+
+int ahci_platform_suspend(struct device *dev)
+{
+	struct ahci_platform_data *pdata = dev_get_platdata(dev);
+	struct ata_host *host = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	int rc;
+
+	rc = ahci_platform_suspend_host(dev);
 	if (rc)
 		return rc;
 
@@ -388,8 +416,9 @@ static int ahci_suspend(struct device *dev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(ahci_platform_suspend);
 
-static int ahci_resume(struct device *dev)
+int ahci_platform_resume(struct device *dev)
 {
 	struct ahci_platform_data *pdata = dev_get_platdata(dev);
 	struct ata_host *host = dev_get_drvdata(dev);
@@ -406,15 +435,9 @@ static int ahci_resume(struct device *dev)
 			goto disable_resources;
 	}
 
-	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
-		rc = ahci_reset_controller(host);
-		if (rc)
-			goto disable_resources;
-
-		ahci_init_controller(host);
-	}
-
-	ata_host_resume(host);
+	rc = ahci_platform_resume_host(dev);
+	if (rc)
+		goto disable_resources;
 
 	return 0;
 
@@ -423,9 +446,11 @@ disable_resources:
 
 	return rc;
 }
+EXPORT_SYMBOL_GPL(ahci_platform_resume);
 #endif
 
-static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_suspend, ahci_resume);
+static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
+			 ahci_platform_resume);
 
 static const struct of_device_id ahci_of_match[] = {
 	{ .compatible = "snps,spear-ahci", },
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 1dc7602..b484ac0 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -50,4 +50,11 @@ int ahci_platform_init_host(struct platform_device *pdev,
 			    unsigned int force_port_map,
 			    unsigned int mask_port_map);
 
+#ifdef CONFIG_PM_SLEEP
+int ahci_platform_suspend_host(struct device *dev);
+int ahci_platform_resume_host(struct device *dev);
+int ahci_platform_suspend(struct device *dev);
+int ahci_platform_resume(struct device *dev);
+#endif
+
 #endif /* _AHCI_PLATFORM_H */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH RFC v4 07/10] ahci-platform: "Library-ise" ahci_probe functionality
From: Hans de Goede @ 2014-01-20 16:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236303-22538-1-git-send-email-hdegoede@redhat.com>

ahci_probe consists of 3 steps:
1) Get resources (get mmio, clks, regulator)
2) Enable resources, handled by ahci_platform_enable_resouces
3) The more or less standard ahci-host controller init sequence

This commit refactors step 1 and 3 into separate functions, so the platform
drivers for AHCI implementations which need a specific order in step 2,
and / or need to do some custom register poking at some time, can re-use
ahci-platform.c code without needing to copy and paste it.

Note that ahci_platform_init_host's prototype takes the 3 non function
members of ahci_platform_data as arguments, the idea is that drivers using
the new exported utility functions will not use ahci_platform_data at all,
and hopefully in the future ahci_platform_data can go away entirely.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/ata/ahci_platform.c   | 158 ++++++++++++++++++++++++------------------
 include/linux/ahci_platform.h |  14 ++++
 2 files changed, 106 insertions(+), 66 deletions(-)

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 1cce7a2..b260ebe 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -150,60 +150,31 @@ void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
 EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
 
 
-static void ahci_put_clks(struct ahci_host_priv *hpriv)
-{
-	int c;
-
-	for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
-		clk_put(hpriv->clks[c]);
-}
-
-static int ahci_probe(struct platform_device *pdev)
+struct ahci_host_priv *ahci_platform_get_resources(
+	struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct ahci_platform_data *pdata = dev_get_platdata(dev);
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	struct ata_port_info pi = ahci_port_info[id ? id->driver_data : 0];
-	const struct ata_port_info *ppi[] = { &pi, NULL };
 	struct ahci_host_priv *hpriv;
-	struct ata_host *host;
-	struct resource *mem;
 	struct clk *clk;
-	int i, irq, max_clk, n_ports, rc;
-
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(dev, "no mmio space\n");
-		return -EINVAL;
-	}
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0) {
-		dev_err(dev, "no irq\n");
-		return -EINVAL;
-	}
-
-	if (pdata && pdata->ata_port_info)
-		pi = *pdata->ata_port_info;
+	int i, max_clk, rc;
 
 	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
 	if (!hpriv) {
 		dev_err(dev, "can't alloc ahci_host_priv\n");
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 	}
 
-	hpriv->flags |= (unsigned long)pi.private_data;
-
-	hpriv->mmio = devm_ioremap(dev, mem->start, resource_size(mem));
+	hpriv->mmio = devm_ioremap_resource(dev,
+			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
 	if (!hpriv->mmio) {
-		dev_err(dev, "can't map %pR\n", mem);
-		return -ENOMEM;
+		dev_err(dev, "no mmio space\n");
+		return ERR_PTR(-EINVAL);
 	}
 
 	hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
 	if (IS_ERR(hpriv->target_pwr)) {
 		if (PTR_ERR(hpriv->target_pwr) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
+			return ERR_PTR(-EPROBE_DEFER);
 		hpriv->target_pwr = NULL;
 	}
 
@@ -223,27 +194,48 @@ static int ahci_probe(struct platform_device *pdev)
 		hpriv->clks[i] = clk;
 	}
 
-	rc = ahci_platform_enable_resources(hpriv);
-	if (rc)
-		goto free_clk;
+	return hpriv;
 
-	/*
-	 * Some platforms might need to prepare for mmio region access,
-	 * which could be done in the following init call. So, the mmio
-	 * region shouldn't be accessed before init (if provided) has
-	 * returned successfully.
-	 */
-	if (pdata && pdata->init) {
-		rc = pdata->init(dev, hpriv);
-		if (rc)
-			goto disable_resources;
-	}
+free_clk:
+	while (--i >= 0)
+		clk_put(hpriv->clks[i]);
+	return ERR_PTR(rc);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_get_resources);
+
+void ahci_platform_put_resources(struct ahci_host_priv *hpriv)
+{
+	int c;
+
+	for (c = 0; c < AHCI_MAX_CLKS && hpriv->clks[c]; c++)
+		clk_put(hpriv->clks[c]);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_put_resources);
+
+
+int ahci_platform_init_host(struct platform_device *pdev,
+			    struct ahci_host_priv *hpriv,
+			    const struct ata_port_info *pi_template,
+			    unsigned int force_port_map,
+			    unsigned int mask_port_map)
+{
+	struct device *dev = &pdev->dev;
+	struct ata_port_info pi = *pi_template;
+	const struct ata_port_info *ppi[] = { &pi, NULL };
+	struct ata_host *host;
+	int i, irq, n_ports, rc;
 
-	ahci_save_initial_config(dev, hpriv,
-		pdata ? pdata->force_port_map : 0,
-		pdata ? pdata->mask_port_map  : 0);
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0) {
+		dev_err(dev, "no irq\n");
+		return -EINVAL;
+	}
 
 	/* prepare host */
+	hpriv->flags |= (unsigned long)pi.private_data;
+
+	ahci_save_initial_config(dev, hpriv, force_port_map, mask_port_map);
+
 	if (hpriv->cap & HOST_CAP_NCQ)
 		pi.flags |= ATA_FLAG_NCQ;
 
@@ -260,10 +252,8 @@ static int ahci_probe(struct platform_device *pdev)
 	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
 
 	host = ata_host_alloc_pinfo(dev, ppi, n_ports);
-	if (!host) {
-		rc = -ENOMEM;
-		goto pdata_exit;
-	}
+	if (!host)
+		return -ENOMEM;
 
 	host->private_data = hpriv;
 
@@ -278,7 +268,8 @@ static int ahci_probe(struct platform_device *pdev)
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
 
-		ata_port_desc(ap, "mmio %pR", mem);
+		ata_port_desc(ap, "mmio %pR",
+			      platform_get_resource(pdev, IORESOURCE_MEM, 0));
 		ata_port_desc(ap, "port 0x%x", 0x100 + ap->port_no * 0x80);
 
 		/* set enclosure management message type */
@@ -292,13 +283,48 @@ static int ahci_probe(struct platform_device *pdev)
 
 	rc = ahci_reset_controller(host);
 	if (rc)
-		goto pdata_exit;
+		return rc;
 
 	ahci_init_controller(host);
 	ahci_print_info(host, "platform");
 
-	rc = ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
-			       &ahci_platform_sht);
+	return ata_host_activate(host, irq, ahci_interrupt, IRQF_SHARED,
+				 &ahci_platform_sht);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_init_host);
+
+static int ahci_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ahci_platform_data *pdata = dev_get_platdata(dev);
+	const struct platform_device_id *id = platform_get_device_id(pdev);
+	struct ahci_host_priv *hpriv;
+	int rc;
+
+	hpriv = ahci_platform_get_resources(pdev);
+	if (IS_ERR(hpriv))
+		return PTR_ERR(hpriv);
+
+	rc = ahci_platform_enable_resources(hpriv);
+	if (rc)
+		goto put_resources;
+
+	/*
+	 * Some platforms might need to prepare for mmio region access,
+	 * which could be done in the following init call. So, the mmio
+	 * region shouldn't be accessed before init (if provided) has
+	 * returned successfully.
+	 */
+	if (pdata && pdata->init) {
+		rc = pdata->init(dev, hpriv);
+		if (rc)
+			goto disable_resources;
+	}
+
+	rc = ahci_platform_init_host(pdev, hpriv,
+				     &ahci_port_info[id ? id->driver_data : 0],
+				     pdata ? pdata->force_port_map : 0,
+				     pdata ? pdata->mask_port_map  : 0);
 	if (rc)
 		goto pdata_exit;
 
@@ -308,8 +334,8 @@ pdata_exit:
 		pdata->exit(dev);
 disable_resources:
 	ahci_platform_disable_resources(hpriv);
-free_clk:
-	ahci_put_clks(hpriv);
+put_resources:
+	ahci_platform_put_resources(hpriv);
 	return rc;
 }
 
@@ -323,7 +349,7 @@ static void ahci_host_stop(struct ata_host *host)
 		pdata->exit(dev);
 
 	ahci_platform_disable_resources(hpriv);
-	ahci_put_clks(hpriv);
+	ahci_platform_put_resources(hpriv);
 }
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 5e5f85e..1dc7602 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -20,7 +20,13 @@
 struct device;
 struct ata_port_info;
 struct ahci_host_priv;
+struct platform_device;
 
+/*
+ * Note ahci_platform_data is deprecated. New drivers which need to override
+ * any of these, should instead declare there own platform_driver struct, and
+ * use ahci_platform* functions in their own probe, suspend and resume methods.
+ */
 struct ahci_platform_data {
 	int (*init)(struct device *dev, struct ahci_host_priv *hpriv);
 	void (*exit)(struct device *dev);
@@ -35,5 +41,13 @@ int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
 int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
+struct ahci_host_priv *ahci_platform_get_resources(
+	struct platform_device *pdev);
+void ahci_platform_put_resources(struct ahci_host_priv *hpriv);
+int ahci_platform_init_host(struct platform_device *pdev,
+			    struct ahci_host_priv *hpriv,
+			    const struct ata_port_info *pi_template,
+			    unsigned int force_port_map,
+			    unsigned int mask_port_map);
 
 #endif /* _AHCI_PLATFORM_H */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH RFC v4 06/10] ahci-platform: Add enable_ / disable_resources helper functions
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236303-22538-1-git-send-email-hdegoede@redhat.com>

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/ata/ahci_platform.c   | 83 ++++++++++++++++++++++++-------------------
 include/linux/ahci_platform.h |  2 ++
 2 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index 2f319e9..1cce7a2 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -117,6 +117,39 @@ void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
 EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
 
 
+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
+{
+	int rc;
+
+	if (hpriv->target_pwr) {
+		rc = regulator_enable(hpriv->target_pwr);
+		if (rc)
+			return rc;
+	}
+
+	rc = ahci_platform_enable_clks(hpriv);
+	if (rc)
+		goto disable_regulator;
+
+	return 0;
+
+disable_regulator:
+	if (hpriv->target_pwr)
+		regulator_disable(hpriv->target_pwr);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
+
+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
+{
+	ahci_platform_disable_clks(hpriv);
+
+	if (hpriv->target_pwr)
+		regulator_disable(hpriv->target_pwr);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_disable_resources);
+
+
 static void ahci_put_clks(struct ahci_host_priv *hpriv)
 {
 	int c;
@@ -190,15 +223,9 @@ static int ahci_probe(struct platform_device *pdev)
 		hpriv->clks[i] = clk;
 	}
 
-	if (hpriv->target_pwr) {
-		rc = regulator_enable(hpriv->target_pwr);
-		if (rc)
-			goto free_clk;
-	}
-
-	rc = ahci_enable_clks(dev, hpriv);
+	rc = ahci_platform_enable_resources(hpriv);
 	if (rc)
-		goto disable_regulator;
+		goto free_clk;
 
 	/*
 	 * Some platforms might need to prepare for mmio region access,
@@ -209,7 +236,7 @@ static int ahci_probe(struct platform_device *pdev)
 	if (pdata && pdata->init) {
 		rc = pdata->init(dev, hpriv);
 		if (rc)
-			goto disable_unprepare_clk;
+			goto disable_resources;
 	}
 
 	ahci_save_initial_config(dev, hpriv,
@@ -279,11 +306,8 @@ static int ahci_probe(struct platform_device *pdev)
 pdata_exit:
 	if (pdata && pdata->exit)
 		pdata->exit(dev);
-disable_unprepare_clk:
-	ahci_disable_clks(hpriv);
-disable_regulator:
-	if (hpriv->target_pwr)
-		regulator_disable(hpriv->target_pwr);
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
 free_clk:
 	ahci_put_clks(hpriv);
 	return rc;
@@ -298,11 +322,8 @@ static void ahci_host_stop(struct ata_host *host)
 	if (pdata && pdata->exit)
 		pdata->exit(dev);
 
-	ahci_disable_clks(hpriv);
+	ahci_platform_disable_resources(hpriv);
 	ahci_put_clks(hpriv);
-
-	if (hpriv->target_pwr)
-		regulator_disable(hpriv->target_pwr);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -337,10 +358,7 @@ static int ahci_suspend(struct device *dev)
 	if (pdata && pdata->suspend)
 		return pdata->suspend(dev);
 
-	ahci_disable_clks(hpriv);
-
-	if (hpriv->target_pwr)
-		regulator_disable(hpriv->target_pwr);
+	ahci_platform_disable_resources(hpriv);
 
 	return 0;
 }
@@ -352,26 +370,20 @@ static int ahci_resume(struct device *dev)
 	struct ahci_host_priv *hpriv = host->private_data;
 	int rc;
 
-	if (hpriv->target_pwr) {
-		rc = regulator_enable(hpriv->target_pwr);
-		if (rc)
-			return rc;
-	}
-
-	rc = ahci_enable_clks(dev, hpriv);
+	rc = ahci_platform_enable_resources(hpriv);
 	if (rc)
-		goto disable_regulator;
+		return rc;
 
 	if (pdata && pdata->resume) {
 		rc = pdata->resume(dev);
 		if (rc)
-			goto disable_unprepare_clk;
+			goto disable_resources;
 	}
 
 	if (dev->power.power_state.event == PM_EVENT_SUSPEND) {
 		rc = ahci_reset_controller(host);
 		if (rc)
-			goto disable_unprepare_clk;
+			goto disable_resources;
 
 		ahci_init_controller(host);
 	}
@@ -380,11 +392,8 @@ static int ahci_resume(struct device *dev)
 
 	return 0;
 
-disable_unprepare_clk:
-	ahci_disable_clks(hpriv);
-disable_regulator:
-	if (hpriv->target_pwr)
-		regulator_disable(hpriv->target_pwr);
+disable_resources:
+	ahci_platform_disable_resources(hpriv);
 
 	return rc;
 }
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index 0071d0b..5e5f85e 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -33,5 +33,7 @@ struct ahci_platform_data {
 
 int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
+int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
+void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
 
 #endif /* _AHCI_PLATFORM_H */
-- 
1.8.5.3

^ permalink raw reply related

* [PATCH RFC v4 05/10] ahci-platform: Add support for an optional regulator for sata-target power
From: Hans de Goede @ 2014-01-20 16:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1390236303-22538-1-git-send-email-hdegoede@redhat.com>

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../devicetree/bindings/ata/ahci-platform.txt      |  1 +
 drivers/ata/ahci_platform.c                        | 35 ++++++++++++++++++++--
 include/linux/ahci.h                               |  2 ++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
index 3ced07d..1ac807f 100644
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
@@ -11,6 +11,7 @@ Required properties:
 Optional properties:
 - dma-coherent      : Present if dma operations are coherent
 - clocks            : a list of phandle + clock specifier pairs
+- target-supply     : regulator for SATA target power
 
 Example:
         sata at ffe08000 {
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
index aaa0c08..2f319e9 100644
--- a/drivers/ata/ahci_platform.c
+++ b/drivers/ata/ahci_platform.c
@@ -167,6 +167,13 @@ static int ahci_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	hpriv->target_pwr = devm_regulator_get_optional(dev, "target");
+	if (IS_ERR(hpriv->target_pwr)) {
+		if (PTR_ERR(hpriv->target_pwr) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		hpriv->target_pwr = NULL;
+	}
+
 	max_clk = dev->of_node ? AHCI_MAX_CLKS : 1;
 	for (i = 0; i < max_clk; i++) {
 		if (i == 0)
@@ -183,9 +190,15 @@ static int ahci_probe(struct platform_device *pdev)
 		hpriv->clks[i] = clk;
 	}
 
+	if (hpriv->target_pwr) {
+		rc = regulator_enable(hpriv->target_pwr);
+		if (rc)
+			goto free_clk;
+	}
+
 	rc = ahci_enable_clks(dev, hpriv);
 	if (rc)
-		goto free_clk;
+		goto disable_regulator;
 
 	/*
 	 * Some platforms might need to prepare for mmio region access,
@@ -268,6 +281,9 @@ pdata_exit:
 		pdata->exit(dev);
 disable_unprepare_clk:
 	ahci_disable_clks(hpriv);
+disable_regulator:
+	if (hpriv->target_pwr)
+		regulator_disable(hpriv->target_pwr);
 free_clk:
 	ahci_put_clks(hpriv);
 	return rc;
@@ -284,6 +300,9 @@ static void ahci_host_stop(struct ata_host *host)
 
 	ahci_disable_clks(hpriv);
 	ahci_put_clks(hpriv);
+
+	if (hpriv->target_pwr)
+		regulator_disable(hpriv->target_pwr);
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -320,6 +339,9 @@ static int ahci_suspend(struct device *dev)
 
 	ahci_disable_clks(hpriv);
 
+	if (hpriv->target_pwr)
+		regulator_disable(hpriv->target_pwr);
+
 	return 0;
 }
 
@@ -330,9 +352,15 @@ static int ahci_resume(struct device *dev)
 	struct ahci_host_priv *hpriv = host->private_data;
 	int rc;
 
+	if (hpriv->target_pwr) {
+		rc = regulator_enable(hpriv->target_pwr);
+		if (rc)
+			return rc;
+	}
+
 	rc = ahci_enable_clks(dev, hpriv);
 	if (rc)
-		return rc;
+		goto disable_regulator;
 
 	if (pdata && pdata->resume) {
 		rc = pdata->resume(dev);
@@ -354,6 +382,9 @@ static int ahci_resume(struct device *dev)
 
 disable_unprepare_clk:
 	ahci_disable_clks(hpriv);
+disable_regulator:
+	if (hpriv->target_pwr)
+		regulator_disable(hpriv->target_pwr);
 
 	return rc;
 }
diff --git a/include/linux/ahci.h b/include/linux/ahci.h
index 19970b0..ac69cdc 100644
--- a/include/linux/ahci.h
+++ b/include/linux/ahci.h
@@ -22,6 +22,7 @@
 #define __LINUX_AHCI_H__
 
 #include <linux/clk.h>
+#include <linux/regulator/consumer.h>
 
 #define AHCI_MAX_CLKS		3
 
@@ -40,6 +41,7 @@ struct ahci_host_priv {
 	u32			em_buf_sz;	/* EM buffer size in byte */
 	u32			em_msg_type;	/* EM message type */
 	struct clk		*clks[AHCI_MAX_CLKS]; /* Optional */
+	struct regulator	*target_pwr;	/* Optional */
 	void			*plat_data;	/* Other platform data */
 	/* Optional ahci_start_engine override */
 	void			(*start_engine)(struct ata_port *ap);
-- 
1.8.5.3

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox