[PATCH v4 00/28] ARM: Initial Actions Semi S500 and S900 enablement

STALE3291d

Revision v4 of 4 in this series.

97 messages, 11 authors, 2017-09-05 · page 1 of 2 · open the first message on its own page

[PATCH v4 00/28] ARM: Initial Actions Semi S500 and S900 enablement

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:01:37

Hello,

This patch series adds initial support for Actions Semiconductor S500 (ARMv7)
and S900 (ARMv8) SoCs.

v4 refactors the clocksource driver again and fixes power-gating for CPU2/CPU3.

With this v4 I would like to start applying initial patches to my tree for 4.13.

@Actions:    Last call for comments on vendor prefix and SoC bindings!
@uCRobotics: Last call for comments on vendor prefix and board bindings!
@LeMaker:    Last call for comments on module and board bindings!

Work branch for testing:
https://github.com/afaerber/linux/commits/bg96-next

Booting from U-Boot to initrd is straightforward on both boards:

https://en.opensuse.org/HCL:Guitar
https://en.opensuse.org/HCL:Bubblegum-96

Have a lot of fun!

Cheers,
Andreas

v3 -> v4:
* Revert to hardcoded TIMER0/1 in clocksource (Daniel)
* Make power domains CPU2 and CPU3 always-on
* Clean up SMP vs. PM domains code duplication
* Extend earlycon documentation (Jonathan)
* Update MAINTAINERS with SPS files

v2 -> v3:
* Clocksource fix
* Clocksource cleanups (Daniel)
* Serial cleanups
* Add S500 CPU enable-method
* Add power domain driver
* Rework clocksource for S900 compatibility

v1 -> v2:
* S900 DT fixes (Mark)
* Kconfig name changes (Arnd)
* Bubblegum-96 .dts rename
* Vendor prefix rename
* Minor cleanups
* Add serial driver
* Add MAINTAINERS section
* Use SPDX-License-Identifier in DT (Rob)
* Add clocksource driver

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Olof Johansson <redacted>
Cc: Rob Herring <robh@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Daniel Lezcano <redacted>
Cc: Thomas Gleixner <redacted>

Cc: mp-cs at actions-semi.com
Cc: Thomas Liau <redacted>
Cc: 96boards at ucrobotics.com
Cc: support at lemaker.org

Cc: linux-serial at vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Cc: linux-pm at vger.kernel.org
Cc: Rafael J. Wysocki <redacted>
Cc: Kevin Hilman <khilman@kernel.org>
Cc: Ulf Hansson <redacted>

Cc: linux-doc at vger.kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>

Cc: devicetree at vger.kernel.org

Andreas F?rber (28):
  dt-bindings: Add vendor prefix for Actions Semi
  dt-bindings: arm: Document Actions Semi S500
  dt-bindings: timer: Document Owl timer
  clocksource: Add Owl timer
  clocksource: owl: Add S900 support
  ARM: Prepare Actions Semi S500
  ARM64: Prepare Actions Semi S900
  dt-bindings: serial: Document Actions Semi Owl UARTs
  tty: serial: Add Actions Semi Owl UART earlycon
  Documentation: kernel-parameters: Document owl earlycon
  ARM: dts: Add Actions Semi S500 and LeMaker Guitar
  dt-bindings: Add vendor prefix for uCRobotics
  dt-bindings: arm: Document Actions Semi S900
  ARM64: dts: Add Actions Semi S900 and Bubblegum-96
  MAINTAINERS: Add Actions Semi Owl section
  tty: serial: owl: Implement console driver
  ARM64: dts: actions: s900-bubblegum-96: Add fake uart5 clock
  ARM: dts: s500-guitar-bb-rev-b: Add fake uart3 clock
  dt-bindings: arm: cpus: Add S500 enable-method
  ARM: owl: Implement CPU enable-method for S500
  ARM: dts: s500: Set CPU enable-method
  dt-bindings: power: Add Owl SPS power domains
  soc: actions: Add Owl SPS
  MAINTAINERS: Update Actions Semi section with SPS
  ARM: dts: s500: Add SPS node
  ARM: dts: s500: Set power domains for CPU2 and CPU3
  soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating
  ARM: owl: smp: Implement SPS power-gating for CPU2 and CPU3

 Documentation/admin-guide/kernel-parameters.txt    |   6 +
 Documentation/devicetree/bindings/arm/actions.txt  |  39 ++
 Documentation/devicetree/bindings/arm/cpus.txt     |   1 +
 .../devicetree/bindings/power/actions,owl-sps.txt  |  17 +
 .../bindings/serial/actions,owl-uart.txt           |  16 +
 .../bindings/timer/actions,owl-timer.txt           |  20 +
 .../devicetree/bindings/vendor-prefixes.txt        |   2 +
 MAINTAINERS                                        |  13 +
 arch/arm/Kconfig                                   |   2 +
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts         |  33 +
 arch/arm/boot/dts/s500-guitar.dtsi                 |  22 +
 arch/arm/boot/dts/s500.dtsi                        | 189 ++++++
 arch/arm/mach-actions/Kconfig                      |  16 +
 arch/arm/mach-actions/Makefile                     |   4 +
 arch/arm/mach-actions/headsmp.S                    |  68 ++
 arch/arm/mach-actions/owl.c                        |  28 +
 arch/arm/mach-actions/platsmp.c                    | 198 ++++++
 arch/arm64/Kconfig.platforms                       |   6 +
 arch/arm64/boot/dts/Makefile                       |   1 +
 arch/arm64/boot/dts/actions/Makefile               |   5 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts  |  42 ++
 arch/arm64/boot/dts/actions/s900.dtsi              | 164 +++++
 drivers/clocksource/Kconfig                        |   7 +
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/owl-timer.c                    | 172 +++++
 drivers/soc/Kconfig                                |   1 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/actions/Kconfig                        |  16 +
 drivers/soc/actions/Makefile                       |   2 +
 drivers/soc/actions/owl-sps-helper.c               |  51 ++
 drivers/soc/actions/owl-sps.c                      | 224 +++++++
 drivers/tty/serial/Kconfig                         |  19 +
 drivers/tty/serial/Makefile                        |   1 +
 drivers/tty/serial/owl-uart.c                      | 724 +++++++++++++++++++++
 include/dt-bindings/power/s500-powergate.h         |  19 +
 include/linux/soc/actions/owl-sps.h                |  11 +
 include/uapi/linux/serial_core.h                   |   3 +
 39 files changed, 2147 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/actions.txt
 create mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.txt
 create mode 100644 Documentation/devicetree/bindings/serial/actions,owl-uart.txt
 create mode 100644 Documentation/devicetree/bindings/timer/actions,owl-timer.txt
 create mode 100644 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
 create mode 100644 arch/arm/boot/dts/s500-guitar.dtsi
 create mode 100644 arch/arm/boot/dts/s500.dtsi
 create mode 100644 arch/arm/mach-actions/Kconfig
 create mode 100644 arch/arm/mach-actions/Makefile
 create mode 100644 arch/arm/mach-actions/headsmp.S
 create mode 100644 arch/arm/mach-actions/owl.c
 create mode 100644 arch/arm/mach-actions/platsmp.c
 create mode 100644 arch/arm64/boot/dts/actions/Makefile
 create mode 100644 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
 create mode 100644 arch/arm64/boot/dts/actions/s900.dtsi
 create mode 100644 drivers/clocksource/owl-timer.c
 create mode 100644 drivers/soc/actions/Kconfig
 create mode 100644 drivers/soc/actions/Makefile
 create mode 100644 drivers/soc/actions/owl-sps-helper.c
 create mode 100644 drivers/soc/actions/owl-sps.c
 create mode 100644 drivers/tty/serial/owl-uart.c
 create mode 100644 include/dt-bindings/power/s500-powergate.h
 create mode 100644 include/linux/soc/actions/owl-sps.h

-- 
2.12.3

[PATCH v4 01/28] dt-bindings: Add vendor prefix for Actions Semi

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:07

Actions Semiconductor was listed on NASDAQ as ACTS until Dec 16, 2016.

Cc: mp-cs at actions-semi.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Fixed sort order after rename
 
 v1 -> v2:
 * Reverted from "acts" to "actions" (cf. IAP140 "mrvl" vs. "marvell")
 
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d808f24af949..3b02d90e2003 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -5,6 +5,7 @@ using them to avoid name-space collisions.
 
 abcn	Abracon Corporation
 abilis	Abilis Systems
+actions	Actions Semiconductor Co., Ltd.
 active-semi	Active-Semi International Inc
 ad	Avionic Design GmbH
 adapteva	Adapteva, Inc.
-- 
2.12.3

[PATCH v4 02/28] dt-bindings: arm: Document Actions Semi S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:09

The Actions Semi S500 is a quad-core ARM Cortex-A9 SoC.
The LeMaker Guitar is an SODIMM-format module with that SoC.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v1 -> v2:
 * Adopted "actions" vendor prefix
 * Extended text
 
 Documentation/devicetree/bindings/arm/actions.txt | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/actions.txt
diff --git a/Documentation/devicetree/bindings/arm/actions.txt b/Documentation/devicetree/bindings/arm/actions.txt
new file mode 100644
index 000000000000..1d3782e41b00
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/actions.txt
@@ -0,0 +1,24 @@
+Actions Semi platforms device tree bindings
+-------------------------------------------
+
+
+S500 SoC
+========
+
+Required root node properties:
+
+ - compatible :  must contain "actions,s500"
+
+
+Modules:
+
+Root node property compatible must contain, depending on module:
+
+ - LeMaker Guitar: "lemaker,guitar"
+
+
+Boards:
+
+Root node property compatible must contain, depending on board:
+
+ - LeMaker Guitar Base Board rev. B: "lemaker,guitar-bb-rev-b", "lemaker,guitar"
-- 
2.12.3

[PATCH v4 05/28] clocksource: owl: Add S900 support

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:11

The Actions Semi S900 SoC provides four 32-bit timers, TIMER0/1/2/3,
but no 2Hz timers.

An S900 datasheet can be found in 96Boards documentation:
https://github.com/96boards/documentation/blob/master/ConsumerEdition/Bubblegum-96/HardwareDocs/SoC_bubblegum96.pdf

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Dropped S900 DT data
 
 v3: new
 
 drivers/clocksource/owl-timer.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/drivers/clocksource/owl-timer.c b/drivers/clocksource/owl-timer.c
index 4609363a79a6..d19c53c11094 100644
--- a/drivers/clocksource/owl-timer.c
+++ b/drivers/clocksource/owl-timer.c
@@ -169,3 +169,4 @@ static int __init owl_timer_init(struct device_node *node)
 	return 0;
 }
 CLOCKSOURCE_OF_DECLARE(owl_s500, "actions,s500-timer", owl_timer_init);
+CLOCKSOURCE_OF_DECLARE(owl_s900, "actions,s900-timer", owl_timer_init);
-- 
2.12.3

[PATCH v4 13/28] dt-bindings: arm: Document Actions Semi S900

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:15

The Actions Semi S900 is a quad-core ARM Cortex-A53 SoC.
The Bubblegum-96 is a 96Boards Consumer Edition compliant board (4/96).

Cc: 96boards at ucrobotics.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v1 -> v2:
 * Adopted "actions" vendor prefix
 * Extended text
 
 Documentation/devicetree/bindings/arm/actions.txt | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/actions.txt b/Documentation/devicetree/bindings/arm/actions.txt
index 1d3782e41b00..3bc7ea575564 100644
--- a/Documentation/devicetree/bindings/arm/actions.txt
+++ b/Documentation/devicetree/bindings/arm/actions.txt
@@ -22,3 +22,18 @@ Boards:
 Root node property compatible must contain, depending on board:
 
  - LeMaker Guitar Base Board rev. B: "lemaker,guitar-bb-rev-b", "lemaker,guitar"
+
+
+S900 SoC
+========
+
+Required root node properties:
+
+- compatible :  must contain "actions,s900"
+
+
+Boards:
+
+Root node property compatible must contain, depending on board:
+
+ - uCRobotics Bubblegum-96: "ucrobotics,bubblegum-96"
-- 
2.12.3

[PATCH v4 12/28] dt-bindings: Add vendor prefix for uCRobotics

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:17

Cc: 96boards at ucrobotics.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v1 -> v2 -> v3 -> v4: unchanged
 
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 3b02d90e2003..6e514b3174ab 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -336,6 +336,7 @@ tronfy	Tronfy
 tronsmart	Tronsmart
 truly	Truly Semiconductors Limited
 tyan	Tyan Computer Corporation
+ucrobotics	uCRobotics
 udoo	Udoo
 uniwest	United Western Technologies Corp (UniWest)
 upisemi	uPI Semiconductor Corp.
-- 
2.12.3

[PATCH v4 11/28] ARM: dts: Add Actions Semi S500 and LeMaker Guitar

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:18

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Adopted lower-case timer interrupt-names (Mark)
 
 v2 -> v3:
 * Fixed uart2 reg offset
 * Enlarged timer reg size
 * Added 2 Hz timer interrupts, interrupt-names
 * Disabled CPUs 1-3 for now (cf. later patches)
 * Added Cortex-A9 SCU, global timer, TWD timer/wdt nodes
 * Added HOSC clock for timer
 
 v1 -> v2:
 * Reworded subject
 * Updated ARCH_OWL to ARCH_ACTIONS (Arnd)
 * Adopted "actions" vendor prefix
 * Dropped irq.h include
 * Added memory at 0 node for Guitar SoM
 * Dropped bogus uart3 clock-frequency
 * Added device_type for CPU nodes
 * Fixed UART reg size
 * Adopted SPDX-License-Identifier (Rob)
 * Added remaining UART nodes
 * Added timer node
 
 arch/arm/boot/dts/Makefile                 |   2 +
 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts |  26 +++++
 arch/arm/boot/dts/s500-guitar.dtsi         |  22 ++++
 arch/arm/boot/dts/s500.dtsi                | 176 +++++++++++++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
 create mode 100644 arch/arm/boot/dts/s500-guitar.dtsi
 create mode 100644 arch/arm/boot/dts/s500.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 3d6e288a49f7..e1ce692f9190 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -668,6 +668,8 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
 	orion5x-maxtor-shared-storage-2.dtb \
 	orion5x-netgear-wnr854t.dtb \
 	orion5x-rd88f5182-nas.dtb
+dtb-$(CONFIG_ARCH_ACTIONS) += \
+	s500-guitar-bb-rev-b.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += \
 	prima2-evb.dtb
 dtb-$(CONFIG_ARCH_OXNAS) += \
diff --git a/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts b/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
new file mode 100644
index 000000000000..834b71df31bd
--- /dev/null
+++ b/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+/dts-v1/;
+
+#include "s500-guitar.dtsi"
+
+/ {
+	compatible = "lemaker,guitar-bb-rev-b", "lemaker,guitar", "actions,s500";
+	model = "LeMaker Guitar Base Board rev. B";
+
+	aliases {
+		serial3 = &uart3;
+	};
+
+	chosen {
+		stdout-path = "serial3:115200n8";
+	};
+};
+
+&uart3 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/s500-guitar.dtsi b/arch/arm/boot/dts/s500-guitar.dtsi
new file mode 100644
index 000000000000..063ada966c94
--- /dev/null
+++ b/arch/arm/boot/dts/s500-guitar.dtsi
@@ -0,0 +1,22 @@
+/*
+ * LeMaker Guitar SoM
+ *
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include "s500.dtsi"
+
+/ {
+	compatible = "lemaker,guitar", "actions,s500";
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&timer {
+	clocks = <&hosc>;
+};
diff --git a/arch/arm/boot/dts/s500.dtsi b/arch/arm/boot/dts/s500.dtsi
new file mode 100644
index 000000000000..fc9f71a4106a
--- /dev/null
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -0,0 +1,176 @@
+/*
+ * Actions Semi S500 SoC
+ *
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "actions,s500";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+	};
+
+	chosen {
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x0>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x1>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x2>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x3>;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	hosc: hosc {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		scu: scu at b0020000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0xb0020000 0x100>;
+		};
+
+		global_timer: timer at b0020200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0xb0020200 0x100>;
+			interrupts = <GIC_PPI 0 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+			status = "disabled";
+		};
+
+		twd_timer: timer at b0020600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0xb0020600 0x20>;
+			interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+			status = "disabled";
+		};
+
+		twd_wdt: wdt at b0020620 {
+			compatible = "arm,cortex-a9-twd-wdt";
+			reg = <0xb0020620 0xe0>;
+			interrupts = <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller at b0021000 {
+			compatible = "arm,cortex-a9-gic";
+			reg = <0xb0021000 0x1000>,
+			      <0xb0020100 0x0100>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		l2: cache-controller at b0022000 {
+			compatible = "arm,pl310-cache";
+			reg = <0xb0022000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			arm,tag-latency = <3 3 2>;
+			arm,data-latency = <5 3 3>;
+		};
+
+		uart0: serial at b0120000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0120000 0x2000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart1: serial at b0122000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0122000 0x2000>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart2: serial at b0124000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0124000 0x2000>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart3: serial at b0126000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0126000 0x2000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart4: serial at b0128000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0128000 0x2000>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart5: serial at b012a000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb012a000 0x2000>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart6: serial at b012c000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb012c000 0x2000>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		timer: timer at b0168000 {
+			compatible = "actions,s500-timer";
+			reg = <0xb0168000 0x8000>;
+			interrupts = <GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "2hz0", "2hz1", "timer0", "timer1";
+		};
+	};
+};
-- 
2.12.3

[PATCH v4 10/28] Documentation: kernel-parameters: Document owl earlycon

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:19

Add the "owl" earlycon option to kernel-parameters.txt.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Extended help text and commit message (Jonathan)
 
 v1 -> v2 -> v3: unchanged
 
 Documentation/admin-guide/kernel-parameters.txt | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 042aa5e9c47d..e2fb7a87bc84 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -961,6 +961,12 @@
 			must already be setup and configured. Options are not
 			yet supported.
 
+		owl,<addr>
+			Start an early, polled-mode console on a serial port
+			of an Actions Semi SoC, such as S500 or S900, at the
+			specified address. The serial port must already be
+			setup and configured. Options are not yet supported.
+
 		smh	Use ARM semihosting calls for early console.
 
 		s3c2410,<addr>
-- 
2.12.3

[PATCH v4 22/28] dt-bindings: power: Add Owl SPS power domains

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:24

Define power domains for all non-reserved S500 power gates.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 .../devicetree/bindings/power/actions,owl-sps.txt     | 17 +++++++++++++++++
 include/dt-bindings/power/s500-powergate.h            | 19 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.txt
 create mode 100644 include/dt-bindings/power/s500-powergate.h
diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt
new file mode 100644
index 000000000000..c5eed06c771e
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/actions,owl-sps.txt
@@ -0,0 +1,17 @@
+Actions Semi Owl Smart Power System (SPS)
+
+Required properties:
+- compatible          :  "actions,s500-sps" for S500
+- reg                 :  Offset and length of the register set for the device.
+- #power-domain-cells :  Must be 1.
+                         See macros in:
+                          include/dt-bindings/power/s500-powergate.h for S500
+
+
+Example:
+
+		sps: power-controller at b01b0100 {
+			compatible = "actions,s500-sps";
+			reg = <0xb01b0100 0x100>;
+			#power-domain-cells = <1>;
+		};
diff --git a/include/dt-bindings/power/s500-powergate.h b/include/dt-bindings/power/s500-powergate.h
new file mode 100644
index 000000000000..ccc4ac37bc42
--- /dev/null
+++ b/include/dt-bindings/power/s500-powergate.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+#ifndef DT_BINDINGS_POWER_S500_POWERGATE_H
+#define DT_BINDINGS_POWER_S500_POWERGATE_H
+
+#define S500_PD_VDE	0
+#define S500_PD_VCE_SI	1
+#define S500_PD_USB2_1	2
+#define S500_PD_CPU2	3
+#define S500_PD_CPU3	4
+#define S500_PD_DMA	5
+#define S500_PD_DS	6
+#define S500_PD_USB3	7
+#define S500_PD_USB2_0	8
+
+#endif
-- 
2.12.3

[PATCH v4 17/28] ARM64: dts: actions: s900-bubblegum-96: Add fake uart5 clock

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:26

Give the serial driver a fixed-clock as input for baudrate 115200.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v2: new
 
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index a0c3484dbd12..21ca80f9941c 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -24,6 +24,12 @@
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x80000000>;
 	};
+
+	uart5_clk: uart5-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <921600>;
+		#clock-cells = <0>;
+	};
 };
 
 &timer {
@@ -32,4 +38,5 @@
 
 &uart5 {
 	status = "okay";
+	clocks = <&uart5_clk>;
 };
-- 
2.12.3

[PATCH v4 16/28] tty: serial: owl: Implement console driver

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:30

Implement serial console driver to complement earlycon.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Adopted BIT() macro
 * Implemented baudrate setting
 
 v2: new
 
 drivers/tty/serial/Kconfig       |   4 +-
 drivers/tty/serial/owl-uart.c    | 591 ++++++++++++++++++++++++++++++++++++++-
 include/uapi/linux/serial_core.h |   3 +
 3 files changed, 595 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 38f90ea45cf7..b0cddfbd8d74 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1689,7 +1689,7 @@ config SERIAL_MVEBU_CONSOLE
 	  Otherwise, say 'N'.
 
 config SERIAL_OWL
-	bool "Actions Semi Owl serial port support"
+	tristate "Actions Semi Owl serial port support"
 	depends on ARCH_ACTIONS || COMPILE_TEST
 	select SERIAL_CORE
 	help
@@ -1705,7 +1705,7 @@ config SERIAL_OWL_CONSOLE
 	default y
 	help
 	  Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART
-	  as the system console. Only earlycon is implemented currently.
+	  as the system console.
 
 endmenu
 
diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c
index 1b8008797a1b..14e0324144cf 100644
--- a/drivers/tty/serial/owl-uart.c
+++ b/drivers/tty/serial/owl-uart.c
@@ -20,6 +20,7 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/clk.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -28,22 +29,59 @@
 #include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#define OWL_UART_PORT_NUM 7
+#define OWL_UART_DEV_NAME "ttyOWL"
 
 #define OWL_UART_CTL	0x000
+#define OWL_UART_RXDAT	0x004
 #define OWL_UART_TXDAT	0x008
 #define OWL_UART_STAT	0x00c
 
+#define OWL_UART_CTL_DWLS_MASK		(0x3 << 0)
+#define OWL_UART_CTL_DWLS_5BITS		(0x0 << 0)
+#define OWL_UART_CTL_DWLS_6BITS		(0x1 << 0)
+#define OWL_UART_CTL_DWLS_7BITS		(0x2 << 0)
+#define OWL_UART_CTL_DWLS_8BITS		(0x3 << 0)
+#define OWL_UART_CTL_STPS_2BITS		BIT(2)
+#define OWL_UART_CTL_PRS_MASK		(0x7 << 4)
+#define OWL_UART_CTL_PRS_NONE		(0x0 << 4)
+#define OWL_UART_CTL_PRS_ODD		(0x4 << 4)
+#define OWL_UART_CTL_PRS_MARK		(0x5 << 4)
+#define OWL_UART_CTL_PRS_EVEN		(0x6 << 4)
+#define OWL_UART_CTL_PRS_SPACE		(0x7 << 4)
+#define OWL_UART_CTL_AFE		BIT(12)
 #define OWL_UART_CTL_TRFS_TX		BIT(14)
 #define OWL_UART_CTL_EN			BIT(15)
+#define OWL_UART_CTL_RXDE		BIT(16)
+#define OWL_UART_CTL_TXDE		BIT(17)
 #define OWL_UART_CTL_RXIE		BIT(18)
 #define OWL_UART_CTL_TXIE		BIT(19)
 
 #define OWL_UART_STAT_RIP		BIT(0)
 #define OWL_UART_STAT_TIP		BIT(1)
+#define OWL_UART_STAT_RXER		BIT(2)
+#define OWL_UART_STAT_TFER		BIT(3)
+#define OWL_UART_STAT_RXST		BIT(4)
+#define OWL_UART_STAT_RFEM		BIT(5)
 #define OWL_UART_STAT_TFFU		BIT(6)
+#define OWL_UART_STAT_TFES		BIT(10)
 #define OWL_UART_STAT_TRFL_MASK		(0x1f << 11)
 #define OWL_UART_STAT_UTBB		BIT(17)
 
+static struct uart_driver owl_uart_driver;
+
+struct owl_uart_port {
+	struct uart_port port;
+	struct clk *clk;
+};
+
+#define to_owl_uart_port(prt) container_of(prt, struct owl_uart_port, prt)
+
+static struct owl_uart_port *owl_uart_ports[OWL_UART_PORT_NUM];
+
 static inline void owl_uart_write(struct uart_port *port, u32 val, unsigned int off)
 {
 	writel(val, port->membase + off);
@@ -54,6 +92,380 @@ static inline u32 owl_uart_read(struct uart_port *port, unsigned int off)
 	return readl(port->membase + off);
 }
 
+static void owl_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static unsigned int owl_uart_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+static unsigned int owl_uart_tx_empty(struct uart_port *port)
+{
+	unsigned long flags;
+	u32 val;
+	unsigned int ret;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	val = owl_uart_read(port, OWL_UART_STAT);
+	ret = (val & OWL_UART_STAT_TFES) ? TIOCSER_TEMT : 0;
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return ret;
+}
+
+static void owl_uart_stop_rx(struct uart_port *port)
+{
+	u32 val;
+
+	val = owl_uart_read(port, OWL_UART_CTL);
+	val &= ~(OWL_UART_CTL_RXIE | OWL_UART_CTL_RXDE);
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	val = owl_uart_read(port, OWL_UART_STAT);
+	val |= OWL_UART_STAT_RIP;
+	owl_uart_write(port, val, OWL_UART_STAT);
+}
+
+static void owl_uart_stop_tx(struct uart_port *port)
+{
+	u32 val;
+
+	val = owl_uart_read(port, OWL_UART_CTL);
+	val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_TXDE);
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	val = owl_uart_read(port, OWL_UART_STAT);
+	val |= OWL_UART_STAT_TIP;
+	owl_uart_write(port, val, OWL_UART_STAT);
+}
+
+static void owl_uart_start_tx(struct uart_port *port)
+{
+	u32 val;
+
+	if (uart_tx_stopped(port)) {
+		owl_uart_stop_tx(port);
+		return;
+	}
+
+	val = owl_uart_read(port, OWL_UART_STAT);
+	val |= OWL_UART_STAT_TIP;
+	owl_uart_write(port, val, OWL_UART_STAT);
+
+	val = owl_uart_read(port, OWL_UART_CTL);
+	val |= OWL_UART_CTL_TXIE;
+	owl_uart_write(port, val, OWL_UART_CTL);
+}
+
+static void owl_uart_send_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+	unsigned int ch;
+
+	if (uart_tx_stopped(port))
+		return;
+
+	if (port->x_char) {
+		while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU))
+			cpu_relax();
+		owl_uart_write(port, port->x_char, OWL_UART_TXDAT);
+		port->icount.tx++;
+		port->x_char = 0;
+	}
+
+	while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) {
+		if (uart_circ_empty(xmit))
+			break;
+
+		ch = xmit->buf[xmit->tail];
+		owl_uart_write(port, ch, OWL_UART_TXDAT);
+		xmit->tail = (xmit->tail + 1) & (SERIAL_XMIT_SIZE - 1);
+		port->icount.tx++;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		owl_uart_stop_tx(port);
+}
+
+static void owl_uart_receive_chars(struct uart_port *port)
+{
+	u32 stat, val;
+
+	val = owl_uart_read(port, OWL_UART_CTL);
+	val &= ~OWL_UART_CTL_TRFS_TX;
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	stat = owl_uart_read(port, OWL_UART_STAT);
+	while (!(stat & OWL_UART_STAT_RFEM)) {
+		char flag = TTY_NORMAL;
+
+		if (stat & OWL_UART_STAT_RXER)
+			port->icount.overrun++;
+
+		if (stat & OWL_UART_STAT_RXST) {
+			/* We are not able to distinguish the error type. */
+			port->icount.brk++;
+			port->icount.frame++;
+
+			stat &= port->read_status_mask;
+			if (stat & OWL_UART_STAT_RXST)
+				flag = TTY_PARITY;
+		} else
+			port->icount.rx++;
+
+		val = owl_uart_read(port, OWL_UART_RXDAT);
+		val &= 0xff;
+
+		if ((stat & port->ignore_status_mask) == 0)
+			tty_insert_flip_char(&port->state->port, val, flag);
+
+		stat = owl_uart_read(port, OWL_UART_STAT);
+	}
+
+	spin_unlock(&port->lock);
+	tty_flip_buffer_push(&port->state->port);
+	spin_lock(&port->lock);
+}
+
+static irqreturn_t owl_uart_irq(int irq, void *dev_id)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	u32 stat;
+
+	spin_lock(&port->lock);
+
+	stat = owl_uart_read(port, OWL_UART_STAT);
+
+	if (stat & OWL_UART_STAT_RIP)
+		owl_uart_receive_chars(port);
+
+	if (stat & OWL_UART_STAT_TIP)
+		owl_uart_send_chars(port);
+
+	stat = owl_uart_read(port, OWL_UART_STAT);
+	stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP;
+	owl_uart_write(port, stat, OWL_UART_STAT);
+
+	spin_unlock(&port->lock);
+
+	return IRQ_HANDLED;
+}
+
+static void owl_uart_shutdown(struct uart_port *port)
+{
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	val = owl_uart_read(port, OWL_UART_CTL);
+	val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_RXIE
+		| OWL_UART_CTL_TXDE | OWL_UART_CTL_RXDE | OWL_UART_CTL_EN);
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	free_irq(port->irq, port);
+}
+
+static int owl_uart_startup(struct uart_port *port)
+{
+	u32 val;
+	unsigned long flags;
+	int ret;
+
+	ret = request_irq(port->irq, owl_uart_irq, IRQF_TRIGGER_HIGH,
+			"owl-uart", port);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	val = owl_uart_read(port, OWL_UART_STAT);
+	val |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP
+		| OWL_UART_STAT_RXER | OWL_UART_STAT_TFER | OWL_UART_STAT_RXST;
+	owl_uart_write(port, val, OWL_UART_STAT);
+
+	val = owl_uart_read(port, OWL_UART_CTL);
+	val |= OWL_UART_CTL_RXIE | OWL_UART_CTL_TXIE;
+	val |= OWL_UART_CTL_EN;
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return 0;
+}
+
+static void owl_uart_change_baudrate(struct owl_uart_port *owl_port,
+				     unsigned long baud)
+{
+	clk_set_rate(owl_port->clk, baud * 8);
+}
+
+static void owl_uart_set_termios(struct uart_port *port,
+				 struct ktermios *termios,
+				 struct ktermios *old)
+{
+	struct owl_uart_port *owl_port = to_owl_uart_port(port);
+	unsigned int baud;
+	u32 ctl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* We don't support modem control lines. */
+	termios->c_cflag &= ~(HUPCL | CMSPAR);
+	termios->c_cflag |= CLOCAL;
+
+	/* We don't support BREAK character recognition. */
+	termios->c_iflag &= ~(IGNBRK | BRKINT);
+
+	ctl = owl_uart_read(port, OWL_UART_CTL);
+
+	ctl &= ~OWL_UART_CTL_DWLS_MASK;
+	switch (termios->c_cflag & CSIZE) {
+	case CS5:
+		ctl |= OWL_UART_CTL_DWLS_5BITS;
+		break;
+	case CS6:
+		ctl |= OWL_UART_CTL_DWLS_6BITS;
+		break;
+	case CS7:
+		ctl |= OWL_UART_CTL_DWLS_7BITS;
+		break;
+	case CS8:
+	default:
+		ctl |= OWL_UART_CTL_DWLS_8BITS;
+		break;
+	}
+
+	if (termios->c_cflag & CSTOPB)
+		ctl |= OWL_UART_CTL_STPS_2BITS;
+	else
+		ctl &= ~OWL_UART_CTL_STPS_2BITS;
+
+	ctl &= ~OWL_UART_CTL_PRS_MASK;
+	if (termios->c_cflag & PARENB) {
+		if (termios->c_cflag & CMSPAR) {
+			if (termios->c_cflag & PARODD)
+				ctl |= OWL_UART_CTL_PRS_MARK;
+			else
+				ctl |= OWL_UART_CTL_PRS_SPACE;
+		} else if (termios->c_cflag & PARODD)
+			ctl |= OWL_UART_CTL_PRS_ODD;
+		else
+			ctl |= OWL_UART_CTL_PRS_EVEN;
+	} else
+		ctl |= OWL_UART_CTL_PRS_NONE;
+
+	if (termios->c_cflag & CRTSCTS)
+		ctl |= OWL_UART_CTL_AFE;
+	else
+		ctl &= ~OWL_UART_CTL_AFE;
+
+	owl_uart_write(port, ctl, OWL_UART_CTL);
+
+	baud = uart_get_baud_rate(port, termios, old, 9600, 3200000);
+	owl_uart_change_baudrate(owl_port, baud);
+
+	port->read_status_mask |= OWL_UART_STAT_RXER;
+	if (termios->c_iflag & INPCK)
+		port->read_status_mask |= OWL_UART_STAT_RXST;
+
+	uart_update_timeout(port, termios->c_cflag, baud);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void owl_uart_release_port(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return;
+
+	if (port->flags & UPF_IOREMAP) {
+		devm_release_mem_region(port->dev, port->mapbase,
+			resource_size(res));
+		devm_iounmap(port->dev, port->membase);
+		port->membase = NULL;
+	}
+}
+
+static int owl_uart_request_port(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENXIO;
+
+	if (!devm_request_mem_region(port->dev, port->mapbase,
+			resource_size(res), dev_name(port->dev)))
+		return -EBUSY;
+
+	if (port->flags & UPF_IOREMAP) {
+		port->membase = devm_ioremap_nocache(port->dev, port->mapbase,
+				resource_size(res));
+		if (!port->membase)
+			return -EBUSY;
+	}
+
+	return 0;
+}
+
+static const char *owl_uart_type(struct uart_port *port)
+{
+	return (port->type == PORT_OWL) ? "owl-uart" : NULL;
+}
+
+static int owl_uart_verify_port(struct uart_port *port,
+				struct serial_struct *ser)
+{
+	if (port->type != PORT_OWL)
+		return -EINVAL;
+
+	if (port->irq != ser->irq)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void owl_uart_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_OWL;
+		owl_uart_request_port(port);
+	}
+}
+
+static struct uart_ops owl_uart_ops = {
+	.set_mctrl = owl_uart_set_mctrl,
+	.get_mctrl = owl_uart_get_mctrl,
+	.tx_empty = owl_uart_tx_empty,
+	.start_tx = owl_uart_start_tx,
+	.stop_rx = owl_uart_stop_rx,
+	.stop_tx = owl_uart_stop_tx,
+	.startup = owl_uart_startup,
+	.shutdown = owl_uart_shutdown,
+	.set_termios = owl_uart_set_termios,
+	.type = owl_uart_type,
+	.config_port = owl_uart_config_port,
+	.request_port = owl_uart_request_port,
+	.release_port = owl_uart_release_port,
+	.verify_port = owl_uart_verify_port,
+};
+
 #ifdef CONFIG_SERIAL_OWL_CONSOLE
 
 static void owl_console_putchar(struct uart_port *port, int ch)
@@ -110,6 +522,57 @@ static void owl_uart_port_write(struct uart_port *port, const char *s,
 	local_irq_restore(flags);
 }
 
+static void owl_uart_console_write(struct console *co, const char *s,
+				   u_int count)
+{
+	struct owl_uart_port *owl_port;
+
+	owl_port = owl_uart_ports[co->index];
+	if (!owl_port)
+		return;
+
+	owl_uart_port_write(&owl_port->port, s, count);
+}
+
+static int owl_uart_console_setup(struct console *co, char *options)
+{
+	struct owl_uart_port *owl_port;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (co->index < 0 || co->index >= OWL_UART_PORT_NUM)
+		return -EINVAL;
+
+	owl_port = owl_uart_ports[co->index];
+	if (!owl_port || !owl_port->port.membase)
+		return -ENODEV;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(&owl_port->port, co, baud, parity, bits, flow);
+}
+
+static struct console owl_uart_console = {
+	.name = OWL_UART_DEV_NAME,
+	.write = owl_uart_console_write,
+	.device = uart_console_device,
+	.setup = owl_uart_console_setup,
+	.flags = CON_PRINTBUFFER,
+	.index = -1,
+	.data = &owl_uart_driver,
+};
+
+static int __init owl_uart_console_init(void)
+{
+	register_console(&owl_uart_console);
+
+	return 0;
+}
+console_initcall(owl_uart_console_init);
+
 static void owl_uart_early_console_write(struct console *co,
 					 const char *s,
 					 u_int count)
@@ -132,4 +595,130 @@ owl_uart_early_console_setup(struct earlycon_device *device, const char *opt)
 OF_EARLYCON_DECLARE(owl, "actions,owl-uart",
 		    owl_uart_early_console_setup);
 
-#endif /* CONFIG_SERIAL_OWL_CONSOLE */
+#define OWL_UART_CONSOLE (&owl_uart_console)
+#else
+#define OWL_UART_CONSOLE NULL
+#endif
+
+static struct uart_driver owl_uart_driver = {
+	.owner = THIS_MODULE,
+	.driver_name = "owl-uart",
+	.dev_name = OWL_UART_DEV_NAME,
+	.nr = OWL_UART_PORT_NUM,
+	.cons = OWL_UART_CONSOLE,
+};
+
+static int owl_uart_probe(struct platform_device *pdev)
+{
+	struct resource *res_mem, *res_irq;
+	struct owl_uart_port *owl_port;
+	int ret;
+
+	if (pdev->dev.of_node)
+		pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+
+	if (pdev->id < 0 || pdev->id >= OWL_UART_PORT_NUM) {
+		dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
+		return -EINVAL;
+	}
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res_mem) {
+		dev_err(&pdev->dev, "could not get mem\n");
+		return -ENODEV;
+	}
+
+	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res_irq) {
+		dev_err(&pdev->dev, "could not get irq\n");
+		return -ENODEV;
+	}
+
+	if (owl_uart_ports[pdev->id]) {
+		dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
+		return -EBUSY;
+	}
+
+	owl_port = devm_kzalloc(&pdev->dev, sizeof(*owl_port), GFP_KERNEL);
+	if (!owl_port)
+		return -ENOMEM;
+
+	owl_port->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(owl_port->clk)) {
+		dev_err(&pdev->dev, "could not get clk\n");
+		return PTR_ERR(owl_port->clk);
+	}
+
+	owl_port->port.dev = &pdev->dev;
+	owl_port->port.line = pdev->id;
+	owl_port->port.type = PORT_OWL;
+	owl_port->port.iotype = UPIO_MEM;
+	owl_port->port.mapbase = res_mem->start;
+	owl_port->port.irq = res_irq->start;
+	owl_port->port.uartclk = clk_get_rate(owl_port->clk);
+	owl_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY;
+	owl_port->port.x_char = 0;
+	owl_port->port.fifosize = 16;
+	owl_port->port.ops = &owl_uart_ops;
+
+	owl_uart_ports[pdev->id] = owl_port;
+	platform_set_drvdata(pdev, owl_port);
+
+	ret = uart_add_one_port(&owl_uart_driver, &owl_port->port);
+	if (ret)
+		owl_uart_ports[pdev->id] = NULL;
+
+	return ret;
+}
+
+static int owl_uart_remove(struct platform_device *pdev)
+{
+	struct owl_uart_port *owl_port;
+
+	owl_port = platform_get_drvdata(pdev);
+	uart_remove_one_port(&owl_uart_driver, &owl_port->port);
+	owl_uart_ports[pdev->id] = NULL;
+
+	return 0;
+}
+
+static const struct of_device_id owl_uart_dt_matches[] = {
+	{ .compatible = "actions,owl-uart" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, owl_uart_dt_matches);
+
+static struct platform_driver owl_uart_platform_driver = {
+	.probe = owl_uart_probe,
+	.remove = owl_uart_remove,
+	.driver = {
+		.name = "owl-uart",
+		.of_match_table = owl_uart_dt_matches,
+	},
+};
+
+static int __init owl_uart_init(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&owl_uart_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&owl_uart_platform_driver);
+	if (ret)
+		uart_unregister_driver(&owl_uart_driver);
+
+	return ret;
+}
+
+static void __init owl_uart_exit(void)
+{
+	platform_driver_unregister(&owl_uart_platform_driver);
+	uart_unregister_driver(&owl_uart_driver);
+}
+
+module_init(owl_uart_init);
+module_exit(owl_uart_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index 9ec741b133fe..5e850e68930d 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -271,4 +271,7 @@
 /* MPS2 UART */
 #define PORT_MPS2UART	116
 
+/* Actions Semi Owl UART */
+#define PORT_OWL	117
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
-- 
2.12.3

[PATCH v4 26/28] ARM: dts: s500: Set power domains for CPU2 and CPU3

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:32

CPU2 has its own power domain PD_CPU2, and CPU3 has PD_CPU3.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4: new (split off due to dt-bindings dependency)
 
 arch/arm/boot/dts/s500.dtsi | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/arch/arm/boot/dts/s500.dtsi b/arch/arm/boot/dts/s500.dtsi
index 51a48741d4c0..4e4478a3ec08 100644
--- a/arch/arm/boot/dts/s500.dtsi
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -7,6 +7,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/s500-powergate.h>
 
 / {
 	compatible = "actions,s500";
@@ -43,6 +44,7 @@
 			compatible = "arm,cortex-a9";
 			reg = <0x2>;
 			enable-method = "actions,s500-smp";
+			power-domains = <&sps S500_PD_CPU2>;
 		};
 
 		cpu3: cpu at 3 {
@@ -50,6 +52,7 @@
 			compatible = "arm,cortex-a9";
 			reg = <0x3>;
 			enable-method = "actions,s500-smp";
+			power-domains = <&sps S500_PD_CPU3>;
 		};
 	};
 
-- 
2.12.3

[PATCH v4 19/28] dt-bindings: arm: cpus: Add S500 enable-method

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:55:59

The Actions Semi S500 SoC requires a special secondary CPU boot procedure.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 2713aadb7411..ad1913bea8d7 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -193,6 +193,7 @@ nodes to be present and contain the properties described below.
 			     "spin-table"
 			# On ARM 32-bit systems this property is optional and
 			  can be one of:
+			    "actions,s500-smp"
 			    "allwinner,sun6i-a31"
 			    "allwinner,sun8i-a23"
 			    "arm,realview-smp"
-- 
2.12.3

[PATCH v4 24/28] MAINTAINERS: Update Actions Semi section with SPS

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:56:13

Add file patterns to cover the SPS power domain driver and DT binding.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4: new
 
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index a9faa30def9c..1bfd357f5279 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1044,7 +1044,10 @@ N:	owl
 F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/s500*
 F:	arch/arm64/boot/dts/actions/
+F:	drivers/soc/actions/
+F:	include/linux/soc/actions/
 F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
 
 ARM/ADS SPHERE MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
-- 
2.12.3

[PATCH v4 23/28] soc: actions: Add Owl SPS

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:56:15

Implement S500 Smart Power System power-gating.
For now flag PD_CPU2 and PD_CPU3 as always-on.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Added genpd_flags field and set GENPD_FLAG_ALWAYS_ON for CPU2/CPU3
 * Added debug output
 
 v3: new
 
 drivers/soc/Kconfig           |   1 +
 drivers/soc/Makefile          |   1 +
 drivers/soc/actions/Kconfig   |  12 ++
 drivers/soc/actions/Makefile  |   1 +
 drivers/soc/actions/owl-sps.c | 252 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 267 insertions(+)
 create mode 100644 drivers/soc/actions/Kconfig
 create mode 100644 drivers/soc/actions/Makefile
 create mode 100644 drivers/soc/actions/owl-sps.c
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 309643fe35f9..a63eb0ffba98 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,5 +1,6 @@
 menu "SOC (System On Chip) specific Drivers"
 
+source "drivers/soc/actions/Kconfig"
 source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/fsl/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 824b44281efa..a3b27a33c309 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_ARCH_ACTIONS)	+= actions/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
 obj-y				+= bcm/
 obj-$(CONFIG_ARCH_DOVE)		+= dove/
diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig
new file mode 100644
index 000000000000..bdf827d5ce78
--- /dev/null
+++ b/drivers/soc/actions/Kconfig
@@ -0,0 +1,12 @@
+if ARCH_ACTIONS || COMPILE_TEST
+
+config OWL_PM_DOMAINS
+	bool "Actions Semi SPS power domains"
+	depends on PM
+	select PM_GENERIC_DOMAINS
+	help
+	  Say 'y' here to enable support for Smart Power System (SPS)
+	  power-gating on Actions Semiconductor S500 SoC.
+	  If unsure, say 'n'.
+
+endif
diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile
new file mode 100644
index 000000000000..720c34ed16e4
--- /dev/null
+++ b/drivers/soc/actions/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c
new file mode 100644
index 000000000000..d9160579b542
--- /dev/null
+++ b/drivers/soc/actions/owl-sps.c
@@ -0,0 +1,252 @@
+/*
+ * Actions Semi Owl Smart Power System (SPS)
+ *
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pm_domain.h>
+#include <dt-bindings/power/s500-powergate.h>
+
+#define OWL_SPS_PG_CTL	0x0
+
+struct owl_sps_domain_info {
+	const char *name;
+	int pwr_bit;
+	int ack_bit;
+	unsigned int genpd_flags;
+};
+
+struct owl_sps_info {
+	unsigned num_domains;
+	const struct owl_sps_domain_info *domains;
+};
+
+struct owl_sps {
+	struct device *dev;
+	const struct owl_sps_info *info;
+	void __iomem *base;
+	struct genpd_onecell_data genpd_data;
+	struct generic_pm_domain *domains[];
+};
+
+#define to_owl_pd(gpd) container_of(gpd, struct owl_sps_domain, genpd)
+
+struct owl_sps_domain {
+	struct generic_pm_domain genpd;
+	const struct owl_sps_domain_info *info;
+	struct owl_sps *sps;
+};
+
+static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable)
+{
+	u32 val, pwr_mask, ack_mask;
+	int timeout;
+	bool ack;
+
+	ack_mask = BIT(pd->info->ack_bit);
+	pwr_mask = BIT(pd->info->pwr_bit);
+	val = readl(pd->sps->base + OWL_SPS_PG_CTL);
+	ack = val & ack_mask;
+
+	if (ack == enable)
+		return 0;
+
+	if (enable)
+		val |= pwr_mask;
+	else
+		val &= ~pwr_mask;
+
+	writel(val, pd->sps->base + OWL_SPS_PG_CTL);
+
+	for (timeout = 5000; timeout > 0; timeout -= 50) {
+		val = readl(pd->sps->base + OWL_SPS_PG_CTL);
+		if ((val & ack_mask) == (enable ? ack_mask : 0))
+			break;
+		udelay(50);
+	}
+	if (timeout <= 0)
+		return -ETIMEDOUT;
+
+	udelay(10);
+
+	return 0;
+}
+
+static int owl_sps_power_on(struct generic_pm_domain *domain)
+{
+	struct owl_sps_domain *pd = to_owl_pd(domain);
+
+	dev_dbg(pd->sps->dev, "%s power on", pd->info->name);
+
+	return owl_sps_set_power(pd, true);
+}
+
+static int owl_sps_power_off(struct generic_pm_domain *domain)
+{
+	struct owl_sps_domain *pd = to_owl_pd(domain);
+
+	dev_dbg(pd->sps->dev, "%s power off", pd->info->name);
+
+	return owl_sps_set_power(pd, false);
+}
+
+static int owl_sps_init_domain(struct owl_sps *sps, int index)
+{
+	struct owl_sps_domain *pd;
+
+	pd = devm_kzalloc(sps->dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+
+	pd->info = &sps->info->domains[index];
+	pd->sps = sps;
+
+	pd->genpd.name = pd->info->name;
+	pd->genpd.power_on = owl_sps_power_on;
+	pd->genpd.power_off = owl_sps_power_off;
+	pd->genpd.flags = pd->info->genpd_flags;
+	pm_genpd_init(&pd->genpd, NULL, false);
+
+	sps->genpd_data.domains[index] = &pd->genpd;
+
+	return 0;
+}
+
+static int owl_sps_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	const struct owl_sps_info *sps_info;
+	struct owl_sps *sps;
+	int i, ret;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "no device node\n");
+		return -ENODEV;
+	}
+
+	match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
+	if (!match || !match->data) {
+		dev_err(&pdev->dev, "unknown compatible or missing data\n");
+		return -EINVAL;
+	}
+
+	sps_info = match->data;
+
+	sps = devm_kzalloc(&pdev->dev, sizeof(*sps) +
+			   sps_info->num_domains * sizeof(sps->domains[0]),
+			   GFP_KERNEL);
+	if (!sps)
+		return -ENOMEM;
+
+	sps->base = of_io_request_and_map(pdev->dev.of_node, 0, "owl-sps");
+	if (IS_ERR(sps->base)) {
+		dev_err(&pdev->dev, "failed to map sps registers\n");
+		return PTR_ERR(sps->base);
+	}
+
+	sps->dev = &pdev->dev;
+	sps->info = sps_info;
+	sps->genpd_data.domains = sps->domains;
+	sps->genpd_data.num_domains = sps_info->num_domains;
+
+	for (i = 0; i < sps_info->num_domains; i++) {
+		ret = owl_sps_init_domain(sps, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = of_genpd_add_provider_onecell(pdev->dev.of_node, &sps->genpd_data);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add provider (%d)", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct owl_sps_domain_info s500_sps_domains[] = {
+	[S500_PD_VDE] = {
+		.name = "VDE",
+		.pwr_bit = 0,
+		.ack_bit = 16,
+	},
+	[S500_PD_VCE_SI] = {
+		.name = "VCE_SI",
+		.pwr_bit = 1,
+		.ack_bit = 17,
+	},
+	[S500_PD_USB2_1] = {
+		.name = "USB2_1",
+		.pwr_bit = 2,
+		.ack_bit = 18,
+	},
+	[S500_PD_CPU2] = {
+		.name = "CPU2",
+		.pwr_bit = 5,
+		.ack_bit = 21,
+		.genpd_flags = GENPD_FLAG_ALWAYS_ON,
+	},
+	[S500_PD_CPU3] = {
+		.name = "CPU3",
+		.pwr_bit = 6,
+		.ack_bit = 22,
+		.genpd_flags = GENPD_FLAG_ALWAYS_ON,
+	},
+	[S500_PD_DMA] = {
+		.name = "DMA",
+		.pwr_bit = 8,
+		.ack_bit = 12,
+	},
+	[S500_PD_DS] = {
+		.name = "DS",
+		.pwr_bit = 9,
+		.ack_bit = 13,
+	},
+	[S500_PD_USB3] = {
+		.name = "USB3",
+		.pwr_bit = 10,
+		.ack_bit = 14,
+	},
+	[S500_PD_USB2_0] = {
+		.name = "USB2_0",
+		.pwr_bit = 11,
+		.ack_bit = 15,
+	},
+};
+
+static const struct owl_sps_info s500_sps_info = {
+	.num_domains = ARRAY_SIZE(s500_sps_domains),
+	.domains = s500_sps_domains,
+};
+
+static const struct of_device_id owl_sps_of_matches[] = {
+	{ .compatible = "actions,s500-sps", .data = &s500_sps_info },
+	{ }
+};
+
+static struct platform_driver owl_sps_platform_driver = {
+	.probe = owl_sps_probe,
+	.driver = {
+		.name = "owl-sps",
+		.of_match_table = owl_sps_of_matches,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int __init owl_sps_init(void)
+{
+	return platform_driver_register(&owl_sps_platform_driver);
+}
+postcore_initcall(owl_sps_init);
-- 
2.12.3

[PATCH v4 28/28] ARM: owl: smp: Implement SPS power-gating for CPU2 and CPU3

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:56:47

Bring up the two remaining CPUs by calling into PM domain code.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Reused PM domain helper code to avoid code duplication
 
 v3: new
 
 arch/arm/mach-actions/Kconfig   |  1 +
 arch/arm/mach-actions/platsmp.c | 36 ++++++++++++++++++++++++++++++++++--
 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-actions/Kconfig b/arch/arm/mach-actions/Kconfig
index 717adc1630a1..ad9c5c89c683 100644
--- a/arch/arm/mach-actions/Kconfig
+++ b/arch/arm/mach-actions/Kconfig
@@ -10,6 +10,7 @@ menuconfig ARCH_ACTIONS
 	select GENERIC_IRQ_CHIP
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
+	select OWL_PM_DOMAINS_HELPER
 	select OWL_TIMER
 	help
 	  This enables support for the Actions Semiconductor S500 SoC family.
diff --git a/arch/arm/mach-actions/platsmp.c b/arch/arm/mach-actions/platsmp.c
index 9d3601ebe535..b4806ce0e9bb 100644
--- a/arch/arm/mach-actions/platsmp.c
+++ b/arch/arm/mach-actions/platsmp.c
@@ -19,6 +19,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/smp.h>
+#include <linux/soc/actions/owl-sps.h>
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
@@ -28,7 +29,13 @@
 
 #define OWL_CPUx_FLAG_BOOT	0x55aa
 
+#define OWL_SPS_PG_CTL_PWR_CPU2	BIT(5)
+#define OWL_SPS_PG_CTL_PWR_CPU3	BIT(6)
+#define OWL_SPS_PG_CTL_ACK_CPU2	BIT(21)
+#define OWL_SPS_PG_CTL_ACK_CPU3	BIT(22)
+
 static void __iomem *scu_base_addr;
+static void __iomem *sps_base_addr;
 static void __iomem *timer_base_addr;
 static int ncores;
 
@@ -58,14 +65,27 @@ void owl_secondary_startup(void);
 
 static int s500_wakeup_secondary(unsigned int cpu)
 {
+	int ret;
+
 	if (cpu > 3)
 		return -EINVAL;
 
+	/* The generic PM domain driver is not available this early. */
 	switch (cpu) {
 	case 2:
+		ret = owl_sps_set_pg(sps_base_addr,
+		                     OWL_SPS_PG_CTL_PWR_CPU2,
+				     OWL_SPS_PG_CTL_ACK_CPU2, true);
+		if (ret)
+			return ret;
+		break;
 	case 3:
-		/* CPU2/3 are power-gated */
-		return -EINVAL;
+		ret = owl_sps_set_pg(sps_base_addr,
+		                     OWL_SPS_PG_CTL_PWR_CPU3,
+				     OWL_SPS_PG_CTL_ACK_CPU3, true);
+		if (ret)
+			return ret;
+		break;
 	}
 
 	/* wait for CPUx to run to WFE instruction */
@@ -133,6 +153,18 @@ static void __init s500_smp_prepare_cpus(unsigned int max_cpus)
 		return;
 	}
 
+	node = of_find_compatible_node(NULL, NULL, "actions,s500-sps");
+	if (!node) {
+		pr_err("%s: missing sps\n", __func__);
+		return;
+	}
+
+	sps_base_addr = of_iomap(node, 0);
+	if (!sps_base_addr) {
+		pr_err("%s: could not map sps registers\n", __func__);
+		return;
+	}
+
 	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
 		node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
 		if (!node) {
-- 
2.12.3

[PATCH v4 21/28] ARM: dts: s500: Set CPU enable-method

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:56:49

Use a custom S500 enable-method for all CPUs.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 arch/arm/boot/dts/s500.dtsi | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/s500.dtsi b/arch/arm/boot/dts/s500.dtsi
index fc9f71a4106a..6d6024027ee2 100644
--- a/arch/arm/boot/dts/s500.dtsi
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -28,24 +28,28 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x0>;
+			enable-method = "actions,s500-smp";
 		};
 
 		cpu1: cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x1>;
+			enable-method = "actions,s500-smp";
 		};
 
 		cpu2: cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x2>;
+			enable-method = "actions,s500-smp";
 		};
 
 		cpu3: cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x3>;
+			enable-method = "actions,s500-smp";
 		};
 	};
 
-- 
2.12.3

[PATCH v4 27/28] soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:57:14

Allow the SMP code to reuse PM domain code for CPU2/CPU3 wakeup.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4: new
 
 drivers/soc/actions/Kconfig          |  4 +++
 drivers/soc/actions/Makefile         |  1 +
 drivers/soc/actions/owl-sps-helper.c | 51 ++++++++++++++++++++++++++++++++++++
 drivers/soc/actions/owl-sps.c        | 34 +++---------------------
 include/linux/soc/actions/owl-sps.h  | 11 ++++++++
 5 files changed, 70 insertions(+), 31 deletions(-)
 create mode 100644 drivers/soc/actions/owl-sps-helper.c
 create mode 100644 include/linux/soc/actions/owl-sps.h
diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig
index bdf827d5ce78..9d68b5a771c3 100644
--- a/drivers/soc/actions/Kconfig
+++ b/drivers/soc/actions/Kconfig
@@ -1,8 +1,12 @@
 if ARCH_ACTIONS || COMPILE_TEST
 
+config OWL_PM_DOMAINS_HELPER
+	bool
+
 config OWL_PM_DOMAINS
 	bool "Actions Semi SPS power domains"
 	depends on PM
+	select OWL_PM_DOMAINS_HELPER
 	select PM_GENERIC_DOMAINS
 	help
 	  Say 'y' here to enable support for Smart Power System (SPS)
diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile
index 720c34ed16e4..1e101b06bab1 100644
--- a/drivers/soc/actions/Makefile
+++ b/drivers/soc/actions/Makefile
@@ -1 +1,2 @@
+obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o
 obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
diff --git a/drivers/soc/actions/owl-sps-helper.c b/drivers/soc/actions/owl-sps-helper.c
new file mode 100644
index 000000000000..9d7a2c2b44ec
--- /dev/null
+++ b/drivers/soc/actions/owl-sps-helper.c
@@ -0,0 +1,51 @@
+/*
+ * Actions Semi Owl Smart Power System (SPS) shared helpers
+ *
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#define OWL_SPS_PG_CTL	0x0
+
+int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable)
+{
+	u32 val;
+	bool ack;
+	int timeout;
+
+	val = readl(base + OWL_SPS_PG_CTL);
+	ack = val & ack_mask;
+	if (ack == enable)
+		return 0;
+
+	if (enable)
+		val |= pwr_mask;
+	else
+		val &= ~pwr_mask;
+
+	writel(val, base + OWL_SPS_PG_CTL);
+
+	for (timeout = 5000; timeout > 0; timeout -= 50) {
+		val = readl(base + OWL_SPS_PG_CTL);
+		if ((val & ack_mask) == (enable ? ack_mask : 0))
+			break;
+		udelay(50);
+	}
+	if (timeout <= 0)
+		return -ETIMEDOUT;
+
+	udelay(10);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(owl_sps_set_pg);
diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c
index d9160579b542..41991c5217a0 100644
--- a/drivers/soc/actions/owl-sps.c
+++ b/drivers/soc/actions/owl-sps.c
@@ -12,15 +12,12 @@
  * option) any later version.
  */
 
-#include <linux/delay.h>
-#include <linux/io.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_domain.h>
+#include <linux/soc/actions/owl-sps.h>
 #include <dt-bindings/power/s500-powergate.h>
 
-#define OWL_SPS_PG_CTL	0x0
-
 struct owl_sps_domain_info {
 	const char *name;
 	int pwr_bit;
@@ -51,37 +48,12 @@ struct owl_sps_domain {
 
 static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable)
 {
-	u32 val, pwr_mask, ack_mask;
-	int timeout;
-	bool ack;
+	u32 pwr_mask, ack_mask;
 
 	ack_mask = BIT(pd->info->ack_bit);
 	pwr_mask = BIT(pd->info->pwr_bit);
-	val = readl(pd->sps->base + OWL_SPS_PG_CTL);
-	ack = val & ack_mask;
-
-	if (ack == enable)
-		return 0;
-
-	if (enable)
-		val |= pwr_mask;
-	else
-		val &= ~pwr_mask;
-
-	writel(val, pd->sps->base + OWL_SPS_PG_CTL);
 
-	for (timeout = 5000; timeout > 0; timeout -= 50) {
-		val = readl(pd->sps->base + OWL_SPS_PG_CTL);
-		if ((val & ack_mask) == (enable ? ack_mask : 0))
-			break;
-		udelay(50);
-	}
-	if (timeout <= 0)
-		return -ETIMEDOUT;
-
-	udelay(10);
-
-	return 0;
+	return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable);
 }
 
 static int owl_sps_power_on(struct generic_pm_domain *domain)
diff --git a/include/linux/soc/actions/owl-sps.h b/include/linux/soc/actions/owl-sps.h
new file mode 100644
index 000000000000..33d0dbeceb55
--- /dev/null
+++ b/include/linux/soc/actions/owl-sps.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef SOC_ACTIONS_OWL_SPS_H
+#define SOC_ACTIONS_OWL_SPS_H
+
+int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable);
+
+#endif
-- 
2.12.3

[PATCH v4 25/28] ARM: dts: s500: Add SPS node

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:57:38

Add Smart Power System node for PM domains.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Extended commit message
 * Split off association of power-domains (avoids include/dt-bindings/ dependency)
 
 v3: new
 
 arch/arm/boot/dts/s500.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/s500.dtsi b/arch/arm/boot/dts/s500.dtsi
index 6d6024027ee2..51a48741d4c0 100644
--- a/arch/arm/boot/dts/s500.dtsi
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -176,5 +176,11 @@
 			             <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "2hz0", "2hz1", "timer0", "timer1";
 		};
+
+		sps: power-controller at b01b0100 {
+			compatible = "actions,s500-sps";
+			reg = <0xb01b0100 0x100>;
+			#power-domain-cells = <1>;
+		};
 	};
 };
-- 
2.12.3

[PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:58:23

Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 arch/arm/mach-actions/Makefile  |   3 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 237 insertions(+)
 create mode 100644 arch/arm/mach-actions/headsmp.S
 create mode 100644 arch/arm/mach-actions/platsmp.c
diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile
index 524c3817bcb3..217e95d04b43 100644
--- a/arch/arm/mach-actions/Makefile
+++ b/arch/arm/mach-actions/Makefile
@@ -1 +1,4 @@
 obj-$(CONFIG_ARCH_ACTIONS) += owl.o
+obj-${CONFIG_ARCH_ACTIONS} += platsmp.o headsmp.o
+
+AFLAGS_headsmp.o := -Wa,-march=armv7-a
diff --git a/arch/arm/mach-actions/headsmp.S b/arch/arm/mach-actions/headsmp.S
new file mode 100644
index 000000000000..dc4832fc101a
--- /dev/null
+++ b/arch/arm/mach-actions/headsmp.S
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ENTRY(owl_v7_invalidate_l1)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0	@ invalidate I cache
+	mcr	p15, 2, r0, c0, c0, 0
+	mrc	p15, 1, r0, c0, c0, 0
+
+	ldr	r1, =0x7fff
+	and	r2, r1, r0, lsr #13
+
+	ldr	r1, =0x3ff
+
+	and	r3, r1, r0, lsr #3	@ NumWays - 1
+	add	r2, r2, #1		@ NumSets
+
+	and	r0, r0, #0x7
+	add	r0, r0, #4	@ SetShift
+
+	clz	r1, r3		@ WayShift
+	add	r4, r3, #1	@ NumWays
+1:	sub	r2, r2, #1	@ NumSets--
+	mov	r3, r4		@ Temp = NumWays
+2:	subs	r3, r3, #1	@ Temp--
+	mov	r5, r3, lsl r1
+	mov	r6, r2, lsl r0
+	orr	r5, r5, r6	@ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+	mcr	p15, 0, r5, c7, c6, 2
+	bgt	2b
+	cmp	r2, #0
+	bgt	1b
+	dsb
+	isb
+	mov	pc, lr
+ENDPROC(owl_v7_invalidate_l1)
+
+ENTRY(owl_secondary_startup)
+	mrc	p15, 0, r0, c0, c0, 5
+	and	r0, r0, #0xf
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	add	r6, r6, r4
+pen:
+	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	bl	owl_v7_invalidate_l1
+	b	secondary_startup
+
+1:	.long	.
+	.long	pen_release
diff --git a/arch/arm/mach-actions/platsmp.c b/arch/arm/mach-actions/platsmp.c
new file mode 100644
index 000000000000..9d3601ebe535
--- /dev/null
+++ b/arch/arm/mach-actions/platsmp.c
@@ -0,0 +1,166 @@
+/*
+ * Actions Semi Leopard
+ *
+ * This file is based on arm realview smp platform.
+ *
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#define OWL_CPU1_ADDR	0x50
+#define OWL_CPU1_FLAG	0x5c
+
+#define OWL_CPUx_FLAG_BOOT	0x55aa
+
+static void __iomem *scu_base_addr;
+static void __iomem *timer_base_addr;
+static int ncores;
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	smp_wmb();
+	__cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void s500_smp_secondary_init(unsigned int cpu)
+{
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+void owl_secondary_startup(void);
+
+static int s500_wakeup_secondary(unsigned int cpu)
+{
+	if (cpu > 3)
+		return -EINVAL;
+
+	switch (cpu) {
+	case 2:
+	case 3:
+		/* CPU2/3 are power-gated */
+		return -EINVAL;
+	}
+
+	/* wait for CPUx to run to WFE instruction */
+	udelay(200);
+
+	writel(virt_to_phys(owl_secondary_startup),
+	       timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4);
+	writel(OWL_CPUx_FLAG_BOOT,
+	       timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4);
+
+	dsb_sev();
+	mb();
+
+	return 0;
+}
+
+static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+	int ret;
+
+	ret = s500_wakeup_secondary(cpu);
+	if (ret)
+		return ret;
+
+	udelay(10);
+
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 */
+	write_pen_release(cpu_logical_map(cpu));
+	smp_send_reschedule(cpu);
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		if (pen_release == -1)
+			break;
+	}
+
+	writel(0, timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4);
+	writel(0, timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4);
+
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init s500_smp_prepare_cpus(unsigned int max_cpus)
+{
+	struct device_node *node;
+
+	node = of_find_compatible_node(NULL, NULL, "actions,s500-timer");
+	if (!node) {
+		pr_err("%s: missing timer\n", __func__);
+		return;
+	}
+
+	timer_base_addr = of_iomap(node, 0);
+	if (!timer_base_addr) {
+		pr_err("%s: could not map timer registers\n", __func__);
+		return;
+	}
+
+	if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+		node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+		if (!node) {
+			pr_err("%s: missing scu\n", __func__);
+			return;
+		}
+
+		scu_base_addr = of_iomap(node, 0);
+		if (!scu_base_addr) {
+			pr_err("%s: could not map scu registers\n", __func__);
+			return;
+		}
+
+		/*
+		 * While the number of cpus is gathered from dt, also get the
+		 * number of cores from the scu to verify this value when
+		 * booting the cores.
+		 */
+		ncores = scu_get_core_count(scu_base_addr);
+		pr_debug("%s: ncores %d\n", __func__, ncores);
+
+		scu_enable(scu_base_addr);
+	}
+}
+
+static const struct smp_operations s500_smp_ops __initconst = {
+	.smp_prepare_cpus = s500_smp_prepare_cpus,
+	.smp_secondary_init = s500_smp_secondary_init,
+	.smp_boot_secondary = s500_smp_boot_secondary,
+};
+CPU_METHOD_OF_DECLARE(s500_smp, "actions,s500-smp", &s500_smp_ops);
-- 
2.12.3

[PATCH v4 18/28] ARM: dts: s500-guitar-bb-rev-b: Add fake uart3 clock

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:58:55

Add a fixed-clock for baudrate 115200.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v2: new
 
 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts b/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
index 834b71df31bd..f6fd10a9cd34 100644
--- a/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
+++ b/arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
@@ -19,8 +19,15 @@
 	chosen {
 		stdout-path = "serial3:115200n8";
 	};
+
+	uart3_clk: uart3-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <921600>;
+		#clock-cells = <0>;
+	};
 };
 
 &uart3 {
 	status = "okay";
+	clocks = <&uart3_clk>;
 };
-- 
2.12.3

[PATCH v4 15/28] MAINTAINERS: Add Actions Semi Owl section

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:59:26

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v2: new
 
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index f17ffa17abef..a9faa30def9c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1036,6 +1036,16 @@ S:	Maintained
 F:	drivers/amba/
 F:	include/linux/amba/bus.h
 
+ARM/ACTIONS SEMI ARCHITECTURE
+M:	Andreas F?rber <afaerber@suse.de>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+N:	owl
+F:	arch/arm/mach-actions/
+F:	arch/arm/boot/dts/s500*
+F:	arch/arm64/boot/dts/actions/
+F:	Documentation/devicetree/bindings/arm/actions.txt
+
 ARM/ADS SPHERE MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.12.3

[PATCH v4 14/28] ARM64: dts: Add Actions Semi S900 and Bubblegum-96

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 00:59:42

UART0/1/4/6 interrupts are guesses.

Cc: 96boards at ucrobotics.com
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Adopted lower-case timer interrupt-names (Mark)
 
 v2 -> v3:
 * Added remaining UART nodes -- some interrupts are guesses
 * Added timer node -- only TIMER1 interrupt known
 
 v1 -> v2:
 * Reworded subject
 * Added memory at 0 node for Bubblegum-96 (Mark)
 * Filled in reserved-memory sub-node for Bubblegum-96 (Mark)
 * Added arm-pmu interrupt-affinity property (Mark)
 * Changed second GIC reg size 0x1000 -> 0x2000 for Bubblegum-96 (Mark)
 * Updated ARCH_OWL to ARCH_ACTIONS (Arnd)
 * Renamed s900-bubblegum96.dts to s900-bubblegum-96.dts
 * Adopted "actions" vendor prefix
 * Dropped irq.h include
 * Adopted SPDX-License-Identifier (Rob)
 
 arch/arm64/boot/dts/Makefile                      |   1 +
 arch/arm64/boot/dts/actions/Makefile              |   5 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts |  35 +++++
 arch/arm64/boot/dts/actions/s900.dtsi             | 164 ++++++++++++++++++++++
 4 files changed, 205 insertions(+)
 create mode 100644 arch/arm64/boot/dts/actions/Makefile
 create mode 100644 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
 create mode 100644 arch/arm64/boot/dts/actions/s900.dtsi
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 78f7991a5906..8e1951273fd7 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,3 +1,4 @@
+dts-dirs += actions
 dts-dirs += al
 dts-dirs += allwinner
 dts-dirs += altera
diff --git a/arch/arm64/boot/dts/actions/Makefile b/arch/arm64/boot/dts/actions/Makefile
new file mode 100644
index 000000000000..62922d688ce3
--- /dev/null
+++ b/arch/arm64/boot/dts/actions/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_ACTIONS) += s900-bubblegum-96.dtb
+
+always		:= $(dtb-y)
+subdir-y	:= $(dts-dirs)
+clean-files	:= *.dtb
diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
new file mode 100644
index 000000000000..a0c3484dbd12
--- /dev/null
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+/dts-v1/;
+
+#include "s900.dtsi"
+
+/ {
+	compatible = "ucrobotics,bubblegum-96", "actions,s900";
+	model = "Bubblegum-96";
+
+	aliases {
+		serial5 = &uart5;
+	};
+
+	chosen {
+		stdout-path = "serial5:115200n8";
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x80000000>;
+	};
+};
+
+&timer {
+	clocks = <&hosc>;
+};
+
+&uart5 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
new file mode 100644
index 000000000000..11406f6d3a6d
--- /dev/null
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "actions,s900";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		secmon at 1f000000 {
+			reg = <0x0 0x1f000000 0x0 0x1000000>;
+			no-map;
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10
+			(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	hosc: hosc {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller at e00f1000 {
+			compatible = "arm,gic-400";
+			reg = <0x0 0xe00f1000 0x0 0x1000>,
+			      <0x0 0xe00f2000 0x0 0x2000>,
+			      <0x0 0xe00f4000 0x0 0x2000>,
+			      <0x0 0xe00f6000 0x0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		uart0: serial at e0120000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe0120000 0x0 0x2000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart1: serial at e0122000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe0122000 0x0 0x2000>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart2: serial at e0124000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe0124000 0x0 0x2000>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart3: serial at e0126000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe0126000 0x0 0x2000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart4: serial at e0128000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe0128000 0x0 0x2000>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart5: serial at e012a000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe012a000 0x0 0x2000>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart6: serial at e012c000 {
+			compatible = "actions,s900-uart", "actions,owl-uart";
+			reg = <0x0 0xe012c000 0x0 0x2000>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		timer: timer at e0228000 {
+			compatible = "actions,s900-timer";
+			reg = <0x0 0xe0228000 0x0 0x8000>;
+			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "timer1";
+		};
+	};
+};
-- 
2.12.3

[PATCH v4 09/28] tty: serial: Add Actions Semi Owl UART earlycon

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:00:02

This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Adopted BIT() macro
 
 v1 -> v2:
 * Extended Kconfig help to mention earlycon (Arnd)
 * Spelled out Actions Semiconductor in Kconfig help
 * Adopted "actions" vendor prefix
 
 drivers/tty/serial/Kconfig    |  19 ++++++
 drivers/tty/serial/Makefile   |   1 +
 drivers/tty/serial/owl-uart.c | 135 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/tty/serial/owl-uart.c
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 5c8850f7a2a0..38f90ea45cf7 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1688,6 +1688,25 @@ config SERIAL_MVEBU_CONSOLE
 	  and warnings and which allows logins in single user mode)
 	  Otherwise, say 'N'.
 
+config SERIAL_OWL
+	bool "Actions Semi Owl serial port support"
+	depends on ARCH_ACTIONS || COMPILE_TEST
+	select SERIAL_CORE
+	help
+	  This driver is for Actions Semiconductor S500/S900 SoC's UART.
+	  Say 'Y' here if you wish to use the on-board serial port.
+	  Otherwise, say 'N'.
+
+config SERIAL_OWL_CONSOLE
+	bool "Console on Actions Semi Owl serial port"
+	depends on SERIAL_OWL=y
+	select SERIAL_CORE_CONSOLE
+	select SERIAL_EARLYCON
+	default y
+	help
+	  Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART
+	  as the system console. Only earlycon is implemented currently.
+
 endmenu
 
 config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 53c03e005132..fe88a75d9a59 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_SERIAL_STM32)	+= stm32-usart.o
 obj-$(CONFIG_SERIAL_MVEBU_UART)	+= mvebu-uart.o
 obj-$(CONFIG_SERIAL_PIC32)	+= pic32_uart.o
 obj-$(CONFIG_SERIAL_MPS2_UART)	+= mps2-uart.o
+obj-$(CONFIG_SERIAL_OWL)	+= owl-uart.o
 
 # GPIOLIB helpers for modem control lines
 obj-$(CONFIG_SERIAL_MCTRL_GPIO)	+= serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c
new file mode 100644
index 000000000000..1b8008797a1b
--- /dev/null
+++ b/drivers/tty/serial/owl-uart.c
@@ -0,0 +1,135 @@
+/*
+ * Actions Semi Owl family serial console
+ *
+ * Copyright 2013 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#define OWL_UART_CTL	0x000
+#define OWL_UART_TXDAT	0x008
+#define OWL_UART_STAT	0x00c
+
+#define OWL_UART_CTL_TRFS_TX		BIT(14)
+#define OWL_UART_CTL_EN			BIT(15)
+#define OWL_UART_CTL_RXIE		BIT(18)
+#define OWL_UART_CTL_TXIE		BIT(19)
+
+#define OWL_UART_STAT_RIP		BIT(0)
+#define OWL_UART_STAT_TIP		BIT(1)
+#define OWL_UART_STAT_TFFU		BIT(6)
+#define OWL_UART_STAT_TRFL_MASK		(0x1f << 11)
+#define OWL_UART_STAT_UTBB		BIT(17)
+
+static inline void owl_uart_write(struct uart_port *port, u32 val, unsigned int off)
+{
+	writel(val, port->membase + off);
+}
+
+static inline u32 owl_uart_read(struct uart_port *port, unsigned int off)
+{
+	return readl(port->membase + off);
+}
+
+#ifdef CONFIG_SERIAL_OWL_CONSOLE
+
+static void owl_console_putchar(struct uart_port *port, int ch)
+{
+	if (!port->membase)
+		return;
+
+	while (owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)
+		cpu_relax();
+
+	owl_uart_write(port, ch, OWL_UART_TXDAT);
+}
+
+static void owl_uart_port_write(struct uart_port *port, const char *s,
+				u_int count)
+{
+	u32 old_ctl, val;
+	unsigned long flags;
+	int locked;
+
+	local_irq_save(flags);
+
+	if (port->sysrq)
+		locked = 0;
+	else if (oops_in_progress)
+		locked = spin_trylock(&port->lock);
+	else {
+		spin_lock(&port->lock);
+		locked = 1;
+	}
+
+	old_ctl = owl_uart_read(port, OWL_UART_CTL);
+	val = old_ctl | OWL_UART_CTL_TRFS_TX;
+	/* disable IRQ */
+	val &= ~(OWL_UART_CTL_RXIE | OWL_UART_CTL_TXIE);
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	uart_console_write(port, s, count, owl_console_putchar);
+
+	/* wait until all contents have been sent out */
+	while (owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TRFL_MASK)
+		cpu_relax();
+
+	/* clear IRQ pending */
+	val = owl_uart_read(port, OWL_UART_STAT);
+	val |= OWL_UART_STAT_TIP | OWL_UART_STAT_RIP;
+	owl_uart_write(port, val, OWL_UART_STAT);
+
+	owl_uart_write(port, old_ctl, OWL_UART_CTL);
+
+	if (locked)
+		spin_unlock(&port->lock);
+
+	local_irq_restore(flags);
+}
+
+static void owl_uart_early_console_write(struct console *co,
+					 const char *s,
+					 u_int count)
+{
+	struct earlycon_device *dev = co->data;
+
+	owl_uart_port_write(&dev->port, s, count);
+}
+
+static int __init
+owl_uart_early_console_setup(struct earlycon_device *device, const char *opt)
+{
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->con->write = owl_uart_early_console_write;
+
+	return 0;
+}
+OF_EARLYCON_DECLARE(owl, "actions,owl-uart",
+		    owl_uart_early_console_setup);
+
+#endif /* CONFIG_SERIAL_OWL_CONSOLE */
-- 
2.12.3

[PATCH v4 08/28] dt-bindings: serial: Document Actions Semi Owl UARTs

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:00:19

This UART is found on S500 and S900 SoCs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3: unchanged
 
 v1 -> v2:
 * Adopted "actions" vendor prefix
 
 .../devicetree/bindings/serial/actions,owl-uart.txt      | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serial/actions,owl-uart.txt
diff --git a/Documentation/devicetree/bindings/serial/actions,owl-uart.txt b/Documentation/devicetree/bindings/serial/actions,owl-uart.txt
new file mode 100644
index 000000000000..aa873eada02d
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/actions,owl-uart.txt
@@ -0,0 +1,16 @@
+Actions Semi Owl UART
+
+Required properties:
+- compatible :  "actions,s500-uart", "actions,owl-uart" for S500
+                "actions,s900-uart", "actions,owl-uart" for S900
+- reg        :  Offset and length of the register set for the device.
+- interrupts :  Should contain UART interrupt.
+
+
+Example:
+
+		uart3: serial at b0126000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0126000 0x1000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		};
-- 
2.12.3

[PATCH v4 06/28] ARM: Prepare Actions Semi S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:00:41

Add ARCH_ACTIONS and mach-actions/owl.c for "actions,s500".

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Selected AMBA, global timer, TWD drivers
 * Fixed copy&paste in machine definition (Alberto)
 
 v1 -> v2:
 * Renamed ARCH_OWL to ARCH_ACTION (Arnd)
 * Renamed mach-owl to mach-actions, leaving owl.c
 * Adopted "actions" vendor prefix
 * Selected new clocksource driver
 
 arch/arm/Kconfig               |  2 ++
 arch/arm/Makefile              |  1 +
 arch/arm/mach-actions/Kconfig  | 15 +++++++++++++++
 arch/arm/mach-actions/Makefile |  1 +
 arch/arm/mach-actions/owl.c    | 28 ++++++++++++++++++++++++++++
 5 files changed, 47 insertions(+)
 create mode 100644 arch/arm/mach-actions/Kconfig
 create mode 100644 arch/arm/mach-actions/Makefile
 create mode 100644 arch/arm/mach-actions/owl.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4a5876ff38bf..763700e74030 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -712,6 +712,8 @@ config ARCH_VIRT
 #
 source "arch/arm/mach-mvebu/Kconfig"
 
+source "arch/arm/mach-actions/Kconfig"
+
 source "arch/arm/mach-alpine/Kconfig"
 
 source "arch/arm/mach-artpec/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 65f4e2a4eb94..47d3a1ab08d2 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -151,6 +151,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
 
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_ACTIONS)		+= actions
 machine-$(CONFIG_ARCH_ALPINE)		+= alpine
 machine-$(CONFIG_ARCH_ARTPEC)		+= artpec
 machine-$(CONFIG_ARCH_AT91)		+= at91
diff --git a/arch/arm/mach-actions/Kconfig b/arch/arm/mach-actions/Kconfig
new file mode 100644
index 000000000000..717adc1630a1
--- /dev/null
+++ b/arch/arm/mach-actions/Kconfig
@@ -0,0 +1,15 @@
+menuconfig ARCH_ACTIONS
+	bool "Actions Semi SoCs"
+	depends on ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select ARM_GLOBAL_TIMER
+	select CACHE_L2X0
+	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
+	select COMMON_CLK
+	select GENERIC_IRQ_CHIP
+	select HAVE_ARM_SCU if SMP
+	select HAVE_ARM_TWD if SMP
+	select OWL_TIMER
+	help
+	  This enables support for the Actions Semiconductor S500 SoC family.
diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile
new file mode 100644
index 000000000000..524c3817bcb3
--- /dev/null
+++ b/arch/arm/mach-actions/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_ACTIONS) += owl.o
diff --git a/arch/arm/mach-actions/owl.c b/arch/arm/mach-actions/owl.c
new file mode 100644
index 000000000000..4ac4a860f3d6
--- /dev/null
+++ b/arch/arm/mach-actions/owl.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+
+static const char * const owl_dt_compat[] = {
+	"actions,s500",
+	NULL
+};
+
+DT_MACHINE_START(OWL, "Actions Semi Owl platform")
+	.dt_compat	= owl_dt_compat,
+	.l2c_aux_val	= 0,
+	.l2c_aux_mask	= ~0,
+MACHINE_END
-- 
2.12.3

[PATCH v4 07/28] ARM64: Prepare Actions Semi S900

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:00:42

Add ARCH_ACTIONS.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Selected clocksource driver
 
 v1 -> v2:
 * Renamed ARCH_OWL to ARCH_ACTION (Arnd)
 
 arch/arm64/Kconfig.platforms | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 9a6f50fed239..7b0615161750 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -1,5 +1,11 @@
 menu "Platform selection"
 
+config ARCH_ACTIONS
+	bool "Actions Semi Platforms"
+	select OWL_TIMER
+	help
+	  This enables support for the Actions Semiconductor S900 SoC family.
+
 config ARCH_SUNXI
 	bool "Allwinner sunxi 64-bit SoC Family"
 	select ARCH_HAS_RESET_CONTROLLER
-- 
2.12.3

[PATCH v4 04/28] clocksource: Add Owl timer

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:01:19

The Actions Semi S500 SoC provides four timers, 2Hz0/1 and 32-bit TIMER0/1.

Use TIMER0 as clocksource and TIMER1 as clockevents.

Based on LeMaker linux-actions tree.

An S500 datasheet can be found on the LeMaker Guitar pages:
http://www.lemaker.org/product-guitar-download-29.html

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Dropped DT-dependent node iteration (Daniel)
 * Introduced owl_timer_set_enabled() (Daniel)
 * Fixed one timer reset
 
 v2 -> v3:
 * Cleared interrupt pending flag for Timer1
 * Adopted named interrupts for Timer1
 * Extended commit message (Daniel)
 * Adopted BIT() macros (Daniel)
 * Adopted PTR_ERR() (Daniel)
 * Adopted request_irq() (Daniel)
 * Factored timer reset out (Daniel)
 * Adopted CLOCK_EVT_FEAT_DYNIRQ (Daniel)
 * Adopted clk input for rate (Daniel)
 * Prepared for S900, adopting S500 DT compatible
 
 v2: new
 
 drivers/clocksource/Kconfig     |   7 ++
 drivers/clocksource/Makefile    |   1 +
 drivers/clocksource/owl-timer.c | 171 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+)
 create mode 100644 drivers/clocksource/owl-timer.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 4ba230d8e679..da3f1d926c6b 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -102,6 +102,13 @@ config ORION_TIMER
 	help
 	  Enables the support for the Orion timer driver
 
+config OWL_TIMER
+	bool "Owl timer driver" if COMPILE_TEST
+	depends on GENERIC_CLOCKEVENTS
+	select CLKSRC_MMIO
+	help
+	  Enables the support for the Actions Semi Owl timer driver.
+
 config SUN4I_TIMER
 	bool "Sun4i timer driver" if COMPILE_TEST
 	depends on GENERIC_CLOCKEVENTS
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index ec559212edf6..90309d4a719e 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_CLKSRC_PISTACHIO)	+= time-pistachio.o
 obj-$(CONFIG_CLKSRC_TI_32K)	+= timer-ti-32k.o
 obj-$(CONFIG_CLKSRC_NPS)	+= timer-nps.o
 obj-$(CONFIG_OXNAS_RPS_TIMER)	+= timer-oxnas-rps.o
+obj-$(CONFIG_OWL_TIMER)		+= owl-timer.o
 
 obj-$(CONFIG_ARC_TIMERS)		+= arc_timer.o
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
diff --git a/drivers/clocksource/owl-timer.c b/drivers/clocksource/owl-timer.c
new file mode 100644
index 000000000000..4609363a79a6
--- /dev/null
+++ b/drivers/clocksource/owl-timer.c
@@ -0,0 +1,171 @@
+/*
+ * Actions Semi Owl timer
+ *
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2017 SUSE Linux GmbH
+ * Author: Andreas F?rber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/sched_clock.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define OWL_Tx_CTL		0x0
+#define OWL_Tx_CMP		0x4
+#define OWL_Tx_VAL		0x8
+
+#define OWL_Tx_CTL_PD		BIT(0)
+#define OWL_Tx_CTL_INTEN	BIT(1)
+#define OWL_Tx_CTL_EN		BIT(2)
+
+static void __iomem *owl_timer_base;
+static void __iomem *owl_clksrc_base;
+static void __iomem *owl_clkevt_base;
+
+static inline void owl_timer_reset(void __iomem *base)
+{
+	writel(0, base + OWL_Tx_CTL);
+	writel(0, base + OWL_Tx_VAL);
+	writel(0, base + OWL_Tx_CMP);
+}
+
+static inline void owl_timer_set_enabled(void __iomem *base, bool enabled)
+{
+	u32 ctl = readl(base + OWL_Tx_CTL);
+
+	/* PD bit is cleared when set */
+	ctl &= ~OWL_Tx_CTL_PD;
+
+	if (enabled)
+		ctl |= OWL_Tx_CTL_EN;
+	else
+		ctl &= ~OWL_Tx_CTL_EN;
+
+	writel(ctl, base + OWL_Tx_CTL);
+}
+
+static u64 notrace owl_timer_sched_read(void)
+{
+	return (u64)readl(owl_clksrc_base + OWL_Tx_VAL);
+}
+
+static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
+{
+	owl_timer_set_enabled(owl_clkevt_base, false);
+
+	return 0;
+}
+
+static int owl_timer_set_state_oneshot(struct clock_event_device *evt)
+{
+	owl_timer_reset(owl_clkevt_base);
+
+	return 0;
+}
+
+static int owl_timer_tick_resume(struct clock_event_device *evt)
+{
+	return 0;
+}
+
+static int owl_timer_set_next_event(unsigned long evt,
+				    struct clock_event_device *ev)
+{
+	void __iomem *base = owl_clkevt_base;
+
+	owl_timer_set_enabled(base, false);
+	writel(OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
+	writel(0, base + OWL_Tx_VAL);
+	writel(evt, base + OWL_Tx_CMP);
+	owl_timer_set_enabled(base, true);
+
+	return 0;
+}
+
+static struct clock_event_device owl_clockevent = {
+	.name			= "owl_tick",
+	.rating			= 200,
+	.features		= CLOCK_EVT_FEAT_ONESHOT |
+				  CLOCK_EVT_FEAT_DYNIRQ,
+	.set_state_shutdown	= owl_timer_set_state_shutdown,
+	.set_state_oneshot	= owl_timer_set_state_oneshot,
+	.tick_resume		= owl_timer_tick_resume,
+	.set_next_event		= owl_timer_set_next_event,
+};
+
+static irqreturn_t owl_timer1_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+
+	writel(OWL_Tx_CTL_PD, owl_clkevt_base + OWL_Tx_CTL);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static int __init owl_timer_init(struct device_node *node)
+{
+	struct clk *clk;
+	unsigned long rate;
+	int timer1_irq, ret;
+
+	owl_timer_base = of_io_request_and_map(node, 0, "owl-timer");
+	if (IS_ERR(owl_timer_base)) {
+		pr_err("Can't map timer registers");
+		return PTR_ERR(owl_timer_base);
+	}
+
+	owl_clksrc_base = owl_timer_base + 0x08;
+	owl_clkevt_base = owl_timer_base + 0x14;
+
+	timer1_irq = of_irq_get_byname(node, "timer1");
+	if (timer1_irq <= 0) {
+		pr_err("Can't parse timer1 IRQ");
+		return -EINVAL;
+	}
+
+	clk = of_clk_get(node, 0);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	rate = clk_get_rate(clk);
+
+	owl_timer_reset(owl_clksrc_base);
+	owl_timer_set_enabled(owl_clksrc_base, true);
+
+	sched_clock_register(owl_timer_sched_read, 32, rate);
+	clocksource_mmio_init(owl_clksrc_base + OWL_Tx_VAL, node->name,
+			      rate, 200, 32, clocksource_mmio_readl_up);
+
+	owl_timer_reset(owl_clkevt_base);
+
+	ret = request_irq(timer1_irq, owl_timer1_interrupt, IRQF_TIMER,
+			  "owl-timer", &owl_clockevent);
+	if (ret) {
+		pr_err("failed to request irq %d\n", timer1_irq);
+		return ret;
+	}
+
+	owl_clockevent.cpumask = cpumask_of(0);
+	owl_clockevent.irq = timer1_irq;
+
+	clockevents_config_and_register(&owl_clockevent, rate,
+					0xf, 0xffffffff);
+
+	return 0;
+}
+CLOCKSOURCE_OF_DECLARE(owl_s500, "actions,s500-timer", owl_timer_init);
-- 
2.12.3

[PATCH v4 03/28] dt-bindings: timer: Document Owl timer

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-06 01:01:54

The Actions Semi S500 SoC contains a timer block with two 2 Hz and two
32-bit timers. The S900 SoC timer block has four 32-bit timers.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Changed interrupt names to lower-case (Mark)
 
 v2 -> v3:
 * Adopted interrupt-names
 * Changed compatible for S500
 * Added S900 compatible and interrupt names
 
 v2: new
 
 .../devicetree/bindings/timer/actions,owl-timer.txt  | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/actions,owl-timer.txt
diff --git a/Documentation/devicetree/bindings/timer/actions,owl-timer.txt b/Documentation/devicetree/bindings/timer/actions,owl-timer.txt
new file mode 100644
index 000000000000..e3c28da80cb2
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/actions,owl-timer.txt
@@ -0,0 +1,20 @@
+Actions Semi Owl Timer
+
+Required properties:
+- compatible      :  "actions,s500-timer" for S500
+                     "actions,s900-timer" for S900
+- reg             :  Offset and length of the register set for the device.
+- interrupts      :  Should contain the interrupts.
+- interrupt-names :  Valid names are: "2hz0", "2hz1",
+                                      "timer0", "timer1", "timer2", "timer3"
+                     See ../resource-names.txt
+
+Example:
+
+		timer at b0168000 {
+			compatible = "actions,s500-timer";
+			reg = <0xb0168000 0x100>;
+			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "timer0", "timer1";
+		};
-- 
2.12.3

Re: [PATCH v4 16/28] tty: serial: owl: Implement console driver

From: Alan Cox <hidden>
Date: 2017-06-06 13:35:15

+
+static void owl_uart_set_termios(struct uart_port *port,
+				 struct ktermios *termios,
+				 struct ktermios *old)
+{
+	struct owl_uart_port *owl_port = to_owl_uart_port(port);
+	unsigned int baud;
+	u32 ctl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* We don't support modem control lines. */
+	termios->c_cflag &= ~(HUPCL | CMSPAR);
+	termios->c_cflag |= CLOCAL;
CLOCAL and HUPCL are software not hardware properties so are probably
best not forced (it'll confuse some apps if you do)
+
+	/* We don't support BREAK character recognition. */
+	termios->c_iflag &= ~(IGNBRK | BRKINT);
Ditto these


You do clear CMSPAR which is right if not supported but then later on we
have:
+	if (termios->c_cflag & PARENB) {
+		if (termios->c_cflag & CMSPAR) {
+			if (termios->c_cflag & PARODD)
+				ctl |= OWL_UART_CTL_PRS_MARK;
+			else
+				ctl |= OWL_UART_CTL_PRS_SPACE;
+		} else if (termios->c_cflag & PARODD)
+			ctl |= OWL_UART_CTL_PRS_ODD;
+		else
+			ctl |= OWL_UART_CTL_PRS_EVEN;
+	} else
+		ctl |= OWL_UART_CTL_PRS_NONE;

Which seems to indicate you do support CMSPAR so shouldn't be clearing it.
+
+	if (termios->c_cflag & CRTSCTS)
+		ctl |= OWL_UART_CTL_AFE;
+	else
+		ctl &= ~OWL_UART_CTL_AFE;
+
+	owl_uart_write(port, ctl, OWL_UART_CTL);
+
+	baud = uart_get_baud_rate(port, termios, old, 9600, 3200000);
+	owl_uart_change_baudrate(owl_port, baud);
You should re-encode the resulting baud rate into the termios

        /* Don't rewrite B0 */
        if (tty_termios_baud_rate(termios))
                tty_termios_encode_baud_rate(termios, baud, baud);

Re: [PATCH v4 04/28] clocksource: Add Owl timer

From: Daniel Lezcano <hidden>
Date: 2017-06-06 16:34:03

On Tue, Jun 06, 2017 at 02:54:02AM +0200, Andreas F?rber wrote:
The Actions Semi S500 SoC provides four timers, 2Hz0/1 and 32-bit TIMER0/1.

Use TIMER0 as clocksource and TIMER1 as clockevents.

Based on LeMaker linux-actions tree.

An S500 datasheet can be found on the LeMaker Guitar pages:
http://www.lemaker.org/product-guitar-download-29.html

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
Acked-by: Daniel Lezcano <redacted>

Re: [PATCH v4 05/28] clocksource: owl: Add S900 support

From: Daniel Lezcano <hidden>
Date: 2017-06-06 16:35:01

On Tue, Jun 06, 2017 at 02:54:03AM +0200, Andreas F?rber wrote:
The Actions Semi S900 SoC provides four 32-bit timers, TIMER0/1/2/3,
but no 2Hz timers.

An S900 datasheet can be found in 96Boards documentation:
https://github.com/96boards/documentation/blob/master/ConsumerEdition/Bubblegum-96/HardwareDocs/SoC_bubblegum96.pdf

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
Acked-by: Daniel Lezcano <redacted>


-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

Re: [PATCH v4 16/28] tty: serial: owl: Implement console driver

From: Andy Shevchenko <hidden>
Date: 2017-06-07 14:38:03

On Tue, Jun 6, 2017 at 3:54 AM, Andreas F?rber [off-list ref] wrote:
Implement serial console driver to complement earlycon.

Based on LeMaker linux-actions tree.
+#define OWL_UART_CTL_DWLS_MASK         (0x3 << 0)
GENMASK() ?
+#define OWL_UART_CTL_PRS_MASK          (0x7 << 4)
Ditto.
 #define OWL_UART_STAT_TRFL_MASK                (0x1f << 11)
Ditto.
+static struct owl_uart_port *owl_uart_ports[OWL_UART_PORT_NUM];
And this is needed for...?
+static void owl_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
Do we need an empty stub?
+static void owl_uart_send_chars(struct uart_port *port)
+{
+               xmit->tail = (xmit->tail + 1) & (SERIAL_XMIT_SIZE - 1);
% SERIAL_XMIT_SIZE shorter (I hope it's a power of 2), but it's up to you.
+}
+static irqreturn_t owl_uart_irq(int irq, void *dev_id)
+{
+       struct uart_port *port = (struct uart_port *)dev_id;
Useless casting.
+       spin_lock(&port->lock);
spin_lock_irqsave() ?

Consider the kernel command option that switches all IRQ handlers to
be threaded.
+}
+static void owl_uart_change_baudrate(struct owl_uart_port *owl_port,
+                                    unsigned long baud)
+{
+       clk_set_rate(owl_port->clk, baud * 8);
+}
+static void owl_uart_release_port(struct uart_port *port)
+{
+       struct platform_device *pdev = to_platform_device(port->dev);
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return;
+
+       if (port->flags & UPF_IOREMAP) {
+               devm_release_mem_region(port->dev, port->mapbase,
+                       resource_size(res));
+               devm_iounmap(port->dev, port->membase);
+               port->membase = NULL;
+       }
Above is entirely redundant.
+}
+
+static int owl_uart_request_port(struct uart_port *port)
+{
+       struct platform_device *pdev = to_platform_device(port->dev);
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENXIO;
+
+       if (!devm_request_mem_region(port->dev, port->mapbase,
+                       resource_size(res), dev_name(port->dev)))
+               return -EBUSY;
+
+       if (port->flags & UPF_IOREMAP) {
+               port->membase = devm_ioremap_nocache(port->dev, port->mapbase,
+                               resource_size(res));
+               if (!port->membase)
+                       return -EBUSY;
+       }
+
+       return 0;
+}
+static void owl_uart_config_port(struct uart_port *port, int flags)
+{
+       if (flags & UART_CONFIG_TYPE) {
if (!(...))
 return;

?
+               port->type = PORT_OWL;
+               owl_uart_request_port(port);
+       }
+}
+static int owl_uart_probe(struct platform_device *pdev)
+{
+       struct resource *res_mem, *res_irq;
+       struct owl_uart_port *owl_port;
+       int ret;
+
+       if (pdev->dev.of_node)
+               pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
+
+       if (pdev->id < 0 || pdev->id >= OWL_UART_PORT_NUM) {
+               dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
+               return -EINVAL;
+       }
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res_mem) {
+               dev_err(&pdev->dev, "could not get mem\n");
+               return -ENODEV;
+       }
You can use

struct resource *mem;

mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
x = devm_ioremap_resource();
if (IS_ERR(x))
 return PTR_ERR(x);

and remote IOREMAP flag below.
+       res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res_irq) {
+               dev_err(&pdev->dev, "could not get irq\n");
+               return -ENODEV;
+       }
platform_get_irq()
+       if (owl_uart_ports[pdev->id]) {
+               dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
+               return -EBUSY;
+       }
I guess it's redundant. It should be conflicting by resource (for example, IRQ).
+       owl_port->clk = clk_get(&pdev->dev, NULL);
devm_ ?
+       owl_port->port.iotype = UPIO_MEM;
+       owl_port->port.mapbase = res_mem->start;
+       owl_port->port.irq = res_irq->start;
+       owl_port->port.uartclk = clk_get_rate(owl_port->clk);
You need to check if it's 0 and use device property instead or bail out.
+       owl_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY;
+       owl_port->port.x_char = 0;
+       owl_port->port.fifosize = 16;
+       owl_port->port.ops = &owl_uart_ops;
+
+       owl_uart_ports[pdev->id] = owl_port;
+       platform_set_drvdata(pdev, owl_port);
It should be just before return 0, right?..
+
+       ret = uart_add_one_port(&owl_uart_driver, &owl_port->port);
+       if (ret)
+               owl_uart_ports[pdev->id] = NULL;
...and thus, taking into consideration redundancy of that global var:

      ret = uart_add_one_port(&owl_uart_driver, &owl_port->port);
      if (ret)
          retrun ret;

      platform_set_drvdata(pdev, owl_port);
      return 0;
+       return ret;
+}
+
+static int owl_uart_remove(struct platform_device *pdev)
+{
+       struct owl_uart_port *owl_port;
+
+       owl_port = platform_get_drvdata(pdev);
Do above in one line.
+       uart_remove_one_port(&owl_uart_driver, &owl_port->port);
+       owl_uart_ports[pdev->id] = NULL;
Redundant.
+
+       return 0;
+}
+/* Actions Semi Owl UART */
+#define PORT_OWL       117
We can use holes for now IIUC.

See 36 or alike

-- 
With Best Regards,
Andy Shevchenko

Re: [PATCH v4 07/28] ARM64: Prepare Actions Semi S900

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-11 13:04:26

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Add ARCH_ACTIONS.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Selected clocksource driver
 
 v1 -> v2:
 * Renamed ARCH_OWL to ARCH_ACTION (Arnd)
 
 arch/arm64/Kconfig.platforms | 6 ++++++
 1 file changed, 6 insertions(+)
To make a start somewhere, given Daniel's ack for OWL_TIMER, I'm
applying this to my new linux-actions.git v4.13/arm64 branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/arm64

For arm I'm still giving Actions Semi a final chance to comment on the
vendor prefix and DT bindings (none on v3 and none for a week for v4).

Regards,
Andreas
quoted hunk
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 9a6f50fed239..7b0615161750 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -1,5 +1,11 @@
 menu "Platform selection"
 
+config ARCH_ACTIONS
+	bool "Actions Semi Platforms"
+	select OWL_TIMER
+	help
+	  This enables support for the Actions Semiconductor S900 SoC family.
+
 config ARCH_SUNXI
 	bool "Allwinner sunxi 64-bit SoC Family"
 	select ARCH_HAS_RESET_CONTROLLER
-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 01/28] dt-bindings: Add vendor prefix for Actions Semi

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 18:46:41

Am 06.06.2017 um 02:53 schrieb Andreas F?rber:
Actions Semiconductor was listed on NASDAQ as ACTS until Dec 16, 2016.

Cc: mp-cs at actions-semi.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Fixed sort order after rename
 
 v1 -> v2:
 * Reverted from "acts" to "actions" (cf. IAP140 "mrvl" vs. "marvell")
 
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)
With still no Acked-by or other reply from Actions, I have now applied
this patch to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 02/28] dt-bindings: arm: Document Actions Semi S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 18:48:07

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
The Actions Semi S500 is a quad-core ARM Cortex-A9 SoC.
The LeMaker Guitar is an SODIMM-format module with that SoC.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v1 -> v2:
 * Adopted "actions" vendor prefix
 * Extended text
 
 Documentation/devicetree/bindings/arm/actions.txt | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/actions.txt
Thanks, applied:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 03/28] dt-bindings: timer: Document Owl timer

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 20:18:46

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
The Actions Semi S500 SoC contains a timer block with two 2 Hz and two
32-bit timers. The S900 SoC timer block has four 32-bit timers.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Changed interrupt names to lower-case (Mark)
 
 v2 -> v3:
 * Adopted interrupt-names
 * Changed compatible for S500
 * Added S900 compatible and interrupt names
 
 v2: new
 
 .../devicetree/bindings/timer/actions,owl-timer.txt  | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/actions,owl-timer.txt
Thanks, applied to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 04/28] clocksource: Add Owl timer

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 20:43:59

Am 06.06.2017 um 18:33 schrieb Daniel Lezcano:
On Tue, Jun 06, 2017 at 02:54:02AM +0200, Andreas F?rber wrote:
quoted
The Actions Semi S500 SoC provides four timers, 2Hz0/1 and 32-bit TIMER0/1.

Use TIMER0 as clocksource and TIMER1 as clockevents.

Based on LeMaker linux-actions tree.

An S500 datasheet can be found on the LeMaker Guitar pages:
http://www.lemaker.org/product-guitar-download-29.html

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
Acked-by: Daniel Lezcano <redacted>
Thanks. It seems this is not going through a central clocksource tree,
so I'm applying it to a new linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Let me know if you intend to take it through some other tree instead.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 05/28] clocksource: owl: Add S900 support

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 20:50:47

Am 06.06.2017 um 18:34 schrieb Daniel Lezcano:
On Tue, Jun 06, 2017 at 02:54:03AM +0200, Andreas F?rber wrote:
quoted
The Actions Semi S900 SoC provides four 32-bit timers, TIMER0/1/2/3,
but no 2Hz timers.

An S900 datasheet can be found in 96Boards documentation:
https://github.com/96boards/documentation/blob/master/ConsumerEdition/Bubblegum-96/HardwareDocs/SoC_bubblegum96.pdf

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
Acked-by: Daniel Lezcano <redacted>
Thanks, applied to linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 06/28] ARM: Prepare Actions Semi S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 21:21:13

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Add ARCH_ACTIONS and mach-actions/owl.c for "actions,s500".

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Selected AMBA, global timer, TWD drivers
 * Fixed copy&paste in machine definition (Alberto)
 
 v1 -> v2:
 * Renamed ARCH_OWL to ARCH_ACTION (Arnd)
 * Renamed mach-owl to mach-actions, leaving owl.c
 * Adopted "actions" vendor prefix
 * Selected new clocksource driver
 
 arch/arm/Kconfig               |  2 ++
 arch/arm/Makefile              |  1 +
 arch/arm/mach-actions/Kconfig  | 15 +++++++++++++++
 arch/arm/mach-actions/Makefile |  1 +
 arch/arm/mach-actions/owl.c    | 28 ++++++++++++++++++++++++++++
 5 files changed, 47 insertions(+)
 create mode 100644 arch/arm/mach-actions/Kconfig
 create mode 100644 arch/arm/mach-actions/Makefile
 create mode 100644 arch/arm/mach-actions/owl.c
Applied to linux-actions.git v4.13/arm branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/arm

There have been no more comments - I believe we could simplify it with a
Makefile hack as seen in mach-uniphier, but since no one asked for
dropping owl.c in 4 patch revisions, I'll consider that as follow-up.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 09/28] tty: serial: Add Actions Semi Owl UART earlycon

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 21:45:33

Greg,

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Adopted BIT() macro
 
 v1 -> v2:
 * Extended Kconfig help to mention earlycon (Arnd)
 * Spelled out Actions Semiconductor in Kconfig help
 * Adopted "actions" vendor prefix
 
 drivers/tty/serial/Kconfig    |  19 ++++++
 drivers/tty/serial/Makefile   |   1 +
 drivers/tty/serial/owl-uart.c | 135 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/tty/serial/owl-uart.c
The DT vendor prefix is applied to my linux-actions.git tree now, and
the serial binding has been ack'ed by Rob.

Is there anything keeping you from adding this patch, the preceding DT
binding (08/28) and the following documentation patch (10/28) to your
tree for 4.13?

The full serial driver (16/28) needs another spin and may miss 4.13, but
earlycon would prove the rest is working.

Thanks,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 11/28] ARM: dts: Add Actions Semi S500 and LeMaker Guitar

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 22:10:09

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Adopted lower-case timer interrupt-names (Mark)
 
 v2 -> v3:
 * Fixed uart2 reg offset
 * Enlarged timer reg size
 * Added 2 Hz timer interrupts, interrupt-names
 * Disabled CPUs 1-3 for now (cf. later patches)
 * Added Cortex-A9 SCU, global timer, TWD timer/wdt nodes
 * Added HOSC clock for timer
 
 v1 -> v2:
 * Reworded subject
 * Updated ARCH_OWL to ARCH_ACTIONS (Arnd)
 * Adopted "actions" vendor prefix
 * Dropped irq.h include
 * Added memory at 0 node for Guitar SoM
 * Dropped bogus uart3 clock-frequency
 * Added device_type for CPU nodes
 * Fixed UART reg size
 * Adopted SPDX-License-Identifier (Rob)
 * Added remaining UART nodes
 * Added timer node
 
 arch/arm/boot/dts/Makefile                 |   2 +
 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts |  26 +++++
 arch/arm/boot/dts/s500-guitar.dtsi         |  22 ++++
 arch/arm/boot/dts/s500.dtsi                | 176 +++++++++++++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 arch/arm/boot/dts/s500-guitar-bb-rev-b.dts
 create mode 100644 arch/arm/boot/dts/s500-guitar.dtsi
 create mode 100644 arch/arm/boot/dts/s500.dtsi
Following a previous discussion with Thomas (that Actions unfortunately
didn't follow-up to with replies here...), I am planning to respin with
s500*.dts[i] renamed to owl-s500*. That will avoid name clashes and will
future-proof the file pattern in MAINTAINERS.

For S900 I don't think we need owl-, as we have actions/* there.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 12/28] dt-bindings: Add vendor prefix for uCRobotics

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 22:19:49

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Cc: 96boards at ucrobotics.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v1 -> v2 -> v3 -> v4: unchanged
 
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)
Still no response from uCRobotics on how exactly to write their company
name here, so applying as is to linux-actions.git v4.13/dt64 branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt64

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 13/28] dt-bindings: arm: Document Actions Semi S900

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 22:29:31

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
The Actions Semi S900 is a quad-core ARM Cortex-A53 SoC.
The Bubblegum-96 is a 96Boards Consumer Edition compliant board (4/96).

Cc: 96boards at ucrobotics.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v1 -> v2:
 * Adopted "actions" vendor prefix
 * Extended text
 
 Documentation/devicetree/bindings/arm/actions.txt | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
Still no comments from uCRobotics received...

Due to S500 dependency applying to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Let me know if we need a topic branch for dt+dt64 instead.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 14/28] ARM64: dts: Add Actions Semi S900 and Bubblegum-96

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 22:40:25

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
UART0/1/4/6 interrupts are guesses.

Cc: 96boards at ucrobotics.com
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Adopted lower-case timer interrupt-names (Mark)
 
 v2 -> v3:
 * Added remaining UART nodes -- some interrupts are guesses
 * Added timer node -- only TIMER1 interrupt known
 
 v1 -> v2:
 * Reworded subject
 * Added memory at 0 node for Bubblegum-96 (Mark)
 * Filled in reserved-memory sub-node for Bubblegum-96 (Mark)
 * Added arm-pmu interrupt-affinity property (Mark)
 * Changed second GIC reg size 0x1000 -> 0x2000 for Bubblegum-96 (Mark)
 * Updated ARCH_OWL to ARCH_ACTIONS (Arnd)
 * Renamed s900-bubblegum96.dts to s900-bubblegum-96.dts
 * Adopted "actions" vendor prefix
 * Dropped irq.h include
 * Adopted SPDX-License-Identifier (Rob)
 
 arch/arm64/boot/dts/Makefile                      |   1 +
 arch/arm64/boot/dts/actions/Makefile              |   5 +
 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts |  35 +++++
 arch/arm64/boot/dts/actions/s900.dtsi             | 164 ++++++++++++++++++++++
 4 files changed, 205 insertions(+)
 create mode 100644 arch/arm64/boot/dts/actions/Makefile
 create mode 100644 arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
 create mode 100644 arch/arm64/boot/dts/actions/s900.dtsi
Applying (with extended commit message) to linux-actions.git v4.13/dt64:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt64

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 15/28] MAINTAINERS: Add Actions Semi Owl section

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-18 22:49:24

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
quoted hunk
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4: unchanged
 
 v2: new
 
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index f17ffa17abef..a9faa30def9c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1036,6 +1036,16 @@ S:	Maintained
 F:	drivers/amba/
 F:	include/linux/amba/bus.h
 
+ARM/ACTIONS SEMI ARCHITECTURE
+M:	Andreas F?rber <afaerber@suse.de>> +L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+N:	owl
+F:	arch/arm/mach-actions/
+F:	arch/arm/boot/dts/s500*
This will need to be updated for owl-s500*
+F:	arch/arm64/boot/dts/actions/
+F:	Documentation/devicetree/bindings/arm/actions.txt
This is lacking the two clocksource files.
+
 ARM/ADS SPHERE MACHINE SUPPORT
 M:	Lennert Buytenhek [off-list ref]
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

[PATCH v5 10/27] ARM: dts: Add Actions Semi S500 and LeMaker Guitar

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 01:08:39

Add Device Trees for Actions Semiconductor S500 SoC and LeMaker Guitar SoM
and base board.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Renamed files from s500* to owl-s500*

 v3 -> v4:
 * Adopted lower-case timer interrupt-names (Mark)
 
 v2 -> v3:
 * Fixed uart2 reg offset
 * Enlarged timer reg size
 * Added 2 Hz timer interrupts, interrupt-names
 * Disabled CPUs 1-3 for now (cf. later patches)
 * Added Cortex-A9 SCU, global timer, TWD timer/wdt nodes
 * Added HOSC clock for timer
 
 v1 -> v2:
 * Reworded subject
 * Updated ARCH_OWL to ARCH_ACTIONS (Arnd)
 * Adopted "actions" vendor prefix
 * Dropped irq.h include
 * Added memory at 0 node for Guitar SoM
 * Dropped bogus uart3 clock-frequency
 * Added device_type for CPU nodes
 * Fixed UART reg size
 * Adopted SPDX-License-Identifier (Rob)
 * Added remaining UART nodes
 * Added timer node
 
 arch/arm/boot/dts/Makefile                     |   2 +
 arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts |  26 ++++
 arch/arm/boot/dts/owl-s500-guitar.dtsi         |  22 ++++
 arch/arm/boot/dts/owl-s500.dtsi                | 176 +++++++++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts
 create mode 100644 arch/arm/boot/dts/owl-s500-guitar.dtsi
 create mode 100644 arch/arm/boot/dts/owl-s500.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e81d87db22cc..ff9671c27fc8 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -669,6 +669,8 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
 	orion5x-maxtor-shared-storage-2.dtb \
 	orion5x-netgear-wnr854t.dtb \
 	orion5x-rd88f5182-nas.dtb
+dtb-$(CONFIG_ARCH_ACTIONS) += \
+	owl-s500-guitar-bb-rev-b.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += \
 	prima2-evb.dtb
 dtb-$(CONFIG_ARCH_OXNAS) += \
diff --git a/arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts b/arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts
new file mode 100644
index 000000000000..521463d4cac6
--- /dev/null
+++ b/arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+/dts-v1/;
+
+#include "owl-s500-guitar.dtsi"
+
+/ {
+	compatible = "lemaker,guitar-bb-rev-b", "lemaker,guitar", "actions,s500";
+	model = "LeMaker Guitar Base Board rev. B";
+
+	aliases {
+		serial3 = &uart3;
+	};
+
+	chosen {
+		stdout-path = "serial3:115200n8";
+	};
+};
+
+&uart3 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/owl-s500-guitar.dtsi b/arch/arm/boot/dts/owl-s500-guitar.dtsi
new file mode 100644
index 000000000000..079b2c02cc13
--- /dev/null
+++ b/arch/arm/boot/dts/owl-s500-guitar.dtsi
@@ -0,0 +1,22 @@
+/*
+ * LeMaker Guitar SoM
+ *
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include "owl-s500.dtsi"
+
+/ {
+	compatible = "lemaker,guitar", "actions,s500";
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&timer {
+	clocks = <&hosc>;
+};
diff --git a/arch/arm/boot/dts/owl-s500.dtsi b/arch/arm/boot/dts/owl-s500.dtsi
new file mode 100644
index 000000000000..fc9f71a4106a
--- /dev/null
+++ b/arch/arm/boot/dts/owl-s500.dtsi
@@ -0,0 +1,176 @@
+/*
+ * Actions Semi S500 SoC
+ *
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "actions,s500";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+	};
+
+	chosen {
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x0>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x1>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x2>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x3>;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a9-pmu";
+		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+		             <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	hosc: hosc {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		scu: scu at b0020000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0xb0020000 0x100>;
+		};
+
+		global_timer: timer at b0020200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0xb0020200 0x100>;
+			interrupts = <GIC_PPI 0 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+			status = "disabled";
+		};
+
+		twd_timer: timer at b0020600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0xb0020600 0x20>;
+			interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+			status = "disabled";
+		};
+
+		twd_wdt: wdt at b0020620 {
+			compatible = "arm,cortex-a9-twd-wdt";
+			reg = <0xb0020620 0xe0>;
+			interrupts = <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+			status = "disabled";
+		};
+
+		gic: interrupt-controller at b0021000 {
+			compatible = "arm,cortex-a9-gic";
+			reg = <0xb0021000 0x1000>,
+			      <0xb0020100 0x0100>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		l2: cache-controller at b0022000 {
+			compatible = "arm,pl310-cache";
+			reg = <0xb0022000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			arm,tag-latency = <3 3 2>;
+			arm,data-latency = <5 3 3>;
+		};
+
+		uart0: serial at b0120000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0120000 0x2000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart1: serial at b0122000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0122000 0x2000>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart2: serial at b0124000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0124000 0x2000>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart3: serial at b0126000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0126000 0x2000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart4: serial at b0128000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0128000 0x2000>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart5: serial at b012a000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb012a000 0x2000>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart6: serial at b012c000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb012c000 0x2000>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		timer: timer at b0168000 {
+			compatible = "actions,s500-timer";
+			reg = <0xb0168000 0x8000>;
+			interrupts = <GIC_SPI  8 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+			             <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "2hz0", "2hz1", "timer0", "timer1";
+		};
+	};
+};
-- 
2.12.3

Re: [PATCH v4 09/28] tty: serial: Add Actions Semi Owl UART earlycon

From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: 2017-06-19 01:16:48

On Sun, Jun 18, 2017 at 11:45:28PM +0200, Andreas F?rber wrote:
Greg,

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
quoted
This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Adopted BIT() macro
 
 v1 -> v2:
 * Extended Kconfig help to mention earlycon (Arnd)
 * Spelled out Actions Semiconductor in Kconfig help
 * Adopted "actions" vendor prefix
 
 drivers/tty/serial/Kconfig    |  19 ++++++
 drivers/tty/serial/Makefile   |   1 +
 drivers/tty/serial/owl-uart.c | 135 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/tty/serial/owl-uart.c
The DT vendor prefix is applied to my linux-actions.git tree now, and
the serial binding has been ack'ed by Rob.

Is there anything keeping you from adding this patch, the preceding DT
binding (08/28) and the following documentation patch (10/28) to your
tree for 4.13?
Yeah, I don't have it in my queue anymore :)

Can you resend it just as a single patch?

thanks,

greg k-h

Re: [PATCH v4 09/28] tty: serial: Add Actions Semi Owl UART earlycon

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 01:24:52

Am 19.06.2017 um 03:16 schrieb Greg Kroah-Hartman:
On Sun, Jun 18, 2017 at 11:45:28PM +0200, Andreas F?rber wrote:
quoted
Greg,

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
quoted
This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
The DT vendor prefix is applied to my linux-actions.git tree now, and
the serial binding has been ack'ed by Rob.

Is there anything keeping you from adding this patch, the preceding DT
binding (08/28) and the following documentation patch (10/28) to your
tree for 4.13?
Yeah, I don't have it in my queue anymore :)

Can you resend it just as a single patch?
Do you mean squash the documentation into this tty patch? As you wish.
But the DT binding is supposed to be a separate patch - I can queue it
in my tree if you prefer.

Cheers,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

[PATCH v5 07/26] dt-bindings: serial: Document Actions Semi Owl UARTs

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 01:46:55

This UART is found on S500 and S900 SoCs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v2 -> v3 -> v4 -> v5: Unchanged
 
 v1 -> v2:
 * Adopted "actions" vendor prefix
 
 .../devicetree/bindings/serial/actions,owl-uart.txt      | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serial/actions,owl-uart.txt
diff --git a/Documentation/devicetree/bindings/serial/actions,owl-uart.txt b/Documentation/devicetree/bindings/serial/actions,owl-uart.txt
new file mode 100644
index 000000000000..aa873eada02d
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/actions,owl-uart.txt
@@ -0,0 +1,16 @@
+Actions Semi Owl UART
+
+Required properties:
+- compatible :  "actions,s500-uart", "actions,owl-uart" for S500
+                "actions,s900-uart", "actions,owl-uart" for S900
+- reg        :  Offset and length of the register set for the device.
+- interrupts :  Should contain UART interrupt.
+
+
+Example:
+
+		uart3: serial at b0126000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0126000 0x1000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		};
-- 
2.12.3

[PATCH v5 08/26] tty: serial: Add Actions Semi Owl UART earlycon

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 01:46:59

This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Squashed documentation (Greg)
 
 v3 -> v4: Unchanged
 
 v2 -> v3:
 * Adopted BIT() macro
 
 v1 -> v2:
 * Extended Kconfig help to mention earlycon (Arnd)
 * Spelled out Actions Semiconductor in Kconfig help
 * Adopted "actions" vendor prefix
 
 Documentation/admin-guide/kernel-parameters.txt |   6 ++
 drivers/tty/serial/Kconfig                      |  19 ++++
 drivers/tty/serial/Makefile                     |   1 +
 drivers/tty/serial/owl-uart.c                   | 135 ++++++++++++++++++++++++
 4 files changed, 161 insertions(+)
 create mode 100644 drivers/tty/serial/owl-uart.c
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index fb311bdccb7b..cc8a6bfcb299 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -961,6 +961,12 @@
 			must already be setup and configured. Options are not
 			yet supported.
 
+		owl,<addr>
+			Start an early, polled-mode console on a serial port
+			of an Actions Semi SoC, such as S500 or S900, at the
+			specified address. The serial port must already be
+			setup and configured. Options are not yet supported.
+
 		smh	Use ARM semihosting calls for early console.
 
 		s3c2410,<addr>
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 07812a7ea2a4..1f096e2bb398 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1688,6 +1688,25 @@ config SERIAL_MVEBU_CONSOLE
 	  and warnings and which allows logins in single user mode)
 	  Otherwise, say 'N'.
 
+config SERIAL_OWL
+	bool "Actions Semi Owl serial port support"
+	depends on ARCH_ACTIONS || COMPILE_TEST
+	select SERIAL_CORE
+	help
+	  This driver is for Actions Semiconductor S500/S900 SoC's UART.
+	  Say 'Y' here if you wish to use the on-board serial port.
+	  Otherwise, say 'N'.
+
+config SERIAL_OWL_CONSOLE
+	bool "Console on Actions Semi Owl serial port"
+	depends on SERIAL_OWL=y
+	select SERIAL_CORE_CONSOLE
+	select SERIAL_EARLYCON
+	default y
+	help
+	  Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART
+	  as the system console. Only earlycon is implemented currently.
+
 endmenu
 
 config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 53c03e005132..fe88a75d9a59 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_SERIAL_STM32)	+= stm32-usart.o
 obj-$(CONFIG_SERIAL_MVEBU_UART)	+= mvebu-uart.o
 obj-$(CONFIG_SERIAL_PIC32)	+= pic32_uart.o
 obj-$(CONFIG_SERIAL_MPS2_UART)	+= mps2-uart.o
+obj-$(CONFIG_SERIAL_OWL)	+= owl-uart.o
 
 # GPIOLIB helpers for modem control lines
 obj-$(CONFIG_SERIAL_MCTRL_GPIO)	+= serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c
new file mode 100644
index 000000000000..1b8008797a1b
--- /dev/null
+++ b/drivers/tty/serial/owl-uart.c
@@ -0,0 +1,135 @@
+/*
+ * Actions Semi Owl family serial console
+ *
+ * Copyright 2013 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2016-2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#define OWL_UART_CTL	0x000
+#define OWL_UART_TXDAT	0x008
+#define OWL_UART_STAT	0x00c
+
+#define OWL_UART_CTL_TRFS_TX		BIT(14)
+#define OWL_UART_CTL_EN			BIT(15)
+#define OWL_UART_CTL_RXIE		BIT(18)
+#define OWL_UART_CTL_TXIE		BIT(19)
+
+#define OWL_UART_STAT_RIP		BIT(0)
+#define OWL_UART_STAT_TIP		BIT(1)
+#define OWL_UART_STAT_TFFU		BIT(6)
+#define OWL_UART_STAT_TRFL_MASK		(0x1f << 11)
+#define OWL_UART_STAT_UTBB		BIT(17)
+
+static inline void owl_uart_write(struct uart_port *port, u32 val, unsigned int off)
+{
+	writel(val, port->membase + off);
+}
+
+static inline u32 owl_uart_read(struct uart_port *port, unsigned int off)
+{
+	return readl(port->membase + off);
+}
+
+#ifdef CONFIG_SERIAL_OWL_CONSOLE
+
+static void owl_console_putchar(struct uart_port *port, int ch)
+{
+	if (!port->membase)
+		return;
+
+	while (owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)
+		cpu_relax();
+
+	owl_uart_write(port, ch, OWL_UART_TXDAT);
+}
+
+static void owl_uart_port_write(struct uart_port *port, const char *s,
+				u_int count)
+{
+	u32 old_ctl, val;
+	unsigned long flags;
+	int locked;
+
+	local_irq_save(flags);
+
+	if (port->sysrq)
+		locked = 0;
+	else if (oops_in_progress)
+		locked = spin_trylock(&port->lock);
+	else {
+		spin_lock(&port->lock);
+		locked = 1;
+	}
+
+	old_ctl = owl_uart_read(port, OWL_UART_CTL);
+	val = old_ctl | OWL_UART_CTL_TRFS_TX;
+	/* disable IRQ */
+	val &= ~(OWL_UART_CTL_RXIE | OWL_UART_CTL_TXIE);
+	owl_uart_write(port, val, OWL_UART_CTL);
+
+	uart_console_write(port, s, count, owl_console_putchar);
+
+	/* wait until all contents have been sent out */
+	while (owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TRFL_MASK)
+		cpu_relax();
+
+	/* clear IRQ pending */
+	val = owl_uart_read(port, OWL_UART_STAT);
+	val |= OWL_UART_STAT_TIP | OWL_UART_STAT_RIP;
+	owl_uart_write(port, val, OWL_UART_STAT);
+
+	owl_uart_write(port, old_ctl, OWL_UART_CTL);
+
+	if (locked)
+		spin_unlock(&port->lock);
+
+	local_irq_restore(flags);
+}
+
+static void owl_uart_early_console_write(struct console *co,
+					 const char *s,
+					 u_int count)
+{
+	struct earlycon_device *dev = co->data;
+
+	owl_uart_port_write(&dev->port, s, count);
+}
+
+static int __init
+owl_uart_early_console_setup(struct earlycon_device *device, const char *opt)
+{
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->con->write = owl_uart_early_console_write;
+
+	return 0;
+}
+OF_EARLYCON_DECLARE(owl, "actions,owl-uart",
+		    owl_uart_early_console_setup);
+
+#endif /* CONFIG_SERIAL_OWL_CONSOLE */
-- 
2.12.3

Re: [PATCH v5 10/27] ARM: dts: Add Actions Semi S500 and LeMaker Guitar

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 02:01:56

Am 19.06.2017 um 03:08 schrieb Andreas F?rber:
Add Device Trees for Actions Semiconductor S500 SoC and LeMaker Guitar SoM
and base board.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Renamed files from s500* to owl-s500*

 v3 -> v4:
 * Adopted lower-case timer interrupt-names (Mark)
 
 v2 -> v3:
 * Fixed uart2 reg offset
 * Enlarged timer reg size
 * Added 2 Hz timer interrupts, interrupt-names
 * Disabled CPUs 1-3 for now (cf. later patches)
 * Added Cortex-A9 SCU, global timer, TWD timer/wdt nodes
 * Added HOSC clock for timer
 
 v1 -> v2:
 * Reworded subject
 * Updated ARCH_OWL to ARCH_ACTIONS (Arnd)
 * Adopted "actions" vendor prefix
 * Dropped irq.h include
 * Added memory at 0 node for Guitar SoM
 * Dropped bogus uart3 clock-frequency
 * Added device_type for CPU nodes
 * Fixed UART reg size
 * Adopted SPDX-License-Identifier (Rob)
 * Added remaining UART nodes
 * Added timer node
 
 arch/arm/boot/dts/Makefile                     |   2 +
 arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts |  26 ++++
 arch/arm/boot/dts/owl-s500-guitar.dtsi         |  22 ++++
 arch/arm/boot/dts/owl-s500.dtsi                | 176 +++++++++++++++++++++++++
 4 files changed, 226 insertions(+)
 create mode 100644 arch/arm/boot/dts/owl-s500-guitar-bb-rev-b.dts
 create mode 100644 arch/arm/boot/dts/owl-s500-guitar.dtsi
 create mode 100644 arch/arm/boot/dts/owl-s500.dtsi
Applying to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 19/28] dt-bindings: arm: cpus: Add S500 enable-method

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 02:09:05

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
The Actions Semi S500 SoC requires a special secondary CPU boot procedure.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)
Thanks, applied to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 21/28] ARM: dts: s500: Set CPU enable-method

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 02:09:53

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Use a custom S500 enable-method for all CPUs.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 arch/arm/boot/dts/s500.dtsi | 4 ++++
 1 file changed, 4 insertions(+)
Applied to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 02:11:16

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged
 
 v3: new
 
 arch/arm/mach-actions/Makefile  |   3 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 237 insertions(+)
 create mode 100644 arch/arm/mach-actions/headsmp.S
 create mode 100644 arch/arm/mach-actions/platsmp.c
Applied to linux-actions.git v4.13/arm branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/arm

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 09/28] tty: serial: Add Actions Semi Owl UART earlycon

From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Date: 2017-06-19 02:12:48

On Mon, Jun 19, 2017 at 03:24:44AM +0200, Andreas F?rber wrote:
Am 19.06.2017 um 03:16 schrieb Greg Kroah-Hartman:
quoted
On Sun, Jun 18, 2017 at 11:45:28PM +0200, Andreas F?rber wrote:
quoted
Greg,

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
quoted
This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
The DT vendor prefix is applied to my linux-actions.git tree now, and
the serial binding has been ack'ed by Rob.

Is there anything keeping you from adding this patch, the preceding DT
binding (08/28) and the following documentation patch (10/28) to your
tree for 4.13?
Yeah, I don't have it in my queue anymore :)

Can you resend it just as a single patch?
Do you mean squash the documentation into this tty patch? As you wish.
But the DT binding is supposed to be a separate patch - I can queue it
in my tree if you prefer.
No, just send me what ever you want me to apply to my tree.  If you want
me to pick some random patch out of the middle of a series, um, that's a
bit hard for me to know what to do, right?

Make it very very obvious please :)

thanks,

greg k-h

Re: [PATCH v4 09/28] tty: serial: Add Actions Semi Owl UART earlycon

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 02:26:43

Am 19.06.2017 um 04:12 schrieb Greg Kroah-Hartman:
On Mon, Jun 19, 2017 at 03:24:44AM +0200, Andreas F?rber wrote:
quoted
Am 19.06.2017 um 03:16 schrieb Greg Kroah-Hartman:
quoted
On Sun, Jun 18, 2017 at 11:45:28PM +0200, Andreas F?rber wrote:
quoted
Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
quoted
This implements an earlycon for Actions Semi S500/S900 SoCs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
The DT vendor prefix is applied to my linux-actions.git tree now, and
the serial binding has been ack'ed by Rob.

Is there anything keeping you from adding this patch, the preceding DT
binding (08/28) and the following documentation patch (10/28) to your
tree for 4.13?
Yeah, I don't have it in my queue anymore :)

Can you resend it just as a single patch?
Do you mean squash the documentation into this tty patch? As you wish.
But the DT binding is supposed to be a separate patch - I can queue it
in my tree if you prefer.
No, just send me what ever you want me to apply to my tree.  If you want
me to pick some random patch out of the middle of a series, um, that's a
bit hard for me to know what to do, right?
Well, I thought that would be obvious from subject, diff stat and CC...
Only dependencies were ARCH_ACTIONS and actions vendor prefix, which
should be in linux-next by tomorrow.
Make it very very obvious please :)
I already resent the now two patches as v5 with you as only To.

Thanks,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

[PATCH v5 13/26] MAINTAINERS: Add Actions Semi Owl section

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 02:44:52

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Updated arm dts file pattern
 * Added clocksource file patterns
 
 v2 -> v3 -> v4: unchanged
 
 v2: new
 
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d56524402f36..831bfd5cc68b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1036,6 +1036,18 @@ S:	Maintained
 F:	drivers/amba/
 F:	include/linux/amba/bus.h
 
+ARM/ACTIONS SEMI ARCHITECTURE
+M:	Andreas F?rber <afaerber@suse.de>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+N:	owl
+F:	arch/arm/mach-actions/
+F:	arch/arm/boot/dts/owl-*
+F:	arch/arm64/boot/dts/actions/
+F:	drivers/clocksource/owl-*
+F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
+
 ARM/ADS SPHERE MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.12.3

[PATCH v5 20/26] dt-bindings: power: Add Owl SPS power domains

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 03:37:33

Define power domains for all non-reserved S500 power gates.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Renamed header file with owl- prefix for uniqueness
 
 v3 -> v4: Unchanged
 
 v3: new
 
 .../devicetree/bindings/power/actions,owl-sps.txt     | 17 +++++++++++++++++
 include/dt-bindings/power/owl-s500-powergate.h        | 19 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.txt
 create mode 100644 include/dt-bindings/power/owl-s500-powergate.h
diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt
new file mode 100644
index 000000000000..007b9a7ae723
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/actions,owl-sps.txt
@@ -0,0 +1,17 @@
+Actions Semi Owl Smart Power System (SPS)
+
+Required properties:
+- compatible          :  "actions,s500-sps" for S500
+- reg                 :  Offset and length of the register set for the device.
+- #power-domain-cells :  Must be 1.
+                         See macros in:
+                          include/dt-bindings/power/owl-s500-powergate.h for S500
+
+
+Example:
+
+		sps: power-controller at b01b0100 {
+			compatible = "actions,s500-sps";
+			reg = <0xb01b0100 0x100>;
+			#power-domain-cells = <1>;
+		};
diff --git a/include/dt-bindings/power/owl-s500-powergate.h b/include/dt-bindings/power/owl-s500-powergate.h
new file mode 100644
index 000000000000..0a1c451865ea
--- /dev/null
+++ b/include/dt-bindings/power/owl-s500-powergate.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+#ifndef DT_BINDINGS_POWER_OWL_S500_POWERGATE_H
+#define DT_BINDINGS_POWER_OWL_S500_POWERGATE_H
+
+#define S500_PD_VDE	0
+#define S500_PD_VCE_SI	1
+#define S500_PD_USB2_1	2
+#define S500_PD_CPU2	3
+#define S500_PD_CPU3	4
+#define S500_PD_DMA	5
+#define S500_PD_DS	6
+#define S500_PD_USB3	7
+#define S500_PD_USB2_0	8
+
+#endif
-- 
2.12.3

[PATCH v5 21/26] soc: actions: Add Owl SPS

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 03:40:31

Implement S500 Smart Power System power-gating.
For now flag PD_CPU2 and PD_CPU3 as always-on.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Updated for header file rename
 
 v3 -> v4:
 * Added genpd_flags field and set GENPD_FLAG_ALWAYS_ON for CPU2/CPU3
 * Added debug output
 
 v3: new
 
 drivers/soc/Kconfig           |   1 +
 drivers/soc/Makefile          |   1 +
 drivers/soc/actions/Kconfig   |  12 ++
 drivers/soc/actions/Makefile  |   1 +
 drivers/soc/actions/owl-sps.c | 252 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 267 insertions(+)
 create mode 100644 drivers/soc/actions/Kconfig
 create mode 100644 drivers/soc/actions/Makefile
 create mode 100644 drivers/soc/actions/owl-sps.c
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index f8c0286f8a65..07fc0ac51c52 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,5 +1,6 @@
 menu "SOC (System On Chip) specific Drivers"
 
+source "drivers/soc/actions/Kconfig"
 source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/fsl/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index c0b2a610efcd..9241125416ba 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #
 
+obj-$(CONFIG_ARCH_ACTIONS)	+= actions/
 obj-$(CONFIG_ARCH_AT91)		+= atmel/
 obj-y				+= bcm/
 obj-$(CONFIG_ARCH_DOVE)		+= dove/
diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig
new file mode 100644
index 000000000000..bdf827d5ce78
--- /dev/null
+++ b/drivers/soc/actions/Kconfig
@@ -0,0 +1,12 @@
+if ARCH_ACTIONS || COMPILE_TEST
+
+config OWL_PM_DOMAINS
+	bool "Actions Semi SPS power domains"
+	depends on PM
+	select PM_GENERIC_DOMAINS
+	help
+	  Say 'y' here to enable support for Smart Power System (SPS)
+	  power-gating on Actions Semiconductor S500 SoC.
+	  If unsure, say 'n'.
+
+endif
diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile
new file mode 100644
index 000000000000..720c34ed16e4
--- /dev/null
+++ b/drivers/soc/actions/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c
new file mode 100644
index 000000000000..8abb72f01929
--- /dev/null
+++ b/drivers/soc/actions/owl-sps.c
@@ -0,0 +1,252 @@
+/*
+ * Actions Semi Owl Smart Power System (SPS)
+ *
+ * Copyright 2012 Actions Semi Inc.
+ * Author: Actions Semi, Inc.
+ *
+ * Copyright (c) 2017 Andreas F?rber
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pm_domain.h>
+#include <dt-bindings/power/owl-s500-powergate.h>
+
+#define OWL_SPS_PG_CTL	0x0
+
+struct owl_sps_domain_info {
+	const char *name;
+	int pwr_bit;
+	int ack_bit;
+	unsigned int genpd_flags;
+};
+
+struct owl_sps_info {
+	unsigned num_domains;
+	const struct owl_sps_domain_info *domains;
+};
+
+struct owl_sps {
+	struct device *dev;
+	const struct owl_sps_info *info;
+	void __iomem *base;
+	struct genpd_onecell_data genpd_data;
+	struct generic_pm_domain *domains[];
+};
+
+#define to_owl_pd(gpd) container_of(gpd, struct owl_sps_domain, genpd)
+
+struct owl_sps_domain {
+	struct generic_pm_domain genpd;
+	const struct owl_sps_domain_info *info;
+	struct owl_sps *sps;
+};
+
+static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable)
+{
+	u32 val, pwr_mask, ack_mask;
+	int timeout;
+	bool ack;
+
+	ack_mask = BIT(pd->info->ack_bit);
+	pwr_mask = BIT(pd->info->pwr_bit);
+	val = readl(pd->sps->base + OWL_SPS_PG_CTL);
+	ack = val & ack_mask;
+
+	if (ack == enable)
+		return 0;
+
+	if (enable)
+		val |= pwr_mask;
+	else
+		val &= ~pwr_mask;
+
+	writel(val, pd->sps->base + OWL_SPS_PG_CTL);
+
+	for (timeout = 5000; timeout > 0; timeout -= 50) {
+		val = readl(pd->sps->base + OWL_SPS_PG_CTL);
+		if ((val & ack_mask) == (enable ? ack_mask : 0))
+			break;
+		udelay(50);
+	}
+	if (timeout <= 0)
+		return -ETIMEDOUT;
+
+	udelay(10);
+
+	return 0;
+}
+
+static int owl_sps_power_on(struct generic_pm_domain *domain)
+{
+	struct owl_sps_domain *pd = to_owl_pd(domain);
+
+	dev_dbg(pd->sps->dev, "%s power on", pd->info->name);
+
+	return owl_sps_set_power(pd, true);
+}
+
+static int owl_sps_power_off(struct generic_pm_domain *domain)
+{
+	struct owl_sps_domain *pd = to_owl_pd(domain);
+
+	dev_dbg(pd->sps->dev, "%s power off", pd->info->name);
+
+	return owl_sps_set_power(pd, false);
+}
+
+static int owl_sps_init_domain(struct owl_sps *sps, int index)
+{
+	struct owl_sps_domain *pd;
+
+	pd = devm_kzalloc(sps->dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+
+	pd->info = &sps->info->domains[index];
+	pd->sps = sps;
+
+	pd->genpd.name = pd->info->name;
+	pd->genpd.power_on = owl_sps_power_on;
+	pd->genpd.power_off = owl_sps_power_off;
+	pd->genpd.flags = pd->info->genpd_flags;
+	pm_genpd_init(&pd->genpd, NULL, false);
+
+	sps->genpd_data.domains[index] = &pd->genpd;
+
+	return 0;
+}
+
+static int owl_sps_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	const struct owl_sps_info *sps_info;
+	struct owl_sps *sps;
+	int i, ret;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "no device node\n");
+		return -ENODEV;
+	}
+
+	match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev);
+	if (!match || !match->data) {
+		dev_err(&pdev->dev, "unknown compatible or missing data\n");
+		return -EINVAL;
+	}
+
+	sps_info = match->data;
+
+	sps = devm_kzalloc(&pdev->dev, sizeof(*sps) +
+			   sps_info->num_domains * sizeof(sps->domains[0]),
+			   GFP_KERNEL);
+	if (!sps)
+		return -ENOMEM;
+
+	sps->base = of_io_request_and_map(pdev->dev.of_node, 0, "owl-sps");
+	if (IS_ERR(sps->base)) {
+		dev_err(&pdev->dev, "failed to map sps registers\n");
+		return PTR_ERR(sps->base);
+	}
+
+	sps->dev = &pdev->dev;
+	sps->info = sps_info;
+	sps->genpd_data.domains = sps->domains;
+	sps->genpd_data.num_domains = sps_info->num_domains;
+
+	for (i = 0; i < sps_info->num_domains; i++) {
+		ret = owl_sps_init_domain(sps, i);
+		if (ret)
+			return ret;
+	}
+
+	ret = of_genpd_add_provider_onecell(pdev->dev.of_node, &sps->genpd_data);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add provider (%d)", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct owl_sps_domain_info s500_sps_domains[] = {
+	[S500_PD_VDE] = {
+		.name = "VDE",
+		.pwr_bit = 0,
+		.ack_bit = 16,
+	},
+	[S500_PD_VCE_SI] = {
+		.name = "VCE_SI",
+		.pwr_bit = 1,
+		.ack_bit = 17,
+	},
+	[S500_PD_USB2_1] = {
+		.name = "USB2_1",
+		.pwr_bit = 2,
+		.ack_bit = 18,
+	},
+	[S500_PD_CPU2] = {
+		.name = "CPU2",
+		.pwr_bit = 5,
+		.ack_bit = 21,
+		.genpd_flags = GENPD_FLAG_ALWAYS_ON,
+	},
+	[S500_PD_CPU3] = {
+		.name = "CPU3",
+		.pwr_bit = 6,
+		.ack_bit = 22,
+		.genpd_flags = GENPD_FLAG_ALWAYS_ON,
+	},
+	[S500_PD_DMA] = {
+		.name = "DMA",
+		.pwr_bit = 8,
+		.ack_bit = 12,
+	},
+	[S500_PD_DS] = {
+		.name = "DS",
+		.pwr_bit = 9,
+		.ack_bit = 13,
+	},
+	[S500_PD_USB3] = {
+		.name = "USB3",
+		.pwr_bit = 10,
+		.ack_bit = 14,
+	},
+	[S500_PD_USB2_0] = {
+		.name = "USB2_0",
+		.pwr_bit = 11,
+		.ack_bit = 15,
+	},
+};
+
+static const struct owl_sps_info s500_sps_info = {
+	.num_domains = ARRAY_SIZE(s500_sps_domains),
+	.domains = s500_sps_domains,
+};
+
+static const struct of_device_id owl_sps_of_matches[] = {
+	{ .compatible = "actions,s500-sps", .data = &s500_sps_info },
+	{ }
+};
+
+static struct platform_driver owl_sps_platform_driver = {
+	.probe = owl_sps_probe,
+	.driver = {
+		.name = "owl-sps",
+		.of_match_table = owl_sps_of_matches,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int __init owl_sps_init(void)
+{
+	return platform_driver_register(&owl_sps_platform_driver);
+}
+postcore_initcall(owl_sps_init);
-- 
2.12.3

[PATCH v5 22/26] MAINTAINERS: Update Actions Semi section with SPS

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 03:44:14

Add file patterns to cover the SPS power domain driver and DT binding.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Rebased onto timer additions
 * Added dt-bindings header file pattern
 
 v4: new
 
 MAINTAINERS | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 831bfd5cc68b..eb62d294095e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1045,7 +1045,11 @@ F:	arch/arm/mach-actions/
 F:	arch/arm/boot/dts/owl-*
 F:	arch/arm64/boot/dts/actions/
 F:	drivers/clocksource/owl-*
+F:	drivers/soc/actions/
+F:	include/dt-bindings/power/owl-*
+F:	include/linux/soc/actions/
 F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/power/actions,owl-sps.txt
 F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
 
 ARM/ADS SPHERE MACHINE SUPPORT
-- 
2.12.3

Re: [PATCH v5 20/26] dt-bindings: power: Add Owl SPS power domains

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 03:58:09

Am 19.06.2017 um 05:36 schrieb Andreas F?rber:
Define power domains for all non-reserved S500 power gates.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Renamed header file with owl- prefix for uniqueness
 
 v3 -> v4: Unchanged
 
 v3: new
 
 .../devicetree/bindings/power/actions,owl-sps.txt     | 17 +++++++++++++++++
 include/dt-bindings/power/owl-s500-powergate.h        | 19 +++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/actions,owl-sps.txt
 create mode 100644 include/dt-bindings/power/owl-s500-powergate.h
Due to include dependency applying to linux-actions.git v4.13/soc:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v5 21/26] soc: actions: Add Owl SPS

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 03:59:16

Am 19.06.2017 um 05:40 schrieb Andreas F?rber:
Implement S500 Smart Power System power-gating.
For now flag PD_CPU2 and PD_CPU3 as always-on.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Updated for header file rename
 
 v3 -> v4:
 * Added genpd_flags field and set GENPD_FLAG_ALWAYS_ON for CPU2/CPU3
 * Added debug output
 
 v3: new
 
 drivers/soc/Kconfig           |   1 +
 drivers/soc/Makefile          |   1 +
 drivers/soc/actions/Kconfig   |  12 ++
 drivers/soc/actions/Makefile  |   1 +
 drivers/soc/actions/owl-sps.c | 252 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 267 insertions(+)
 create mode 100644 drivers/soc/actions/Kconfig
 create mode 100644 drivers/soc/actions/Makefile
 create mode 100644 drivers/soc/actions/owl-sps.c
Applied to linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v5 22/26] MAINTAINERS: Update Actions Semi section with SPS

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 04:00:15

Am 19.06.2017 um 05:44 schrieb Andreas F?rber:
Add file patterns to cover the SPS power domain driver and DT binding.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Rebased onto timer additions
 * Added dt-bindings header file pattern
 
 v4: new
 
 MAINTAINERS | 4 ++++
 1 file changed, 4 insertions(+)
Applied to linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 25/28] ARM: dts: s500: Add SPS node

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 04:01:36

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Add Smart Power System node for PM domains.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4:
 * Extended commit message
 * Split off association of power-domains (avoids include/dt-bindings/ dependency)
 
 v3: new
 
 arch/arm/boot/dts/s500.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)
Applied to linux-actions.git v4.13/dt branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/dt

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 27/28] soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 04:12:45

Am 06.06.2017 um 02:54 schrieb Andreas F?rber:
Allow the SMP code to reuse PM domain code for CPU2/CPU3 wakeup.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4: new
 
 drivers/soc/actions/Kconfig          |  4 +++
 drivers/soc/actions/Makefile         |  1 +
 drivers/soc/actions/owl-sps-helper.c | 51 ++++++++++++++++++++++++++++++++++++
 drivers/soc/actions/owl-sps.c        | 34 +++---------------------
 include/linux/soc/actions/owl-sps.h  | 11 ++++++++
 5 files changed, 70 insertions(+), 31 deletions(-)
 create mode 100644 drivers/soc/actions/owl-sps-helper.c
 create mode 100644 include/linux/soc/actions/owl-sps.h
Applied to linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Needs to get merged first so that arm branch can start using it.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 04/28] clocksource: Add Owl timer

From: Daniel Lezcano <hidden>
Date: 2017-06-19 13:53:11

On 18/06/2017 22:43, Andreas F?rber wrote:
Am 06.06.2017 um 18:33 schrieb Daniel Lezcano:
quoted
On Tue, Jun 06, 2017 at 02:54:02AM +0200, Andreas F?rber wrote:
quoted
The Actions Semi S500 SoC provides four timers, 2Hz0/1 and 32-bit TIMER0/1.

Use TIMER0 as clocksource and TIMER1 as clockevents.

Based on LeMaker linux-actions tree.

An S500 datasheet can be found on the LeMaker Guitar pages:
http://www.lemaker.org/product-guitar-download-29.html

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
Acked-by: Daniel Lezcano <redacted>
Thanks. It seems this is not going through a central clocksource tree,
so I'm applying it to a new linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Let me know if you intend to take it through some other tree instead.
No, it is ok. In the future, submit for the clocksource tree
(tip/timers/core).

Thanks!

  -- Daniel


-- 
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

Re: [PATCH v4 04/28] clocksource: Add Owl timer

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-19 14:31:23

Am 19.06.2017 um 15:53 schrieb Daniel Lezcano:
On 18/06/2017 22:43, Andreas F?rber wrote:
quoted
Am 06.06.2017 um 18:33 schrieb Daniel Lezcano:
quoted
On Tue, Jun 06, 2017 at 02:54:02AM +0200, Andreas F?rber wrote:
quoted
The Actions Semi S500 SoC provides four timers, 2Hz0/1 and 32-bit TIMER0/1.

Use TIMER0 as clocksource and TIMER1 as clockevents.

Based on LeMaker linux-actions tree.

An S500 datasheet can be found on the LeMaker Guitar pages:
http://www.lemaker.org/product-guitar-download-29.html

Signed-off-by: Andreas F?rber <afaerber@suse.de>
Acked-by: Daniel Lezcano <redacted>
Thanks. It seems this is not going through a central clocksource tree,
so I'm applying it to a new linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Let me know if you intend to take it through some other tree instead.
No, it is ok. In the future, submit for the clocksource tree
(tip/timers/core).
Hm, I did see that tree in MAINTAINERS, but it specifically said
"CLOCKSOURCE CORE" and it does not have any
F:	drivers/clocksource/
or
F:	Documentation/devicetree/bindings/timer/
entries, therefore I added the files to Actions like other SoCs did...

I can easily unqueue the patches - what does submit for the clocksource
tree mean? Just CC the two maintainers on resend or anything else?
I intend to rename my branch to v4.13/drivers on Olof's feedback anyway.

Sorry,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-06-21 08:16:51

On Tue, Jun 6, 2017 at 2:54 AM, Andreas F?rber [off-list ref] wrote:
Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged

 v3: new

 arch/arm/mach-actions/Makefile  |   3 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
I now see build errors in linux-next:

/git/arm-soc/arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
/git/arm-soc/arch/arm/mach-actions/platsmp.c:39:2: error:
'pen_release' undeclared (first use in this function); did you mean
'seq_release'?
  pen_release = val;
  ^~~~~~~~~~~
  seq_release
/git/arm-soc/arch/arm/mach-actions/platsmp.c:39:2: note: each
undeclared identifier is reported only once for each function it
appears in
/git/arm-soc/arch/arm/mach-actions/platsmp.c: In function
's500_wakeup_secondary':
/git/arm-soc/arch/arm/mach-actions/platsmp.c:79:2: error: implicit
declaration of function 'dsb_sev'
[-Werror=implicit-function-declaration]
  dsb_sev();
  ^~~~~~~
/git/arm-soc/arch/arm/mach-actions/platsmp.c: In function
's500_smp_boot_secondary':
/git/arm-soc/arch/arm/mach-actions/platsmp.c:108:7: error:
'pen_release' undeclared (first use in this function); did you mean
'seq_release'?

+static DEFINE_SPINLOCK(boot_lock);
+
+static void write_pen_release(int val)
+{
+       pen_release = val;
+       smp_wmb();
+       __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+       outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void s500_smp_secondary_init(unsigned int cpu)
+{
+       /*
+        * let the primary processor know we're out of the
+        * pen, then head off into the C entry point
+        */
+       write_pen_release(-1);
+
+       spin_lock(&boot_lock);
+       spin_unlock(&boot_lock);
+}
+
+void owl_secondary_startup(void);
+
+static int s500_wakeup_secondary(unsigned int cpu)
+{
+       if (cpu > 3)
+               return -EINVAL;
+
+       switch (cpu) {
+       case 2:
+       case 3:
+               /* CPU2/3 are power-gated */
+               return -EINVAL;
+       }
+
+       /* wait for CPUx to run to WFE instruction */
+       udelay(200);
+
+       writel(virt_to_phys(owl_secondary_startup),
+              timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4);
+       writel(OWL_CPUx_FLAG_BOOT,
+              timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4);
+
+       dsb_sev();
+       mb();
+
+       return 0;
+}
+
+static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       unsigned long timeout;
+       int ret;
+
+       ret = s500_wakeup_secondary(cpu);
+       if (ret)
+               return ret;
+
+       udelay(10);
+
+       spin_lock(&boot_lock);
+
+       /*
+        * The secondary processor is waiting to be released from
+        * the holding pen - release it, then wait for it to flag
+        * that it has been released by resetting pen_release.
+        */
+       write_pen_release(cpu_logical_map(cpu));
+       smp_send_reschedule(cpu);
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               if (pen_release == -1)
+                       break;
+       }
+
+       writel(0, timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4);
+       writel(0, timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4);
+
+       spin_unlock(&boot_lock);
+
+       return pen_release != -1 ? -ENOSYS : 0;
+}
This looks more complicated than necessary. Why do you need the holding
pen when you have a register to start up the CPU?

        Arnd

Re: [PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-06-21 10:25:37

On Wed, Jun 21, 2017 at 10:16 AM, Arnd Bergmann [off-list ref] wrote:
On Tue, Jun 6, 2017 at 2:54 AM, Andreas F?rber [off-list ref] wrote:
quoted
Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged

 v3: new

 arch/arm/mach-actions/Makefile  |   3 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
I now see build errors in linux-next:

/git/arm-soc/arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
/git/arm-soc/arch/arm/mach-actions/platsmp.c:39:2: error:
'pen_release' undeclared (first use in this function); did you mean
I have a fix and tested it now. Please fold this into your patch:

       Arnd

Subject: [PATCH] ARM: owl: fix non-SMP build

arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
arch/arm/mach-actions/platsmp.c:39:2: error: 'pen_release' undeclared
(first use in this function); did you mean 'seq_release'?

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile
index 217e95d04b43..94f8dbafba21 100644
--- a/arch/arm/mach-actions/Makefile
+++ b/arch/arm/mach-actions/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_ARCH_ACTIONS) += owl.o
-obj-${CONFIG_ARCH_ACTIONS} += platsmp.o headsmp.o
+obj-y += owl.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o

 AFLAGS_headsmp.o := -Wa,-march=armv7-a

Re: [PATCH v4 04/28] clocksource: Add Owl timer

From: Daniel Lezcano <hidden>
Date: 2017-06-21 11:57:48

On Mon, Jun 19, 2017 at 04:31:18PM +0200, Andreas F?rber wrote:
Am 19.06.2017 um 15:53 schrieb Daniel Lezcano:
quoted
On 18/06/2017 22:43, Andreas F?rber wrote:
quoted
Am 06.06.2017 um 18:33 schrieb Daniel Lezcano:
quoted
On Tue, Jun 06, 2017 at 02:54:02AM +0200, Andreas F?rber wrote:
quoted
The Actions Semi S500 SoC provides four timers, 2Hz0/1 and 32-bit TIMER0/1.

Use TIMER0 as clocksource and TIMER1 as clockevents.

Based on LeMaker linux-actions tree.

An S500 datasheet can be found on the LeMaker Guitar pages:
http://www.lemaker.org/product-guitar-download-29.html

Signed-off-by: Andreas F?rber <afaerber@suse.de>
Acked-by: Daniel Lezcano <redacted>
Thanks. It seems this is not going through a central clocksource tree,
so I'm applying it to a new linux-actions.git v4.13/soc branch:

https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.13/soc

Let me know if you intend to take it through some other tree instead.
No, it is ok. In the future, submit for the clocksource tree
(tip/timers/core).
Hm, I did see that tree in MAINTAINERS, but it specifically said
"CLOCKSOURCE CORE" and it does not have any
F:	drivers/clocksource/
or
F:	Documentation/devicetree/bindings/timer/
entries, therefore I added the files to Actions like other SoCs did...
You probably missed the entry:

CLOCKSOURCE, CLOCKEVENT DRIVERS
M:      Daniel Lezcano [off-list ref]
M:      Thomas Gleixner [off-list ref]
L:      linux-kernel at vger.kernel.org
T:      git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
S:      Supported
F:      drivers/clocksource
 
I can easily unqueue the patches - what does submit for the clocksource
tree mean? Just CC the two maintainers on resend or anything else?
I intend to rename my branch to v4.13/drivers on Olof's feedback anyway.
I could have directly picked the clocksource/clockevent changes to my tree but
I decided to let them go through the ARM's tree. I meant, as the patches are
acked (by me), it is ok they are merged through arm's tree. From my POV, it is
somewho acceptable when a new SoC support is added.

In the future, when the clockevent/clocksource drivers are merged and if there
are more changes, at this time, send the patches to Thomas and me as stated in
the maintainer file entry, I will take care of them.

IOW, everything is fine ;)

  -- Daniel

-- 

 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

Re: [PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Andreas Färber <afaerber@suse.de>
Date: 2017-06-21 16:48:30

Am 21.06.2017 um 12:25 schrieb Arnd Bergmann:
quoted hunk
On Wed, Jun 21, 2017 at 10:16 AM, Arnd Bergmann [off-list ref] wrote:
quoted
On Tue, Jun 6, 2017 at 2:54 AM, Andreas F?rber [off-list ref] wrote:
quoted
Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged

 v3: new

 arch/arm/mach-actions/Makefile  |   3 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
I now see build errors in linux-next:

/git/arm-soc/arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
/git/arm-soc/arch/arm/mach-actions/platsmp.c:39:2: error:
'pen_release' undeclared (first use in this function); did you mean
I have a fix and tested it now. Please fold this into your patch:

       Arnd

Subject: [PATCH] ARM: owl: fix non-SMP build

arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
arch/arm/mach-actions/platsmp.c:39:2: error: 'pen_release' undeclared
(first use in this function); did you mean 'seq_release'?

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile
index 217e95d04b43..94f8dbafba21 100644
--- a/arch/arm/mach-actions/Makefile
+++ b/arch/arm/mach-actions/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_ARCH_ACTIONS) += owl.o
-obj-${CONFIG_ARCH_ACTIONS} += platsmp.o headsmp.o
+obj-y += owl.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
Sorry. Fixed up the two patches, thanks!

Interestingly the below issue had been found by automatic patch testing,
but the above wasn't. Maybe you can contribute your non-SMP config for
the bots, to help catch this earlier?
 AFLAGS_headsmp.o := -Wa,-march=armv7-a
Cheers,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)

Re: [PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-06-21 18:02:41

On Wed, Jun 21, 2017 at 6:48 PM, Andreas F?rber [off-list ref] wrote:
Am 21.06.2017 um 12:25 schrieb Arnd Bergmann:
quoted
On Wed, Jun 21, 2017 at 10:16 AM, Arnd Bergmann [off-list ref] wrote:
quoted
On Tue, Jun 6, 2017 at 2:54 AM, Andreas F?rber [off-list ref] wrote:
quoted
Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v3 -> v4: Unchanged

 v3: new

 arch/arm/mach-actions/Makefile  |   3 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
I now see build errors in linux-next:

/git/arm-soc/arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
/git/arm-soc/arch/arm/mach-actions/platsmp.c:39:2: error:
'pen_release' undeclared (first use in this function); did you mean
I have a fix and tested it now. Please fold this into your patch:

       Arnd

Subject: [PATCH] ARM: owl: fix non-SMP build

arch/arm/mach-actions/platsmp.c: In function 'write_pen_release':
arch/arm/mach-actions/platsmp.c:39:2: error: 'pen_release' undeclared
(first use in this function); did you mean 'seq_release'?

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile
index 217e95d04b43..94f8dbafba21 100644
--- a/arch/arm/mach-actions/Makefile
+++ b/arch/arm/mach-actions/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_ARCH_ACTIONS) += owl.o
-obj-${CONFIG_ARCH_ACTIONS} += platsmp.o headsmp.o
+obj-y += owl.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
Sorry. Fixed up the two patches, thanks!

Interestingly the below issue had been found by automatic patch testing,
but the above wasn't. Maybe you can contribute your non-SMP config for
the bots, to help catch this earlier?
This was just a randconfig build. On ARM32, we do test
"multi_v7_defconfig+CONFIG_SMP=n"
in kernelci, but that only tests mach-actions after that gets added to
multi_v7_defconfig. Not sure if it's worth adding an allmodconfig+CONFIG_SMP=n"
build, the allmodconfig builds are rather expensive.

        Arnd

答复: [PATCH v5 13/26] MAINTAINERS: Add Actions Semi Owl section

From: 张天益 <hidden>
Date: 2017-06-26 07:12:25

+c

-----????-----
???: Andreas F?rber [mailto:afaerber at suse.de] 
????: 2017?6?19? 10:45
???: linux-arm-kernel at lists.infradead.org
??: mp-cs; Thomas Liau; ???; ??; ???; 96boards at ucrobotics.com; support at lemaker.org; linux-kernel at vger.kernel.org; Andreas F?rber
??: [PATCH v5 13/26] MAINTAINERS: Add Actions Semi Owl section

Signed-off-by: Andreas F?rber <afaerber@suse.de>
---
 v4 -> v5:
 * Updated arm dts file pattern
 * Added clocksource file patterns
 
 v2 -> v3 -> v4: unchanged
 
 v2: new
 
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d56524402f36..831bfd5cc68b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1036,6 +1036,18 @@ S:	Maintained
 F:	drivers/amba/
 F:	include/linux/amba/bus.h
 
+ARM/ACTIONS SEMI ARCHITECTURE
+M:	Andreas F?rber <afaerber@suse.de>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+N:	owl
+F:	arch/arm/mach-actions/
+F:	arch/arm/boot/dts/owl-*
+F:	arch/arm64/boot/dts/actions/
+F:	drivers/clocksource/owl-*
+F:	Documentation/devicetree/bindings/arm/actions.txt
+F:	Documentation/devicetree/bindings/timer/actions,owl-timer.txt
+
 ARM/ADS SPHERE MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
2.12.3

Re: [PATCH v4 20/28] ARM: owl: Implement CPU enable-method for S500

From: Arnd Bergmann <arnd@arndb.de>
Date: 2017-06-29 15:07:44

quoted
+static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       unsigned long timeout;
+       int ret;
+
+       ret = s500_wakeup_secondary(cpu);
+       if (ret)
+               return ret;
+
+       udelay(10);
+
+       spin_lock(&boot_lock);
+
+       /*
+        * The secondary processor is waiting to be released from
+        * the holding pen - release it, then wait for it to flag
+        * that it has been released by resetting pen_release.
+        */
+       write_pen_release(cpu_logical_map(cpu));
+       smp_send_reschedule(cpu);
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               if (pen_release == -1)
+                       break;
+       }
+
+       writel(0, timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4);
+       writel(0, timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4);
+
+       spin_unlock(&boot_lock);
+
+       return pen_release != -1 ? -ENOSYS : 0;
+}
This looks more complicated than necessary. Why do you need the holding
pen when you have a register to start up the CPU?
It seems you missed my question here. Can you please follow up, and
if possible send a patch to remove the pen_release logic that appears
to be unnecessary here?

        Arnd
Next 22 of 22 remaining
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help