linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement
@ 2017-02-28  6:35 Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 01/25] dt-bindings: Add vendor prefix for Actions Semi Andreas Färber
                   ` (24 more replies)
  0 siblings, 25 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Mark Rutland, Arnd Bergmann, Rob Herring,
	Daniel Lezcano, linux-serial, linux-doc, devicetree

Hello,

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

v3 has the serial driver working almost equally for both, still glitch on S900.
SMP support and power-gating for S500 are implemented, so both get 4 CPUs up.

https://github.com/afaerber/linux/commits/bg96-next

Booting from U-Boot 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

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: Mark Rutland <mark.rutland@arm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Rob Herring <robh@kernel.org>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: mp-cs@actions-semi.com
Cc: 96boards@ucrobotics.com
Cc: support@lemaker.org
Cc: linux-serial@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Cc: devicetree@vger.kernel.org

Andreas Färber (25):
  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
  ARM: dts: s500: Add SPS node
  ARM: owl: smp: Reimplement 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                                        |  10 +
 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                 |  24 +
 arch/arm/boot/dts/s500.dtsi                        | 183 ++++++
 arch/arm/mach-actions/Kconfig                      |  15 +
 arch/arm/mach-actions/Makefile                     |   2 +
 arch/arm/mach-actions/headsmp.S                    |  68 ++
 arch/arm/mach-actions/owl.c                        |  28 +
 arch/arm/mach-actions/platsmp.c                    | 229 +++++++
 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                    | 205 ++++++
 drivers/soc/Kconfig                                |   1 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/actions/Kconfig                        |  12 +
 drivers/soc/actions/Makefile                       |   1 +
 drivers/soc/actions/owl-sps.c                      | 245 +++++++
 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/uapi/linux/serial_core.h                   |   3 +
 37 files changed, 2155 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.c
 create mode 100644 drivers/tty/serial/owl-uart.c
 create mode 100644 include/dt-bindings/power/s500-powergate.h

-- 
2.10.2

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH v3 01/25] dt-bindings: Add vendor prefix for Actions Semi
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 02/25] dt-bindings: arm: Document Actions Semi S500 Andreas Färber
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

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

Cc: mp-cs@actions-semi.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 a76b981..2f294c8 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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 02/25] dt-bindings: arm: Document Actions Semi S500
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 01/25] dt-bindings: Add vendor prefix for Actions Semi Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 03/25] dt-bindings: timer: Document Owl timer Andreas Färber
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

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: 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 0000000..1d3782e
--- /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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 03/25] dt-bindings: timer: Document Owl timer
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 01/25] dt-bindings: Add vendor prefix for Actions Semi Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 02/25] dt-bindings: arm: Document Actions Semi S500 Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28 12:39   ` Mark Rutland
  2017-02-28  6:35 ` [PATCH v3 04/25] clocksource: Add " Andreas Färber
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

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.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 0000000..5b4834d
--- /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@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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (2 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 03/25] dt-bindings: timer: Document Owl timer Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28 16:47   ` Daniel Lezcano
  2017-02-28  6:35 ` [PATCH v3 05/25] clocksource: owl: Add S900 support Andreas Färber
                   ` (20 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Daniel Lezcano, Thomas Gleixner

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>
---
 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 | 193 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 201 insertions(+)
 create mode 100644 drivers/clocksource/owl-timer.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 3356ab8..2551365 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -107,6 +107,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 d227d13..801b65a 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -53,6 +53,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 0000000..1b1e26d
--- /dev/null
+++ b/drivers/clocksource/owl-timer.c
@@ -0,0 +1,193 @@
+/*
+ * 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)
+
+#define OWL_MAX_Tx 2
+
+struct owl_timer_info {
+	int timer_offset[OWL_MAX_Tx];
+};
+
+static const struct owl_timer_info *owl_timer_info;
+
+static void __iomem *owl_timer_base;
+
+static inline void __iomem *owl_timer_get_base(unsigned timer_nr)
+{
+	if (timer_nr >= OWL_MAX_Tx)
+		return NULL;
+
+	return owl_timer_base + owl_timer_info->timer_offset[timer_nr];
+}
+
+static inline void owl_timer_reset(unsigned index)
+{
+	void __iomem *base;
+
+	base = owl_timer_get_base(index);
+	if (!base)
+		return;
+
+	writel(0, base + OWL_Tx_CTL);
+	writel(0, base + OWL_Tx_VAL);
+	writel(0, base + OWL_Tx_CMP);
+}
+
+static u64 notrace owl_timer_sched_read(void)
+{
+	return (u64)readl(owl_timer_get_base(0) + OWL_Tx_VAL);
+}
+
+static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
+{
+	writel(0, owl_timer_get_base(0) + OWL_Tx_CTL);
+
+	return 0;
+}
+
+static int owl_timer_set_state_oneshot(struct clock_event_device *evt)
+{
+	owl_timer_reset(1);
+
+	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_timer_get_base(1);
+
+	writel(0, base + OWL_Tx_CTL);
+
+	writel(0, base + OWL_Tx_VAL);
+	writel(evt, base + OWL_Tx_CMP);
+
+	writel(OWL_Tx_CTL_EN | OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
+
+	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_timer_get_base(1) + OWL_Tx_CTL);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static const struct owl_timer_info s500_timer_info = {
+	.timer_offset[0] = 0x08,
+	.timer_offset[1] = 0x14,
+};
+
+static const struct of_device_id owl_timer_of_matches[] = {
+	{ .compatible = "actions,s500-timer", .data = &s500_timer_info },
+	{ }
+};
+
+static int __init owl_timer_init(struct device_node *node)
+{
+	const struct of_device_id *match;
+	struct clk *clk;
+	unsigned long rate;
+	int timer1_irq, i, ret;
+
+	match = of_match_node(owl_timer_of_matches, node);
+	if (!match || !match->data) {
+		pr_err("Unknown compatible");
+		return -EINVAL;
+	}
+
+	owl_timer_info = match->data;
+
+	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);
+	}
+
+	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);
+
+	for (i = 0; i < OWL_MAX_Tx; i++)
+		owl_timer_reset(i);
+
+	writel(OWL_Tx_CTL_EN, owl_timer_get_base(0) + OWL_Tx_CTL);
+
+	sched_clock_register(owl_timer_sched_read, 32, rate);
+	clocksource_mmio_init(owl_timer_get_base(0) + OWL_Tx_VAL, node->name,
+			      rate, 200, 32, clocksource_mmio_readl_up);
+
+	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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 05/25] clocksource: owl: Add S900 support
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (3 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 04/25] clocksource: Add " Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28 17:16   ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 06/25] ARM: Prepare Actions Semi S500 Andreas Färber
                   ` (19 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Daniel Lezcano, Thomas Gleixner

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

Deal with the S500 having less 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: new
 
 drivers/clocksource/owl-timer.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/owl-timer.c b/drivers/clocksource/owl-timer.c
index 1b1e26d..babbfd5 100644
--- a/drivers/clocksource/owl-timer.c
+++ b/drivers/clocksource/owl-timer.c
@@ -31,7 +31,7 @@
 #define OWL_Tx_CTL_INTEN	BIT(1)
 #define OWL_Tx_CTL_EN		BIT(2)
 
-#define OWL_MAX_Tx 2
+#define OWL_MAX_Tx 4
 
 struct owl_timer_info {
 	int timer_offset[OWL_MAX_Tx];
@@ -43,7 +43,8 @@ static void __iomem *owl_timer_base;
 
 static inline void __iomem *owl_timer_get_base(unsigned timer_nr)
 {
-	if (timer_nr >= OWL_MAX_Tx)
+	if (timer_nr >= OWL_MAX_Tx ||
+	    owl_timer_info->timer_offset[timer_nr] == -1)
 		return NULL;
 
 	return owl_timer_base + owl_timer_info->timer_offset[timer_nr];
@@ -126,10 +127,20 @@ static irqreturn_t owl_timer1_interrupt(int irq, void *dev_id)
 static const struct owl_timer_info s500_timer_info = {
 	.timer_offset[0] = 0x08,
 	.timer_offset[1] = 0x14,
+	.timer_offset[2] = -1,
+	.timer_offset[3] = -1,
+};
+
+static const struct owl_timer_info s900_timer_info = {
+	.timer_offset[0] = 0x08,
+	.timer_offset[1] = 0x14,
+	.timer_offset[2] = 0x30,
+	.timer_offset[3] = 0x3c,
 };
 
 static const struct of_device_id owl_timer_of_matches[] = {
 	{ .compatible = "actions,s500-timer", .data = &s500_timer_info },
+	{ .compatible = "actions,s900-timer", .data = &s900_timer_info },
 	{ }
 };
 
@@ -191,3 +202,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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 06/25] ARM: Prepare Actions Semi S500
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (4 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 05/25] clocksource: owl: Add S900 support Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 07/25] ARM64: Prepare Actions Semi S900 Andreas Färber
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Russell King

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

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 0d4e71b..94fa3925 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -720,6 +720,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 ab30cc6..d2ccf72 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 0000000..717adc1
--- /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 0000000..524c381
--- /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 0000000..4ac4a86
--- /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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 07/25] ARM64: Prepare Actions Semi S900
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (5 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 06/25] ARM: Prepare Actions Semi S500 Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 08/25] dt-bindings: serial: Document Actions Semi Owl UARTs Andreas Färber
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Catalin Marinas, Will Deacon

Add ARCH_ACTIONS.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 129cc5a..761b31f 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 GENERIC_IRQ_CHIP
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 08/25] dt-bindings: serial: Document Actions Semi Owl UARTs
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (6 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 07/25] ARM64: Prepare Actions Semi S900 Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 09/25] tty: serial: Add Actions Semi Owl UART earlycon Andreas Färber
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Greg Kroah-Hartman, Rob Herring,
	Mark Rutland, linux-serial, devicetree

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: 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 0000000..aa873ea
--- /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@b0126000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0126000 0x1000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		};
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 09/25] tty: serial: Add Actions Semi Owl UART earlycon
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (7 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 08/25] dt-bindings: serial: Document Actions Semi Owl UARTs Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 10/25] Documentation: kernel-parameters: Document owl earlycon Andreas Färber
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Greg Kroah-Hartman, Jiri Slaby,
	linux-serial

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>
---
 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 6117ac8..e145822 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1677,6 +1677,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 2d6288b..91f3571 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -91,6 +91,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 0000000..1b80087
--- /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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 10/25] Documentation: kernel-parameters: Document owl earlycon
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (8 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 09/25] tty: serial: Add Actions Semi Owl UART earlycon Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar Andreas Färber
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Jonathan Corbet, linux-doc

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 986e443..f48a142 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -943,6 +943,12 @@
 			must already be setup and configured. Options are not
 			yet supported.
 
+		owl,<addr>
+			Start an early, polled-mode console on an Owl serial
+			port 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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (9 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 10/25] Documentation: kernel-parameters: Document owl earlycon Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28 12:32   ` Mark Rutland
  2017-02-28  6:35 ` [PATCH v3 12/25] dt-bindings: Add vendor prefix for uCRobotics Andreas Färber
                   ` (13 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, Russell King,
	devicetree

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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@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         |  24 ++++
 arch/arm/boot/dts/s500.dtsi                | 170 +++++++++++++++++++++++++++++
 4 files changed, 222 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 0118084..578a20b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -638,6 +638,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 0000000..834b71d
--- /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 0000000..31c5def
--- /dev/null
+++ b/arch/arm/boot/dts/s500-guitar.dtsi
@@ -0,0 +1,24 @@
+/*
+ * 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";
+
+	/delete-node/ memory;
+
+	memory@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 0000000..1973181
--- /dev/null
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -0,0 +1,170 @@
+/*
+ * Actions Semi S500 SoC
+ *
+ * Copyright (c) 2016-2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include "skeleton.dtsi"
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "actions,s500";
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x1>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x2>;
+		};
+
+		cpu3: cpu@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@b0020000 {
+			compatible = "arm,cortex-a9-scu";
+			reg = <0xb0020000 0x100>;
+		};
+
+		global_timer: timer@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@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@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@b0021000 {
+			compatible = "arm,cortex-a9-gic";
+			reg = <0xb0021000 0x1000>,
+			      <0xb0020100 0x0100>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+		};
+
+		l2: cache-controller@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@b0120000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0120000 0x2000>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart1: serial@b0122000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0122000 0x2000>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart2: serial@b0124000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0124000 0x2000>;
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart3: serial@b0126000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0126000 0x2000>;
+			interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart4: serial@b0128000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb0128000 0x2000>;
+			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart5: serial@b012a000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb012a000 0x2000>;
+			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		uart6: serial@b012c000 {
+			compatible = "actions,s500-uart", "actions,owl-uart";
+			reg = <0xb012c000 0x2000>;
+			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		timer: timer@b0168000 {
+			compatible = "actions,s500-timer", "actions,owl-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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 12/25] dt-bindings: Add vendor prefix for uCRobotics
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (10 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 13/25] dt-bindings: arm: Document Actions Semi S900 Andreas Färber
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

Cc: 96boards@ucrobotics.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v1 -> v2 -> v3: 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 2f294c8..44232c2 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -320,6 +320,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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 13/25] dt-bindings: arm: Document Actions Semi S900
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (11 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 12/25] dt-bindings: Add vendor prefix for uCRobotics Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 14/25] ARM64: dts: Add Actions Semi S900 and Bubblegum-96 Andreas Färber
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

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@ucrobotics.com
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v2 -> v3: 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 1d3782e..3bc7ea5 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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 14/25] ARM64: dts: Add Actions Semi S900 and Bubblegum-96
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (12 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 13/25] dt-bindings: arm: Document Actions Semi S900 Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 15/25] MAINTAINERS: Add Actions Semi Owl section Andreas Färber
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, devicetree

UART0/1/4/6 interrupts are guesses.

Cc: 96boards@ucrobotics.com
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v2 -> v3:
 * Added remaining UART nodes -- some interrupts are guesses
 * Added timer node -- only TIMER1 interrupt known
 
 v1 -> v2:
 * Reworded subject
 * Added memory@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 080232b..d1a6b0a 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 0000000..62922d6
--- /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 0000000..a0c3484
--- /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@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 0000000..6048651
--- /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@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53", "arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu@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@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@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@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@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@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@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@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@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@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@e0228000 {
+			compatible = "actions,s900-timer";
+			reg = <0x0 0xe0228000 0x0 0x8000>;
+			interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "Timer1";
+		};
+	};
+};
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 15/25] MAINTAINERS: Add Actions Semi Owl section
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (13 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 14/25] ARM64: dts: Add Actions Semi S900 and Bubblegum-96 Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 16/25] tty: serial: owl: Implement console driver Andreas Färber
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v2 -> v3: unchanged
 
 v2: new
 
 MAINTAINERS | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b9af886..467121e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1026,6 +1026,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@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@lists.infradead.org (moderated for non-subscribers)
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 16/25] tty: serial: owl: Implement console driver
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (14 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 15/25] MAINTAINERS: Add Actions Semi Owl section Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 17/25] ARM64: dts: actions: s900-bubblegum-96: Add fake uart5 clock Andreas Färber
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Greg Kroah-Hartman, Jiri Slaby,
	linux-serial

Implement serial console driver to complement earlycon.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 e145822..ef232ac 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1678,7 +1678,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
@@ -1694,7 +1694,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 1b80087..14e0324 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 9ec741b..5e850e6 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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 17/25] ARM64: dts: actions: s900-bubblegum-96: Add fake uart5 clock
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (15 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 16/25] tty: serial: owl: Implement console driver Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 18/25] ARM: dts: s500-guitar-bb-rev-b: Add fake uart3 clock Andreas Färber
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon, devicetree

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

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v2 -> v3: 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 a0c3484..21ca80f 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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 18/25] ARM: dts: s500-guitar-bb-rev-b: Add fake uart3 clock
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (16 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 17/25] ARM64: dts: actions: s900-bubblegum-96: Add fake uart5 clock Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 19/25] dt-bindings: arm: cpus: Add S500 enable-method Andreas Färber
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, Russell King,
	devicetree

Add a fixed-clock for baudrate 115200.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v2 -> v3: 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 834b71d..f6fd10a 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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 19/25] dt-bindings: arm: cpus: Add S500 enable-method
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (17 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 18/25] ARM: dts: s500-guitar-bb-rev-b: Add fake uart3 clock Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-03-03  6:21   ` Rob Herring
  2017-02-28  6:35 ` [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500 Andreas Färber
                   ` (5 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

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

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 698ad1f0..e3e1e2f 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -192,6 +192,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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (18 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 19/25] dt-bindings: arm: cpus: Add S500 enable-method Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-03-01  7:19   ` kbuild test robot
  2017-02-28  6:35 ` [PATCH v3 21/25] ARM: dts: s500: Set CPU enable-method Andreas Färber
                   ` (4 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Russell King

Allow to bring up CPU1.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v3: new
 
 arch/arm/mach-actions/Makefile  |   1 +
 arch/arm/mach-actions/headsmp.S |  68 ++++++++++++++++
 arch/arm/mach-actions/platsmp.c | 166 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 235 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 524c381..2fb61f8 100644
--- a/arch/arm/mach-actions/Makefile
+++ b/arch/arm/mach-actions/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ARCH_ACTIONS) += owl.o
+obj-${CONFIG_ARCH_ACTIONS} += platsmp.o headsmp.o
diff --git a/arch/arm/mach-actions/headsmp.S b/arch/arm/mach-actions/headsmp.S
new file mode 100644
index 0000000..dc4832f
--- /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 0000000..9d3601e
--- /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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 21/25] ARM: dts: s500: Set CPU enable-method
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (19 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500 Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 22/25] dt-bindings: power: Add Owl SPS power domains Andreas Färber
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, Russell King,
	devicetree

Use a custom S500 enable-method for all CPUs.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 1973181..b4ebd27 100644
--- a/arch/arm/boot/dts/s500.dtsi
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -22,24 +22,28 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x0>;
+			enable-method = "actions,s500-smp";
 		};
 
 		cpu1: cpu@1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x1>;
+			enable-method = "actions,s500-smp";
 		};
 
 		cpu2: cpu@2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x2>;
+			enable-method = "actions,s500-smp";
 		};
 
 		cpu3: cpu@3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0x3>;
+			enable-method = "actions,s500-smp";
 		};
 	};
 
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 22/25] dt-bindings: power: Add Owl SPS power domains
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (20 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 21/25] ARM: dts: s500: Set CPU enable-method Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-03-03  6:21   ` Rob Herring
  2017-02-28  6:35 ` [PATCH v3 23/25] soc: actions: Add Owl SPS Andreas Färber
                   ` (2 subsequent siblings)
  24 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, devicetree

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

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 0000000..c5eed06
--- /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@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 0000000..ccc4ac3
--- /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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 23/25] soc: actions: Add Owl SPS
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (21 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 22/25] dt-bindings: power: Add Owl SPS power domains Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 24/25] ARM: dts: s500: Add SPS node Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 25/25] ARM: owl: smp: Reimplement SPS power-gating for CPU2 and CPU3 Andreas Färber
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber

Implement S500 Smart Power System power-gating.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 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 | 245 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 260 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 45e5b13..afd3c43 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 3467de7..a934480 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 0000000..f877f7d
--- /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 0000000..720c34e
--- /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 0000000..caf777e
--- /dev/null
+++ b/drivers/soc/actions/owl-sps.c
@@ -0,0 +1,245 @@
+/*
+ * 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;
+};
+
+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);
+
+	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);
+
+	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 = 0;
+	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,
+	},
+	[S500_PD_CPU3] = {
+		.name = "CPU3",
+		.pwr_bit = 6,
+		.ack_bit = 22,
+	},
+	[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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 24/25] ARM: dts: s500: Add SPS node
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (22 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 23/25] soc: actions: Add Owl SPS Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  2017-02-28  6:35 ` [PATCH v3 25/25] ARM: owl: smp: Reimplement SPS power-gating for CPU2 and CPU3 Andreas Färber
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Rob Herring, Mark Rutland, Russell King,
	devicetree

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v3: new
 
 arch/arm/boot/dts/s500.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/s500.dtsi b/arch/arm/boot/dts/s500.dtsi
index b4ebd27..e802896 100644
--- a/arch/arm/boot/dts/s500.dtsi
+++ b/arch/arm/boot/dts/s500.dtsi
@@ -9,6 +9,7 @@
 #include "skeleton.dtsi"
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/s500-powergate.h>
 
 / {
 	compatible = "actions,s500";
@@ -37,6 +38,7 @@
 			compatible = "arm,cortex-a9";
 			reg = <0x2>;
 			enable-method = "actions,s500-smp";
+			power-domains = <&sps S500_PD_CPU2>;
 		};
 
 		cpu3: cpu@3 {
@@ -44,6 +46,7 @@
 			compatible = "arm,cortex-a9";
 			reg = <0x3>;
 			enable-method = "actions,s500-smp";
+			power-domains = <&sps S500_PD_CPU3>;
 		};
 	};
 
@@ -170,5 +173,11 @@
 			             <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "2Hz0", "2Hz1", "Timer0", "Timer1";
 		};
+
+		sps: power-controller@b01b0100 {
+			compatible = "actions,s500-sps";
+			reg = <0xb01b0100 0x100>;
+			#power-domain-cells = <1>;
+		};
 	};
 };
-- 
2.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH v3 25/25] ARM: owl: smp: Reimplement SPS power-gating for CPU2 and CPU3
  2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
                   ` (23 preceding siblings ...)
  2017-02-28  6:35 ` [PATCH v3 24/25] ARM: dts: s500: Add SPS node Andreas Färber
@ 2017-02-28  6:35 ` Andreas Färber
  24 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-02-28  6:35 UTC (permalink / raw)
  To: arm
  Cc: linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Andreas Färber, Russell King

Bring up the two remaining CPUs.

Based on LeMaker linux-actions tree.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 v3: new
 
 arch/arm/mach-actions/platsmp.c | 67 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-actions/platsmp.c b/arch/arm/mach-actions/platsmp.c
index 9d3601e..45b4bc5 100644
--- a/arch/arm/mach-actions/platsmp.c
+++ b/arch/arm/mach-actions/platsmp.c
@@ -28,7 +28,15 @@
 
 #define OWL_CPUx_FLAG_BOOT	0x55aa
 
+#define OWL_SPS_PG_CTL	0x0
+
+#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;
 
@@ -42,6 +50,39 @@ static void write_pen_release(int val)
 	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
 }
 
+/* The generic PM domain driver is not available this early. */
+static int owl_sps_set_pg(u32 pwr_mask, u32 ack_mask, bool enable)
+{
+	u32 val;
+	bool ack;
+	int timeout;
+
+	val = readl(sps_base_addr + OWL_SPS_PG_CTL);
+	ack = val & ack_mask;
+	if (ack == enable)
+		return 0;
+
+	if (enable)
+		val |= pwr_mask;
+	else
+		val &= ~pwr_mask;
+
+	writel(val, sps_base_addr + OWL_SPS_PG_CTL);
+
+	for (timeout = 5000; timeout > 0; timeout -= 50) {
+		val = readl(sps_base_addr + 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 void s500_smp_secondary_init(unsigned int cpu)
 {
 	/*
@@ -58,14 +99,24 @@ void owl_secondary_startup(void);
 
 static int s500_wakeup_secondary(unsigned int cpu)
 {
+	int ret;
+
 	if (cpu > 3)
 		return -EINVAL;
 
 	switch (cpu) {
 	case 2:
+		ret = owl_sps_set_pg(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(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 +184,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.10.2

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar
  2017-02-28  6:35 ` [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar Andreas Färber
@ 2017-02-28 12:32   ` Mark Rutland
  2017-02-28 15:13     ` Andreas Färber
  0 siblings, 1 reply; 45+ messages in thread
From: Mark Rutland @ 2017-02-28 12:32 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Rob Herring, Russell King, devicetree

Hi,

On Tue, Feb 28, 2017 at 07:35:21AM +0100, Andreas Färber wrote:
> +/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";
> +};

> +#include "s500.dtsi"
> +
> +/ {
> +	compatible = "lemaker,guitar", "actions,s500";
> +
> +	/delete-node/ memory;

Eww. Is this just bodging around skeleton.dtsi?

> +
> +	memory@0 {
> +		device_type = "memory";
> +		reg = <0x0 0x40000000>;
> +	};
> +};

> +#include "skeleton.dtsi"

Please don't include skeleton.dtsi. Please add the relevant nodes and
properties explciitly to your dts{i,} files.

> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {

Please define your #address-cells and #size-cells here.

If you want, add an empty /chosen node (not strictly necessary since
your dts file has a non-empty one anyhow).

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 03/25] dt-bindings: timer: Document Owl timer
  2017-02-28  6:35 ` [PATCH v3 03/25] dt-bindings: timer: Document Owl timer Andreas Färber
@ 2017-02-28 12:39   ` Mark Rutland
  2017-03-03  6:20     ` Rob Herring
  0 siblings, 1 reply; 45+ messages in thread
From: Mark Rutland @ 2017-02-28 12:39 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Rob Herring, devicetree

On Tue, Feb 28, 2017 at 07:35:13AM +0100, Andreas Färber wrote:
> 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.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  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 0000000..5b4834d
> --- /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"

Sticking to lower case for the names would be preferable.

Otherwise, this looks fine.

Mark,.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar
  2017-02-28 12:32   ` Mark Rutland
@ 2017-02-28 15:13     ` Andreas Färber
  2017-03-01 18:43       ` Mark Rutland
  0 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28 15:13 UTC (permalink / raw)
  To: Mark Rutland, Arnd Bergmann
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Rob Herring, Russell King, devicetree, outreachy-kernel

Hi Mark,

Am 28.02.2017 um 13:32 schrieb Mark Rutland:
> On Tue, Feb 28, 2017 at 07:35:21AM +0100, Andreas Färber wrote:
>> +/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";
>> +};
> 
>> +#include "s500.dtsi"
>> +
>> +/ {
>> +	compatible = "lemaker,guitar", "actions,s500";
>> +
>> +	/delete-node/ memory;
> 
> Eww. Is this just bodging around skeleton.dtsi?

I guess so: Working around its hardcoded name without unit address, not
finding a /rename-node/ to that effect.

>> +
>> +	memory@0 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x40000000>;
>> +	};
>> +};
> 
>> +#include "skeleton.dtsi"
> 
> Please don't include skeleton.dtsi.

Wasn't aware that was permissible. I now see it has been updated with a
textual comment, which predates my past uses of skeleton.dtsi - for
other pending work such as FM4 and XMC4500 I only noticed it was moved
out of armv7m.dtsi so that dtc started spewing scary messages. ;)

A #warning might be a more effective way to make people aware of its
deprecation - but sadly we have users that predate #include:

$ git grep /include/ -- arch/arm/boot/dts/ | grep skeleton.dtsi | wc --lines
32
$ git grep /include/ -- arch/arm/boot/dts/ | grep skeleton64.dtsi | wc
--lines
0
$ git grep skeleton -- arch/arm/boot/dts/ | wc --lines
117

Might updating those 32 users be a suitable Outreachy project (CC'ed),
to then get the remaining 85 occurrences to be eliminated by their
maintainers, so that it doesn't get copied for new SoCs any more? :)

> Please add the relevant nodes and
> properties explciitly to your dts{i,} files.

Great, will do.

But this series has grown too large to resend just for such nits. Is
there a chance we can get initial patches queued on some arm-soc
for-next branch soonish? It seems -rc1 pulls were merged 5 days ago?

Regards,
Andreas

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28  6:35 ` [PATCH v3 04/25] clocksource: Add " Andreas Färber
@ 2017-02-28 16:47   ` Daniel Lezcano
  2017-02-28 17:08     ` Andreas Färber
  0 siblings, 1 reply; 45+ messages in thread
From: Daniel Lezcano @ 2017-02-28 16:47 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Thomas Gleixner

On Tue, Feb 28, 2017 at 07:35:14AM +0100, 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>
> ---
>  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 | 193 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 201 insertions(+)
>  create mode 100644 drivers/clocksource/owl-timer.c
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 3356ab8..2551365 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -107,6 +107,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 d227d13..801b65a 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -53,6 +53,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 0000000..1b1e26d
> --- /dev/null
> +++ b/drivers/clocksource/owl-timer.c
> @@ -0,0 +1,193 @@
> +/*
> + * 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)
> +
> +#define OWL_MAX_Tx 2
> +
> +struct owl_timer_info {
> +	int timer_offset[OWL_MAX_Tx];
> +};
> +
> +static const struct owl_timer_info *owl_timer_info;
> +
> +static void __iomem *owl_timer_base;
> +
> +static inline void __iomem *owl_timer_get_base(unsigned timer_nr)
> +{
> +	if (timer_nr >= OWL_MAX_Tx)
> +		return NULL;

The driver is supposed to know what is doing. owl_timer_get_base won't be
called with an invalid index. This test will have a cost as it is called from
owl_timer_sched_read.

> +
> +	return owl_timer_base + owl_timer_info->timer_offset[timer_nr];

Actually, you just need a clkevt base @ and a clocksource base @.

Instead of computing again and again the base, why not just precompute:

	owl_clksrc_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER0]
	owl_clkevt_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER1]

  at init time.

And use these variables directly in the functions.

> +}
> +
> +static inline void owl_timer_reset(unsigned index)
> +{
> +	void __iomem *base;
> +
> +	base = owl_timer_get_base(index);
> +	if (!base)
> +		return;

Same here, this test is pointless.

> +	writel(0, base + OWL_Tx_CTL);
> +	writel(0, base + OWL_Tx_VAL);
> +	writel(0, base + OWL_Tx_CMP);
> +}

I suggest:

static inline void owl_timer_reset(void __iomem *addr)
{
	writel(0, addr + OWL_Tx_CTL);
	writel(0, addr + OWL_Tx_VAL);
	writel(0, addr + OWL_Tx_CMP);
}

> +
> +static u64 notrace owl_timer_sched_read(void)
> +{
> +	return (u64)readl(owl_timer_get_base(0) + OWL_Tx_VAL);

	return (u64)readl(owl_clksrc_base + OWL_Tx_VAL);

> +}
> +

static inline int owl_timer_set_state_disable(struct clock_event_device *evt)
{
	return writel(0, owl_clkevt_base + OWL_Tx_CTL);
}


> +static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
> +{
> +	writel(0, owl_timer_get_base(0) + OWL_Tx_CTL);

	return owl_timer_set_state_disable(evt);

> +
> +	return 0;
> +}
> +
> +static int owl_timer_set_state_oneshot(struct clock_event_device *evt)
> +{
> +	owl_timer_reset(1);

Do you really need to do reset here ? Why not just owl_timer_set_state_disable(evt) ?

> +	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_timer_get_base(1);
> +
> +	writel(0, base + OWL_Tx_CTL);
> +
> +	writel(0, base + OWL_Tx_VAL);

> +	writel(evt, base + OWL_Tx_CMP);
> +
> +	writel(OWL_Tx_CTL_EN | OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
> +
> +	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_timer_get_base(1) + OWL_Tx_CTL);
> +
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct owl_timer_info s500_timer_info = {
> +	.timer_offset[0] = 0x08,
> +	.timer_offset[1] = 0x14,
> +};
> +
> +static const struct of_device_id owl_timer_of_matches[] = {
> +	{ .compatible = "actions,s500-timer", .data = &s500_timer_info },
> +	{ }
> +};
> +
> +static int __init owl_timer_init(struct device_node *node)
> +{
> +	const struct of_device_id *match;
> +	struct clk *clk;
> +	unsigned long rate;
> +	int timer1_irq, i, ret;
> +
> +	match = of_match_node(owl_timer_of_matches, node);
> +	if (!match || !match->data) {
> +		pr_err("Unknown compatible");
> +		return -EINVAL;
> +	}
> +
> +	owl_timer_info = match->data;
> +
> +	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);
> +	}
> +
> +	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);
> +
> +	for (i = 0; i < OWL_MAX_Tx; i++)
> +		owl_timer_reset(i);
> +
> +	writel(OWL_Tx_CTL_EN, owl_timer_get_base(0) + OWL_Tx_CTL);
> +
> +	sched_clock_register(owl_timer_sched_read, 32, rate);
> +	clocksource_mmio_init(owl_timer_get_base(0) + OWL_Tx_VAL, node->name,
> +			      rate, 200, 32, clocksource_mmio_readl_up);
> +
> +	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.10.2
> 

-- 

 <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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28 16:47   ` Daniel Lezcano
@ 2017-02-28 17:08     ` Andreas Färber
  2017-02-28 17:39       ` Daniel Lezcano
  0 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28 17:08 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Thomas Gleixner

Am 28.02.2017 um 17:47 schrieb Daniel Lezcano:
> On Tue, Feb 28, 2017 at 07:35:14AM +0100, 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>
>> ---
>>  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 | 193 ++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 201 insertions(+)
>>  create mode 100644 drivers/clocksource/owl-timer.c
>>
>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>> index 3356ab8..2551365 100644
>> --- a/drivers/clocksource/Kconfig
>> +++ b/drivers/clocksource/Kconfig
>> @@ -107,6 +107,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 d227d13..801b65a 100644
>> --- a/drivers/clocksource/Makefile
>> +++ b/drivers/clocksource/Makefile
>> @@ -53,6 +53,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 0000000..1b1e26d
>> --- /dev/null
>> +++ b/drivers/clocksource/owl-timer.c
>> @@ -0,0 +1,193 @@
>> +/*
>> + * 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)
>> +
>> +#define OWL_MAX_Tx 2
>> +
>> +struct owl_timer_info {
>> +	int timer_offset[OWL_MAX_Tx];
>> +};
>> +
>> +static const struct owl_timer_info *owl_timer_info;
>> +
>> +static void __iomem *owl_timer_base;
>> +
>> +static inline void __iomem *owl_timer_get_base(unsigned timer_nr)
>> +{
>> +	if (timer_nr >= OWL_MAX_Tx)
>> +		return NULL;
> 
> The driver is supposed to know what is doing. owl_timer_get_base won't be
> called with an invalid index. This test will have a cost as it is called from
> owl_timer_sched_read.

OK

>> +
>> +	return owl_timer_base + owl_timer_info->timer_offset[timer_nr];
> 
> Actually, you just need a clkevt base @ and a clocksource base @.
> 
> Instead of computing again and again the base, why not just precompute:
> 
> 	owl_clksrc_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER0]
> 	owl_clkevt_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER1]
> 
>   at init time.
> 
> And use these variables directly in the functions.

Either that, or revert to previous simpler behavior...

>> +}
>> +
>> +static inline void owl_timer_reset(unsigned index)
>> +{
>> +	void __iomem *base;
>> +
>> +	base = owl_timer_get_base(index);
>> +	if (!base)
>> +		return;
> 
> Same here, this test is pointless.

Seems like you didn't look at the following patch yet. It sets two S500
offsets as -1, i.e. non-existant, which then results in NULL here.

>> +	writel(0, base + OWL_Tx_CTL);
>> +	writel(0, base + OWL_Tx_VAL);
>> +	writel(0, base + OWL_Tx_CMP);
>> +}
> 
> I suggest:
> 
> static inline void owl_timer_reset(void __iomem *addr)
> {
> 	writel(0, addr + OWL_Tx_CTL);
> 	writel(0, addr + OWL_Tx_VAL);
> 	writel(0, addr + OWL_Tx_CMP);
> }

OK

>> +
>> +static u64 notrace owl_timer_sched_read(void)
>> +{
>> +	return (u64)readl(owl_timer_get_base(0) + OWL_Tx_VAL);
> 
> 	return (u64)readl(owl_clksrc_base + OWL_Tx_VAL);
> 
>> +}
>> +
> 
> static inline int owl_timer_set_state_disable(struct clock_event_device *evt)
> {
> 	return writel(0, owl_clkevt_base + OWL_Tx_CTL);
> }

That I don't like. Disabling is just setting a bit. We save a readl by
just writing where we know it's safe. An API like this is not safe.

>> +static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
>> +{
>> +	writel(0, owl_timer_get_base(0) + OWL_Tx_CTL);
> 
> 	return owl_timer_set_state_disable(evt);
> 
>> +
>> +	return 0;
>> +}
>> +
>> +static int owl_timer_set_state_oneshot(struct clock_event_device *evt)
>> +{
>> +	owl_timer_reset(1);
> 
> Do you really need to do reset here ? Why not just owl_timer_set_state_disable(evt) ?

Matches downstream, will consider changing.

>> +	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_timer_get_base(1);
>> +
>> +	writel(0, base + OWL_Tx_CTL);
>> +
>> +	writel(0, base + OWL_Tx_VAL);
> 

Are you suggesting a while line here? The point was disable first, then
initialize (2x), then activate. Maybe add comments instead?

>> +	writel(evt, base + OWL_Tx_CMP);
>> +
>> +	writel(OWL_Tx_CTL_EN | OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
>> +
>> +	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_timer_get_base(1) + OWL_Tx_CTL);
>> +
>> +	evt->event_handler(evt);

Is there any guideline as to whether to clear such flag before or after?

>> +
>> +	return IRQ_HANDLED;
>> +}

Regards,
Andreas

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 05/25] clocksource: owl: Add S900 support
  2017-02-28  6:35 ` [PATCH v3 05/25] clocksource: owl: Add S900 support Andreas Färber
@ 2017-02-28 17:16   ` Andreas Färber
  2017-02-28 17:42     ` Daniel Lezcano
  0 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28 17:16 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: arm, support, linux-kernel, mp-cs, 96boards, Thomas Gleixner,
	linux-arm-kernel

Daniel,

Am 28.02.2017 um 07:35 schrieb Andreas Färber:
> The Actions Semi S900 SoC provides four 32-bit timers, TIMER0/1/2/3,
> but no 2Hz timers.
> 
> Deal with the S500 having less 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>
[...]
> @@ -126,10 +127,20 @@ static irqreturn_t owl_timer1_interrupt(int irq, void *dev_id)
>  static const struct owl_timer_info s500_timer_info = {
>  	.timer_offset[0] = 0x08,
>  	.timer_offset[1] = 0x14,
> +	.timer_offset[2] = -1,
> +	.timer_offset[3] = -1,
> +};
> +
> +static const struct owl_timer_info s900_timer_info = {
> +	.timer_offset[0] = 0x08,
> +	.timer_offset[1] = 0x14,
> +	.timer_offset[2] = 0x30,
> +	.timer_offset[3] = 0x3c,
>  };

I noticed later that the S900 manual describes TIMER2/3 as "used only in
Secure mode". My driver code resetting them seems to work though.

Should we just drop these extra timer initializations then to make the
driver simpler and more performant again? I'd still like to keep the two
compatible strings in the DT though, and we may want to disable the 2Hz
timers on S500 just in case.

Regards,
Andreas

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28 17:08     ` Andreas Färber
@ 2017-02-28 17:39       ` Daniel Lezcano
  2017-02-28 18:01         ` Andreas Färber
  2017-02-28 18:53         ` Thomas Gleixner
  0 siblings, 2 replies; 45+ messages in thread
From: Daniel Lezcano @ 2017-02-28 17:39 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Thomas Gleixner

On Tue, Feb 28, 2017 at 06:08:06PM +0100, Andreas Färber wrote:

[ ... ]

> > Instead of computing again and again the base, why not just precompute:
> > 
> > 	owl_clksrc_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER0]
> > 	owl_clkevt_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER1]
> > 
> >   at init time.
> > 
> > And use these variables directly in the functions.
> 
> Either that, or revert to previous simpler behavior...

Not sure to get what the 'previous simpler behavior' is, but until it does not
recompute the offset each time, I'm fine with that.

> >> +}
> >> +
> >> +static inline void owl_timer_reset(unsigned index)
> >> +{
> >> +	void __iomem *base;
> >> +
> >> +	base = owl_timer_get_base(index);
> >> +	if (!base)
> >> +		return;
> > 
> > Same here, this test is pointless.
> 
> Seems like you didn't look at the following patch yet. It sets two S500
> offsets as -1, i.e. non-existant, which then results in NULL here.

May be I missed something, but so far, the base addresses must be setup before
reset is called, no?

> >> +	writel(0, base + OWL_Tx_CTL);
> >> +	writel(0, base + OWL_Tx_VAL);
> >> +	writel(0, base + OWL_Tx_CMP);
> >> +}
> > 
> > I suggest:
> > 
> > static inline void owl_timer_reset(void __iomem *addr)
> > {
> > 	writel(0, addr + OWL_Tx_CTL);
> > 	writel(0, addr + OWL_Tx_VAL);
> > 	writel(0, addr + OWL_Tx_CMP);
> > }
> 
> OK
> 
> >> +
> >> +static u64 notrace owl_timer_sched_read(void)
> >> +{
> >> +	return (u64)readl(owl_timer_get_base(0) + OWL_Tx_VAL);
> > 
> > 	return (u64)readl(owl_clksrc_base + OWL_Tx_VAL);
> > 
> >> +}
> >> +
> > 
> > static inline int owl_timer_set_state_disable(struct clock_event_device *evt)
> > {
> > 	return writel(0, owl_clkevt_base + OWL_Tx_CTL);
> > }
> 
> That I don't like. Disabling is just setting a bit. We save a readl by
> just writing where we know it's safe. An API like this is not safe.

I don't get the point. Writing this simple function has the benefit to give the
reader the information about the disabling register. Even if it does make sense
for you, for me it has its purpose when I try to factor out different drivers
code.

> >> +static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
> >> +{
> >> +	writel(0, owl_timer_get_base(0) + OWL_Tx_CTL);
> > 
> > 	return owl_timer_set_state_disable(evt);
> > 
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int owl_timer_set_state_oneshot(struct clock_event_device *evt)
> >> +{
> >> +	owl_timer_reset(1);
> > 
> > Do you really need to do reset here ? Why not just owl_timer_set_state_disable(evt) ?
> 
> Matches downstream, will consider changing.
> 
> >> +	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_timer_get_base(1);
> >> +
> >> +	writel(0, base + OWL_Tx_CTL);
> >> +
> >> +	writel(0, base + OWL_Tx_VAL);
> > 
> 
> Are you suggesting a while line here? The point was disable first, then
> initialize (2x), then activate. Maybe add comments instead?

I meant, base + OWL_Tx_CTL and base + OWL_Tx_VAL are set to zero since the
beginning. If their values do not change, it is not necessary to set their
values to zero again.
 
> >> +	writel(evt, base + OWL_Tx_CMP);
> >> +
> >> +	writel(OWL_Tx_CTL_EN | OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
> >> +
> >> +	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_timer_get_base(1) + OWL_Tx_CTL);
> >> +
> >> +	evt->event_handler(evt);
> 
> Is there any guideline as to whether to clear such flag before or after?

Mmh, good question. I'm not sure it makes a different.

> >> +
> >> +	return IRQ_HANDLED;
> >> +}
> 
> Regards,
> Andreas
> 
> -- 
> SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)

-- 

 <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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 05/25] clocksource: owl: Add S900 support
  2017-02-28 17:16   ` Andreas Färber
@ 2017-02-28 17:42     ` Daniel Lezcano
  0 siblings, 0 replies; 45+ messages in thread
From: Daniel Lezcano @ 2017-02-28 17:42 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, support, linux-kernel, mp-cs, 96boards, Thomas Gleixner,
	linux-arm-kernel

On Tue, Feb 28, 2017 at 06:16:10PM +0100, Andreas Färber wrote:
> Daniel,
> 
> Am 28.02.2017 um 07:35 schrieb Andreas Färber:
> > The Actions Semi S900 SoC provides four 32-bit timers, TIMER0/1/2/3,
> > but no 2Hz timers.
> > 
> > Deal with the S500 having less 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>
> [...]
> > @@ -126,10 +127,20 @@ static irqreturn_t owl_timer1_interrupt(int irq, void *dev_id)
> >  static const struct owl_timer_info s500_timer_info = {
> >  	.timer_offset[0] = 0x08,
> >  	.timer_offset[1] = 0x14,
> > +	.timer_offset[2] = -1,
> > +	.timer_offset[3] = -1,
> > +};
> > +
> > +static const struct owl_timer_info s900_timer_info = {
> > +	.timer_offset[0] = 0x08,
> > +	.timer_offset[1] = 0x14,
> > +	.timer_offset[2] = 0x30,
> > +	.timer_offset[3] = 0x3c,
> >  };
> 
> I noticed later that the S900 manual describes TIMER2/3 as "used only in
> Secure mode". My driver code resetting them seems to work though.
> 
> Should we just drop these extra timer initializations then to make the
> driver simpler and more performant again? I'd still like to keep the two
> compatible strings in the DT though, and we may want to disable the 2Hz
> timers on S500 just in case.

Yes, makes sense.

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

-- 

 <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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28 17:39       ` Daniel Lezcano
@ 2017-02-28 18:01         ` Andreas Färber
  2017-02-28 18:56           ` Thomas Gleixner
  2017-02-28 18:53         ` Thomas Gleixner
  1 sibling, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-02-28 18:01 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Thomas Gleixner

Am 28.02.2017 um 18:39 schrieb Daniel Lezcano:
> On Tue, Feb 28, 2017 at 06:08:06PM +0100, Andreas Färber wrote:
>>> Instead of computing again and again the base, why not just precompute:
>>>
>>> 	owl_clksrc_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER0]
>>> 	owl_clkevt_base = owl_timer_base + owl_timer_info->timer_offset[OWL_TIMER1]
>>>
>>>   at init time.
>>>
>>> And use these variables directly in the functions.
>>
>> Either that, or revert to previous simpler behavior...
> 
> Not sure to get what the 'previous simpler behavior' is,

v2. :)

> but until it does not
> recompute the offset each time, I'm fine with that.

>>>> +}
>>>> +
>>>> +static inline void owl_timer_reset(unsigned index)
>>>> +{
>>>> +	void __iomem *base;
>>>> +
>>>> +	base = owl_timer_get_base(index);
>>>> +	if (!base)
>>>> +		return;
>>>
>>> Same here, this test is pointless.
>>
>> Seems like you didn't look at the following patch yet. It sets two S500
>> offsets as -1, i.e. non-existant, which then results in NULL here.
> 
> May be I missed something, but so far, the base addresses must be setup before
> reset is called, no?

They are known in advance, yes. Where/how we set them up is the culprit.

>>> static inline int owl_timer_set_state_disable(struct clock_event_device *evt)
>>> {
>>> 	return writel(0, owl_clkevt_base + OWL_Tx_CTL);
>>> }
>>
>> That I don't like. Disabling is just setting a bit. We save a readl by
>> just writing where we know it's safe. An API like this is not safe.
> 
> I don't get the point. Writing this simple function has the benefit to give the
> reader the information about the disabling register. Even if it does make sense
> for you, for me it has its purpose when I try to factor out different drivers
> code.

I mean a proper _disable() function would need to do:

val = readl()
val &= ~bit;
writel(val)

Not just writel(0), overwriting any other bits. Therefore an inline
write would be faster - your concern elsewhere. I'll happily implement
the proper API if you prefer.

>>>> +static int owl_timer_set_state_shutdown(struct clock_event_device *evt)
>>>> +{
>>>> +	writel(0, owl_timer_get_base(0) + OWL_Tx_CTL);
>>>
>>> 	return owl_timer_set_state_disable(evt);
>>>
>>>> +
>>>> +	return 0;
>>>> +}

>>>> +static int owl_timer_set_next_event(unsigned long evt,
>>>> +				    struct clock_event_device *ev)
>>>> +{
>>>> +	void __iomem *base = owl_timer_get_base(1);
>>>> +
>>>> +	writel(0, base + OWL_Tx_CTL);
>>>> +
>>>> +	writel(0, base + OWL_Tx_VAL);
>>>
>>
>> Are you suggesting a while line here? The point was disable first, then
>> initialize (2x), then activate. Maybe add comments instead?
> 
> I meant, base + OWL_Tx_CTL and base + OWL_Tx_VAL are set to zero since the
> beginning. If their values do not change, it is not necessary to set their
> values to zero again.

This is a callback, which I thought is re-entrant. VAL changes when the
timer is running, and CTL changes every time we enable the timer. We
could call _reset() here, but then we would be initializing CMP twice,
which again would be less performant then just setting the registers to
their final values directly.

>>>> +	writel(evt, base + OWL_Tx_CMP);
>>>> +
>>>> +	writel(OWL_Tx_CTL_EN | OWL_Tx_CTL_INTEN, base + OWL_Tx_CTL);
>>>> +
>>>> +	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_timer_get_base(1) + OWL_Tx_CTL);
>>>> +
>>>> +	evt->event_handler(evt);
>>
>> Is there any guideline as to whether to clear such flag before or after?
> 
> Mmh, good question. I'm not sure it makes a different.
> 
>>>> +
>>>> +	return IRQ_HANDLED;
>>>> +}

Thanks,
Andreas

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28 17:39       ` Daniel Lezcano
  2017-02-28 18:01         ` Andreas Färber
@ 2017-02-28 18:53         ` Thomas Gleixner
  1 sibling, 0 replies; 45+ messages in thread
From: Thomas Gleixner @ 2017-02-28 18:53 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Andreas Färber, arm, linux-arm-kernel, mp-cs, 96boards,
	support, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 866 bytes --]

On Tue, 28 Feb 2017, Daniel Lezcano wrote:
> On Tue, Feb 28, 2017 at 06:08:06PM +0100, Andreas Färber wrote:
> > >> +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_timer_get_base(1) + OWL_Tx_CTL);
> > >> +
> > >> +	evt->event_handler(evt);
> > 
> > Is there any guideline as to whether to clear such flag before or after?
> 
> Mmh, good question. I'm not sure it makes a different.

It makes a difference depending on what this flag does. If it clears the
current pending interrupt, then you _must_ do it before rearming the
timer. Otherwise you might clear the pending interrupt of the rearmed timer
(when the timeout is very small) which makes the machine wait forever for
the next timer interrupt.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 04/25] clocksource: Add Owl timer
  2017-02-28 18:01         ` Andreas Färber
@ 2017-02-28 18:56           ` Thomas Gleixner
  0 siblings, 0 replies; 45+ messages in thread
From: Thomas Gleixner @ 2017-02-28 18:56 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Daniel Lezcano, arm, linux-arm-kernel, mp-cs, 96boards, support,
	linux-kernel

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

On Tue, 28 Feb 2017, Andreas Färber wrote:
> This is a callback, which I thought is re-entrant.

It's not reentrant at least not on the same CPU. On a SMP machine this
function might be called concurrently on several cores (assumed that the
whole thing is replicated across cores).

> VAL changes when the timer is running, and CTL changes every time we
> enable the timer. We could call _reset() here, but then we would be
> initializing CMP twice, which again would be less performant then just
> setting the registers to their final values directly.

Makes sense.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500
  2017-02-28  6:35 ` [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500 Andreas Färber
@ 2017-03-01  7:19   ` kbuild test robot
  2017-03-01 10:40     ` Andreas Färber
  0 siblings, 1 reply; 45+ messages in thread
From: kbuild test robot @ 2017-03-01  7:19 UTC (permalink / raw)
  To: Andreas Färber
  Cc: kbuild-all, arm, linux-arm-kernel, mp-cs, 96boards, support,
	linux-kernel, Andreas Färber, Russell King

[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]

Hi Andreas,

[auto build test ERROR on next-20170228]
[also build test ERROR on v4.10]
[cannot apply to robh/for-next linus/master linux/master v4.9-rc8 v4.9-rc7 v4.9-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Andreas-F-rber/ARM-Initial-Actions-Semi-S500-and-S900-enablement/20170301-110028
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

   arch/arm/mach-actions/headsmp.S: Assembler messages:
>> arch/arm/mach-actions/headsmp.S:43: Error: selected processor does not support `dsb' in ARM mode
>> arch/arm/mach-actions/headsmp.S:44: Error: selected processor does not support `isb' in ARM mode

vim +43 arch/arm/mach-actions/headsmp.S

    37		mov	r6, r2, lsl r0
    38		orr	r5, r5, r6	@ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
    39		mcr	p15, 0, r5, c7, c6, 2
    40		bgt	2b
    41		cmp	r2, #0
    42		bgt	1b
  > 43		dsb
  > 44		isb
    45		mov	pc, lr
    46	ENDPROC(owl_v7_invalidate_l1)
    47	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 61367 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500
  2017-03-01  7:19   ` kbuild test robot
@ 2017-03-01 10:40     ` Andreas Färber
  2017-03-03 23:00       ` Andreas Färber
  0 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2017-03-01 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kbuild test robot, kbuild-all, arm, mp-cs, 96boards, support,
	linux-kernel, Russell King

Am 01.03.2017 um 08:19 schrieb kbuild test robot:
> Hi Andreas,
> 
> [auto build test ERROR on next-20170228]
> [also build test ERROR on v4.10]
> [cannot apply to robh/for-next linus/master linux/master v4.9-rc8 v4.9-rc7 v4.9-rc6]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Andreas-F-rber/ARM-Initial-Actions-Semi-S500-and-S900-enablement/20170301-110028
> config: arm-allmodconfig (attached as .config)
> compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
>         wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # save the attached .config to linux build tree
>         make.cross ARCH=arm 
> 
> All errors (new ones prefixed by >>):
> 
>    arch/arm/mach-actions/headsmp.S: Assembler messages:
>>> arch/arm/mach-actions/headsmp.S:43: Error: selected processor does not support `dsb' in ARM mode
>>> arch/arm/mach-actions/headsmp.S:44: Error: selected processor does not support `isb' in ARM mode
> 
> vim +43 arch/arm/mach-actions/headsmp.S
> 
>     37		mov	r6, r2, lsl r0
>     38		orr	r5, r5, r6	@ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
>     39		mcr	p15, 0, r5, c7, c6, 2
>     40		bgt	2b
>     41		cmp	r2, #0
>     42		bgt	1b
>   > 43		dsb
>   > 44		isb

Any suggestion what to do about this error? Obviously it built fine for
me, and the only thing I spotted in the attached config was that it's
apparently a BE8 build...

Do we need a Kconfig "depends on" or some #ifdef here? This assembler
part of the code was merely indentation-fixed by me.

Regards,
Andreas

>     45		mov	pc, lr
>     46	ENDPROC(owl_v7_invalidate_l1)
>     47	
> 
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar
  2017-02-28 15:13     ` Andreas Färber
@ 2017-03-01 18:43       ` Mark Rutland
  0 siblings, 0 replies; 45+ messages in thread
From: Mark Rutland @ 2017-03-01 18:43 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Arnd Bergmann, arm, linux-arm-kernel, mp-cs, 96boards, support,
	linux-kernel, Rob Herring, Russell King, devicetree,
	outreachy-kernel

On Tue, Feb 28, 2017 at 04:13:00PM +0100, Andreas Färber wrote:
> Am 28.02.2017 um 13:32 schrieb Mark Rutland:
> > On Tue, Feb 28, 2017 at 07:35:21AM +0100, Andreas Färber wrote:

> >> +#include "skeleton.dtsi"
> > 
> > Please don't include skeleton.dtsi.
> 
> Wasn't aware that was permissible. I now see it has been updated with a
> textual comment, which predates my past uses of skeleton.dtsi - for
> other pending work such as FM4 and XMC4500 I only noticed it was moved
> out of armv7m.dtsi so that dtc started spewing scary messages. ;)
> 
> A #warning might be a more effective way to make people aware of its
> deprecation - but sadly we have users that predate #include:
> 
> $ git grep /include/ -- arch/arm/boot/dts/ | grep skeleton.dtsi | wc --lines
> 32
> $ git grep /include/ -- arch/arm/boot/dts/ | grep skeleton64.dtsi | wc
> --lines
> 0
> $ git grep skeleton -- arch/arm/boot/dts/ | wc --lines
> 117

I deliberately didn't go that route, since people would blindly fix up
the warning and mess it up (e.g. forgetting to add the required nodes).

While it should be avoided for new dts, it's largely not problematic for
old dts, and we can fix those up at our leisure.

> > Please add the relevant nodes and
> > properties explciitly to your dts{i,} files.
> 
> Great, will do.
> 
> But this series has grown too large to resend just for such nits. Is
> there a chance we can get initial patches queued on some arm-soc
> for-next branch soonish? It seems -rc1 pulls were merged 5 days ago?

There seem to be other comments on this series, and I was under the
impression that arm-soc generally pulled branches.

Even if you're not going to repost, surely you can fold in the fixup
before sending the pull request?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 03/25] dt-bindings: timer: Document Owl timer
  2017-02-28 12:39   ` Mark Rutland
@ 2017-03-03  6:20     ` Rob Herring
  2017-03-03 21:36       ` Andreas Färber
  0 siblings, 1 reply; 45+ messages in thread
From: Rob Herring @ 2017-03-03  6:20 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Andreas Färber, arm, linux-arm-kernel, mp-cs, 96boards,
	support, linux-kernel, devicetree

On Tue, Feb 28, 2017 at 12:39:08PM +0000, Mark Rutland wrote:
> On Tue, Feb 28, 2017 at 07:35:13AM +0100, Andreas Färber wrote:
> > 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.
> > 
> > Signed-off-by: Andreas Färber <afaerber@suse.de>
> > ---
> >  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 0000000..5b4834d
> > --- /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"
> 
> Sticking to lower case for the names would be preferable.

With that,

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 19/25] dt-bindings: arm: cpus: Add S500 enable-method
  2017-02-28  6:35 ` [PATCH v3 19/25] dt-bindings: arm: cpus: Add S500 enable-method Andreas Färber
@ 2017-03-03  6:21   ` Rob Herring
  0 siblings, 0 replies; 45+ messages in thread
From: Rob Herring @ 2017-03-03  6:21 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Mark Rutland, devicetree

On Tue, Feb 28, 2017 at 07:35:29AM +0100, Andreas Färber wrote:
> The Actions Semi S500 SoC requires a special secondary CPU boot procedure.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  v3: new
>  
>  Documentation/devicetree/bindings/arm/cpus.txt | 1 +
>  1 file changed, 1 insertion(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 22/25] dt-bindings: power: Add Owl SPS power domains
  2017-02-28  6:35 ` [PATCH v3 22/25] dt-bindings: power: Add Owl SPS power domains Andreas Färber
@ 2017-03-03  6:21   ` Rob Herring
  0 siblings, 0 replies; 45+ messages in thread
From: Rob Herring @ 2017-03-03  6:21 UTC (permalink / raw)
  To: Andreas Färber
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	Mark Rutland, devicetree

On Tue, Feb 28, 2017 at 07:35:32AM +0100, Andreas Färber wrote:
> Define power domains for all non-reserved S500 power gates.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  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

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 03/25] dt-bindings: timer: Document Owl timer
  2017-03-03  6:20     ` Rob Herring
@ 2017-03-03 21:36       ` Andreas Färber
  0 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-03-03 21:36 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: arm, linux-arm-kernel, mp-cs, 96boards, support, linux-kernel,
	devicetree

Am 03.03.2017 um 07:20 schrieb Rob Herring:
> On Tue, Feb 28, 2017 at 12:39:08PM +0000, Mark Rutland wrote:
>> On Tue, Feb 28, 2017 at 07:35:13AM +0100, Andreas Färber wrote:
>>> 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.
>>>
>>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>>> ---
>>>  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 0000000..5b4834d
>>> --- /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"
>>
>> Sticking to lower case for the names would be preferable.

Done.

> With that,
> 
> Acked-by: Rob Herring <robh@kernel.org>

Thanks,
Andreas

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500
  2017-03-01 10:40     ` Andreas Färber
@ 2017-03-03 23:00       ` Andreas Färber
  0 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2017-03-03 23:00 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: kbuild test robot, kbuild-all, arm, mp-cs, 96boards, support,
	linux-kernel, Russell King

Am 01.03.2017 um 11:40 schrieb Andreas Färber:
> Am 01.03.2017 um 08:19 schrieb kbuild test robot:
>> Hi Andreas,
>>
>> [auto build test ERROR on next-20170228]
>> [also build test ERROR on v4.10]
>> [cannot apply to robh/for-next linus/master linux/master v4.9-rc8 v4.9-rc7 v4.9-rc6]
>> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>>
>> url:    https://github.com/0day-ci/linux/commits/Andreas-F-rber/ARM-Initial-Actions-Semi-S500-and-S900-enablement/20170301-110028
>> config: arm-allmodconfig (attached as .config)
>> compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705
>> reproduce:
>>         wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
>>         chmod +x ~/bin/make.cross
>>         # save the attached .config to linux build tree
>>         make.cross ARCH=arm 
>>
>> All errors (new ones prefixed by >>):
>>
>>    arch/arm/mach-actions/headsmp.S: Assembler messages:
>>>> arch/arm/mach-actions/headsmp.S:43: Error: selected processor does not support `dsb' in ARM mode
>>>> arch/arm/mach-actions/headsmp.S:44: Error: selected processor does not support `isb' in ARM mode
>>
>> vim +43 arch/arm/mach-actions/headsmp.S
>>
>>     37		mov	r6, r2, lsl r0
>>     38		orr	r5, r5, r6	@ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
>>     39		mcr	p15, 0, r5, c7, c6, 2
>>     40		bgt	2b
>>     41		cmp	r2, #0
>>     42		bgt	1b
>>   > 43		dsb
>>   > 44		isb
> 
> Any suggestion what to do about this error? Obviously it built fine for
> me, and the only thing I spotted in the attached config was that it's
> apparently a BE8 build...

And it has V6 enabled. If I set

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

then the error seems resolved.

Regards,
Andreas

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

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2017-03-04  0:52 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-28  6:35 [PATCH v3 00/25] ARM: Initial Actions Semi S500 and S900 enablement Andreas Färber
2017-02-28  6:35 ` [PATCH v3 01/25] dt-bindings: Add vendor prefix for Actions Semi Andreas Färber
2017-02-28  6:35 ` [PATCH v3 02/25] dt-bindings: arm: Document Actions Semi S500 Andreas Färber
2017-02-28  6:35 ` [PATCH v3 03/25] dt-bindings: timer: Document Owl timer Andreas Färber
2017-02-28 12:39   ` Mark Rutland
2017-03-03  6:20     ` Rob Herring
2017-03-03 21:36       ` Andreas Färber
2017-02-28  6:35 ` [PATCH v3 04/25] clocksource: Add " Andreas Färber
2017-02-28 16:47   ` Daniel Lezcano
2017-02-28 17:08     ` Andreas Färber
2017-02-28 17:39       ` Daniel Lezcano
2017-02-28 18:01         ` Andreas Färber
2017-02-28 18:56           ` Thomas Gleixner
2017-02-28 18:53         ` Thomas Gleixner
2017-02-28  6:35 ` [PATCH v3 05/25] clocksource: owl: Add S900 support Andreas Färber
2017-02-28 17:16   ` Andreas Färber
2017-02-28 17:42     ` Daniel Lezcano
2017-02-28  6:35 ` [PATCH v3 06/25] ARM: Prepare Actions Semi S500 Andreas Färber
2017-02-28  6:35 ` [PATCH v3 07/25] ARM64: Prepare Actions Semi S900 Andreas Färber
2017-02-28  6:35 ` [PATCH v3 08/25] dt-bindings: serial: Document Actions Semi Owl UARTs Andreas Färber
2017-02-28  6:35 ` [PATCH v3 09/25] tty: serial: Add Actions Semi Owl UART earlycon Andreas Färber
2017-02-28  6:35 ` [PATCH v3 10/25] Documentation: kernel-parameters: Document owl earlycon Andreas Färber
2017-02-28  6:35 ` [PATCH v3 11/25] ARM: dts: Add Actions Semi S500 and LeMaker Guitar Andreas Färber
2017-02-28 12:32   ` Mark Rutland
2017-02-28 15:13     ` Andreas Färber
2017-03-01 18:43       ` Mark Rutland
2017-02-28  6:35 ` [PATCH v3 12/25] dt-bindings: Add vendor prefix for uCRobotics Andreas Färber
2017-02-28  6:35 ` [PATCH v3 13/25] dt-bindings: arm: Document Actions Semi S900 Andreas Färber
2017-02-28  6:35 ` [PATCH v3 14/25] ARM64: dts: Add Actions Semi S900 and Bubblegum-96 Andreas Färber
2017-02-28  6:35 ` [PATCH v3 15/25] MAINTAINERS: Add Actions Semi Owl section Andreas Färber
2017-02-28  6:35 ` [PATCH v3 16/25] tty: serial: owl: Implement console driver Andreas Färber
2017-02-28  6:35 ` [PATCH v3 17/25] ARM64: dts: actions: s900-bubblegum-96: Add fake uart5 clock Andreas Färber
2017-02-28  6:35 ` [PATCH v3 18/25] ARM: dts: s500-guitar-bb-rev-b: Add fake uart3 clock Andreas Färber
2017-02-28  6:35 ` [PATCH v3 19/25] dt-bindings: arm: cpus: Add S500 enable-method Andreas Färber
2017-03-03  6:21   ` Rob Herring
2017-02-28  6:35 ` [PATCH v3 20/25] ARM: owl: Implement CPU enable-method for S500 Andreas Färber
2017-03-01  7:19   ` kbuild test robot
2017-03-01 10:40     ` Andreas Färber
2017-03-03 23:00       ` Andreas Färber
2017-02-28  6:35 ` [PATCH v3 21/25] ARM: dts: s500: Set CPU enable-method Andreas Färber
2017-02-28  6:35 ` [PATCH v3 22/25] dt-bindings: power: Add Owl SPS power domains Andreas Färber
2017-03-03  6:21   ` Rob Herring
2017-02-28  6:35 ` [PATCH v3 23/25] soc: actions: Add Owl SPS Andreas Färber
2017-02-28  6:35 ` [PATCH v3 24/25] ARM: dts: s500: Add SPS node Andreas Färber
2017-02-28  6:35 ` [PATCH v3 25/25] ARM: owl: smp: Reimplement SPS power-gating for CPU2 and CPU3 Andreas Färber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).