linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/18] Add support to STMicroelectronics STM32 family
@ 2015-02-20 18:00 Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 01/18] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel Maxime Coquelin
                   ` (17 more replies)
  0 siblings, 18 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:00 UTC (permalink / raw)
  To: linux-arm-kernel

Thanks for the first round of reviews.
Most of the comments made have been taken into account (see below for details),
except that I failed to find an easy/clean way to move vector_table location in
order to limit the waste of memory.
If you have any idea/example to do that, I will be pleased to add it in next
version of the series.

STM32 MCUs are Cortex-M CPU, used in various applications (consumer
electronics, industrial applications, hobbyists...).
Datasheets, user and programming manuals are publicly available on
STMicroelectronics website.

With this series applied, the STM32F419 Discovery can boot succesfully.

Changes since v1:
-----------------
 - Move bindings documentation in their own patches (Andreas)
 - Rename ARM System timer to armv7m-systick (Rob)
 - Add clock-frequency property handling in armv7m-systick (Rob)
 - Re-factor the reset controllers into a single controller (Philipp)
 - Add kerneldoc to reset_controller_of_init (Philipp)
 - Add named constants in include/dt-bindings/reset/ (Philipp)
 - Make pinctrl driver to depend on ARCH_STM32 or COMPILE_TEST (Geert)
 - Introduce CPUV7M_NUM_IRQ config flag to indicate the number of interrupts
supported by the MCU, in order to limit memory waste in vectors' table (Uwe)


Maxime Coquelin (18):
  scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP
    Kernel
  ARM: ARMv7M: Enlarge vector table to 256 entries
  dt-bindings: Document the ARM System timer bindings
  clocksource: Add ARM System timer driver
  reset: Add reset_controller_of_init() function
  dt-bindings: Document the STM32 reset bindings
  drivers: reset: Add STM32 reset driver
  dt-bindings: Document the STM32 timer bindings
  clockevent: Add STM32 Timer driver
  dt-bindings: Document the STM32 pin controller
  pinctrl: Add pinctrl driver for STM32 MCUs
  dt-bindings: Document the STM32 USART bindings
  serial: stm32-usart: Add STM32 USART Driver
  ARM: Add STM32 family machine
  ARM: dts: Add ARM System timer as clockevent in armv7m
  ARM: dts: Introduce STM32F429 MCU
  ARM: configs: Add STM32 defconfig
  MAINTAINERS: Add entry for STM32 MCUs

 Documentation/arm/stm32/overview.txt               |  32 +
 Documentation/arm/stm32/stm32f429-overview.txt     |  22 +
 .../devicetree/bindings/arm/armv7m_systick.txt     |  26 +
 .../devicetree/bindings/pinctrl/pinctrl-stm32.txt  |  99 +++
 .../devicetree/bindings/reset/st,stm32-reset.txt   |  36 +
 .../devicetree/bindings/serial/st,stm32-usart.txt  |  18 +
 .../devicetree/bindings/timer/st,stm32-timer.txt   |  19 +
 MAINTAINERS                                        |   7 +
 arch/arm/Kconfig                                   |  22 +
 arch/arm/Makefile                                  |   1 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/armv7-m.dtsi                     |   7 +
 arch/arm/boot/dts/stm32f429-disco.dts              |  41 ++
 arch/arm/boot/dts/stm32f429.dtsi                   | 396 +++++++++++
 arch/arm/configs/stm32_defconfig                   |  72 ++
 arch/arm/kernel/entry-v7m.S                        |  13 +-
 arch/arm/mach-stm32/Makefile                       |   1 +
 arch/arm/mach-stm32/Makefile.boot                  |   0
 arch/arm/mach-stm32/board-dt.c                     |  31 +
 arch/arm/mm/Kconfig                                |  15 +
 drivers/clocksource/Kconfig                        |  16 +
 drivers/clocksource/Makefile                       |   2 +
 drivers/clocksource/armv7m_systick.c               |  78 +++
 drivers/clocksource/timer-stm32.c                  | 187 +++++
 drivers/pinctrl/Kconfig                            |  10 +
 drivers/pinctrl/Makefile                           |   1 +
 drivers/pinctrl/pinctrl-stm32.c                    | 779 +++++++++++++++++++++
 drivers/reset/Makefile                             |   1 +
 drivers/reset/core.c                               |  27 +
 drivers/reset/reset-stm32.c                        | 124 ++++
 drivers/tty/serial/Kconfig                         |  17 +
 drivers/tty/serial/Makefile                        |   1 +
 drivers/tty/serial/stm32-usart.c                   | 695 ++++++++++++++++++
 include/asm-generic/vmlinux.lds.h                  |   4 +-
 include/dt-bindings/pinctrl/pinctrl-stm32.h        |  43 ++
 include/dt-bindings/reset/st,stm32f429.h           |  85 +++
 include/linux/reset-controller.h                   |   6 +
 include/uapi/linux/serial_core.h                   |   3 +
 scripts/link-vmlinux.sh                            |   2 +-
 39 files changed, 2934 insertions(+), 6 deletions(-)
 create mode 100644 Documentation/arm/stm32/overview.txt
 create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
 create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt
 create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-reset.txt
 create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
 create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txt
 create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
 create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
 create mode 100644 arch/arm/configs/stm32_defconfig
 create mode 100644 arch/arm/mach-stm32/Makefile
 create mode 100644 arch/arm/mach-stm32/Makefile.boot
 create mode 100644 arch/arm/mach-stm32/board-dt.c
 create mode 100644 drivers/clocksource/armv7m_systick.c
 create mode 100644 drivers/clocksource/timer-stm32.c
 create mode 100644 drivers/pinctrl/pinctrl-stm32.c
 create mode 100644 drivers/reset/reset-stm32.c
 create mode 100644 drivers/tty/serial/stm32-usart.c
 create mode 100644 include/dt-bindings/pinctrl/pinctrl-stm32.h
 create mode 100644 include/dt-bindings/reset/st,stm32f429.h

-- 
1.9.1

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

* [PATCH v2 01/18] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries Maxime Coquelin
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

When Kernel is executed in place from ROM, the symbol addresses can be
lower than the page offset.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 scripts/link-vmlinux.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 86a4fe7..b055d9d 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -82,7 +82,7 @@ kallsyms()
 		kallsymopt="${kallsymopt} --all-symbols"
 	fi
 
-	if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
+	if [ -n "${CONFIG_ARM}" ] && [ -z "${CONFIG_XIP_KERNEL}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
 		kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
 	fi
 
-- 
1.9.1

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 01/18] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 19:47   ` Uwe Kleine-König
  2015-03-09  0:29   ` Stefan Agner
  2015-02-20 18:01 ` [PATCH v2 03/18] dt-bindings: Document the ARM System timer bindings Maxime Coquelin
                   ` (15 subsequent siblings)
  17 siblings, 2 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

>From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
So the number of entries in vectors table is up to 256.

This patch adds a new config flag to specify the number of external interrupts.
Some ifdeferies are added in order to respect the natural alignment without
wasting too much space on smaller systems.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 arch/arm/kernel/entry-v7m.S | 13 +++++++++----
 arch/arm/mm/Kconfig         | 15 +++++++++++++++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 8944f49..68cde36 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -117,9 +117,14 @@ ENTRY(__switch_to)
 ENDPROC(__switch_to)
 
 	.data
-	.align	8
+#if CONFIG_CPUV7M_NUM_IRQ <= 112
+	.align	9
+#else
+	.align	10
+#endif
+
 /*
- * Vector table (64 words => 256 bytes natural alignment)
+ * Vector table (Natural alignment need to be ensured)
  */
 ENTRY(vector_table)
 	.long	0			@ 0 - Reset stack pointer
@@ -138,6 +143,6 @@ ENTRY(vector_table)
 	.long	__invalid_entry		@ 13 - Reserved
 	.long	__pendsv_entry		@ 14 - PendSV
 	.long	__invalid_entry		@ 15 - SysTick
-	.rept	64 - 16
-	.long	__irq_entry		@ 16..64 - External Interrupts
+	.rept	CONFIG_CPUV7M_NUM_IRQ
+	.long	__irq_entry		@ External Interrupts
 	.endr
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c43c714..27eb835 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -604,6 +604,21 @@ config CPU_USE_DOMAINS
 	  This option enables or disables the use of domain switching
 	  via the set_fs() function.
 
+config CPUV7M_NUM_IRQ
+	int "Number of external interrupts connected to the NVIC"
+	depends on CPU_V7M
+	default 90 if ARCH_STM32
+	default 38 if ARCH_EFM32
+	default 240
+	help
+	  This option indicates the number of interrupts connected to the NVIC.
+	  The value can be larger than the real number of interrupts supported
+	  by the system, but must not be lower.
+	  The default value is 240, corresponding to the maximum number of
+	  interrupts supported by the NVIC on Cortex-M family.
+
+	  If unsure, keep default value.
+
 #
 # CPU supports 36-bit I/O
 #
-- 
1.9.1

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

* [PATCH v2 03/18] dt-bindings: Document the ARM System timer bindings
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 01/18] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 04/18] clocksource: Add ARM System timer driver Maxime Coquelin
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This adds documentation of device tree bindings for the
ARM System timer.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 .../devicetree/bindings/arm/armv7m_systick.txt     | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt

diff --git a/Documentation/devicetree/bindings/arm/armv7m_systick.txt b/Documentation/devicetree/bindings/arm/armv7m_systick.txt
new file mode 100644
index 0000000..7cf4a24
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armv7m_systick.txt
@@ -0,0 +1,26 @@
+* ARMv7M System Timer
+
+ARMv7-M includes a system timer, known as SysTick. Current driver only
+implements the clocksource feature.
+
+Required properties:
+- compatible	  : Should be "arm,armv7m-systick"
+- reg		  : The address range of the timer
+
+Required clocking property, have to be one of:
+- clocks	  : The input clock of the timer
+- clock-frequency : The rate in HZ in input of the ARM SysTick
+
+Examples:
+
+systick: timer at e000e010 {
+	compatible = "arm,armv7m-systick";
+	reg = <0xe000e010 0x10>;
+	clocks = <&clk_systick>;
+};
+
+systick: timer at e000e010 {
+	compatible = "arm,armv7m-systick";
+	reg = <0xe000e010 0x10>;
+	clock-frequency = <90000000>;
+};
-- 
1.9.1

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (2 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 03/18] dt-bindings: Document the ARM System timer bindings Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 19:54   ` Uwe Kleine-König
  2015-03-09 15:50   ` Linus Walleij
  2015-02-20 18:01 ` [PATCH v2 05/18] reset: Add reset_controller_of_init() function Maxime Coquelin
                   ` (13 subsequent siblings)
  17 siblings, 2 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds clocksource support for ARMv7-M's System timer,
also known as SysTick.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 drivers/clocksource/Kconfig          |  7 ++++
 drivers/clocksource/Makefile         |  1 +
 drivers/clocksource/armv7m_systick.c | 78 ++++++++++++++++++++++++++++++++++++
 3 files changed, 86 insertions(+)
 create mode 100644 drivers/clocksource/armv7m_systick.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec2..fb6011e 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -124,6 +124,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 	help
 	 Use ARM global timer clock source as sched_clock
 
+config ARMV7M_SYSTICK
+	bool
+	select CLKSRC_OF if OF
+	select CLKSRC_MMIO
+	help
+	  This options enables support for the ARMv7M system timer unit
+
 config ATMEL_PIT
 	select CLKSRC_OF if OF
 	def_bool SOC_AT91SAM9 || SOC_SAMA5
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b2..eeea736 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_MTK_TIMER)		+= mtk_timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
+obj-$(CONFIG_ARMV7M_SYSTICK)		+= armv7m_systick.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
 obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST)	+= dummy_timer.o
 obj-$(CONFIG_ARCH_KEYSTONE)		+= timer-keystone.o
diff --git a/drivers/clocksource/armv7m_systick.c b/drivers/clocksource/armv7m_systick.c
new file mode 100644
index 0000000..23d8249
--- /dev/null
+++ b/drivers/clocksource/armv7m_systick.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/bitops.h>
+
+#define SYST_CSR	0x00
+#define SYST_RVR	0x04
+#define SYST_CVR	0x08
+#define SYST_CALIB	0x0c
+
+#define SYST_CSR_ENABLE BIT(0)
+
+#define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF
+
+static void __init system_timer_of_register(struct device_node *np)
+{
+	struct clk *clk;
+	void __iomem *base;
+	u32 rate = 0;
+	int ret;
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_warn("system-timer: invalid base address\n");
+		return;
+	}
+
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk)) {
+		ret = clk_prepare_enable(clk);
+		if (ret) {
+			clk_put(clk);
+			goto out_unmap;
+		}
+
+		rate = clk_get_rate(clk);
+	}
+
+	/* If no clock found, try to get clock-frequency property */
+	if (!rate) {
+		ret = of_property_read_u32(np, "clock-frequency", &rate);
+		if (ret)
+			goto out_unmap;
+	}
+
+	writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, base + SYST_RVR);
+	writel_relaxed(SYST_CSR_ENABLE, base + SYST_CSR);
+
+	ret = clocksource_mmio_init(base + SYST_CVR, "arm_system_timer", rate,
+			200, 24, clocksource_mmio_readl_down);
+	if (ret) {
+		pr_err("failed to init clocksource (%d)\n", ret);
+		goto out_clk_disable;
+	}
+
+	pr_info("ARM System timer initialized as clocksource\n");
+
+	return;
+
+out_clk_disable:
+	if (!IS_ERR(clk))
+		clk_disable_unprepare(clk);
+out_unmap:
+	iounmap(base);
+	WARN(ret, "ARM System timer register failed (%d)\n", ret);
+}
+
+CLOCKSOURCE_OF_DECLARE(arm_systick, "arm,armv7m-systick",
+			system_timer_of_register);
-- 
1.9.1

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

* [PATCH v2 05/18] reset: Add reset_controller_of_init() function
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (3 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 04/18] clocksource: Add ARM System timer driver Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-03-10 15:00   ` Arnd Bergmann
  2015-02-20 18:01 ` [PATCH v2 06/18] dt-bindings: Document the STM32 reset bindings Maxime Coquelin
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

Some platforms need to initialize the reset controller before the timers.

This patch introduces a reset_controller_of_init() function that can be
called before the timers intialization.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 drivers/reset/core.c              | 27 +++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h |  4 +++-
 include/linux/reset-controller.h  |  6 ++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 7955e00..7eef63e 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -86,6 +86,33 @@ void reset_controller_unregister(struct reset_controller_dev *rcdev)
 }
 EXPORT_SYMBOL_GPL(reset_controller_unregister);
 
+extern struct of_device_id __reset_ctrl_of_table[];
+
+static const struct of_device_id __reset_ctrl_of_table_sentinel
+	__used __section(__reset_ctrl_of_table_end);
+
+/**
+ * reset_controller_of_init - scan and init reset controllers from the DT
+ *
+ * This function scas the device tree for matching reset controllers. It is
+ * used on machines that need reset controls at early stage. To use it, the
+ * controller driver has to be registred with RESET_CONTROLLER_OF_DECLARE().
+ */
+void __init reset_controller_of_init(void)
+{
+	struct device_node *np;
+	const struct of_device_id *match;
+	of_init_fn_1 init_func;
+
+	for_each_matching_node_and_match(np, __reset_ctrl_of_table, &match) {
+		if (!of_device_is_available(np))
+			continue;
+
+		init_func = match->data;
+		init_func(np);
+	}
+}
+
 /**
  * reset_control_reset - reset the controlled device
  * @rstc: reset controller
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bee5d68..1f96365 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -168,6 +168,7 @@
 #define RESERVEDMEM_OF_TABLES()	OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)
 #define CPU_METHOD_OF_TABLES()	OF_TABLE(CONFIG_SMP, cpu_method)
 #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
+#define RESET_CTRL_OF_TABLES()	OF_TABLE(CONFIG_RESET_CONTROLLER, reset_ctrl)
 
 #define KERNEL_DTB()							\
 	STRUCT_ALIGN();							\
@@ -502,7 +503,8 @@
 	CPU_METHOD_OF_TABLES()						\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
-	EARLYCON_OF_TABLES()
+	EARLYCON_OF_TABLES()						\
+	RESET_CTRL_OF_TABLES()
 
 #define INIT_TEXT							\
 	*(.init.text)							\
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index ce6b962..f8a030a 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -51,4 +51,10 @@ struct reset_controller_dev {
 int reset_controller_register(struct reset_controller_dev *rcdev);
 void reset_controller_unregister(struct reset_controller_dev *rcdev);
 
+
+#define RESET_CONTROLLER_OF_DECLARE(name, compat, fn) \
+	OF_DECLARE_1(reset_ctrl, name, compat, fn)
+
+void reset_controller_of_init(void);
+
 #endif
-- 
1.9.1

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

* [PATCH v2 06/18] dt-bindings: Document the STM32 reset bindings
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (4 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 05/18] reset: Add reset_controller_of_init() function Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 07/18] drivers: reset: Add STM32 reset driver Maxime Coquelin
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This adds documentation of device tree bindings for the
STM32 reset controller.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 .../devicetree/bindings/reset/st,stm32-reset.txt   | 36 ++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-reset.txt

diff --git a/Documentation/devicetree/bindings/reset/st,stm32-reset.txt b/Documentation/devicetree/bindings/reset/st,stm32-reset.txt
new file mode 100644
index 0000000..5982528
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/st,stm32-reset.txt
@@ -0,0 +1,36 @@
+STMicroelectronics STM32 Peripheral Reset Controller
+====================================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "st,stm32-reset"
+- reg: should be register base and length as documented in the
+  datasheet
+- #reset-cells: 1, see below
+
+example:
+
+reset_ahb1: reset at 40023810 {
+	#reset-cells = <1>;
+	compatible = "st,stm32-reset";
+	reg = <0x40023810 0x4>;
+};
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use, as described in reset.txt
+
+example:
+
+	timer2 {
+		resets			= <&resets TIM2_RESET>;
+	};
+
+Macro definitions for the supported reset channels can be found in:
+
+include/dt-bindings/reset/st,stm32f429.h
-- 
1.9.1

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (5 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 06/18] dt-bindings: Document the STM32 reset bindings Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-03-10 15:02   ` Arnd Bergmann
  2015-02-20 18:01 ` [PATCH v2 08/18] dt-bindings: Document the STM32 timer bindings Maxime Coquelin
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

The STM32 MCUs family IP can be reset by accessing some shared registers.

The specificity is that some reset lines are used by the timers.
At timer initialization time, the timer has to be reset, that's why
we cannot use a regular driver.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 drivers/reset/Makefile                   |   1 +
 drivers/reset/reset-stm32.c              | 124 +++++++++++++++++++++++++++++++
 include/dt-bindings/reset/st,stm32f429.h |  85 +++++++++++++++++++++
 3 files changed, 210 insertions(+)
 create mode 100644 drivers/reset/reset-stm32.c
 create mode 100644 include/dt-bindings/reset/st,stm32f429.h

diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 157d421..aed12d1 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_RESET_CONTROLLER) += core.o
 obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
 obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o
+obj-$(CONFIG_ARCH_STM32) += reset-stm32.o
 obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_ARCH_STI) += sti/
diff --git a/drivers/reset/reset-stm32.c b/drivers/reset/reset-stm32.c
new file mode 100644
index 0000000..7a96677
--- /dev/null
+++ b/drivers/reset/reset-stm32.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ *
+ * Heavily based on sunxi driver from Maxime Ripard.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct stm32_reset_data {
+	spinlock_t			lock;
+	void __iomem			*membase;
+	struct reset_controller_dev	rcdev;
+};
+
+static int stm32_reset_assert(struct reset_controller_dev *rcdev,
+			      unsigned long id)
+{
+	struct stm32_reset_data *data = container_of(rcdev,
+						     struct stm32_reset_data,
+						     rcdev);
+	int bank = id / BITS_PER_LONG;
+	int offset = id % BITS_PER_LONG;
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	reg = readl_relaxed(data->membase + (bank * 4));
+	writel_relaxed(reg | BIT(offset), data->membase + (bank * 4));
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	return 0;
+}
+
+static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
+				unsigned long id)
+{
+	struct stm32_reset_data *data = container_of(rcdev,
+						     struct stm32_reset_data,
+						     rcdev);
+	int bank = id / BITS_PER_LONG;
+	int offset = id % BITS_PER_LONG;
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(&data->lock, flags);
+
+	reg = readl_relaxed(data->membase + (bank * 4));
+	writel_relaxed(reg & ~BIT(offset), data->membase + (bank * 4));
+
+	spin_unlock_irqrestore(&data->lock, flags);
+
+	return 0;
+}
+
+static struct reset_control_ops stm32_reset_ops = {
+	.assert		= stm32_reset_assert,
+	.deassert	= stm32_reset_deassert,
+};
+
+static void stm32_reset_init(struct device_node *np)
+{
+	struct stm32_reset_data *data;
+	struct resource res;
+	resource_size_t size;
+	int err;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return;
+
+	err = of_address_to_resource(np, 0, &res);
+	if (err)
+		goto err_alloc;
+
+	size = resource_size(&res);
+	if (!request_mem_region(res.start, size, np->name)) {
+		err = -EINVAL;
+		goto err_alloc;
+	}
+
+	data->membase = ioremap(res.start, size);
+	if (!data->membase) {
+		err = -ENOMEM;
+		goto err_alloc;
+	}
+
+	spin_lock_init(&data->lock);
+
+	data->rcdev.owner = THIS_MODULE;
+	data->rcdev.nr_resets = size * 8;
+	data->rcdev.ops = &stm32_reset_ops;
+	data->rcdev.of_node = np;
+
+	err = reset_controller_register(&data->rcdev);
+	if (err)
+		goto err_iomap;
+
+	pr_info("%s: %d reset lines registered\n", np->full_name,
+			data->rcdev.nr_resets);
+	return;
+
+err_iomap:
+	iounmap(data->membase);
+err_alloc:
+	kfree(data);
+	pr_err("%s: Reset ctrl registration failed (%d).\n",
+			np->full_name, err);
+}
+
+RESET_CONTROLLER_OF_DECLARE(stm32, "st,stm32-reset", stm32_reset_init);
+
diff --git a/include/dt-bindings/reset/st,stm32f429.h b/include/dt-bindings/reset/st,stm32f429.h
new file mode 100644
index 0000000..04f2ba8
--- /dev/null
+++ b/include/dt-bindings/reset/st,stm32f429.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#ifndef _DT_BINDINGS_RESET_STM32F429_H
+#define _DT_BINDINGS_RESET_STM32F429_H
+
+/* AHB1 */
+#define GPIOA_RESET	0
+#define GPIOB_RESET	1
+#define GPIOC_RESET	2
+#define GPIOD_RESET	3
+#define GPIOE_RESET	4
+#define GPIOF_RESET	5
+#define GPIOG_RESET	6
+#define GPIOH_RESET	7
+#define GPIOI_RESET	8
+#define GPIOJ_RESET	9
+#define GPIOK_RESET	10
+#define CRC_RESET	12
+#define DMA1_RESET	21
+#define DMA2_RESET	22
+#define DMA2D_RESET	23
+#define ETHMAC_RESET	25
+#define OTGHS_RESET	29
+
+/* AHB2 */
+#define DCMI_RESET	32
+#define CRYP_RESET	36
+#define HASH_RESET	37
+#define RNG_RESET	38
+#define OTGFS_RESET	39
+
+/* AHB3 */
+#define FMC_RESET	64
+
+/* APB1 */
+#define TIM2_RESET	128
+#define TIM3_RESET	129
+#define TIM4_RESET	130
+#define TIM5_RESET	131
+#define TIM6_RESET	132
+#define TIM7_RESET	133
+#define TIM12_RESET	134
+#define TIM13_RESET	135
+#define TIM14_RESET	136
+#define WWDG_RESET	139
+#define SPI2_RESET	142
+#define SPI3_RESET	143
+#define UART2_RESET	145
+#define UART3_RESET	146
+#define UART4_RESET	147
+#define UART5_RESET	148
+#define I2C1_RESET	149
+#define I2C2_RESET	150
+#define I2C3_RESET	151
+#define CAN1_RESET	153
+#define CAN2_RESET	154
+#define PWR_RESET	156
+#define DAC_RESET	157
+#define UART7_RESET	158
+#define UART8_RESET	159
+
+/* APB2 */
+#define TIM1_RESET	160
+#define TIM8_RESET	161
+#define USART1_RESET	164
+#define USART6_RESET	165
+#define ADC_RESET	168
+#define SDIO_RESET	171
+#define SPI1_RESET	172
+#define SPI4_RESET	173
+#define SYSCFG_RESET	174
+#define TIM9_RESET	176
+#define TIM10_RESET	177
+#define TIM11_RESET	178
+#define SPI5_RESET	180
+#define SPI6_RESET	181
+#define SAI1_RESET	182
+#define LTDC_RESET	186
+
+#endif /* _DT_BINDINGS_RESET_STM32F429_H */
+
-- 
1.9.1

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

* [PATCH v2 08/18] dt-bindings: Document the STM32 timer bindings
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (6 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 07/18] drivers: reset: Add STM32 reset driver Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 09/18] clockevent: Add STM32 Timer driver Maxime Coquelin
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This adds documentation of device tree bindings for the
STM32 timer.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 .../devicetree/bindings/timer/st,stm32-timer.txt      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/st,stm32-timer.txt b/Documentation/devicetree/bindings/timer/st,stm32-timer.txt
new file mode 100644
index 0000000..7fffcd8
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/st,stm32-timer.txt
@@ -0,0 +1,19 @@
+. STMicroelectronics STM32 timer
+
+The STM32 MCUs family has several general-purpose 16 and 32 bits timers.
+
+Required properties:
+- compatible : Should be st,stm32-timer"
+- reg : Address and length of the register set
+- clocks : Reference on the timer input clock
+- interrupts : Reference to the timer interrupt
+
+Example:
+
+timer5: timer at 40000c00 {
+	compatible = "st,stm32-timer";
+	reg = <0x40000c00 0x400>;
+	interrupts = <50>;
+	resets = <&reset_apb1 3>;
+	clocks = <&clk_pmtr1>;
+};
-- 
1.9.1

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

* [PATCH v2 09/18] clockevent: Add STM32 Timer driver
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (7 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 08/18] dt-bindings: Document the STM32 timer bindings Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller Maxime Coquelin
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

STM32 MCUs feature 16 and 32 bits general purpose timers with prescalers.
The drivers detects whether the time is 16 or 32 bits, and applies a
1024 prescaler value if it is 16 bits.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 drivers/clocksource/Kconfig       |   9 ++
 drivers/clocksource/Makefile      |   1 +
 drivers/clocksource/timer-stm32.c | 187 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 197 insertions(+)
 create mode 100644 drivers/clocksource/timer-stm32.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fb6011e..f372329 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -91,6 +91,15 @@ config CLKSRC_EFM32
 	  Support to use the timers of EFM32 SoCs as clock source and clock
 	  event device.
 
+config CLKSRC_STM32
+	bool "Clocksource for STM32 SoCs" if !ARCH_STM32
+	depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
+	select CLKSRC_MMIO
+	default ARCH_STM32
+	help
+	  Support to use the timers of STM32 SoCs as clock source and clock
+	  event device.
+
 config ARM_ARCH_TIMER
 	bool
 	select CLKSRC_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index eeea736..8078178 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_ARCH_NSPIRE)	+= zevio-timer.o
 obj-$(CONFIG_ARCH_BCM_MOBILE)	+= bcm_kona_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)	+= cadence_ttc_timer.o
 obj-$(CONFIG_CLKSRC_EFM32)	+= time-efm32.o
+obj-$(CONFIG_CLKSRC_STM32)	+= timer-stm32.o
 obj-$(CONFIG_CLKSRC_EXYNOS_MCT)	+= exynos_mct.o
 obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 obj-$(CONFIG_FSL_FTM_TIMER)	+= fsl_ftm_timer.o
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
new file mode 100644
index 0000000..9839f57
--- /dev/null
+++ b/drivers/clocksource/timer-stm32.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ *
+ * Inspired by time-efm32.c from Uwe Kleine-Koenig
+ */
+
+#include <linux/kernel.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+
+#define TIM_CR1		0x00
+#define TIM_DIER	0x0c
+#define TIM_SR		0x10
+#define TIM_EGR		0x14
+#define TIM_PSC		0x28
+#define TIM_ARR		0x2c
+
+#define TIM_CR1_CEN	BIT(0)
+#define TIM_CR1_OPM	BIT(3)
+#define TIM_CR1_ARPE	BIT(7)
+
+#define TIM_DIER_UIE	BIT(0)
+
+#define TIM_SR_UIF	BIT(0)
+
+#define TIM_EGR_UG	BIT(0)
+
+struct stm32_clock_event_ddata {
+	struct clock_event_device evtdev;
+	unsigned periodic_top;
+	void __iomem *base;
+};
+
+static void stm32_clock_event_set_mode(enum clock_event_mode mode,
+				       struct clock_event_device *evtdev)
+{
+	struct stm32_clock_event_ddata *data =
+		container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
+	void *base = data->base;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		writel_relaxed(data->periodic_top, base + TIM_ARR);
+		writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+	default:
+		writel_relaxed(0, base + TIM_CR1);
+		break;
+	}
+}
+
+static int stm32_clock_event_set_next_event(unsigned long evt,
+					    struct clock_event_device *evtdev)
+{
+	struct stm32_clock_event_ddata *data =
+		container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
+
+	writel_relaxed(evt, data->base + TIM_ARR);
+	writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN,
+		       data->base + TIM_CR1);
+
+	return 0;
+}
+
+static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
+{
+	struct stm32_clock_event_ddata *data = dev_id;
+
+	writel_relaxed(0, data->base + TIM_SR);
+
+	data->evtdev.event_handler(&data->evtdev);
+
+	return IRQ_HANDLED;
+}
+
+static struct stm32_clock_event_ddata clock_event_ddata = {
+	.evtdev = {
+		.name = "stm32 clockevent",
+		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+		.set_mode = stm32_clock_event_set_mode,
+		.set_next_event = stm32_clock_event_set_next_event,
+		.rating = 200,
+	},
+};
+
+static void __init stm32_clockevent_init(struct device_node *np)
+{
+	struct stm32_clock_event_ddata *data = &clock_event_ddata;
+	struct clk *clk;
+	struct reset_control *rstc;
+	unsigned long rate, max_delta;
+	int irq, ret, bits, prescaler = 1;
+
+	clk = of_clk_get(np, 0);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		pr_err("failed to get clock for clockevent (%d)\n", ret);
+		goto err_clk_get;
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		pr_err("failed to enable timer clock for clockevent (%d)\n",
+		       ret);
+		goto err_clk_enable;
+	}
+
+	rate = clk_get_rate(clk);
+
+	rstc = of_reset_control_get(np, NULL);
+	if (IS_ERR(rstc)) {
+		pr_err("%s: Failed to get reset\n", np->full_name);
+		return;
+	}
+
+	reset_control_assert(rstc);
+	reset_control_deassert(rstc);
+
+	data->base = of_iomap(np, 0);
+	if (!data->base) {
+		pr_err("failed to map registers for clockevent\n");
+		goto err_iomap;
+	}
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (!irq) {
+		pr_err("%s: failed to get irq.\n", np->full_name);
+		goto err_get_irq;
+	}
+
+	/* Detect whether the timer is 16 or 32 bits */
+	writel_relaxed(~0UL, data->base + TIM_ARR);
+	max_delta = readl_relaxed(data->base + TIM_ARR);
+	if (max_delta == ~0UL) {
+		prescaler = 1;
+		bits = 32;
+	} else {
+		prescaler = 1024;
+		bits = 16;
+	}
+	writel_relaxed(0, data->base + TIM_ARR);
+
+	writel_relaxed(prescaler - 1, data->base + TIM_PSC);
+	writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR);
+	writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER);
+	writel_relaxed(0, data->base + TIM_SR);
+
+	data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ);
+
+	clockevents_config_and_register(&data->evtdev,
+					DIV_ROUND_CLOSEST(rate, prescaler),
+					0x1, max_delta);
+
+	ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER,
+			"stm32 clockevent", data);
+	if (ret) {
+		pr_err("%s: failed to request irq.\n", np->full_name);
+		goto err_get_irq;
+	}
+
+	pr_info("%s: STM32 clockevent driver initialized (%d bits)\n",
+			np->full_name, bits);
+
+	return;
+
+err_get_irq:
+	iounmap(data->base);
+err_iomap:
+	clk_disable_unprepare(clk);
+err_clk_enable:
+	clk_put(clk);
+err_clk_get:
+	return;
+}
+
+CLOCKSOURCE_OF_DECLARE(stm32, "st,stm32-timer", stm32_clockevent_init);
-- 
1.9.1

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

* [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (8 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 09/18] clockevent: Add STM32 Timer driver Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-03-06  9:12   ` Linus Walleij
  2015-03-06  9:35   ` Linus Walleij
  2015-02-20 18:01 ` [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs Maxime Coquelin
                   ` (7 subsequent siblings)
  17 siblings, 2 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This adds documentation of device tree bindings for the
STM32 pin controller.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 .../devicetree/bindings/pinctrl/pinctrl-stm32.txt  | 99 ++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt
new file mode 100644
index 0000000..0fb5b24
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt
@@ -0,0 +1,99 @@
+* STM32 GPIO and Pin Mux/Config controller
+
+STMicroelectronics's STM32 MCUs intregrate a GPIO and Pin mux/config hardware
+controller. It controls the input/output settings on the available pins and
+also provides ability to multiplex and configure the output of various on-chip
+controllers onto these pads.
+
+Pin controller node:
+Required properies:
+- compatible	: "st,stm32-pinctrl"
+- #address-cells: The value of this property must be 1
+- #size-cells	: The value of this property must be 1
+- ranges	: defines mapping between pin controller node (parent) to
+  gpio-bank node (children).
+
+GPIO controller/bank node:
+Required properties:
+- gpio-controller : Indicates this device is a GPIO controller
+- #gpio-cells	  : Should be two.
+			The first cell is the pin number
+			The second one is the polarity:
+				- 0 for active high
+				- 1 for active low
+- reg		  : The gpio address range, relative to the pinctrl range
+- st,bank-name	  : Should be a name string for this bank as specified in
+  the datasheet
+
+Optional properties:
+- reset:	  : Reference to the reset controller
+
+Example:
+#include <dt-bindings/pinctrl/pinctrl-stm32.h>
+...
+
+	pin-controller {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "st,stm32-pinctrl";
+		ranges = <0 0x40020000 0x3000>;
+
+		gpioa: gpio at 40020000 {
+			gpio-controller;
+			#gpio-cells = <2>;
+			reg = <0x0 0x400>;
+			resets = <&reset_ahb1 0>;
+			st,bank-name = "GPIOA";
+		};
+		...
+		pin-functions nodes follow...
+	};
+
+Contents of function subnode node:
+----------------------------------
+
+Required properties for pin configuration node:
+- st,pins	: Child node with list of pins with configuration.
+
+Below is the format of how each pin conf should look like.
+
+<bank offset altmode pull type speed>
+
+Every PIO is represented with 4 to 6 parameters.
+Each parameter is explained as below.
+
+- bank	  : Should be bank phandle to which this PIO belongs.
+- offset  : Offset in the PIO bank.
+- altmode : Should be mode or alternate function number associated this pin, as
+described in the datasheet (IN, OUT, ALT0...ALT15, ANALOG)
+- pull	  : Should be either NO_PULL, PULL_UP or PULL_DOWN
+- type	  : Should be either PUSH_PULL or OPEN_DRAIN.
+	    Setting it is not needed for IN and ANALOG modes, or alternate
+	    functions acting as inputs.
+- speed	  : Value taken from the datasheet, depending on the function
+(LOW_SPEED, MEDIUM_SPEED, FAST_SPEED, HIGH_SPEED)
+	    Setting it is not needed for IN and ANALOG modes, or alternate
+	    functions acting as inputs.
+
+usart1 {
+	pinctrl_usart1: usart1-0 {
+		st,pins {
+			tx = <&gpioa 9 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
+			rx = <&gpioa 10 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
+		};
+	};
+};
+
+adc2 {
+	pinctrl_adc2: adc2-0 {
+		st,pins {
+			adc0 = <&gpioe 4 ANALOG NO_PULL>;
+		};
+	};
+};
+
+usart1: usart at 40011000 {
+	...
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usart1>;
+};
-- 
1.9.1

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

* [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (9 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-03-06  9:24   ` Linus Walleij
  2015-03-10 15:08   ` Arnd Bergmann
  2015-02-20 18:01 ` [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings Maxime Coquelin
                   ` (6 subsequent siblings)
  17 siblings, 2 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This driver adds pinctrl and GPIO support to STMicrolectronic's
STM32 family of MCUs.

Pin muxing and GPIO handling have been tested on STM32F429
based Discovery board.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 drivers/pinctrl/Kconfig                     |  10 +
 drivers/pinctrl/Makefile                    |   1 +
 drivers/pinctrl/pinctrl-stm32.c             | 779 ++++++++++++++++++++++++++++
 include/dt-bindings/pinctrl/pinctrl-stm32.h |  43 ++
 4 files changed, 833 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-stm32.c
 create mode 100644 include/dt-bindings/pinctrl/pinctrl-stm32.h

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d014f22..84cd081 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -125,6 +125,16 @@ config PINCTRL_ST
 	select PINCONF
 	select GPIOLIB_IRQCHIP
 
+config PINCTRL_STM32
+	bool "STMicroelectronics STM32 pinctrl driver"
+	depends on OF
+	depends on ARCH_STM32 || COMPILE_TEST
+	select PINMUX
+	select PINCONF
+	select GPIOLIB_IRQCHIP
+	help
+	  This selects the device tree based generic pinctrl driver for STM32.
+
 config PINCTRL_TEGRA
 	bool
 	select PINMUX
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index c030b3d..06ef8ab 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o
 obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o
 obj-$(CONFIG_PINCTRL_TB10X)	+= pinctrl-tb10x.o
 obj-$(CONFIG_PINCTRL_ST) 	+= pinctrl-st.o
+obj-$(CONFIG_PINCTRL_STM32) 	+= pinctrl-stm32.o
 
 obj-$(CONFIG_ARCH_BERLIN)	+= berlin/
 obj-y				+= freescale/
diff --git a/drivers/pinctrl/pinctrl-stm32.c b/drivers/pinctrl/pinctrl-stm32.c
new file mode 100644
index 0000000..5c474b0
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-stm32.c
@@ -0,0 +1,779 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ *
+ * Heavily based on pinctrl-st.c from Srinivas Kandagatla
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include "core.h"
+
+#define STM32_GPIO_MODER	0x00
+#define STM32_GPIO_TYPER	0x04
+#define STM32_GPIO_SPEEDR	0x08
+#define STM32_GPIO_PUPDR	0x0c
+#define STM32_GPIO_IDR		0x10
+#define STM32_GPIO_ODR		0x14
+#define STM32_GPIO_BSRR		0x18
+#define STM32_GPIO_LCKR		0x1c
+#define STM32_GPIO_AFRL		0x20
+#define STM32_GPIO_AFRH		0x24
+
+#define STM32_GPIO_PINS_PER_BANK 16
+#define OF_GPIO_ARGS_MIN 4
+
+#define STM32_PINCONF_UNPACK(conf, param)\
+				((conf >> STM32_PINCONF_ ##param ##_SHIFT) \
+				& STM32_PINCONF_ ##param ##_MASK)
+
+#define STM32_PINCONF_PACK(conf, val, param)	(conf |=\
+				((val & STM32_PINCONF_ ##param ##_MASK) << \
+					STM32_PINCONF_ ##param ##_SHIFT))
+
+#define STM32_PINCONF_SPEED_MASK		0x3
+#define STM32_PINCONF_SPEED_SHIFT		3
+#define STM32_PINCONF_UNPACK_SPEED(conf)\
+				STM32_PINCONF_UNPACK(conf, SPEED)
+#define STM32_PINCONF_PACK_SPEED(conf, val)\
+				STM32_PINCONF_PACK(conf, val, SPEED)
+
+#define STM32_PINCONF_TYPE_MASK			0x1
+#define STM32_PINCONF_TYPE_SHIFT		2
+#define STM32_PINCONF_UNPACK_TYPE(conf)\
+				STM32_PINCONF_UNPACK(conf, TYPE)
+#define STM32_PINCONF_PACK_TYPE(conf, val)\
+				STM32_PINCONF_PACK(conf, val, TYPE)
+
+#define STM32_PINCONF_PUPD_MASK			0x3
+#define STM32_PINCONF_PUPD_SHIFT		0
+#define STM32_PINCONF_UNPACK_PUPD(conf)\
+				STM32_PINCONF_UNPACK(conf, PUPD)
+#define STM32_PINCONF_PACK_PUPD(conf, val)\
+				STM32_PINCONF_PACK(conf, val, PUPD)
+
+
+#define STM32_PINCONF_ALT_MASK			0xf
+#define STM32_PINCONF_ALT_SHIFT		2
+#define STM32_PINCONF_UNPACK_ALT(conf)\
+				STM32_PINCONF_UNPACK(conf, ALT)
+#define STM32_PINCONF_PACK_ALT(conf, val)\
+				STM32_PINCONF_PACK(conf, val, ALT)
+
+#define STM32_PINCONF_MODE_MASK			0x3
+#define STM32_PINCONF_MODE_SHIFT		0
+#define STM32_PINCONF_UNPACK_MODE(conf)\
+				STM32_PINCONF_UNPACK(conf, MODE)
+#define STM32_PINCONF_PACK_MODE(conf, val)\
+				STM32_PINCONF_PACK(conf, val, MODE)
+
+
+
+#define gpio_range_to_bank(chip) \
+		container_of(chip, struct stm32_gpio_bank, range)
+
+#define gpio_chip_to_bank(chip) \
+		container_of(chip, struct stm32_gpio_bank, gpio_chip)
+
+struct stm32_pinconf {
+	int		pin;
+	const char	*name;
+	unsigned long	config;
+	int		altfunc;
+};
+
+struct stm32_pmx_func {
+	const char	*name;
+	const char	**groups;
+	unsigned	ngroups;
+};
+
+struct stm32_pctl_group {
+	const char		*name;
+	unsigned int		*pins;
+	unsigned		npins;
+	struct stm32_pinconf	*pin_conf;
+};
+
+struct stm32_gpio_bank {
+	void __iomem *base;
+	struct gpio_chip		gpio_chip;
+	struct pinctrl_gpio_range	range;
+	spinlock_t                      lock;
+};
+
+struct stm32_pinctrl {
+	struct device		*dev;
+	struct pinctrl_dev		*pctl;
+	struct stm32_gpio_bank	*banks;
+	int			nbanks;
+	struct stm32_pmx_func	*functions;
+	int			nfunctions;
+	struct stm32_pctl_group	*groups;
+	int			ngroups;
+};
+
+static inline int stm32_gpio_pin(int gpio)
+{
+	return gpio % STM32_GPIO_PINS_PER_BANK;
+}
+
+/* Pinconf  */
+static void stm32_pinconf_set_config(struct stm32_gpio_bank *bank,
+				int pin, unsigned long config)
+{
+	u32 type, speed, pupd, val;
+	unsigned long flags;
+
+	type = STM32_PINCONF_UNPACK_TYPE(config);
+	spin_lock_irqsave(&bank->lock, flags);
+	val = readl_relaxed(bank->base + STM32_GPIO_TYPER);
+	val &= ~BIT(pin);
+	val |= type << pin;
+	writel_relaxed(val, bank->base + STM32_GPIO_TYPER);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	speed = STM32_PINCONF_UNPACK_SPEED(config);
+	spin_lock_irqsave(&bank->lock, flags);
+	val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR);
+	val &= ~GENMASK(pin * 2 + 1, pin * 2);
+	val |= speed << (pin * 2);
+	writel_relaxed(val, bank->base + STM32_GPIO_SPEEDR);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	pupd = STM32_PINCONF_UNPACK_PUPD(config);
+	spin_lock_irqsave(&bank->lock, flags);
+	val = readl_relaxed(bank->base + STM32_GPIO_PUPDR);
+	val &= ~GENMASK(pin * 2 + 1, pin * 2);
+	val |= pupd << (pin * 2);
+	writel_relaxed(val, bank->base + STM32_GPIO_PUPDR);
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static void stm32_pinconf_get_config(struct stm32_gpio_bank *bank,
+				int pin, unsigned long *config)
+{
+	u32 val;
+
+	val = readl_relaxed(bank->base + STM32_GPIO_TYPER);
+	val = val >> pin;
+	STM32_PINCONF_PACK_TYPE(*config, val);
+
+	val = readl_relaxed(bank->base + STM32_GPIO_SPEEDR);
+	val = val >> (pin * 2);
+	STM32_PINCONF_PACK_SPEED(*config, val);
+
+	val = readl_relaxed(bank->base + STM32_GPIO_PUPDR);
+	val = val >> (pin * 2);
+	STM32_PINCONF_PACK_PUPD(*config, val);
+}
+
+static int stm32_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
+			unsigned long *configs, unsigned num_configs)
+{
+	struct pinctrl_gpio_range *range =
+			 pinctrl_find_gpio_range_from_pin(pctldev, pin_id);
+	struct stm32_gpio_bank *bank = gpio_range_to_bank(range);
+	int pin = stm32_gpio_pin(pin_id);
+	int i;
+
+	for (i = 0; i < num_configs; i++)
+		stm32_pinconf_set_config(bank, pin, configs[i]);
+
+	return 0;
+}
+
+static int stm32_pinconf_get(struct pinctrl_dev *pctldev,
+			     unsigned pin_id, unsigned long *config)
+{
+	struct pinctrl_gpio_range *range =
+			 pinctrl_find_gpio_range_from_pin(pctldev, pin_id);
+	struct stm32_gpio_bank *bank = gpio_range_to_bank(range);
+	int pin = stm32_gpio_pin(pin_id);
+
+	*config = 0;
+	stm32_pinconf_get_config(bank, pin, config);
+
+	return 0;
+}
+
+static void stm32_pinconf_dbg_show(struct pinctrl_dev *pctldev,
+				   struct seq_file *s, unsigned pin_id)
+{
+	unsigned long config;
+
+	stm32_pinconf_get(pctldev, pin_id, &config);
+
+	seq_printf(s, "[PUPD:%ld,TYPE:%ld,SPEED:%ld]\n",
+		STM32_PINCONF_UNPACK_PUPD(config),
+		STM32_PINCONF_UNPACK_TYPE(config),
+		STM32_PINCONF_UNPACK_SPEED(config));
+}
+
+static struct pinconf_ops stm32_confops = {
+	.pin_config_get		= stm32_pinconf_get,
+	.pin_config_set		= stm32_pinconf_set,
+	.pin_config_dbg_show	= stm32_pinconf_dbg_show,
+};
+
+static void stm32_pctl_set_function(struct stm32_gpio_bank *bank,
+		int pin_id, int function)
+{
+	u32 mode, alt, val;
+	int pin = stm32_gpio_pin(pin_id);
+	int alt_shift = (pin % 8) * 4;
+	int alt_offset = STM32_GPIO_AFRL + (pin / 8) * 4;
+	unsigned long flags;
+
+	mode = STM32_PINCONF_UNPACK_MODE(function);
+	alt = STM32_PINCONF_UNPACK_ALT(function);
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	val = readl_relaxed(bank->base + alt_offset);
+	val &= ~GENMASK(alt_shift + 3, alt_shift);
+	val |= (alt << alt_shift);
+	writel_relaxed(val, bank->base + alt_offset);
+
+	val = readl_relaxed(bank->base + STM32_GPIO_MODER);
+	val &= ~GENMASK(pin * 2 + 1, pin * 2);
+	val |= mode << (pin * 2);
+	writel_relaxed(val, bank->base + STM32_GPIO_MODER);
+
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+/* Pinmux */
+static int stm32_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->nfunctions;
+}
+
+static const char *stm32_pmx_get_fname(struct pinctrl_dev *pctldev,
+	unsigned selector)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->functions[selector].name;
+}
+
+static int stm32_pmx_get_groups(struct pinctrl_dev *pctldev,
+	unsigned selector, const char * const **grps, unsigned * const ngrps)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	*grps = info->functions[selector].groups;
+	*ngrps = info->functions[selector].ngroups;
+
+	return 0;
+}
+
+static int stm32_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned fselector,
+			unsigned group)
+{
+	struct pinctrl_gpio_range *range;
+	struct stm32_gpio_bank *bank;
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	struct stm32_pinconf *conf = info->groups[group].pin_conf;
+	int i;
+
+	for (i = 0; i < info->groups[group].npins; i++) {
+		range = pinctrl_find_gpio_range_from_pin(pctldev, conf[i].pin);
+		bank = gpio_range_to_bank(range);
+		stm32_pctl_set_function(bank, conf[i].pin, conf[i].altfunc);
+	}
+
+	return 0;
+}
+
+static int stm32_pmx_set_gpio_direction(struct pinctrl_dev *pctldev,
+			struct pinctrl_gpio_range *range, unsigned gpio,
+			bool input)
+{
+	struct stm32_gpio_bank *bank = gpio_range_to_bank(range);
+
+	stm32_pctl_set_function(bank, gpio, !input);
+
+	return 0;
+}
+
+static struct pinmux_ops stm32_pmxops = {
+	.get_functions_count	= stm32_pmx_get_funcs_count,
+	.get_function_name	= stm32_pmx_get_fname,
+	.get_function_groups	= stm32_pmx_get_groups,
+	.set_mux		= stm32_pmx_set_mux,
+	.gpio_set_direction	= stm32_pmx_set_gpio_direction,
+};
+
+/* Pinctrl Groups */
+static int stm32_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->ngroups;
+}
+
+static const char *stm32_pctl_get_group_name(struct pinctrl_dev *pctldev,
+				       unsigned selector)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	return info->groups[selector].name;
+}
+
+static int stm32_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+	unsigned selector, const unsigned **pins, unsigned *npins)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+
+	if (selector >= info->ngroups)
+		return -EINVAL;
+
+	*pins = info->groups[selector].pins;
+	*npins = info->groups[selector].npins;
+
+	return 0;
+}
+
+static const inline struct stm32_pctl_group *stm32_pctl_find_group_by_name(
+	const struct stm32_pinctrl *info, const char *name)
+{
+	int i;
+
+	for (i = 0; i < info->ngroups; i++) {
+		if (!strcmp(info->groups[i].name, name))
+			return &info->groups[i];
+	}
+
+	return NULL;
+}
+
+static int stm32_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
+	struct device_node *np, struct pinctrl_map **map, unsigned *num_maps)
+{
+	struct stm32_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
+	const struct stm32_pctl_group *grp;
+	struct pinctrl_map *new_map;
+	struct device_node *parent;
+	int map_num, i;
+
+	grp = stm32_pctl_find_group_by_name(info, np->name);
+	if (!grp) {
+		dev_err(info->dev, "unable to find group for node %s\n",
+			np->name);
+		return -EINVAL;
+	}
+
+	map_num = grp->npins + 1;
+	new_map = devm_kzalloc(pctldev->dev,
+				sizeof(*new_map) * map_num, GFP_KERNEL);
+	if (!new_map)
+		return -ENOMEM;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		devm_kfree(pctldev->dev, new_map);
+		return -EINVAL;
+	}
+
+	*map = new_map;
+	*num_maps = map_num;
+	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
+	new_map[0].data.mux.function = parent->name;
+	new_map[0].data.mux.group = np->name;
+	of_node_put(parent);
+
+	/* create config map per pin */
+	new_map++;
+	for (i = 0; i < grp->npins; i++) {
+		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+		new_map[i].data.configs.group_or_pin =
+				pin_get_name(pctldev, grp->pins[i]);
+		new_map[i].data.configs.configs = &grp->pin_conf[i].config;
+		new_map[i].data.configs.num_configs = 1;
+	}
+	dev_info(pctldev->dev, "maps: function %s group %s num %d\n",
+		(*map)->data.mux.function, grp->name, map_num);
+
+	return 0;
+}
+
+static void stm32_pctl_dt_free_map(struct pinctrl_dev *pctldev,
+			struct pinctrl_map *map, unsigned num_maps)
+{
+}
+
+static struct pinctrl_ops stm32_pctlops = {
+	.get_groups_count	= stm32_pctl_get_groups_count,
+	.get_group_pins		= stm32_pctl_get_group_pins,
+	.get_group_name		= stm32_pctl_get_group_name,
+	.dt_node_to_map		= stm32_pctl_dt_node_to_map,
+	.dt_free_map		= stm32_pctl_dt_free_map,
+};
+
+static void stm32_pctl_dt_child_count(struct stm32_pinctrl *info,
+				     struct device_node *np)
+{
+	struct device_node *child;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller")) {
+			info->nbanks++;
+		} else {
+			info->nfunctions++;
+			info->ngroups += of_get_child_count(child);
+		}
+	}
+}
+
+static int stm32_pctl_dt_parse_groups(struct device_node *np,
+	struct stm32_pctl_group *grp, struct stm32_pinctrl *info, int idx)
+{
+	const __be32 *list;
+	struct property *pp;
+	struct stm32_pinconf *conf;
+	struct device_node *pins;
+	int i = 0, npins = 0, nr_props;
+
+	pins = of_get_child_by_name(np, "st,pins");
+	if (!pins)
+		return -ENODATA;
+
+	for_each_property_of_node(pins, pp) {
+		/* Skip those we do not want to proceed */
+		if (!strcmp(pp->name, "name"))
+			continue;
+
+		if (pp  && (pp->length / sizeof(__be32)) >= OF_GPIO_ARGS_MIN) {
+			npins++;
+		} else {
+			pr_warn("Invalid st,pins in %s node\n", np->name);
+			return -EINVAL;
+		}
+	}
+
+	grp->npins = npins;
+	grp->name = np->name;
+	grp->pins = devm_kzalloc(info->dev, npins * sizeof(u32), GFP_KERNEL);
+	grp->pin_conf = devm_kzalloc(info->dev,
+					npins * sizeof(*conf), GFP_KERNEL);
+
+	if (!grp->pins || !grp->pin_conf)
+		return -ENOMEM;
+
+	/* <bank offset mux pull type speed> */
+	for_each_property_of_node(pins, pp) {
+		if (!strcmp(pp->name, "name"))
+			continue;
+		nr_props = pp->length / sizeof(u32);
+		list = pp->value;
+		conf = &grp->pin_conf[i];
+
+		/* bank & offset */
+		be32_to_cpup(list++);
+		be32_to_cpup(list++);
+		conf->pin = of_get_named_gpio(pins, pp->name, 0);
+		conf->name = pp->name;
+		grp->pins[i] = conf->pin;
+		/* mux */
+		conf->altfunc = be32_to_cpup(list++);
+		conf->config = 0;
+		/* pull-up/down */
+		conf->config |= be32_to_cpup(list++);
+		if (nr_props > OF_GPIO_ARGS_MIN) {
+			/* push-pull/open-drain */
+			conf->config |= be32_to_cpup(list++);
+			/* speed */
+			conf->config |= be32_to_cpup(list++);
+		}
+		i++;
+	}
+	of_node_put(pins);
+
+	return 0;
+}
+
+static int stm32_pctl_parse_functions(struct device_node *np,
+			struct stm32_pinctrl *info, u32 index, int *grp_index)
+{
+	struct device_node *child;
+	struct stm32_pmx_func *func;
+	struct stm32_pctl_group *grp;
+	int i = 0, ret;
+
+	func = &info->functions[index];
+	func->name = np->name;
+	func->ngroups = of_get_child_count(np);
+	if (func->ngroups == 0) {
+		dev_err(info->dev, "No groups defined\n");
+		return -EINVAL;
+	}
+	func->groups = devm_kzalloc(info->dev,
+			func->ngroups * sizeof(char *), GFP_KERNEL);
+	if (!func->groups)
+		return -ENOMEM;
+
+	for_each_child_of_node(np, child) {
+		func->groups[i] = child->name;
+		grp = &info->groups[*grp_index];
+		*grp_index += 1;
+		ret = stm32_pctl_dt_parse_groups(child, grp, info, i++);
+		if (ret)
+			return ret;
+	}
+	dev_info(info->dev, "Function[%d\t name:%s,\tgroups:%d]\n",
+				index, func->name, func->ngroups);
+
+	return 0;
+}
+
+static inline void __stm32_gpio_set(struct stm32_gpio_bank *bank,
+	unsigned offset, int value)
+{
+	if (!value)
+		offset += STM32_GPIO_PINS_PER_BANK;
+
+	writel_relaxed(BIT(offset), bank->base + STM32_GPIO_BSRR);
+}
+
+static int stm32_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void stm32_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip);
+
+	return !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset));
+}
+
+static void stm32_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip);
+
+	__stm32_gpio_set(bank, offset, value);
+}
+
+static int stm32_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_gpio_direction_input(chip->base + offset);
+
+	return 0;
+}
+
+static int stm32_gpio_direction_output(struct gpio_chip *chip,
+	unsigned offset, int value)
+{
+	struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip);
+
+	__stm32_gpio_set(bank, offset, value);
+	pinctrl_gpio_direction_output(chip->base + offset);
+
+	return 0;
+}
+
+static struct gpio_chip stm32_gpio_template = {
+	.request		= stm32_gpio_request,
+	.free			= stm32_gpio_free,
+	.get			= stm32_gpio_get,
+	.set			= stm32_gpio_set,
+	.direction_input	= stm32_gpio_direction_input,
+	.direction_output	= stm32_gpio_direction_output,
+	.ngpio			= STM32_GPIO_PINS_PER_BANK,
+};
+
+static int stm32_gpiolib_register_bank(struct stm32_pinctrl *info,
+	int bank_nr, struct device_node *np)
+{
+	struct stm32_gpio_bank *bank = &info->banks[bank_nr];
+	struct pinctrl_gpio_range *range = &bank->range;
+	struct device *dev = info->dev;
+	struct resource res;
+	struct reset_control *rstc;
+	int bank_num = of_alias_get_id(np, "gpio");
+	int err;
+
+	rstc = of_reset_control_get(np, NULL);
+	if (!IS_ERR(rstc))
+		reset_control_deassert(rstc);
+
+	if (of_address_to_resource(np, 0, &res))
+		return -ENODEV;
+
+	bank->base = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(bank->base))
+		return PTR_ERR(bank->base);
+
+	bank->gpio_chip = stm32_gpio_template;
+	bank->gpio_chip.base = bank_num * STM32_GPIO_PINS_PER_BANK;
+	bank->gpio_chip.of_node = np;
+	bank->gpio_chip.dev = dev;
+	spin_lock_init(&bank->lock);
+
+	of_property_read_string(np, "st,bank-name", &range->name);
+	bank->gpio_chip.label = range->name;
+
+	range->id = bank_num;
+	range->pin_base = range->base = range->id * STM32_GPIO_PINS_PER_BANK;
+	range->npins = bank->gpio_chip.ngpio;
+	range->gc = &bank->gpio_chip;
+	err  = gpiochip_add(&bank->gpio_chip);
+	if (err) {
+		dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_num);
+		return err;
+	}
+	dev_info(dev, "%s bank added.\n", range->name);
+
+	return 0;
+}
+
+static int stm32_pctl_probe_dt(struct platform_device *pdev,
+	struct pinctrl_desc *pctl_desc, struct stm32_pinctrl *info)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct pinctrl_pin_desc *pdesc;
+	struct device_node *child;
+	int grp_index = 0;
+	int i = 0, j = 0, k = 0, bank = 0,  ret = 0;
+
+	stm32_pctl_dt_child_count(info, np);
+	if (!info->nbanks) {
+		dev_err(&pdev->dev, "you need atleast one gpio bank\n");
+		return -EINVAL;
+	}
+
+	dev_info(&pdev->dev, "nbanks = %d\n", info->nbanks);
+	dev_info(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
+	dev_info(&pdev->dev, "ngroups = %d\n", info->ngroups);
+
+	info->functions = devm_kzalloc(&pdev->dev,
+		info->nfunctions * sizeof(*info->functions), GFP_KERNEL);
+
+	info->groups = devm_kzalloc(&pdev->dev,
+			info->ngroups * sizeof(*info->groups), GFP_KERNEL);
+
+	info->banks = devm_kzalloc(&pdev->dev,
+			info->nbanks * sizeof(*info->banks), GFP_KERNEL);
+
+	if (!info->functions || !info->groups || !info->banks)
+		return -ENOMEM;
+
+	pctl_desc->npins = info->nbanks * STM32_GPIO_PINS_PER_BANK;
+	pdesc =	devm_kzalloc(&pdev->dev,
+			sizeof(*pdesc) * pctl_desc->npins, GFP_KERNEL);
+	if (!pdesc)
+		return -ENOMEM;
+
+	pctl_desc->pins = pdesc;
+
+	for_each_child_of_node(np, child) {
+		if (of_property_read_bool(child, "gpio-controller")) {
+			const char *bank_name;
+
+			ret = stm32_gpiolib_register_bank(info, bank, child);
+			if (ret)
+				return ret;
+
+			k = info->banks[bank].range.pin_base;
+			bank_name = info->banks[bank].range.name;
+			for (j = 0; j < STM32_GPIO_PINS_PER_BANK; j++, k++) {
+				pdesc->number = k;
+				pdesc->name = kasprintf(GFP_KERNEL, "%s[%d]",
+							bank_name, j);
+				pdesc++;
+			}
+			bank++;
+		} else {
+			ret = stm32_pctl_parse_functions(child, info,
+							i++, &grp_index);
+			if (ret) {
+				dev_err(&pdev->dev, "No functions found.\n");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int stm32_pctl_probe(struct platform_device *pdev)
+{
+	struct stm32_pinctrl *info;
+	struct pinctrl_desc *pctl_desc;
+	int ret, i;
+
+	if (!pdev->dev.of_node) {
+		dev_err(&pdev->dev, "device not found.\n");
+		return -EINVAL;
+	}
+
+	pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl_desc), GFP_KERNEL);
+	if (!pctl_desc)
+		return -ENOMEM;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->dev = &pdev->dev;
+	platform_set_drvdata(pdev, info);
+	ret = stm32_pctl_probe_dt(pdev, pctl_desc, info);
+	if (ret)
+		return ret;
+
+	pctl_desc->owner	= THIS_MODULE;
+	pctl_desc->pctlops	= &stm32_pctlops;
+	pctl_desc->pmxops	= &stm32_pmxops;
+	pctl_desc->confops	= &stm32_confops;
+	pctl_desc->name		= dev_name(&pdev->dev);
+
+	info->pctl = pinctrl_register(pctl_desc, &pdev->dev, info);
+	if (!info->pctl) {
+		dev_err(&pdev->dev, "Failed pinctrl registration\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < info->nbanks; i++)
+		pinctrl_add_gpio_range(info->pctl, &info->banks[i].range);
+
+	return 0;
+}
+
+static struct of_device_id stm32_pctl_of_match[] = {
+	{ .compatible = "st,stm32-pinctrl" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver stm32_pctl_driver = {
+	.driver = {
+		.name = "stm32-pinctrl",
+		.owner = THIS_MODULE,
+		.of_match_table = stm32_pctl_of_match,
+	},
+	.probe = stm32_pctl_probe,
+};
+
+static int __init stm32_pctl_init(void)
+{
+	return platform_driver_register(&stm32_pctl_driver);
+}
+arch_initcall(stm32_pctl_init);
diff --git a/include/dt-bindings/pinctrl/pinctrl-stm32.h b/include/dt-bindings/pinctrl/pinctrl-stm32.h
new file mode 100644
index 0000000..3e93a86
--- /dev/null
+++ b/include/dt-bindings/pinctrl/pinctrl-stm32.h
@@ -0,0 +1,43 @@
+#ifndef _DT_BINDINGS_PINCTRL_STM32_H
+#define _DT_BINDINGS_PINCTRL_STM32_H
+
+/* Modes */
+#define IN		0
+#define OUT		1
+#define ALT		2
+#define ANALOG		3
+
+/* Alternate functions */
+#define ALT0		((0 << 2) | ALT)
+#define ALT1		((1 << 2) | ALT)
+#define ALT2		((2 << 2) | ALT)
+#define ALT3		((3 << 2) | ALT)
+#define ALT4		((4 << 2) | ALT)
+#define ALT5		((5 << 2) | ALT)
+#define ALT6		((6 << 2) | ALT)
+#define ALT7		((7 << 2) | ALT)
+#define ALT8		((8 << 2) | ALT)
+#define ALT9		((9 << 2) | ALT)
+#define ALT10		((10 << 2) | ALT)
+#define ALT11		((11 << 2) | ALT)
+#define ALT12		((12 << 2) | ALT)
+#define ALT13		((13 << 2) | ALT)
+#define ALT14		((14 << 2) | ALT)
+#define ALT15		((15 << 2) | ALT)
+
+/* Pull-Up/Down */
+#define NO_PULL		0
+#define PULL_UP		1
+#define PULL_DOWN	2
+
+/* Type */
+#define PUSH_PULL	(0 << 2)
+#define OPEN_DRAIN	(1 << 2)
+
+/* Speed */
+#define LOW_SPEED	(0 << 3)
+#define MEDIUM_SPEED	(1 << 3)
+#define FAST_SPEED	(2 << 3)
+#define HIGH_SPEED	(3 << 3)
+
+#endif /* _DT_BINDINGS_PINCTRL_STM32_H */
-- 
1.9.1

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

* [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (10 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-03-10 15:08   ` Arnd Bergmann
  2015-02-20 18:01 ` [PATCH v2 13/18] serial: stm32-usart: Add STM32 USART Driver Maxime Coquelin
                   ` (5 subsequent siblings)
  17 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This adds documentation of device tree bindings for the
STM32 USART

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 .../devicetree/bindings/serial/st,stm32-usart.txt      | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt

diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
new file mode 100644
index 0000000..e49b75ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
@@ -0,0 +1,18 @@
+* STMicroelectronics STM32 USART
+
+Required properties:
+- compatible: Should be "st,stm32-usart"
+- reg: The address and length of the peripheral registers space
+- interrupts: The interrupt line of the USART instance
+- clocks: The input clock of the USART instance
+- pinctrl: The reference on the pins configuration
+
+Example:
+usart1: usart at 40011000 {
+	compatible = "st,stm32-usart";
+	reg = <0x40011000 0x400>;
+	interrupts = <37>;
+	clocks = <&clk_pclk2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usart1>;
+};
-- 
1.9.1

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

* [PATCH v2 13/18] serial: stm32-usart: Add STM32 USART Driver
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (11 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 14/18] ARM: Add STM32 family machine Maxime Coquelin
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This drivers adds support to the STM32 USART controller, which is a
standard serial driver.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 drivers/tty/serial/Kconfig       |  17 +
 drivers/tty/serial/Makefile      |   1 +
 drivers/tty/serial/stm32-usart.c | 695 +++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/serial_core.h |   3 +
 4 files changed, 716 insertions(+)
 create mode 100644 drivers/tty/serial/stm32-usart.c

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index c79b43c..b990bd4 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1577,6 +1577,23 @@ config SERIAL_MEN_Z135
 	  This driver can also be build as a module. If so, the module will be called
 	  men_z135_uart.ko
 
+config SERIAL_STM32
+	tristate "STMicroelectronics STM32 serial port support"
+	select SERIAL_CORE
+	depends on ARM || COMPILE_TEST
+	help
+	  This driver is for the on-chip Serial Controller on
+	  STMicroelectronics STM32 MCUs.
+	  USART supports Rx & Tx functionality.
+	  It support all industry standard baud rates.
+
+	  If unsure, say N.
+
+config SERIAL_STM32_CONSOLE
+	bool "Support for console on STM32"
+	depends on SERIAL_STM32=y
+	select SERIAL_CORE_CONSOLE
+
 endmenu
 
 config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 9a548ac..a582831 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_SERIAL_ARC)	+= arc_uart.o
 obj-$(CONFIG_SERIAL_RP2)	+= rp2.o
 obj-$(CONFIG_SERIAL_FSL_LPUART)	+= fsl_lpuart.o
 obj-$(CONFIG_SERIAL_MEN_Z135)	+= men_z135_uart.o
+obj-$(CONFIG_SERIAL_STM32)	+= stm32-usart.o
 
 # GPIOLIB helpers for modem control lines
 obj-$(CONFIG_SERIAL_MCTRL_GPIO)	+= serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
new file mode 100644
index 0000000..ef3c9fd
--- /dev/null
+++ b/drivers/tty/serial/stm32-usart.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ *
+ * Inspired by st-asc.c from STMicroelectronics (c)
+ */
+
+#if defined(CONFIG_SERIAL_STM32_USART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+
+#define DRIVER_NAME "stm32-usart"
+
+/* Register offsets */
+#define USART_SR		0x00
+#define USART_DR		0x04
+#define USART_BRR		0x08
+#define USART_CR1		0x0c
+#define USART_CR2		0x10
+#define USART_CR3		0x14
+#define USART_GTPR		0x18
+
+/* USART_SR */
+#define USART_SR_PE		BIT(0)
+#define USART_SR_FE		BIT(1)
+#define USART_SR_NF		BIT(2)
+#define USART_SR_ORE		BIT(3)
+#define USART_SR_IDLE		BIT(4)
+#define USART_SR_RXNE		BIT(5)
+#define USART_SR_TC		BIT(6)
+#define USART_SR_TXE		BIT(7)
+#define USART_SR_LBD		BIT(8)
+#define USART_SR_CTS		BIT(9)
+#define USART_SR_ERR_MASK	(USART_SR_LBD | USART_SR_ORE | \
+				 USART_SR_FE | USART_SR_PE)
+/* Dummy bits */
+#define USART_SR_DUMMY_RX	BIT(16)
+
+/* USART_DR */
+#define USART_DR_MASK		GENMASK(8, 0)
+
+/* USART_BRR */
+#define USART_BRR_DIV_F_MASK	GENMASK(3, 0)
+#define USART_BRR_DIV_M_MASK	GENMASK(15, 4)
+#define USART_BRR_DIV_M_SHIFT	4
+
+/* USART_CR1 */
+#define USART_CR1_SBK		BIT(0)
+#define USART_CR1_RWU		BIT(1)
+#define USART_CR1_RE		BIT(2)
+#define USART_CR1_TE		BIT(3)
+#define USART_CR1_IDLEIE	BIT(4)
+#define USART_CR1_RXNEIE	BIT(5)
+#define USART_CR1_TCIE		BIT(6)
+#define USART_CR1_TXEIE		BIT(7)
+#define USART_CR1_PEIE		BIT(8)
+#define USART_CR1_PS		BIT(9)
+#define USART_CR1_PCE		BIT(10)
+#define USART_CR1_WAKE		BIT(11)
+#define USART_CR1_M		BIT(12)
+#define USART_CR1_UE		BIT(13)
+#define USART_CR1_OVER8		BIT(15)
+#define USART_CR1_IE_MASK	GENMASK(8, 4)
+
+/* USART_CR2 */
+#define USART_CR2_ADD_MASK	GENMASK(3, 0)
+#define USART_CR2_LBDL		BIT(5)
+#define USART_CR2_LBDIE		BIT(6)
+#define USART_CR2_LBCL		BIT(8)
+#define USART_CR2_CPHA		BIT(9)
+#define USART_CR2_CPOL		BIT(10)
+#define USART_CR2_CLKEN		BIT(11)
+#define USART_CR2_STOP_2B	BIT(13)
+#define USART_CR2_STOP_MASK	GENMASK(13, 12)
+#define USART_CR2_LINEN		BIT(14)
+
+/* USART_CR3 */
+#define USART_CR3_EIE		BIT(0)
+#define USART_CR3_IREN		BIT(1)
+#define USART_CR3_IRLP		BIT(2)
+#define USART_CR3_HDSEL		BIT(3)
+#define USART_CR3_NACK		BIT(4)
+#define USART_CR3_SCEN		BIT(5)
+#define USART_CR3_DMAR		BIT(6)
+#define USART_CR3_DMAT		BIT(7)
+#define USART_CR3_RTSE		BIT(8)
+#define USART_CR3_CTSE		BIT(9)
+#define USART_CR3_CTSIE		BIT(10)
+#define USART_CR3_ONEBIT	BIT(11)
+
+/* USART_GTPR */
+#define USART_GTPR_PSC_MASK	GENMASK(7, 0)
+#define USART_GTPR_GT_MASK	GENMASK(15, 8)
+
+#define DRIVER_NAME "stm32-usart"
+#define STM32_SERIAL_NAME "ttyS"
+#define STM32_MAX_PORTS 6
+
+struct stm32_port {
+	struct uart_port port;
+	struct clk *clk;
+};
+
+static struct stm32_port stm32_ports[STM32_MAX_PORTS];
+static struct uart_driver stm32_usart_driver;
+
+static void stm32_stop_tx(struct uart_port *port);
+
+static void stm32_set_bits(struct uart_port *port, u32 reg, u32 bits)
+{
+	u32 val;
+
+	val = readl_relaxed(port->membase + reg);
+	val |= bits;
+	writel_relaxed(val, port->membase + reg);
+}
+
+static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
+{
+	u32 val;
+
+	val = readl_relaxed(port->membase + reg);
+	val &= ~bits;
+	writel_relaxed(val, port->membase + reg);
+}
+
+static void stm32_receive_chars(struct uart_port *port)
+{
+	struct tty_port *tport = &port->state->port;
+	unsigned long c;
+	u32 sr;
+	char flag;
+
+	if (port->irq_wake)
+		pm_wakeup_event(tport->tty->dev, 0);
+
+	while ((sr = readl_relaxed(port->membase + USART_SR)) & USART_SR_RXNE) {
+		sr |= USART_SR_DUMMY_RX;
+		c = readl_relaxed(port->membase + USART_DR);
+		flag = TTY_NORMAL;
+		port->icount.rx++;
+
+		if (sr & USART_SR_ERR_MASK) {
+			if (sr & USART_SR_LBD) {
+				port->icount.brk++;
+				if (uart_handle_break(port))
+					continue;
+			} else if (sr & USART_SR_ORE) {
+				port->icount.overrun++;
+			} else if (sr & USART_SR_PE) {
+				port->icount.parity++;
+			} else if (sr & USART_SR_FE) {
+				port->icount.frame++;
+			}
+
+			sr &= port->read_status_mask;
+
+			if (sr & USART_SR_LBD)
+				flag = TTY_BREAK;
+			else if (sr & USART_SR_PE)
+				flag = TTY_PARITY;
+			else if (sr & USART_SR_FE)
+				flag = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(port, c))
+			continue;
+		uart_insert_char(port, sr, USART_SR_ORE, c, flag);
+	}
+
+	spin_unlock(&port->lock);
+	tty_flip_buffer_push(tport);
+	spin_lock(&port->lock);
+}
+
+static void stm32_transmit_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+
+	if (port->x_char) {
+		writel_relaxed(port->x_char, port->membase + USART_DR);
+		port->x_char = 0;
+		port->icount.tx++;
+		return;
+	}
+
+	if (uart_tx_stopped(port)) {
+		stm32_stop_tx(port);
+		return;
+	}
+
+	if (uart_circ_empty(xmit)) {
+		stm32_stop_tx(port);
+		return;
+	}
+
+	writel_relaxed(xmit->buf[xmit->tail], port->membase + USART_DR);
+	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+	port->icount.tx++;
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+
+	if (uart_circ_empty(xmit))
+		stm32_stop_tx(port);
+}
+
+static irqreturn_t stm32_interrupt(int irq, void *ptr)
+{
+	struct uart_port *port = ptr;
+	u32 sr;
+
+	spin_lock(&port->lock);
+
+	sr = readl_relaxed(port->membase + USART_SR);
+
+	if (sr & USART_SR_RXNE)
+		stm32_receive_chars(port);
+
+	if (sr & USART_SR_TXE)
+		stm32_transmit_chars(port);
+
+	spin_unlock(&port->lock);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned int stm32_tx_empty(struct uart_port *port)
+{
+	return readl_relaxed(port->membase + USART_SR) & USART_SR_TXE;
+}
+
+static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	/*
+	 * This routine is used for seting signals of: DTR, DCD, CTS/RTS
+	 * We use USART's hardware for CTS/RTS, so don't need any for that.
+	 * Some boards have DTR and DCD implemented using PIO pins,
+	 * code to do this should be hooked in here.
+	 */
+}
+
+static unsigned int stm32_get_mctrl(struct uart_port *port)
+{
+	/*
+	 * This routine is used for geting signals of: DTR, DCD, DSR, RI,
+	 * and CTS/RTS
+	 */
+	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+/* There are probably characters waiting to be transmitted. */
+static void stm32_start_tx(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+
+	if (uart_circ_empty(xmit))
+		return;
+
+	stm32_set_bits(port, USART_CR1, USART_CR1_TXEIE | USART_CR1_TE);
+}
+
+/* Transmit stop */
+static void stm32_stop_tx(struct uart_port *port)
+{
+	stm32_clr_bits(port, USART_CR1, USART_CR1_TXEIE);
+}
+
+/* Receive stop */
+static void stm32_stop_rx(struct uart_port *port)
+{
+	stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE);
+}
+
+/* Handle breaks - ignored by us */
+static void stm32_break_ctl(struct uart_port *port, int break_state)
+{
+	/* Nothing here yet .. */
+}
+
+static int stm32_startup(struct uart_port *port)
+{
+	const char *name = to_platform_device(port->dev)->name;
+	u32 val;
+
+	if (request_irq(port->irq, stm32_interrupt, IRQF_NO_SUSPEND,
+				name, port)) {
+		dev_err(port->dev, "cannot allocate irq %d\n", port->irq);
+		return -ENODEV;
+	}
+
+	val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+	stm32_set_bits(port, USART_CR1, val);
+
+	return 0;
+}
+
+static void stm32_shutdown(struct uart_port *port)
+{
+	u32 val;
+
+	val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+	stm32_set_bits(port, USART_CR1, val);
+
+	free_irq(port->irq, port);
+}
+
+static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
+			    struct ktermios *old)
+{
+	unsigned int baud;
+	u32 usardiv, mantissa, fraction;
+	tcflag_t cflag;
+	u32 cr1, cr2, cr3;
+	unsigned long flags;
+
+	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
+	cflag = termios->c_cflag;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	/* Stop serial port and reset value */
+	writel_relaxed(0, port->membase + USART_CR1);
+
+	cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE;
+
+	if (cflag & CSTOPB)
+		cr2 = USART_CR2_STOP_2B;
+
+	if (cflag & PARENB) {
+		cr1 |= USART_CR1_PCE;
+		if ((cflag & CSIZE) == CS8)
+			cr1 |= USART_CR1_M;
+	}
+
+	if (cflag & PARODD)
+		cr1 |= USART_CR1_PS;
+
+	if (cflag & CRTSCTS)
+		cr3 = USART_CR3_RTSE | USART_CR3_CTSE;
+
+	usardiv = (port->uartclk * 25) / (baud * 4);
+	mantissa = (usardiv / 100) << USART_BRR_DIV_M_SHIFT;
+	fraction = DIV_ROUND_CLOSEST((usardiv % 100) * 16, 100);
+	if (fraction & ~USART_BRR_DIV_F_MASK) {
+		fraction = 0;
+		mantissa += (1 << USART_BRR_DIV_M_SHIFT);
+	}
+
+	writel_relaxed(mantissa | fraction, port->membase + USART_BRR);
+
+	uart_update_timeout(port, cflag, baud);
+
+	port->read_status_mask = USART_SR_ORE;
+	if (termios->c_iflag & INPCK)
+		port->read_status_mask |= USART_SR_PE | USART_SR_FE;
+	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
+		port->read_status_mask |= USART_SR_LBD;
+
+	/* Characters to ignore */
+	port->ignore_status_mask = 0;
+	if (termios->c_iflag & IGNPAR)
+		port->ignore_status_mask = USART_SR_PE | USART_SR_FE;
+	if (termios->c_iflag & IGNBRK) {
+		port->ignore_status_mask |= USART_SR_LBD;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (termios->c_iflag & IGNPAR)
+			port->ignore_status_mask |= USART_SR_ORE;
+	}
+
+	/*
+	 * Ignore all characters if CREAD is not set.
+	 */
+	if ((termios->c_cflag & CREAD) == 0)
+		port->ignore_status_mask |= USART_SR_DUMMY_RX;
+
+	writel_relaxed(cr3, port->membase + USART_CR3);
+	writel_relaxed(cr2, port->membase + USART_CR2);
+	writel_relaxed(cr1, port->membase + USART_CR1);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *stm32_type(struct uart_port *port)
+{
+	return (port->type == PORT_STM32) ? DRIVER_NAME : NULL;
+}
+
+static void stm32_release_port(struct uart_port *port)
+{
+}
+
+static int stm32_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+static void stm32_config_port(struct uart_port *port, int flags)
+{
+	if ((flags & UART_CONFIG_TYPE))
+		port->type = PORT_STM32;
+}
+
+static int
+stm32_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	/* No user changeable parameters */
+	return -EINVAL;
+}
+
+static void stm32_pm(struct uart_port *port, unsigned int state,
+		unsigned int oldstate)
+{
+	struct stm32_port *stm32port = container_of(port,
+			struct stm32_port, port);
+	unsigned long flags = 0;
+
+	switch (state) {
+	case UART_PM_STATE_ON:
+		clk_prepare_enable(stm32port->clk);
+		break;
+	case UART_PM_STATE_OFF:
+		spin_lock_irqsave(&port->lock, flags);
+		stm32_clr_bits(port, USART_CR1, USART_CR1_UE);
+		spin_unlock_irqrestore(&port->lock, flags);
+		clk_disable_unprepare(stm32port->clk);
+		break;
+	}
+}
+
+static struct uart_ops stm32_uart_ops = {
+	.tx_empty	= stm32_tx_empty,
+	.set_mctrl	= stm32_set_mctrl,
+	.get_mctrl	= stm32_get_mctrl,
+	.start_tx	= stm32_start_tx,
+	.stop_tx	= stm32_stop_tx,
+	.stop_rx	= stm32_stop_rx,
+	.break_ctl	= stm32_break_ctl,
+	.startup	= stm32_startup,
+	.shutdown	= stm32_shutdown,
+	.set_termios	= stm32_set_termios,
+	.type		= stm32_type,
+	.release_port	= stm32_release_port,
+	.request_port	= stm32_request_port,
+	.config_port	= stm32_config_port,
+	.verify_port	= stm32_verify_port,
+	.pm		= stm32_pm,
+};
+
+static int stm32_init_port(struct stm32_port *stm32port,
+			  struct platform_device *pdev)
+{
+	struct uart_port *port = &stm32port->port;
+	struct resource *res;
+
+	port->iotype	= UPIO_MEM;
+	port->flags	= UPF_BOOT_AUTOCONF;
+	port->ops	= &stm32_uart_ops;
+	port->dev	= &pdev->dev;
+	port->irq	= platform_get_irq(pdev, 0);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	port->membase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+	port->mapbase = res->start;
+
+	spin_lock_init(&port->lock);
+
+	stm32port->clk = devm_clk_get(&pdev->dev, NULL);
+
+	if (WARN_ON(IS_ERR(stm32port->clk)))
+		return -EINVAL;
+
+	/* ensure that clk rate is correct by enabling the clk */
+	clk_prepare_enable(stm32port->clk);
+	stm32port->port.uartclk = clk_get_rate(stm32port->clk);
+	WARN_ON(stm32port->port.uartclk == 0);
+	clk_disable_unprepare(stm32port->clk);
+
+	return 0;
+}
+
+static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	int id;
+
+	if (!np)
+		return NULL;
+
+	id = of_alias_get_id(np, STM32_SERIAL_NAME);
+
+	if (id < 0)
+		id = 0;
+
+	if (WARN_ON(id >= STM32_MAX_PORTS))
+		return NULL;
+
+	stm32_ports[id].port.line = id;
+	return &stm32_ports[id];
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id stm32_match[] = {
+	{ .compatible = "st,stm32-usart", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, stm32_match);
+#endif
+
+static int stm32_serial_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct stm32_port *stm32port;
+
+	stm32port = stm32_of_get_stm32_port(pdev);
+	if (!stm32port)
+		return -ENODEV;
+
+	ret = stm32_init_port(stm32port, pdev);
+	if (ret)
+		return ret;
+
+	ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, &stm32port->port);
+
+	return 0;
+}
+
+static int stm32_serial_remove(struct platform_device *pdev)
+{
+	struct uart_port *port = platform_get_drvdata(pdev);
+
+	return uart_remove_one_port(&stm32_usart_driver, port);
+}
+
+
+#ifdef CONFIG_SERIAL_STM32_CONSOLE
+static void stm32_console_putchar(struct uart_port *port, int ch)
+{
+	while (!(readl_relaxed(port->membase + USART_SR) & USART_SR_TXE))
+		cpu_relax();
+
+	writel_relaxed(ch, port->membase + USART_DR);
+}
+
+static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
+{
+	struct uart_port *port = &stm32_ports[co->index].port;
+	unsigned long flags;
+	u32 old_cr1, new_cr1;
+	int locked = 1;
+
+	if (oops_in_progress) {
+		locked = spin_trylock_irqsave(&port->lock, flags);
+	} else {
+		locked = 1;
+		spin_lock_irqsave(&port->lock, flags);
+	}
+
+	/* Save and disable interrupts */
+	old_cr1 = readl_relaxed(port->membase + USART_CR1);
+	new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
+	writel_relaxed(new_cr1, port->membase + USART_CR1);
+
+	uart_console_write(port, s, cnt, stm32_console_putchar);
+
+	/* Restore interrupt state */
+	writel_relaxed(old_cr1, port->membase + USART_CR1);
+
+	if (locked)
+		spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int stm32_console_setup(struct console *co, char *options)
+{
+	struct stm32_port *stm32port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (co->index >= STM32_MAX_PORTS)
+		return -ENODEV;
+
+	stm32port = &stm32_ports[co->index];
+
+	/*
+	 * This driver does not support early console initialization
+	 * (use ARM early printk support instead), so we only expect
+	 * this to be called during the uart port registration when the
+	 * driver gets probed and the port should be mapped at that point.
+	 */
+	if (stm32port->port.mapbase == 0 || stm32port->port.membase == NULL)
+		return -ENXIO;
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(&stm32port->port, co, baud, parity, bits, flow);
+}
+
+static struct console stm32_console = {
+	.name		= STM32_SERIAL_NAME,
+	.device		= uart_console_device,
+	.write		= stm32_console_write,
+	.setup		= stm32_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+	.data		= &stm32_usart_driver,
+};
+
+#define STM32_SERIAL_CONSOLE (&stm32_console)
+
+#else
+#define STM32_SERIAL_CONSOLE NULL
+#endif /* CONFIG_SERIAL_STM32_CONSOLE */
+
+static struct uart_driver stm32_usart_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= DRIVER_NAME,
+	.dev_name	= STM32_SERIAL_NAME,
+	.major		= 0,
+	.minor		= 0,
+	.nr		= STM32_MAX_PORTS,
+	.cons		= STM32_SERIAL_CONSOLE,
+};
+
+static struct platform_driver stm32_serial_driver = {
+	.probe		= stm32_serial_probe,
+	.remove		= stm32_serial_remove,
+	.driver	= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(stm32_match),
+	},
+};
+
+static int __init usart_init(void)
+{
+	int ret;
+	static char banner[] __initdata =
+		KERN_INFO "STM32 USART driver initialized\n";
+
+	printk(banner);
+
+	ret = uart_register_driver(&stm32_usart_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&stm32_serial_driver);
+	if (ret)
+		uart_unregister_driver(&stm32_usart_driver);
+
+	return ret;
+}
+
+static void __exit usart_exit(void)
+{
+	platform_driver_unregister(&stm32_serial_driver);
+	uart_unregister_driver(&stm32_usart_driver);
+}
+
+module_init(usart_init);
+module_exit(usart_exit);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_DESCRIPTION("STMicroelectronics STM32 serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index c172180..14ba8c4 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -248,4 +248,7 @@
 /* MESON */
 #define PORT_MESON	109
 
+/* STM32 USART */
+#define PORT_STM32	110
+
 #endif /* _UAPILINUX_SERIAL_CORE_H */
-- 
1.9.1

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (12 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 13/18] serial: stm32-usart: Add STM32 USART Driver Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:33   ` Peter Meerwald
                     ` (2 more replies)
  2015-02-20 18:01 ` [PATCH v2 15/18] ARM: dts: Add ARM System timer as clockevent in armv7m Maxime Coquelin
                   ` (3 subsequent siblings)
  17 siblings, 3 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

STMicrolectronics's STM32 series is a family of Cortex-M
microcontrollers. It is used in various applications, and
proposes a wide range of peripherals.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 Documentation/arm/stm32/overview.txt           | 32 ++++++++++++++++++++++++++
 Documentation/arm/stm32/stm32f429-overview.txt | 22 ++++++++++++++++++
 arch/arm/Kconfig                               | 22 ++++++++++++++++++
 arch/arm/Makefile                              |  1 +
 arch/arm/mach-stm32/Makefile                   |  1 +
 arch/arm/mach-stm32/Makefile.boot              |  0
 arch/arm/mach-stm32/board-dt.c                 | 31 +++++++++++++++++++++++++
 7 files changed, 109 insertions(+)
 create mode 100644 Documentation/arm/stm32/overview.txt
 create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
 create mode 100644 arch/arm/mach-stm32/Makefile
 create mode 100644 arch/arm/mach-stm32/Makefile.boot
 create mode 100644 arch/arm/mach-stm32/board-dt.c

diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
new file mode 100644
index 0000000..d8bf6bb
--- /dev/null
+++ b/Documentation/arm/stm32/overview.txt
@@ -0,0 +1,32 @@
+			STM32 ARM Linux Overview
+			==========================
+
+Introduction
+------------
+
+  The STMicroelectronics family of Cortex-M based MCUs are supported by the
+  'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
+
+
+Configuration
+-------------
+
+  A generic configuration is provided for STM32 family, and can be used as the
+  default by
+	make stm32_defconfig
+
+Layout
+------
+
+  All the files for multiple machine families are located in the platform code
+  contained in arch/arm/mach-stm32
+
+  There is a generic board board-dt.c in the mach folder which support
+  Flattened Device Tree, which means, It works with any compatible board with
+  Device Trees.
+
+
+Document Author
+---------------
+
+  Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt
new file mode 100644
index 0000000..5206822
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f429-overview.txt
@@ -0,0 +1,22 @@
+			STM32F429 Overview
+			==================
+
+  Introduction
+  ------------
+	The STM32F429 is a Cortex-M4 MCU aimed at various applications.
+	It features:
+	- ARM Cortex-M4 up to 180MHz with FPU
+	- 2MB internal Flash Memory
+	- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
+	- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
+	- LCD controller & Camera interface
+	- Cryptographic processor
+
+  Resources
+  ---------
+	Datasheet and reference manual are publicly available on ST website:
+	- http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
+
+  Document Author
+  ---------------
+	Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..cfd9532 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -774,6 +774,28 @@ config ARCH_OMAP1
 	help
 	  Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
 
+config ARCH_STM32
+	bool "STMicrolectronics STM32"
+	depends on !MMU
+	select ARCH_REQUIRE_GPIOLIB
+	select ARM_NVIC
+	select AUTO_ZRELADDR
+	select ARCH_HAS_RESET_CONTROLLER
+	select RESET_CONTROLLER
+	select PINCTRL
+	select PINCTRL_STM32
+	select CLKSRC_OF
+	select ARMV7M_SYSTICK
+	select COMMON_CLK
+	select CPU_V7M
+	select GENERIC_CLOCKEVENTS
+	select NO_DMA
+	select NO_IOPORT_MAP
+	select SPARSE_IRQ
+	select USE_OF
+	help
+	  Support for STMicorelectronics STM32 processors.
+
 endchoice
 
 menu "Multiple platform selection"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c1785ee..7d00659 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -196,6 +196,7 @@ machine-$(CONFIG_ARCH_SHMOBILE) 	+= shmobile
 machine-$(CONFIG_ARCH_SIRF)		+= prima2
 machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
 machine-$(CONFIG_ARCH_STI)		+= sti
+machine-$(CONFIG_ARCH_STM32)		+= stm32
 machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
 machine-$(CONFIG_ARCH_TEGRA)		+= tegra
 machine-$(CONFIG_ARCH_U300)		+= u300
diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
new file mode 100644
index 0000000..bd0b7b5
--- /dev/null
+++ b/arch/arm/mach-stm32/Makefile
@@ -0,0 +1 @@
+obj-y += board-dt.o
diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot
new file mode 100644
index 0000000..e69de29
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
new file mode 100644
index 0000000..1d681b3
--- /dev/null
+++ b/arch/arm/mach-stm32/board-dt.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/reset-controller.h>
+#include <asm/v7m.h>
+#include <asm/mach/arch.h>
+
+static const char *const stm32_compat[] __initconst = {
+	"st,stm32f429",
+	NULL
+};
+
+static void __init stm32_timer_init(void)
+{
+	of_clk_init(NULL);
+	reset_controller_of_init();
+	clocksource_of_init();
+
+}
+
+DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)")
+	.init_time = stm32_timer_init,
+	.dt_compat = stm32_compat,
+	.restart = armv7m_restart,
+MACHINE_END
-- 
1.9.1

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

* [PATCH v2 15/18] ARM: dts: Add ARM System timer as clockevent in armv7m
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (13 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 14/18] ARM: Add STM32 family machine Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU Maxime Coquelin
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 arch/arm/boot/dts/armv7-m.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/armv7-m.dtsi b/arch/arm/boot/dts/armv7-m.dtsi
index 5a660d0..78a0549 100644
--- a/arch/arm/boot/dts/armv7-m.dtsi
+++ b/arch/arm/boot/dts/armv7-m.dtsi
@@ -8,6 +8,13 @@
 		reg = <0xe000e100 0xc00>;
 	};
 
+	systick: timer at e000e010 {
+		compatible = "arm,armv7m-systick";
+		reg = <0xe000e010 0x10>;
+
+		status = "disabled";
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
1.9.1

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

* [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (14 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 15/18] ARM: dts: Add ARM System timer as clockevent in armv7m Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-03-02 17:42   ` Andreas Färber
  2015-03-09 14:39   ` Linus Walleij
  2015-02-20 18:01 ` [PATCH v2 17/18] ARM: configs: Add STM32 defconfig Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 18/18] MAINTAINERS: Add entry for STM32 MCUs Maxime Coquelin
  17 siblings, 2 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

The STMicrolectornics's STM32F419 MCU has the following main features:
 - Cortex-M4 core running up to @180MHz
 - 2MB internal flash, 256KBytes internal RAM
 - FMC controller to connect SDRAM, NOR and NAND memories
 - SD/MMC/SDIO support
 - Ethernet controller
 - USB OTFG FS & HS controllers
 - I2C, SPI, CAN busses support
 - Several 16 & 32 bits general purpose timers
 - Serial Audio interface
 - LCD controller

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 arch/arm/boot/dts/Makefile            |   1 +
 arch/arm/boot/dts/stm32f429-disco.dts |  41 ++++
 arch/arm/boot/dts/stm32f429.dtsi      | 396 ++++++++++++++++++++++++++++++++++
 3 files changed, 438 insertions(+)
 create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
 create mode 100644 arch/arm/boot/dts/stm32f429.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 91bd5bd..d7da0ef 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -442,6 +442,7 @@ dtb-$(CONFIG_ARCH_STI)+= stih407-b2120.dtb \
 	stih416-b2000.dtb \
 	stih416-b2020.dtb \
 	stih416-b2020e.dtb
+dtb-$(CONFIG_ARCH_STM32)+= stm32f429-disco.dtb
 dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-a1000.dtb \
 	sun4i-a10-ba10-tvbox.dtb \
diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
new file mode 100644
index 0000000..0e79cc1
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -0,0 +1,41 @@
+/dts-v1/;
+#include "stm32f429.dtsi"
+
+/ {
+	model = "STMicroelectronics's STM32F429i-DISCO board";
+	compatible = "st,stm32f429i-disco", "st,stm32f429";
+
+	chosen {
+		bootargs = "console=ttyS0,115200 root=/dev/ram rdinit=/linuxrc";
+		linux,stdout-path = &usart1;
+	};
+
+	memory {
+		reg = <0xd0000000 0x800000>;
+	};
+
+	aliases {
+		ttyS0 = &usart1;
+	};
+
+	soc {
+		usart1: usart at 40011000 {
+			status = "okay";
+		};
+
+		leds {
+			compatible = "gpio-leds";
+			red {
+				#gpio-cells = <2>;
+				label = "Front Panel LED";
+				gpios = <&gpiog 14 0>;
+				linux,default-trigger = "heartbeat";
+			};
+			green {
+				#gpio-cells = <2>;
+				gpios = <&gpiog 13 0>;
+				default-state = "off";
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
new file mode 100644
index 0000000..5b3442a
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -0,0 +1,396 @@
+/*
+ * Device tree for STM32F429
+ */
+#include "armv7-m.dtsi"
+#include <dt-bindings/pinctrl/pinctrl-stm32.h>
+#include <dt-bindings/reset/st,stm32f429.h>
+
+/ {
+
+	aliases {
+		gpio0 = &gpioa;
+		gpio1 = &gpiob;
+		gpio2 = &gpioc;
+		gpio3 = &gpiod;
+		gpio4 = &gpioe;
+		gpio5 = &gpiof;
+		gpio6 = &gpiog;
+		gpio7 = &gpioh;
+		gpio8 = &gpioi;
+		gpio9 = &gpioj;
+		gpio10 = &gpiok;
+	};
+
+	clocks {
+		clk_sysclk: clk-sysclk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <180000000>;
+		};
+
+		clk_hclk: clk-hclk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <180000000>;
+		};
+
+		clk_pclk1: clk-pclk1 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <45000000>;
+		};
+
+		clk_pclk2: clk-pclk2 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <90000000>;
+		};
+
+		clk_pmtr1: clk-pmtr1 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <90000000>;
+		};
+
+		clk_pmtr2: clk-pmtr2 {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <180000000>;
+		};
+
+		clk_systick: clk-systick {
+			compatible = "fixed-factor-clock";
+			clocks = <&clk_hclk>;
+			#clock-cells = <0>;
+			clock-div = <8>;
+			clock-mult = <1>;
+		};
+	};
+
+	systick: timer at e000e010 {
+		clocks = <&clk_systick>;
+
+		status = "okay";
+	};
+
+	soc {
+		reset: reset at 40023810 {
+			#reset-cells = <1>;
+			compatible = "st,stm32-reset";
+			reg = <0x40023810 0x18>;
+		};
+
+		pin-controller {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "st,stm32-pinctrl";
+			ranges = <0 0x40020000 0x3000>;
+
+			gpioa: gpio at 40020000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x0 0x400>;
+				resets = <&reset GPIOA_RESET>;
+				st,bank-name = "GPIOA";
+			};
+
+			gpiob: gpio at 40020400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x400 0x400>;
+				resets = <&reset GPIOB_RESET>;
+				st,bank-name = "GPIOB";
+			};
+
+			gpioc: gpio at 40020800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x800 0x400>;
+				resets = <&reset GPIOC_RESET>;
+				st,bank-name = "GPIOC";
+			};
+
+			gpiod: gpio at 40020c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0xc00 0x400>;
+				resets = <&reset GPIOD_RESET>;
+				st,bank-name = "GPIOD";
+			};
+
+			gpioe: gpio at 40021000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1000 0x400>;
+				resets = <&reset GPIOE_RESET>;
+				st,bank-name = "GPIOE";
+			};
+
+			gpiof: gpio at 40021400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1400 0x400>;
+				resets = <&reset GPIOF_RESET>;
+				st,bank-name = "GPIOF";
+			};
+
+			gpiog: gpio at 40021800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1800 0x400>;
+				resets = <&reset GPIOG_RESET>;
+				st,bank-name = "GPIOG";
+			};
+
+			gpioh: gpio at 40021c00 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x1c00 0x400>;
+				resets = <&reset GPIOH_RESET>;
+				st,bank-name = "GPIOH";
+			};
+
+			gpioi: gpio at 40022000 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2000 0x400>;
+				resets = <&reset GPIOI_RESET>;
+				st,bank-name = "GPIOI";
+			};
+
+			gpioj: gpio at 40022400 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2400 0x400>;
+				resets = <&reset GPIOJ_RESET>;
+				st,bank-name = "GPIOJ";
+			};
+
+			gpiok: gpio at 40022800 {
+				gpio-controller;
+				#gpio-cells = <2>;
+				reg = <0x2800 0x400>;
+				resets = <&reset GPIOK_RESET>;
+				st,bank-name = "GPIOK";
+			};
+
+			usart1 {
+				pinctrl_usart1: usart1-0 {
+					st,pins {
+						tx = <&gpioa 9 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpioa 10 ALT7 NO_PULL>;
+					};
+				};
+			};
+
+			usart2 {
+				pinctrl_usart2: usart2-0 {
+					st,pins {
+						tx = <&gpioa 2 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpioa 3 ALT7 NO_PULL>;
+					};
+				};
+			};
+
+			usart3 {
+				pinctrl_usart3: usart3-0 {
+					st,pins {
+						tx = <&gpiob 10 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpiob 11 ALT7 NO_PULL>;
+					};
+				};
+			};
+
+			usart4 {
+				pinctrl_usart4: usart4-0 {
+					st,pins {
+						tx = <&gpioa 0 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpioa 1 ALT8 NO_PULL>;
+					};
+				};
+			};
+
+			usart5 {
+				pinctrl_usart5: usart5-0 {
+					st,pins {
+						tx = <&gpioc 12 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpiod 2 ALT8 NO_PULL>;
+					};
+				};
+			};
+
+			usart6 {
+				pinctrl_usart6: usart6-0 {
+					st,pins {
+						tx = <&gpioc 6 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpioc 7 ALT8 NO_PULL>;
+					};
+				};
+			};
+
+			usart7 {
+				pinctrl_usart7: usart7-0 {
+					st,pins {
+						tx = <&gpioe 8 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpioe 7 ALT8 NO_PULL>;
+					};
+				};
+			};
+
+			usart8 {
+				pinctrl_usart8: usart8-0 {
+					st,pins {
+						tx = <&gpioe 1 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
+						rx = <&gpioe 0 ALT8 NO_PULL>;
+					};
+				};
+			};
+		};
+
+		timer2: timer at 40000000 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000000 0x400>;
+			interrupts = <28>;
+			resets = <&reset TIM2_RESET>;
+			clocks = <&clk_pmtr1>;
+
+			status = "disabled";
+		};
+
+		timer3: timer at 40000400 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000400 0x400>;
+			interrupts = <29>;
+			resets = <&reset TIM3_RESET>;
+			clocks = <&clk_pmtr1>;
+
+			status = "disabled";
+		};
+
+		timer4: timer at 40000800 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000800 0x400>;
+			interrupts = <30>;
+			resets = <&reset TIM4_RESET>;
+			clocks = <&clk_pmtr1>;
+
+			status = "disabled";
+		};
+
+		timer5: timer at 40000c00 {
+			compatible = "st,stm32-timer";
+			reg = <0x40000c00 0x400>;
+			interrupts = <50>;
+			resets = <&reset TIM5_RESET>;
+			clocks = <&clk_pmtr1>;
+		};
+
+		timer6: timer at 40001000 {
+			compatible = "st,stm32-timer";
+			reg = <0x40001000 0x400>;
+			interrupts = <54>;
+			resets = <&reset TIM6_RESET>;
+			clocks = <&clk_pmtr1>;
+
+			status = "disabled";
+		};
+
+		timer7: timer at 40001400 {
+			compatible = "st,stm32-timer";
+			reg = <0x40001400 0x400>;
+			interrupts = <55>;
+			resets = <&reset TIM7_RESET>;
+			clocks = <&clk_pmtr1>;
+
+			status = "disabled";
+		};
+
+		usart1: usart at 40011000 {
+			compatible = "st,stm32-usart";
+			reg = <0x40011000 0x400>;
+			interrupts = <37>;
+			clocks = <&clk_pclk2>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart2: usart at 40004400 {
+			compatible = "st,stm32-usart";
+			reg = <0x40004400 0x400>;
+			interrupts = <38>;
+			clocks = <&clk_pclk1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart3: usart at 40004800 {
+			compatible = "st,stm32-usart";
+			reg = <0x40004800 0x400>;
+			interrupts = <39>;
+			clocks = <&clk_pclk1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart4: usart at 40004c00 {
+			compatible = "st,stm32-usart";
+			reg = <0x40004c00 0x400>;
+			interrupts = <52>;
+			clocks = <&clk_pclk1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart5: usart at 40005000 {
+			compatible = "st,stm32-usart";
+			reg = <0x40005000 0x400>;
+			interrupts = <53>;
+			clocks = <&clk_pclk1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart6: usart at 40011400 {
+			compatible = "st,stm32-usart";
+			reg = <0x40011400 0x400>;
+			interrupts = <71>;
+			clocks = <&clk_pclk2>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart7: usart at 40007800 {
+			compatible = "st,stm32-usart";
+			reg = <0x40007800 0x400>;
+			interrupts = <82>;
+			clocks = <&clk_pclk1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+
+		usart8: usart at 40007c00 {
+			compatible = "st,stm32-usart";
+			reg = <0x40007c00 0x400>;
+			interrupts = <83>;
+			clocks = <&clk_pclk1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_usart1>;
+
+			status = "disabled";
+		};
+	};
+};
-- 
1.9.1

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

* [PATCH v2 17/18] ARM: configs: Add STM32 defconfig
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (15 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  2015-02-20 18:01 ` [PATCH v2 18/18] MAINTAINERS: Add entry for STM32 MCUs Maxime Coquelin
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds a new config for STM32 MCUs.
STM32F429 Discovery board boots successfully with this config applied.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 arch/arm/configs/stm32_defconfig | 72 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 arch/arm/configs/stm32_defconfig

diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
new file mode 100644
index 0000000..3d7802a
--- /dev/null
+++ b/arch/arm/configs/stm32_defconfig
@@ -0,0 +1,72 @@
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="./rootfs.cpio"
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MMU is not set
+CONFIG_ARCH_STM32=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0xd0000000
+CONFIG_FLASH_MEM_BASE=0x08000000
+CONFIG_FLASH_SIZE=0x00200000
+CONFIG_PREEMPT=y
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_XIP_KERNEL=y
+CONFIG_XIP_PHYS_ADDR=0x08020000
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_COREDUMP is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_EEPROM_93CX6=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_STM32=y
+CONFIG_SERIAL_STM32_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=y
-- 
1.9.1

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

* [PATCH v2 18/18] MAINTAINERS: Add entry for STM32 MCUs
  2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
                   ` (16 preceding siblings ...)
  2015-02-20 18:01 ` [PATCH v2 17/18] ARM: configs: Add STM32 defconfig Maxime Coquelin
@ 2015-02-20 18:01 ` Maxime Coquelin
  17 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

Add a MAINTAINER entry covering all STM32 machine and drivers files.

Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d66a97d..559cd45 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1448,6 +1448,13 @@ F:	drivers/usb/host/ehci-st.c
 F:	drivers/usb/host/ohci-st.c
 F:	drivers/ata/ahci_st.c
 
+ARM/STM32 ARCHITECTURE
+M:	Maxime Coquelin <mcoquelin.stm32@gmail.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+N:	stm32
+F:	drivers/clocksource/armv7m_systick.c
+
 ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
-- 
1.9.1

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 18:01 ` [PATCH v2 14/18] ARM: Add STM32 family machine Maxime Coquelin
@ 2015-02-20 18:33   ` Peter Meerwald
  2015-02-25 11:52     ` Maxime Coquelin
  2015-02-20 20:00   ` Uwe Kleine-König
  2015-03-10 15:10   ` Arnd Bergmann
  2 siblings, 1 reply; 65+ messages in thread
From: Peter Meerwald @ 2015-02-20 18:33 UTC (permalink / raw)
  To: linux-arm-kernel


> STMicrolectronics's STM32 series is a family of Cortex-M
> microcontrollers. It is used in various applications, and
> proposes a wide range of peripherals.

the text describing the STM32 could be a bit more specific :)
some more nitpicking below

> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> ---
>  Documentation/arm/stm32/overview.txt           | 32 ++++++++++++++++++++++++++
>  Documentation/arm/stm32/stm32f429-overview.txt | 22 ++++++++++++++++++
>  arch/arm/Kconfig                               | 22 ++++++++++++++++++
>  arch/arm/Makefile                              |  1 +
>  arch/arm/mach-stm32/Makefile                   |  1 +
>  arch/arm/mach-stm32/Makefile.boot              |  0
>  arch/arm/mach-stm32/board-dt.c                 | 31 +++++++++++++++++++++++++
>  7 files changed, 109 insertions(+)
>  create mode 100644 Documentation/arm/stm32/overview.txt
>  create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
>  create mode 100644 arch/arm/mach-stm32/Makefile
>  create mode 100644 arch/arm/mach-stm32/Makefile.boot
>  create mode 100644 arch/arm/mach-stm32/board-dt.c
> 
> diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
> new file mode 100644
> index 0000000..d8bf6bb
> --- /dev/null
> +++ b/Documentation/arm/stm32/overview.txt
> @@ -0,0 +1,32 @@
> +			STM32 ARM Linux Overview
> +			==========================

overlong ===

> +
> +Introduction
> +------------
> +
> +  The STMicroelectronics family of Cortex-M based MCUs are supported by the
> +  'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
> +
> +
> +Configuration
> +-------------
> +
> +  A generic configuration is provided for STM32 family, and can be used as the
> +  default by
> +	make stm32_defconfig
> +
> +Layout
> +------
> +
> +  All the files for multiple machine families are located in the platform code
> +  contained in arch/arm/mach-stm32
> +
> +  There is a generic board board-dt.c in the mach folder which support
> +  Flattened Device Tree, which means, It works with any compatible board with

it (lowercase)

> +  Device Trees.
> +
> +
> +Document Author
> +---------------
> +
> +  Maxime Coquelin <mcoquelin.stm32@gmail.com>
> diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt
> new file mode 100644
> index 0000000..5206822
> --- /dev/null
> +++ b/Documentation/arm/stm32/stm32f429-overview.txt
> @@ -0,0 +1,22 @@
> +			STM32F429 Overview
> +			==================
> +
> +  Introduction
> +  ------------
> +	The STM32F429 is a Cortex-M4 MCU aimed at various applications.
> +	It features:
> +	- ARM Cortex-M4 up to 180MHz with FPU
> +	- 2MB internal Flash Memory
> +	- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
> +	- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
> +	- LCD controller & Camera interface
> +	- Cryptographic processor
> +
> +  Resources
> +  ---------
> +	Datasheet and reference manual are publicly available on ST website:
> +	- http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
> +
> +  Document Author
> +  ---------------
> +	Maxime Coquelin <mcoquelin.stm32@gmail.com>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..cfd9532 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -774,6 +774,28 @@ config ARCH_OMAP1
>  	help
>  	  Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
>  
> +config ARCH_STM32
> +	bool "STMicrolectronics STM32"
> +	depends on !MMU
> +	select ARCH_REQUIRE_GPIOLIB
> +	select ARM_NVIC
> +	select AUTO_ZRELADDR
> +	select ARCH_HAS_RESET_CONTROLLER
> +	select RESET_CONTROLLER
> +	select PINCTRL
> +	select PINCTRL_STM32
> +	select CLKSRC_OF
> +	select ARMV7M_SYSTICK
> +	select COMMON_CLK
> +	select CPU_V7M
> +	select GENERIC_CLOCKEVENTS
> +	select NO_DMA
> +	select NO_IOPORT_MAP
> +	select SPARSE_IRQ
> +	select USE_OF
> +	help
> +	  Support for STMicorelectronics STM32 processors.

STMicroelectronics

> +
>  endchoice
>  
>  menu "Multiple platform selection"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index c1785ee..7d00659 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -196,6 +196,7 @@ machine-$(CONFIG_ARCH_SHMOBILE) 	+= shmobile
>  machine-$(CONFIG_ARCH_SIRF)		+= prima2
>  machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
>  machine-$(CONFIG_ARCH_STI)		+= sti
> +machine-$(CONFIG_ARCH_STM32)		+= stm32
>  machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
>  machine-$(CONFIG_ARCH_TEGRA)		+= tegra
>  machine-$(CONFIG_ARCH_U300)		+= u300
> diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
> new file mode 100644
> index 0000000..bd0b7b5
> --- /dev/null
> +++ b/arch/arm/mach-stm32/Makefile
> @@ -0,0 +1 @@
> +obj-y += board-dt.o
> diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot
> new file mode 100644
> index 0000000..e69de29
> diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
> new file mode 100644
> index 0000000..1d681b3
> --- /dev/null
> +++ b/arch/arm/mach-stm32/board-dt.c
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (C) Maxime Coquelin 2015
> + * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
> +#include <linux/reset-controller.h>
> +#include <asm/v7m.h>
> +#include <asm/mach/arch.h>
> +
> +static const char *const stm32_compat[] __initconst = {
> +	"st,stm32f429",
> +	NULL
> +};
> +
> +static void __init stm32_timer_init(void)
> +{
> +	of_clk_init(NULL);
> +	reset_controller_of_init();
> +	clocksource_of_init();
> +
> +}
> +
> +DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)")
> +	.init_time = stm32_timer_init,
> +	.dt_compat = stm32_compat,
> +	.restart = armv7m_restart,
> +MACHINE_END
> 

-- 

Peter Meerwald
+43-664-2444418 (mobile)

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-02-20 18:01 ` [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries Maxime Coquelin
@ 2015-02-20 19:47   ` Uwe Kleine-König
  2015-02-23 10:33     ` Maxime Coquelin
  2015-03-09  0:29   ` Stefan Agner
  1 sibling, 1 reply; 65+ messages in thread
From: Uwe Kleine-König @ 2015-02-20 19:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 20, 2015 at 07:01:01PM +0100, Maxime Coquelin wrote:
> From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
> So the number of entries in vectors table is up to 256.
> 
> This patch adds a new config flag to specify the number of external interrupts.
> Some ifdeferies are added in order to respect the natural alignment without
> wasting too much space on smaller systems.
> 
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> ---
>  arch/arm/kernel/entry-v7m.S | 13 +++++++++----
>  arch/arm/mm/Kconfig         | 15 +++++++++++++++
>  2 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
> index 8944f49..68cde36 100644
> --- a/arch/arm/kernel/entry-v7m.S
> +++ b/arch/arm/kernel/entry-v7m.S
> @@ -117,9 +117,14 @@ ENTRY(__switch_to)
>  ENDPROC(__switch_to)
>  
>  	.data
> -	.align	8
> +#if CONFIG_CPUV7M_NUM_IRQ <= 112
I would have called this CONFIG_CPU_V7M_NUM_IRQ to match the already
existing CPU_V7M symbol.

> +	.align	9
> +#else
> +	.align	10
> +#endif
> +

Other than that:
Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>

Who do you target to apply this series?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-02-20 18:01 ` [PATCH v2 04/18] clocksource: Add ARM System timer driver Maxime Coquelin
@ 2015-02-20 19:54   ` Uwe Kleine-König
  2015-02-20 21:48     ` Paul Bolle
  2015-03-09 15:50   ` Linus Walleij
  1 sibling, 1 reply; 65+ messages in thread
From: Uwe Kleine-König @ 2015-02-20 19:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Fri, Feb 20, 2015 at 07:01:03PM +0100, Maxime Coquelin wrote:
> This patch adds clocksource support for ARMv7-M's System timer,
> also known as SysTick.
> 
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> ---
>  drivers/clocksource/Kconfig          |  7 ++++
>  drivers/clocksource/Makefile         |  1 +
>  drivers/clocksource/armv7m_systick.c | 78 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 86 insertions(+)
>  create mode 100644 drivers/clocksource/armv7m_systick.c
> 
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index fc01ec2..fb6011e 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -124,6 +124,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
>  	help
>  	 Use ARM global timer clock source as sched_clock
>  
> +config ARMV7M_SYSTICK
> +	bool
I assume this symbol is enabled later in the series. Would it make sense
to allow enabing the symbol for compile test coverage?

> +	select CLKSRC_OF if OF
What happens if ARMV7M_SYSTICK=y but OF=n? Doesn't the driver fail to
compile?

> +	select CLKSRC_MMIO
> +	help
> +	  This options enables support for the ARMv7M system timer unit
the right spelling is ARMv7-M.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 18:01 ` [PATCH v2 14/18] ARM: Add STM32 family machine Maxime Coquelin
  2015-02-20 18:33   ` Peter Meerwald
@ 2015-02-20 20:00   ` Uwe Kleine-König
  2015-02-20 21:37     ` Paul Bolle
  2015-02-25 12:03     ` Maxime Coquelin
  2015-03-10 15:10   ` Arnd Bergmann
  2 siblings, 2 replies; 65+ messages in thread
From: Uwe Kleine-König @ 2015-02-20 20:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Fri, Feb 20, 2015 at 07:01:13PM +0100, Maxime Coquelin wrote:
> STMicrolectronics's STM32 series is a family of Cortex-M
> microcontrollers. It is used in various applications, and
> proposes a wide range of peripherals.
> 
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> ---
>  Documentation/arm/stm32/overview.txt           | 32 ++++++++++++++++++++++++++
>  Documentation/arm/stm32/stm32f429-overview.txt | 22 ++++++++++++++++++
>  arch/arm/Kconfig                               | 22 ++++++++++++++++++
>  arch/arm/Makefile                              |  1 +
>  arch/arm/mach-stm32/Makefile                   |  1 +
>  arch/arm/mach-stm32/Makefile.boot              |  0
>  arch/arm/mach-stm32/board-dt.c                 | 31 +++++++++++++++++++++++++
>  7 files changed, 109 insertions(+)
>  create mode 100644 Documentation/arm/stm32/overview.txt
>  create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
>  create mode 100644 arch/arm/mach-stm32/Makefile
>  create mode 100644 arch/arm/mach-stm32/Makefile.boot
>  create mode 100644 arch/arm/mach-stm32/board-dt.c
> 
> diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
> new file mode 100644
> index 0000000..d8bf6bb
> --- /dev/null
> +++ b/Documentation/arm/stm32/overview.txt
> @@ -0,0 +1,32 @@
> +			STM32 ARM Linux Overview
> +			==========================
> +
> +Introduction
> +------------
> +
> +  The STMicroelectronics family of Cortex-M based MCUs are supported by the
> +  'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
> +
> +
> +Configuration
> +-------------
> +
> +  A generic configuration is provided for STM32 family, and can be used as the
> +  default by
> +	make stm32_defconfig
> +
> +Layout
> +------
> +
> +  All the files for multiple machine families are located in the platform code
> +  contained in arch/arm/mach-stm32
> +
> +  There is a generic board board-dt.c in the mach folder which support
> +  Flattened Device Tree, which means, It works with any compatible board with
> +  Device Trees.
> +
> +
> +Document Author
> +---------------
> +
> +  Maxime Coquelin <mcoquelin.stm32@gmail.com>
> diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt
> new file mode 100644
> index 0000000..5206822
> --- /dev/null
> +++ b/Documentation/arm/stm32/stm32f429-overview.txt
> @@ -0,0 +1,22 @@
> +			STM32F429 Overview
> +			==================
> +
> +  Introduction
> +  ------------
> +	The STM32F429 is a Cortex-M4 MCU aimed at various applications.
> +	It features:
> +	- ARM Cortex-M4 up to 180MHz with FPU
> +	- 2MB internal Flash Memory
> +	- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
> +	- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
> +	- LCD controller & Camera interface
> +	- Cryptographic processor
> +
> +  Resources
> +  ---------
> +	Datasheet and reference manual are publicly available on ST website:
> +	- http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
> +
> +  Document Author
> +  ---------------
> +	Maxime Coquelin <mcoquelin.stm32@gmail.com>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 97d07ed..cfd9532 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -774,6 +774,28 @@ config ARCH_OMAP1
>  	help
>  	  Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
>  
> +config ARCH_STM32
> +	bool "STMicrolectronics STM32"
> +	depends on !MMU
> +	select ARCH_REQUIRE_GPIOLIB
> +	select ARM_NVIC
> +	select AUTO_ZRELADDR
> +	select ARCH_HAS_RESET_CONTROLLER
> +	select RESET_CONTROLLER
> +	select PINCTRL
> +	select PINCTRL_STM32
> +	select CLKSRC_OF
> +	select ARMV7M_SYSTICK
> +	select COMMON_CLK
> +	select CPU_V7M
> +	select GENERIC_CLOCKEVENTS
> +	select NO_DMA
> +	select NO_IOPORT_MAP
> +	select SPARSE_IRQ
> +	select USE_OF
Please sort this list alphabetically.

> +	help
> +	  Support for STMicorelectronics STM32 processors.
> +
>  endchoice
>  
>  menu "Multiple platform selection"
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index c1785ee..7d00659 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -196,6 +196,7 @@ machine-$(CONFIG_ARCH_SHMOBILE) 	+= shmobile
>  machine-$(CONFIG_ARCH_SIRF)		+= prima2
>  machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
>  machine-$(CONFIG_ARCH_STI)		+= sti
> +machine-$(CONFIG_ARCH_STM32)		+= stm32
>  machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
>  machine-$(CONFIG_ARCH_TEGRA)		+= tegra
>  machine-$(CONFIG_ARCH_U300)		+= u300
> diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
> new file mode 100644
> index 0000000..bd0b7b5
> --- /dev/null
> +++ b/arch/arm/mach-stm32/Makefile
> @@ -0,0 +1 @@
> +obj-y += board-dt.o
> diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot
> new file mode 100644
> index 0000000..e69de29
Maybe note there why this file exists and can be empty. Feel free to
copy the content of efm32's Makefile.boot.

> diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
> new file mode 100644
> index 0000000..1d681b3
> --- /dev/null
> +++ b/arch/arm/mach-stm32/board-dt.c
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (C) Maxime Coquelin 2015
> + * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
> +#include <linux/reset-controller.h>
> +#include <asm/v7m.h>
> +#include <asm/mach/arch.h>
> +
> +static const char *const stm32_compat[] __initconst = {
> +	"st,stm32f429",
> +	NULL
> +};
> +
> +static void __init stm32_timer_init(void)
> +{
> +	of_clk_init(NULL);
> +	reset_controller_of_init();
> +	clocksource_of_init();
Hmm, if reset_controller_of_init was called automatically you wouldn't
need that, right? Maybe arange for that instead?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 20:00   ` Uwe Kleine-König
@ 2015-02-20 21:37     ` Paul Bolle
  2015-02-25 12:04       ` Maxime Coquelin
  2015-02-25 12:03     ` Maxime Coquelin
  1 sibling, 1 reply; 65+ messages in thread
From: Paul Bolle @ 2015-02-20 21:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2015-02-20 at 21:00 +0100, Uwe Kleine-K?nig wrote:
> On Fri, Feb 20, 2015 at 07:01:13PM +0100, Maxime Coquelin wrote:
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 97d07ed..cfd9532 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -774,6 +774,28 @@ config ARCH_OMAP1
> >  	help
> >  	  Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
> >  
> > +config ARCH_STM32
> > +	bool "STMicrolectronics STM32"
> > +	depends on !MMU
> > +	select ARCH_REQUIRE_GPIOLIB
> > +	select ARM_NVIC
> > +	select AUTO_ZRELADDR
> > +	select ARCH_HAS_RESET_CONTROLLER
> > +	select RESET_CONTROLLER
> > +	select PINCTRL
> > +	select PINCTRL_STM32
> > +	select CLKSRC_OF
> > +	select ARMV7M_SYSTICK
> > +	select COMMON_CLK
> > +	select CPU_V7M
> > +	select GENERIC_CLOCKEVENTS
> > +	select NO_DMA
> > +	select NO_IOPORT_MAP
> > +	select SPARSE_IRQ
> > +	select USE_OF
> Please sort this list alphabetically.

And drop
    select NO_DMA

You copied that from ARCH_EFM32, but it's pointless on arm (as arch/arm/
doesn't provide a NO_DMA Kconfig symbol).

I submitted a patch last year to drop it from ARCH_EFM32, which Uwe
Acked, but then nothing happened. I'm to blame, as I should have sent a
reminder.

> > +	help
> > +	  Support for STMicorelectronics STM32 processors.
> > +
> >  endchoice
> >  
> >  menu "Multiple platform selection"


Paul Bolle

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-02-20 19:54   ` Uwe Kleine-König
@ 2015-02-20 21:48     ` Paul Bolle
  2015-03-02 16:53       ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Paul Bolle @ 2015-02-20 21:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 2015-02-20 at 20:54 +0100, Uwe Kleine-K?nig wrote:
> On Fri, Feb 20, 2015 at 07:01:03PM +0100, Maxime Coquelin wrote:
> > This patch adds clocksource support for ARMv7-M's System timer,
> > also known as SysTick.
> > 
> > Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> > ---
> >  drivers/clocksource/Kconfig          |  7 ++++
> >  drivers/clocksource/Makefile         |  1 +
> >  drivers/clocksource/armv7m_systick.c | 78 ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 86 insertions(+)
> >  create mode 100644 drivers/clocksource/armv7m_systick.c
> > 
> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> > index fc01ec2..fb6011e 100644
> > --- a/drivers/clocksource/Kconfig
> > +++ b/drivers/clocksource/Kconfig
> > @@ -124,6 +124,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
> >  	help
> >  	 Use ARM global timer clock source as sched_clock
> >  
> > +config ARMV7M_SYSTICK
> > +	bool
> I assume this symbol is enabled later in the series.

Yes, I noticed it was selected in 14/18 ("ARM: Add STM32 family
machine").

> Would it make sense
> to allow enabing the symbol for compile test coverage?
> 
> > +	select CLKSRC_OF if OF
> What happens if ARMV7M_SYSTICK=y but OF=n? Doesn't the driver fail to
> compile?
> 
> > +	select CLKSRC_MMIO
> > +	help
> > +	  This options enables support for the ARMv7M system timer unit
> the right spelling is ARMv7-M.

This Kconfig entry has no prompt, so no one is going to see this text
during make *config. Perhaps this should be made a comment. In that case
the right spelling should still be used.

Thanks,


Paul Bolle

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-02-20 19:47   ` Uwe Kleine-König
@ 2015-02-23 10:33     ` Maxime Coquelin
  2015-02-26 10:29       ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-23 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

2015-02-20 20:47 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Fri, Feb 20, 2015 at 07:01:01PM +0100, Maxime Coquelin wrote:
>> From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
>> So the number of entries in vectors table is up to 256.
>>
>> This patch adds a new config flag to specify the number of external interrupts.
>> Some ifdeferies are added in order to respect the natural alignment without
>> wasting too much space on smaller systems.
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> ---
>>  arch/arm/kernel/entry-v7m.S | 13 +++++++++----
>>  arch/arm/mm/Kconfig         | 15 +++++++++++++++
>>  2 files changed, 24 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
>> index 8944f49..68cde36 100644
>> --- a/arch/arm/kernel/entry-v7m.S
>> +++ b/arch/arm/kernel/entry-v7m.S
>> @@ -117,9 +117,14 @@ ENTRY(__switch_to)
>>  ENDPROC(__switch_to)
>>
>>       .data
>> -     .align  8
>> +#if CONFIG_CPUV7M_NUM_IRQ <= 112
> I would have called this CONFIG_CPU_V7M_NUM_IRQ to match the already
> existing CPU_V7M symbol.

That's better indeed.
It will be changed in v3.

>
>> +     .align  9
>> +#else
>> +     .align  10
>> +#endif
>> +
>
> Other than that:
> Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>
> Who do you target to apply this series?

I guess it should go through Russell's Patch Tracking System?

Thanks,
Maxime
>
> Best regards
> Uwe
>
> --
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 18:33   ` Peter Meerwald
@ 2015-02-25 11:52     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-25 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

2015-02-20 19:33 GMT+01:00 Peter Meerwald <pmeerw@pmeerw.net>:
>
>> STMicrolectronics's STM32 series is a family of Cortex-M
>> microcontrollers. It is used in various applications, and
>> proposes a wide range of peripherals.
>
> the text describing the STM32 could be a bit more specific :)
> some more nitpicking below
>

Thanks Peter,

I will reword the commit message to add more information, and also fix
the typos you have pointed out.

Best regards,
Maxime

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 20:00   ` Uwe Kleine-König
  2015-02-20 21:37     ` Paul Bolle
@ 2015-02-25 12:03     ` Maxime Coquelin
  1 sibling, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-25 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

2015-02-20 21:00 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
> On Fri, Feb 20, 2015 at 07:01:13PM +0100, Maxime Coquelin wrote:
>> STMicrolectronics's STM32 series is a family of Cortex-M
>> microcontrollers. It is used in various applications, and
>> proposes a wide range of peripherals.
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> ---
>>  Documentation/arm/stm32/overview.txt           | 32 ++++++++++++++++++++++++++
>>  Documentation/arm/stm32/stm32f429-overview.txt | 22 ++++++++++++++++++
>>  arch/arm/Kconfig                               | 22 ++++++++++++++++++
>>  arch/arm/Makefile                              |  1 +
>>  arch/arm/mach-stm32/Makefile                   |  1 +
>>  arch/arm/mach-stm32/Makefile.boot              |  0
>>  arch/arm/mach-stm32/board-dt.c                 | 31 +++++++++++++++++++++++++
>>  7 files changed, 109 insertions(+)
>>  create mode 100644 Documentation/arm/stm32/overview.txt
>>  create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
>>  create mode 100644 arch/arm/mach-stm32/Makefile
>>  create mode 100644 arch/arm/mach-stm32/Makefile.boot
>>  create mode 100644 arch/arm/mach-stm32/board-dt.c
>>

<snip>

>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 97d07ed..cfd9532 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -774,6 +774,28 @@ config ARCH_OMAP1
>>       help
>>         Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
>>
>> +config ARCH_STM32
>> +     bool "STMicrolectronics STM32"
>> +     depends on !MMU
>> +     select ARCH_REQUIRE_GPIOLIB
>> +     select ARM_NVIC
>> +     select AUTO_ZRELADDR
>> +     select ARCH_HAS_RESET_CONTROLLER
>> +     select RESET_CONTROLLER
>> +     select PINCTRL
>> +     select PINCTRL_STM32
>> +     select CLKSRC_OF
>> +     select ARMV7M_SYSTICK
>> +     select COMMON_CLK
>> +     select CPU_V7M
>> +     select GENERIC_CLOCKEVENTS
>> +     select NO_DMA
>> +     select NO_IOPORT_MAP
>> +     select SPARSE_IRQ
>> +     select USE_OF
> Please sort this list alphabetically.

Ok, I will do for v3.

>
>> +     help
>> +       Support for STMicorelectronics STM32 processors.
>> +
>>  endchoice
>>
>>  menu "Multiple platform selection"
>> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
>> index c1785ee..7d00659 100644
>> --- a/arch/arm/Makefile
>> +++ b/arch/arm/Makefile
>> @@ -196,6 +196,7 @@ machine-$(CONFIG_ARCH_SHMOBILE)   += shmobile
>>  machine-$(CONFIG_ARCH_SIRF)          += prima2
>>  machine-$(CONFIG_ARCH_SOCFPGA)               += socfpga
>>  machine-$(CONFIG_ARCH_STI)           += sti
>> +machine-$(CONFIG_ARCH_STM32)         += stm32
>>  machine-$(CONFIG_ARCH_SUNXI)         += sunxi
>>  machine-$(CONFIG_ARCH_TEGRA)         += tegra
>>  machine-$(CONFIG_ARCH_U300)          += u300
>> diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
>> new file mode 100644
>> index 0000000..bd0b7b5
>> --- /dev/null
>> +++ b/arch/arm/mach-stm32/Makefile
>> @@ -0,0 +1 @@
>> +obj-y += board-dt.o
>> diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot
>> new file mode 100644
>> index 0000000..e69de29
> Maybe note there why this file exists and can be empty. Feel free to
> copy the content of efm32's Makefile.boot.

Ok, I will copy efm32's Makefile.boot content.
Do you know why your patch has not been applied yet?

>
>> diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
>> new file mode 100644
>> index 0000000..1d681b3
>> --- /dev/null
>> +++ b/arch/arm/mach-stm32/board-dt.c
>> @@ -0,0 +1,31 @@
>> +/*
>> + * Copyright (C) Maxime Coquelin 2015
>> + * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> + * License terms:  GNU General Public License (GPL), version 2
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/clocksource.h>
>> +#include <linux/reset-controller.h>
>> +#include <asm/v7m.h>
>> +#include <asm/mach/arch.h>
>> +
>> +static const char *const stm32_compat[] __initconst = {
>> +     "st,stm32f429",
>> +     NULL
>> +};
>> +
>> +static void __init stm32_timer_init(void)
>> +{
>> +     of_clk_init(NULL);
>> +     reset_controller_of_init();
>> +     clocksource_of_init();
> Hmm, if reset_controller_of_init was called automatically you wouldn't
> need that, right? Maybe arange for that instead?

This is what I did in the v1:
http://marc.info/?l=linux-arm-kernel&m=142376341008550&w=2

But Rob advised to put it elsewhere.

Thanks,
Maxime

>
> Best regards
> Uwe
>
> --
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 21:37     ` Paul Bolle
@ 2015-02-25 12:04       ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-25 12:04 UTC (permalink / raw)
  To: linux-arm-kernel

2015-02-20 22:37 GMT+01:00 Paul Bolle <pebolle@tiscali.nl>:
> On Fri, 2015-02-20 at 21:00 +0100, Uwe Kleine-K?nig wrote:
>> On Fri, Feb 20, 2015 at 07:01:13PM +0100, Maxime Coquelin wrote:
>> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> > index 97d07ed..cfd9532 100644
>> > --- a/arch/arm/Kconfig
>> > +++ b/arch/arm/Kconfig
>> > @@ -774,6 +774,28 @@ config ARCH_OMAP1
>> >     help
>> >       Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
>> >
>> > +config ARCH_STM32
>> > +   bool "STMicrolectronics STM32"
>> > +   depends on !MMU
>> > +   select ARCH_REQUIRE_GPIOLIB
>> > +   select ARM_NVIC
>> > +   select AUTO_ZRELADDR
>> > +   select ARCH_HAS_RESET_CONTROLLER
>> > +   select RESET_CONTROLLER
>> > +   select PINCTRL
>> > +   select PINCTRL_STM32
>> > +   select CLKSRC_OF
>> > +   select ARMV7M_SYSTICK
>> > +   select COMMON_CLK
>> > +   select CPU_V7M
>> > +   select GENERIC_CLOCKEVENTS
>> > +   select NO_DMA
>> > +   select NO_IOPORT_MAP
>> > +   select SPARSE_IRQ
>> > +   select USE_OF
>> Please sort this list alphabetically.
>
> And drop
>     select NO_DMA
>
> You copied that from ARCH_EFM32, but it's pointless on arm (as arch/arm/
> doesn't provide a NO_DMA Kconfig symbol).

You are right, I will drop NO_DMA in v3.

Thanks,
Maxime

>
> I submitted a patch last year to drop it from ARCH_EFM32, which Uwe
> Acked, but then nothing happened. I'm to blame, as I should have sent a
> reminder.
>
>> > +   help
>> > +     Support for STMicorelectronics STM32 processors.
>> > +
>> >  endchoice
>> >
>> >  menu "Multiple platform selection"
>
>
> Paul Bolle
>

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-02-23 10:33     ` Maxime Coquelin
@ 2015-02-26 10:29       ` Maxime Coquelin
  2015-02-26 10:43         ` Uwe Kleine-König
  0 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-02-26 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

2015-02-23 11:33 GMT+01:00 Maxime Coquelin <mcoquelin.stm32@gmail.com>:
> 2015-02-20 20:47 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> On Fri, Feb 20, 2015 at 07:01:01PM +0100, Maxime Coquelin wrote:
>>> From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
>>> So the number of entries in vectors table is up to 256.
>>>
>>> This patch adds a new config flag to specify the number of external interrupts.
>>> Some ifdeferies are added in order to respect the natural alignment without
>>> wasting too much space on smaller systems.
>>>
>>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>>> ---
>>>  arch/arm/kernel/entry-v7m.S | 13 +++++++++----
>>>  arch/arm/mm/Kconfig         | 15 +++++++++++++++
>>>  2 files changed, 24 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
>>> index 8944f49..68cde36 100644
>>> --- a/arch/arm/kernel/entry-v7m.S
>>> +++ b/arch/arm/kernel/entry-v7m.S
>>> @@ -117,9 +117,14 @@ ENTRY(__switch_to)
>>>  ENDPROC(__switch_to)
>>>
>>>       .data
>>> -     .align  8
>>> +#if CONFIG_CPUV7M_NUM_IRQ <= 112
>> I would have called this CONFIG_CPU_V7M_NUM_IRQ to match the already
>> existing CPU_V7M symbol.
>
> That's better indeed.
> It will be changed in v3.
>
>>
>>> +     .align  9
>>> +#else
>>> +     .align  10
>>> +#endif
>>> +
>>
>> Other than that:
>> Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>>
>> Who do you target to apply this series?
>
> I guess it should go through Russell's Patch Tracking System?

Sorry, I answered your question too quickly.
I meant this patch should go through Russell's Patch Tracking System.

For the other patches, I think it should be picked by their respective
maintainers.
Or I can create an immutable tag (on github or kernel.org?) that will
be merged by the different sub-systems?
What would you advise?

Thanks,
Maxime

>
> Thanks,
> Maxime
>>
>> Best regards
>> Uwe
>>
>> --
>> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
>> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-02-26 10:29       ` Maxime Coquelin
@ 2015-02-26 10:43         ` Uwe Kleine-König
  0 siblings, 0 replies; 65+ messages in thread
From: Uwe Kleine-König @ 2015-02-26 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 26, 2015 at 11:29:52AM +0100, Maxime Coquelin wrote:
> 2015-02-23 11:33 GMT+01:00 Maxime Coquelin <mcoquelin.stm32@gmail.com>:
> > 2015-02-20 20:47 GMT+01:00 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> Who do you target to apply this series?
> >
> > I guess it should go through Russell's Patch Tracking System?
> 
> Sorry, I answered your question too quickly.
> I meant this patch should go through Russell's Patch Tracking System.
> 
> For the other patches, I think it should be picked by their respective
> maintainers.
> Or I can create an immutable tag (on github or kernel.org?) that will
> be merged by the different sub-systems?
> What would you advise?
Depends on the interdependencies of your patches. If each maintainer can
just pick up the patches affecting his area on top of (say) 4.0-rc1 that
would be good.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-02-20 21:48     ` Paul Bolle
@ 2015-03-02 16:53       ` Maxime Coquelin
  2015-03-03 19:43         ` Paul Bolle
  0 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-02 16:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Paul, Uwe,

2015-02-20 22:48 GMT+01:00 Paul Bolle <pebolle@tiscali.nl>:
> On Fri, 2015-02-20 at 20:54 +0100, Uwe Kleine-K?nig wrote:
>> On Fri, Feb 20, 2015 at 07:01:03PM +0100, Maxime Coquelin wrote:
>> > This patch adds clocksource support for ARMv7-M's System timer,
>> > also known as SysTick.
>> >
>> > Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> > ---
>> >  drivers/clocksource/Kconfig          |  7 ++++
>> >  drivers/clocksource/Makefile         |  1 +
>> >  drivers/clocksource/armv7m_systick.c | 78 ++++++++++++++++++++++++++++++++++++
>> >  3 files changed, 86 insertions(+)
>> >  create mode 100644 drivers/clocksource/armv7m_systick.c
>> >
>> > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>> > index fc01ec2..fb6011e 100644
>> > --- a/drivers/clocksource/Kconfig
>> > +++ b/drivers/clocksource/Kconfig
>> > @@ -124,6 +124,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
>> >     help
>> >      Use ARM global timer clock source as sched_clock
>> >
>> > +config ARMV7M_SYSTICK
>> > +   bool
>> I assume this symbol is enabled later in the series.
>
> Yes, I noticed it was selected in 14/18 ("ARM: Add STM32 family
> machine").
>
>> Would it make sense
>> to allow enabing the symbol for compile test coverage?
>>
>> > +   select CLKSRC_OF if OF
>> What happens if ARMV7M_SYSTICK=y but OF=n? Doesn't the driver fail to
>> compile?
>>
>> > +   select CLKSRC_MMIO
>> > +   help
>> > +     This options enables support for the ARMv7M system timer unit
>> the right spelling is ARMv7-M.
>
> This Kconfig entry has no prompt, so no one is going to see this text
> during make *config. Perhaps this should be made a comment. In that case
> the right spelling should still be used.

Yes, you are right.
Do you agree if I define it like this:

config ARMV7M_SYSTICK
    bool "Clocksource driver for ARMv7-M System timer"
    depends on OF && (CPU_V7M || COMPILE_TEST)
    select CLKSRC_OF
    select CLKSRC_MMIO
    help
      This options enables clocksource support for the ARMv7-M system
      timer unit.

Thanks,
Maxime
>
> Thanks,
>
>
> Paul Bolle
>

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

* [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU
  2015-02-20 18:01 ` [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU Maxime Coquelin
@ 2015-03-02 17:42   ` Andreas Färber
  2015-03-03 17:59     ` Maxime Coquelin
  2015-03-09 14:39   ` Linus Walleij
  1 sibling, 1 reply; 65+ messages in thread
From: Andreas Färber @ 2015-03-02 17:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Maxime,

Please don't put the whole world in To, that makes replying to you much
harder. You can put maintainers in CC instead.

Am 20.02.2015 um 19:01 schrieb Maxime Coquelin:
> The STMicrolectornics's STM32F419 MCU has the following main features:
>  - Cortex-M4 core running up to @180MHz
>  - 2MB internal flash, 256KBytes internal RAM
>  - FMC controller to connect SDRAM, NOR and NAND memories
>  - SD/MMC/SDIO support
>  - Ethernet controller
>  - USB OTFG FS & HS controllers
>  - I2C, SPI, CAN busses support
>  - Several 16 & 32 bits general purpose timers
>  - Serial Audio interface
>  - LCD controller
> 
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> ---
>  arch/arm/boot/dts/Makefile            |   1 +
>  arch/arm/boot/dts/stm32f429-disco.dts |  41 ++++
>  arch/arm/boot/dts/stm32f429.dtsi      | 396 ++++++++++++++++++++++++++++++++++
>  3 files changed, 438 insertions(+)
>  create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
>  create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 91bd5bd..d7da0ef 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -442,6 +442,7 @@ dtb-$(CONFIG_ARCH_STI)+= stih407-b2120.dtb \
>  	stih416-b2000.dtb \
>  	stih416-b2020.dtb \
>  	stih416-b2020e.dtb
> +dtb-$(CONFIG_ARCH_STM32)+= stm32f429-disco.dtb
>  dtb-$(CONFIG_MACH_SUN4I) += \
>  	sun4i-a10-a1000.dtb \
>  	sun4i-a10-ba10-tvbox.dtb \
> diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
> new file mode 100644
> index 0000000..0e79cc1
> --- /dev/null
> +++ b/arch/arm/boot/dts/stm32f429-disco.dts
> @@ -0,0 +1,41 @@

Add a suitable license header here? There had been attempts to
dual-license as GPL and MIT/X11.

> +/dts-v1/;
> +#include "stm32f429.dtsi"
> +
> +/ {
> +	model = "STMicroelectronics's STM32F429i-DISCO board";

"'s" seems uncommon here and "s's" looks wrong. Just use
"STMicroelectronics STM32F429I-DISCO board"?

> +	compatible = "st,stm32f429i-disco", "st,stm32f429";
> +
> +	chosen {
> +		bootargs = "console=ttyS0,115200 root=/dev/ram rdinit=/linuxrc";
> +		linux,stdout-path = &usart1;

I have actually been using USART3, following a guide I found on GitHub.
Which pins do you use for USART1, and is one better than the other?

> +	};
> +
> +	memory {
> +		reg = <0xd0000000 0x800000>;

I have it at 0x90000000!

> +	};
> +
> +	aliases {
> +		ttyS0 = &usart1;

Why ttyS0 here? Shouldn't that be serial0 by convention?

> +	};
> +
> +	soc {
> +		usart1: usart at 40011000 {
> +			status = "okay";
> +		};

This is a new target, so please use the new-style &usart1 {...};
reference rather than replicating the hierarchy.

> +
> +		leds {

These LEDs are definitely not on the SoC, they're on the board. Please
move one level up.

> +			compatible = "gpio-leds";

In this file you're being parsimonious with newline, yet in the .dtsi
you unnecessarily add newlines before the trailing status property.

> +			red {
> +				#gpio-cells = <2>;

This looks weird. Drop it?

> +				label = "Front Panel LED";

"Front Panel"? Both LEDs are on the front, and several other
architectures avoid spaces in the label for accessing it from /sys.

> +				gpios = <&gpiog 14 0>;

GPIO_ACTIVE_HIGH

> +				linux,default-trigger = "heartbeat";

Suggest to leave both off by default.

> +			};
> +			green {
> +				#gpio-cells = <2>;

Ditto.

> +				gpios = <&gpiog 13 0>;

Ditto.

> +				default-state = "off";
> +			};
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
> new file mode 100644
> index 0000000..5b3442a
> --- /dev/null
> +++ b/arch/arm/boot/dts/stm32f429.dtsi
> @@ -0,0 +1,396 @@
> +/*
> + * Device tree for STM32F429

License?

> + */
> +#include "armv7-m.dtsi"
> +#include <dt-bindings/pinctrl/pinctrl-stm32.h>
> +#include <dt-bindings/reset/st,stm32f429.h>
> +
> +/ {
> +
> +	aliases {
> +		gpio0 = &gpioa;
> +		gpio1 = &gpiob;
> +		gpio2 = &gpioc;
> +		gpio3 = &gpiod;
> +		gpio4 = &gpioe;
> +		gpio5 = &gpiof;
> +		gpio6 = &gpiog;
> +		gpio7 = &gpioh;
> +		gpio8 = &gpioi;
> +		gpio9 = &gpioj;
> +		gpio10 = &gpiok;
> +	};
> +
> +	clocks {
> +		clk_sysclk: clk-sysclk {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <180000000>;
> +		};
> +
> +		clk_hclk: clk-hclk {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <180000000>;
> +		};
> +
> +		clk_pclk1: clk-pclk1 {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <45000000>;
> +		};
> +
> +		clk_pclk2: clk-pclk2 {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <90000000>;
> +		};
> +
> +		clk_pmtr1: clk-pmtr1 {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <90000000>;
> +		};
> +
> +		clk_pmtr2: clk-pmtr2 {
> +			#clock-cells = <0>;
> +			compatible = "fixed-clock";
> +			clock-frequency = <180000000>;
> +		};
> +
> +		clk_systick: clk-systick {
> +			compatible = "fixed-factor-clock";
> +			clocks = <&clk_hclk>;
> +			#clock-cells = <0>;
> +			clock-div = <8>;
> +			clock-mult = <1>;
> +		};

Most of these should be replaceable with my clk driver.

> +	};
> +
> +	systick: timer at e000e010 {
> +		clocks = <&clk_systick>;
> +
> +		status = "okay";
> +	};

&systick {...};

> +
> +	soc {
> +		reset: reset at 40023810 {
> +			#reset-cells = <1>;
> +			compatible = "st,stm32-reset";
> +			reg = <0x40023810 0x18>;
> +		};

Still, this feels wrong, given that it's an RCC IP block...

> +
> +		pin-controller {
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			compatible = "st,stm32-pinctrl";
> +			ranges = <0 0x40020000 0x3000>;
> +
> +			gpioa: gpio at 40020000 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x0 0x400>;
> +				resets = <&reset GPIOA_RESET>;
> +				st,bank-name = "GPIOA";
> +			};
> +
> +			gpiob: gpio at 40020400 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x400 0x400>;
> +				resets = <&reset GPIOB_RESET>;
> +				st,bank-name = "GPIOB";
> +			};
> +
> +			gpioc: gpio at 40020800 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x800 0x400>;
> +				resets = <&reset GPIOC_RESET>;
> +				st,bank-name = "GPIOC";
> +			};
> +
> +			gpiod: gpio at 40020c00 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0xc00 0x400>;
> +				resets = <&reset GPIOD_RESET>;
> +				st,bank-name = "GPIOD";
> +			};
> +
> +			gpioe: gpio at 40021000 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x1000 0x400>;
> +				resets = <&reset GPIOE_RESET>;
> +				st,bank-name = "GPIOE";
> +			};
> +
> +			gpiof: gpio at 40021400 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x1400 0x400>;
> +				resets = <&reset GPIOF_RESET>;
> +				st,bank-name = "GPIOF";
> +			};
> +
> +			gpiog: gpio at 40021800 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x1800 0x400>;
> +				resets = <&reset GPIOG_RESET>;
> +				st,bank-name = "GPIOG";
> +			};
> +
> +			gpioh: gpio at 40021c00 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x1c00 0x400>;
> +				resets = <&reset GPIOH_RESET>;
> +				st,bank-name = "GPIOH";
> +			};
> +
> +			gpioi: gpio at 40022000 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x2000 0x400>;
> +				resets = <&reset GPIOI_RESET>;
> +				st,bank-name = "GPIOI";
> +			};
> +
> +			gpioj: gpio at 40022400 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x2400 0x400>;
> +				resets = <&reset GPIOJ_RESET>;
> +				st,bank-name = "GPIOJ";
> +			};
> +
> +			gpiok: gpio at 40022800 {
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				reg = <0x2800 0x400>;
> +				resets = <&reset GPIOK_RESET>;
> +				st,bank-name = "GPIOK";
> +			};
> +
> +			usart1 {
> +				pinctrl_usart1: usart1-0 {
> +					st,pins {
> +						tx = <&gpioa 9 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpioa 10 ALT7 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart2 {
> +				pinctrl_usart2: usart2-0 {
> +					st,pins {
> +						tx = <&gpioa 2 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpioa 3 ALT7 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart3 {
> +				pinctrl_usart3: usart3-0 {
> +					st,pins {
> +						tx = <&gpiob 10 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpiob 11 ALT7 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart4 {
> +				pinctrl_usart4: usart4-0 {
> +					st,pins {
> +						tx = <&gpioa 0 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpioa 1 ALT8 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart5 {
> +				pinctrl_usart5: usart5-0 {
> +					st,pins {
> +						tx = <&gpioc 12 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpiod 2 ALT8 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart6 {
> +				pinctrl_usart6: usart6-0 {
> +					st,pins {
> +						tx = <&gpioc 6 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpioc 7 ALT8 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart7 {
> +				pinctrl_usart7: usart7-0 {
> +					st,pins {
> +						tx = <&gpioe 8 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpioe 7 ALT8 NO_PULL>;
> +					};
> +				};
> +			};
> +
> +			usart8 {
> +				pinctrl_usart8: usart8-0 {
> +					st,pins {
> +						tx = <&gpioe 1 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
> +						rx = <&gpioe 0 ALT8 NO_PULL>;
> +					};
> +				};
> +			};

Can't the outer level be avoided here to save space and indentation?

> +		};
> +
> +		timer2: timer at 40000000 {
> +			compatible = "st,stm32-timer";
> +			reg = <0x40000000 0x400>;
> +			interrupts = <28>;
> +			resets = <&reset TIM2_RESET>;
> +			clocks = <&clk_pmtr1>;
> +
> +			status = "disabled";
> +		};
> +
> +		timer3: timer at 40000400 {
> +			compatible = "st,stm32-timer";
> +			reg = <0x40000400 0x400>;
> +			interrupts = <29>;
> +			resets = <&reset TIM3_RESET>;
> +			clocks = <&clk_pmtr1>;
> +
> +			status = "disabled";
> +		};
> +
> +		timer4: timer at 40000800 {
> +			compatible = "st,stm32-timer";
> +			reg = <0x40000800 0x400>;
> +			interrupts = <30>;
> +			resets = <&reset TIM4_RESET>;
> +			clocks = <&clk_pmtr1>;
> +
> +			status = "disabled";
> +		};
> +
> +		timer5: timer at 40000c00 {
> +			compatible = "st,stm32-timer";
> +			reg = <0x40000c00 0x400>;
> +			interrupts = <50>;
> +			resets = <&reset TIM5_RESET>;
> +			clocks = <&clk_pmtr1>;
> +		};
> +
> +		timer6: timer at 40001000 {
> +			compatible = "st,stm32-timer";
> +			reg = <0x40001000 0x400>;
> +			interrupts = <54>;
> +			resets = <&reset TIM6_RESET>;
> +			clocks = <&clk_pmtr1>;
> +
> +			status = "disabled";
> +		};
> +
> +		timer7: timer at 40001400 {
> +			compatible = "st,stm32-timer";
> +			reg = <0x40001400 0x400>;
> +			interrupts = <55>;
> +			resets = <&reset TIM7_RESET>;
> +			clocks = <&clk_pmtr1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart1: usart at 40011000 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40011000 0x400>;
> +			interrupts = <37>;
> +			clocks = <&clk_pclk2>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart2: usart at 40004400 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40004400 0x400>;
> +			interrupts = <38>;
> +			clocks = <&clk_pclk1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;

Copy&paste, also below. Is this really .dtsi material?

> +
> +			status = "disabled";
> +		};
> +
> +		usart3: usart at 40004800 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40004800 0x400>;
> +			interrupts = <39>;
> +			clocks = <&clk_pclk1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart4: usart at 40004c00 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40004c00 0x400>;
> +			interrupts = <52>;
> +			clocks = <&clk_pclk1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart5: usart at 40005000 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40005000 0x400>;
> +			interrupts = <53>;
> +			clocks = <&clk_pclk1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart6: usart at 40011400 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40011400 0x400>;
> +			interrupts = <71>;
> +			clocks = <&clk_pclk2>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart7: usart at 40007800 {

Please order all nodes by unit address, not by label.

> +			compatible = "st,stm32-usart";
> +			reg = <0x40007800 0x400>;
> +			interrupts = <82>;
> +			clocks = <&clk_pclk1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};
> +
> +		usart8: usart at 40007c00 {
> +			compatible = "st,stm32-usart";
> +			reg = <0x40007c00 0x400>;
> +			interrupts = <83>;
> +			clocks = <&clk_pclk1>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&pinctrl_usart1>;
> +
> +			status = "disabled";
> +		};

I remember two of them not being USART but UART? Similarly, two of them
support flow control (or two don't?), for which we would either need a
property or two different compatible strings.

> +	};
> +};

Regards,
Andreas

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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150302/1315830b/attachment-0001.sig>

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

* [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU
  2015-03-02 17:42   ` Andreas Färber
@ 2015-03-03 17:59     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-03 17:59 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Andreas,

Thanks for this detailed review.

2015-03-02 18:42 GMT+01:00 Andreas F?rber <afaerber@suse.de>:
> Hi Maxime,
>
> Please don't put the whole world in To, that makes replying to you much
> harder. You can put maintainers in CC instead.
Ok.
>
> Am 20.02.2015 um 19:01 schrieb Maxime Coquelin:
>> The STMicrolectornics's STM32F419 MCU has the following main features:
>>  - Cortex-M4 core running up to @180MHz
>>  - 2MB internal flash, 256KBytes internal RAM
>>  - FMC controller to connect SDRAM, NOR and NAND memories
>>  - SD/MMC/SDIO support
>>  - Ethernet controller
>>  - USB OTFG FS & HS controllers
>>  - I2C, SPI, CAN busses support
>>  - Several 16 & 32 bits general purpose timers
>>  - Serial Audio interface
>>  - LCD controller
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> ---
>>  arch/arm/boot/dts/Makefile            |   1 +
>>  arch/arm/boot/dts/stm32f429-disco.dts |  41 ++++
>>  arch/arm/boot/dts/stm32f429.dtsi      | 396 ++++++++++++++++++++++++++++++++++
>>  3 files changed, 438 insertions(+)
>>  create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
>>  create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 91bd5bd..d7da0ef 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -442,6 +442,7 @@ dtb-$(CONFIG_ARCH_STI)+= stih407-b2120.dtb \
>>       stih416-b2000.dtb \
>>       stih416-b2020.dtb \
>>       stih416-b2020e.dtb
>> +dtb-$(CONFIG_ARCH_STM32)+= stm32f429-disco.dtb
>>  dtb-$(CONFIG_MACH_SUN4I) += \
>>       sun4i-a10-a1000.dtb \
>>       sun4i-a10-ba10-tvbox.dtb \
>> diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
>> new file mode 100644
>> index 0000000..0e79cc1
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/stm32f429-disco.dts
>> @@ -0,0 +1,41 @@
>
> Add a suitable license header here? There had been attempts to
> dual-license as GPL and MIT/X11.

I agree to add the dual GPL and MIT/X11 licence.

>
>> +/dts-v1/;
>> +#include "stm32f429.dtsi"
>> +
>> +/ {
>> +     model = "STMicroelectronics's STM32F429i-DISCO board";
>
> "'s" seems uncommon here and "s's" looks wrong. Just use
> "STMicroelectronics STM32F429I-DISCO board"?

Ok, it will be fixed in v3.

>
>> +     compatible = "st,stm32f429i-disco", "st,stm32f429";
>> +
>> +     chosen {
>> +             bootargs = "console=ttyS0,115200 root=/dev/ram rdinit=/linuxrc";
>> +             linux,stdout-path = &usart1;
>
> I have actually been using USART3, following a guide I found on GitHub.
> Which pins do you use for USART1, and is one better than the other?

I used U-boot from Emcraft, which uses USART1, that is the only reason
I used this one.
Regarding USART3, I had a look at your boot-wrapper, and you configure
the USART3 to PC10/PC11 pins.

>From the schematics, I see the PC10 pin is connected to the LCD.


>
>> +     };
>> +
>> +     memory {
>> +             reg = <0xd0000000 0x800000>;
>
> I have it at 0x90000000!

Ok. But you use a specific setting:
https://github.com/afaerber/afboot-stm32/blob/master/foo.c#L338

By default this is the PC Card bank (Bank 4) at 0x90000000.

Maybe you could change your boot-wrapper to use also the default setting?

>
>> +     };
>> +
>> +     aliases {
>> +             ttyS0 = &usart1;
>
> Why ttyS0 here? Shouldn't that be serial0 by convention?

I was not aware of this. Do you know whether it is documented somewhere?
Anyway, I will change to serial0 in next version.

>
>> +     };
>> +
>> +     soc {
>> +             usart1: usart at 40011000 {
>> +                     status = "okay";
>> +             };
>
> This is a new target, so please use the new-style &usart1 {...};
> reference rather than replicating the hierarchy.
Ok.

>
>> +
>> +             leds {
>
> These LEDs are definitely not on the SoC, they're on the board. Please
> move one level up.

Ok.

>
>> +                     compatible = "gpio-leds";
>
> In this file you're being parsimonious with newline, yet in the .dtsi
> you unnecessarily add newlines before the trailing status property.
>
>> +                     red {
>> +                             #gpio-cells = <2>;
>
> This looks weird. Drop it?

Yes.

>
>> +                             label = "Front Panel LED";
>
> "Front Panel"? Both LEDs are on the front, and several other
> architectures avoid spaces in the label for accessing it from /sys.

That's an unfortunate copy/paste. For sure it has no meaning here.

>
>> +                             gpios = <&gpiog 14 0>;
>
> GPIO_ACTIVE_HIGH
Ok.

>
>> +                             linux,default-trigger = "heartbeat";
>
> Suggest to leave both off by default.
Ok.

>
>> +                     };
>> +                     green {
>> +                             #gpio-cells = <2>;
>
> Ditto.
>
>> +                             gpios = <&gpiog 13 0>;
>
> Ditto.
>
>> +                             default-state = "off";
>> +                     };
>> +             };
>> +     };
>> +};
>> diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
>> new file mode 100644
>> index 0000000..5b3442a
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/stm32f429.dtsi
>> @@ -0,0 +1,396 @@
>> +/*
>> + * Device tree for STM32F429
>
> License?

Yes. I will do the same as for the board file.

>
>> + */
>> +#include "armv7-m.dtsi"
>> +#include <dt-bindings/pinctrl/pinctrl-stm32.h>
>> +#include <dt-bindings/reset/st,stm32f429.h>
>> +
>> +/ {
>> +
>> +     aliases {
>> +             gpio0 = &gpioa;
>> +             gpio1 = &gpiob;
>> +             gpio2 = &gpioc;
>> +             gpio3 = &gpiod;
>> +             gpio4 = &gpioe;
>> +             gpio5 = &gpiof;
>> +             gpio6 = &gpiog;
>> +             gpio7 = &gpioh;
>> +             gpio8 = &gpioi;
>> +             gpio9 = &gpioj;
>> +             gpio10 = &gpiok;
>> +     };
>> +
>> +     clocks {
>> +             clk_sysclk: clk-sysclk {
>> +                     #clock-cells = <0>;
>> +                     compatible = "fixed-clock";
>> +                     clock-frequency = <180000000>;
>> +             };
>> +
>> +             clk_hclk: clk-hclk {
>> +                     #clock-cells = <0>;
>> +                     compatible = "fixed-clock";
>> +                     clock-frequency = <180000000>;
>> +             };
>> +
>> +             clk_pclk1: clk-pclk1 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "fixed-clock";
>> +                     clock-frequency = <45000000>;
>> +             };
>> +
>> +             clk_pclk2: clk-pclk2 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "fixed-clock";
>> +                     clock-frequency = <90000000>;
>> +             };
>> +
>> +             clk_pmtr1: clk-pmtr1 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "fixed-clock";
>> +                     clock-frequency = <90000000>;
>> +             };
>> +
>> +             clk_pmtr2: clk-pmtr2 {
>> +                     #clock-cells = <0>;
>> +                     compatible = "fixed-clock";
>> +                     clock-frequency = <180000000>;
>> +             };
>> +
>> +             clk_systick: clk-systick {
>> +                     compatible = "fixed-factor-clock";
>> +                     clocks = <&clk_hclk>;
>> +                     #clock-cells = <0>;
>> +                     clock-div = <8>;
>> +                     clock-mult = <1>;
>> +             };
>
> Most of these should be replaceable with my clk driver.
>

I agree, but adding more drivers is likely to delay the STM32 machine
to be merged.
Once this first round accepted, it will be easier for others to contribute.
It will help to have sooner a good support of the machine.

Does that look reasonable for you?

>> +     };
>> +
>> +     systick: timer at e000e010 {
>> +             clocks = <&clk_systick>;
>> +
>> +             status = "okay";
>> +     };
>
> &systick {...};
Ok.

>
>> +
>> +     soc {
>> +             reset: reset at 40023810 {
>> +                     #reset-cells = <1>;
>> +                     compatible = "st,stm32-reset";
>> +                     reg = <0x40023810 0x18>;
>> +             };
>
> Still, this feels wrong, given that it's an RCC IP block...
Ok, this was already pointed out by Philipp.
I will rework the driver so that the node covers the full RCC IP.


>
>> +
>> +             pin-controller {
>> +                     #address-cells = <1>;
>> +                     #size-cells = <1>;
>> +                     compatible = "st,stm32-pinctrl";
>> +                     ranges = <0 0x40020000 0x3000>;
>> +
>> +                     gpioa: gpio at 40020000 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x0 0x400>;
>> +                             resets = <&reset GPIOA_RESET>;
>> +                             st,bank-name = "GPIOA";
>> +                     };
>> +
>> +                     gpiob: gpio at 40020400 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x400 0x400>;
>> +                             resets = <&reset GPIOB_RESET>;
>> +                             st,bank-name = "GPIOB";
>> +                     };
>> +
>> +                     gpioc: gpio at 40020800 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x800 0x400>;
>> +                             resets = <&reset GPIOC_RESET>;
>> +                             st,bank-name = "GPIOC";
>> +                     };
>> +
>> +                     gpiod: gpio at 40020c00 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0xc00 0x400>;
>> +                             resets = <&reset GPIOD_RESET>;
>> +                             st,bank-name = "GPIOD";
>> +                     };
>> +
>> +                     gpioe: gpio at 40021000 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x1000 0x400>;
>> +                             resets = <&reset GPIOE_RESET>;
>> +                             st,bank-name = "GPIOE";
>> +                     };
>> +
>> +                     gpiof: gpio at 40021400 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x1400 0x400>;
>> +                             resets = <&reset GPIOF_RESET>;
>> +                             st,bank-name = "GPIOF";
>> +                     };
>> +
>> +                     gpiog: gpio at 40021800 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x1800 0x400>;
>> +                             resets = <&reset GPIOG_RESET>;
>> +                             st,bank-name = "GPIOG";
>> +                     };
>> +
>> +                     gpioh: gpio at 40021c00 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x1c00 0x400>;
>> +                             resets = <&reset GPIOH_RESET>;
>> +                             st,bank-name = "GPIOH";
>> +                     };
>> +
>> +                     gpioi: gpio at 40022000 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x2000 0x400>;
>> +                             resets = <&reset GPIOI_RESET>;
>> +                             st,bank-name = "GPIOI";
>> +                     };
>> +
>> +                     gpioj: gpio at 40022400 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x2400 0x400>;
>> +                             resets = <&reset GPIOJ_RESET>;
>> +                             st,bank-name = "GPIOJ";
>> +                     };
>> +
>> +                     gpiok: gpio at 40022800 {
>> +                             gpio-controller;
>> +                             #gpio-cells = <2>;
>> +                             reg = <0x2800 0x400>;
>> +                             resets = <&reset GPIOK_RESET>;
>> +                             st,bank-name = "GPIOK";
>> +                     };
>> +
>> +                     usart1 {
>> +                             pinctrl_usart1: usart1-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioa 9 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpioa 10 ALT7 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart2 {
>> +                             pinctrl_usart2: usart2-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioa 2 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpioa 3 ALT7 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart3 {
>> +                             pinctrl_usart3: usart3-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpiob 10 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpiob 11 ALT7 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart4 {
>> +                             pinctrl_usart4: usart4-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioa 0 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpioa 1 ALT8 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart5 {
>> +                             pinctrl_usart5: usart5-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioc 12 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpiod 2 ALT8 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart6 {
>> +                             pinctrl_usart6: usart6-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioc 6 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpioc 7 ALT8 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart7 {
>> +                             pinctrl_usart7: usart7-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioe 8 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpioe 7 ALT8 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>> +
>> +                     usart8 {
>> +                             pinctrl_usart8: usart8-0 {
>> +                                     st,pins {
>> +                                             tx = <&gpioe 1 ALT8 NO_PULL PUSH_PULL LOW_SPEED>;
>> +                                             rx = <&gpioe 0 ALT8 NO_PULL>;
>> +                                     };
>> +                             };
>> +                     };
>
> Can't the outer level be avoided here to save space and indentation?
Yes. I will rework this too.

>
>> +             };
>> +
>> +             timer2: timer at 40000000 {
>> +                     compatible = "st,stm32-timer";
>> +                     reg = <0x40000000 0x400>;
>> +                     interrupts = <28>;
>> +                     resets = <&reset TIM2_RESET>;
>> +                     clocks = <&clk_pmtr1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             timer3: timer at 40000400 {
>> +                     compatible = "st,stm32-timer";
>> +                     reg = <0x40000400 0x400>;
>> +                     interrupts = <29>;
>> +                     resets = <&reset TIM3_RESET>;
>> +                     clocks = <&clk_pmtr1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             timer4: timer at 40000800 {
>> +                     compatible = "st,stm32-timer";
>> +                     reg = <0x40000800 0x400>;
>> +                     interrupts = <30>;
>> +                     resets = <&reset TIM4_RESET>;
>> +                     clocks = <&clk_pmtr1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             timer5: timer at 40000c00 {
>> +                     compatible = "st,stm32-timer";
>> +                     reg = <0x40000c00 0x400>;
>> +                     interrupts = <50>;
>> +                     resets = <&reset TIM5_RESET>;
>> +                     clocks = <&clk_pmtr1>;
>> +             };
>> +
>> +             timer6: timer at 40001000 {
>> +                     compatible = "st,stm32-timer";
>> +                     reg = <0x40001000 0x400>;
>> +                     interrupts = <54>;
>> +                     resets = <&reset TIM6_RESET>;
>> +                     clocks = <&clk_pmtr1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             timer7: timer at 40001400 {
>> +                     compatible = "st,stm32-timer";
>> +                     reg = <0x40001400 0x400>;
>> +                     interrupts = <55>;
>> +                     resets = <&reset TIM7_RESET>;
>> +                     clocks = <&clk_pmtr1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart1: usart at 40011000 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40011000 0x400>;
>> +                     interrupts = <37>;
>> +                     clocks = <&clk_pclk2>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart2: usart at 40004400 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40004400 0x400>;
>> +                     interrupts = <38>;
>> +                     clocks = <&clk_pclk1>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>
> Copy&paste, also below. Is this really .dtsi material?

Sorry, I am not sure to understand what you mean.
Could you elaborate please?

>
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart3: usart at 40004800 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40004800 0x400>;
>> +                     interrupts = <39>;
>> +                     clocks = <&clk_pclk1>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart4: usart at 40004c00 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40004c00 0x400>;
>> +                     interrupts = <52>;
>> +                     clocks = <&clk_pclk1>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart5: usart at 40005000 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40005000 0x400>;
>> +                     interrupts = <53>;
>> +                     clocks = <&clk_pclk1>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart6: usart at 40011400 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40011400 0x400>;
>> +                     interrupts = <71>;
>> +                     clocks = <&clk_pclk2>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart7: usart at 40007800 {
>
> Please order all nodes by unit address, not by label.
Ok.

>
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40007800 0x400>;
>> +                     interrupts = <82>;
>> +                     clocks = <&clk_pclk1>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>> +
>> +             usart8: usart at 40007c00 {
>> +                     compatible = "st,stm32-usart";
>> +                     reg = <0x40007c00 0x400>;
>> +                     interrupts = <83>;
>> +                     clocks = <&clk_pclk1>;
>> +                     pinctrl-names = "default";
>> +                     pinctrl-0 = <&pinctrl_usart1>;
>> +
>> +                     status = "disabled";
>> +             };
>
> I remember two of them not being USART but UART? Similarly, two of them
> support flow control (or two don't?), for which we would either need a
> property or two different compatible strings.

I have to check what would best fit to handle these differences.
I will come back to you later on this point.

Thanks!
Maxime

>
>> +     };
>> +};
>
> Regards,
> Andreas
>
> --
> SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany
> GF: Felix Imend?rffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
> Graham Norton; HRB 21284 (AG N?rnberg)
>

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-03-02 16:53       ` Maxime Coquelin
@ 2015-03-03 19:43         ` Paul Bolle
  2015-03-04 12:08           ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Paul Bolle @ 2015-03-03 19:43 UTC (permalink / raw)
  To: linux-arm-kernel

Maxime Coquelin schreef op ma 02-03-2015 om 17:53 [+0100]:
> Do you agree if I define it like this:
> 
> config ARMV7M_SYSTICK
>     bool "Clocksource driver for ARMv7-M System timer"
>     depends on OF && (CPU_V7M || COMPILE_TEST)
>     select CLKSRC_OF
>     select CLKSRC_MMIO
>     help
>       This options enables clocksource support for the ARMv7-M system
>       timer unit.

I don't really have strong feelings on whatever way you choose to fix
the, well, minor problem I pointed out.

Having said that, if a Kconfig entry without a prompt (and therefor,
without help) actually does what you want it to do, why bother adding a
prompt and a one line help text?


Paul Bolle

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-03-03 19:43         ` Paul Bolle
@ 2015-03-04 12:08           ` Maxime Coquelin
  2015-03-09 21:12             ` Paul Bolle
  0 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-04 12:08 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-03 20:43 GMT+01:00 Paul Bolle <pebolle@tiscali.nl>:
> Maxime Coquelin schreef op ma 02-03-2015 om 17:53 [+0100]:
>> Do you agree if I define it like this:
>>
>> config ARMV7M_SYSTICK
>>     bool "Clocksource driver for ARMv7-M System timer"
>>     depends on OF && (CPU_V7M || COMPILE_TEST)
>>     select CLKSRC_OF
>>     select CLKSRC_MMIO
>>     help
>>       This options enables clocksource support for the ARMv7-M system
>>       timer unit.
>
> I don't really have strong feelings on whatever way you choose to fix
> the, well, minor problem I pointed out.
>
> Having said that, if a Kconfig entry without a prompt (and therefor,
> without help) actually does what you want it to do, why bother adding a
> prompt and a one line help text?

This is because I added also support for COMPILE_TEST coverage as per
Uwe advice,
and thought it was necessary to have an entry for this.
Maybe I'm just wrong?

Thanks,
Maxime

>
>
> Paul Bolle
>

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

* [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller
  2015-02-20 18:01 ` [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller Maxime Coquelin
@ 2015-03-06  9:12   ` Linus Walleij
  2015-03-06  9:35   ` Linus Walleij
  1 sibling, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2015-03-06  9:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
<mcoquelin.stm32@gmail.com> wrote:

> This adds documentation of device tree bindings for the
> STM32 pin controller.
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
(...)
> +Pin controller node:
> +Required properies:
> +- compatible   : "st,stm32-pinctrl"
> +- #address-cells: The value of this property must be 1
> +- #size-cells  : The value of this property must be 1
> +- ranges       : defines mapping between pin controller node (parent) to
> +  gpio-bank node (children).
> +
> +GPIO controller/bank node:
> +Required properties:
> +- gpio-controller : Indicates this device is a GPIO controller
> +- #gpio-cells    : Should be two.
> +                       The first cell is the pin number
> +                       The second one is the polarity:
> +                               - 0 for active high
> +                               - 1 for active low
> +- reg            : The gpio address range, relative to the pinctrl range
> +- st,bank-name   : Should be a name string for this bank as specified in
> +  the datasheet

OK...

(...)
> +               ...
> +               pin-functions nodes follow...
> +       };
> +
> +Contents of function subnode node:
> +----------------------------------
> +
> +Required properties for pin configuration node:
> +- st,pins      : Child node with list of pins with configuration.

Don't use vendor prefix. Use the new standard notation, just "pins".
See Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

> +Below is the format of how each pin conf should look like.
> +
> +<bank offset altmode pull type speed>
> +
> +Every PIO is represented with 4 to 6 parameters.
> +Each parameter is explained as below.
> +
> +- bank   : Should be bank phandle to which this PIO belongs.
> +- offset  : Offset in the PIO bank.

No. Don't hardcode register offsets into the DTS files. This is
something the driver should know from the compatible string or
instance number, not by explicit reference.

> +- altmode : Should be mode or alternate function number associated this pin, as
> +described in the datasheet (IN, OUT, ALT0...ALT15, ANALOG)
> +- pull   : Should be either NO_PULL, PULL_UP or PULL_DOWN
> +- type   : Should be either PUSH_PULL or OPEN_DRAIN.
> +           Setting it is not needed for IN and ANALOG modes, or alternate
> +           functions acting as inputs.
> +- speed          : Value taken from the datasheet, depending on the function
> +(LOW_SPEED, MEDIUM_SPEED, FAST_SPEED, HIGH_SPEED)
> +           Setting it is not needed for IN and ANALOG modes, or alternate
> +           functions acting as inputs.

NACK. Make your Kconfig select GENERIC_PINCONF and use the
already existing generic pin configuration specifiers from the standard
bindings. Like bias-pull-up; etc.

This kind of custom pin config is a thing of the past.

> +usart1 {
> +       pinctrl_usart1: usart1-0 {
> +               st,pins {
> +                       tx = <&gpioa 9 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
> +                       rx = <&gpioa 10 ALT7 NO_PULL PUSH_PULL LOW_SPEED>;
> +               };
> +       };
> +};

You might have to use separate parameters for muxing and config
in your description.

Yours,
Linus Walleij

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

* [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs
  2015-02-20 18:01 ` [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs Maxime Coquelin
@ 2015-03-06  9:24   ` Linus Walleij
  2015-03-06  9:57     ` Maxime Coquelin
  2015-03-10 15:08   ` Arnd Bergmann
  1 sibling, 1 reply; 65+ messages in thread
From: Linus Walleij @ 2015-03-06  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
<mcoquelin.stm32@gmail.com> wrote:

> This driver adds pinctrl and GPIO support to STMicrolectronic's
> STM32 family of MCUs.
>
> Pin muxing and GPIO handling have been tested on STM32F429
> based Discovery board.
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>

(...)
> +config PINCTRL_STM32
> +       bool "STMicroelectronics STM32 pinctrl driver"
> +       depends on OF
> +       depends on ARCH_STM32 || COMPILE_TEST
> +       select PINMUX
> +       select PINCONF
> +       select GPIOLIB_IRQCHIP
> +       help
> +         This selects the device tree based generic pinctrl driver for STM32.

Good start! Especially that you use GPIOLIB_IRQCHIP.

But this (as discussed earlier) should select GENERIC_PINCONF

Stopping review here so you can reengineer it a bit using GENERIC_PINCONF
for next submission.

Also think about pinmux in single registers, whether you want to do this
with a single value for a register or using strings to identify groups
and functions.

Yours,
Linus Walleij

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

* [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller
  2015-02-20 18:01 ` [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller Maxime Coquelin
  2015-03-06  9:12   ` Linus Walleij
@ 2015-03-06  9:35   ` Linus Walleij
  1 sibling, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2015-03-06  9:35 UTC (permalink / raw)
  To: linux-arm-kernel

I saw this other thing:

On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
<mcoquelin.stm32@gmail.com> wrote:

> This adds documentation of device tree bindings for the
> STM32 pin controller.
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
(...)
> +- altmode : Should be mode or alternate function number associated this pin, as
> +described in the datasheet (IN, OUT, ALT0...ALT15, ANALOG)

We can now describe muxing (altmodes etc) in two ways as described
in the generic bindings in
Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

This is done by strings combining a function with N groups.

We are also discussing having a single config number setting up
all and keeping down the size of the DTB (which
is close to what you're doing here). Please take part in that
discussion to standardize such bindings. Sascha Hauer and
others are involved, don't know the exact topic right now but
it involved using a single "pinmux" parameter in the device treel.

All agree on using the standardized pin config bindings henceforth
so start by migrating to these.

Yours,
Linus Walleij

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

* [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs
  2015-03-06  9:24   ` Linus Walleij
@ 2015-03-06  9:57     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-06  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-06 10:24 GMT+01:00 Linus Walleij <linus.walleij@linaro.org>:
> On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
> <mcoquelin.stm32@gmail.com> wrote:
>
>> This driver adds pinctrl and GPIO support to STMicrolectronic's
>> STM32 family of MCUs.
>>
>> Pin muxing and GPIO handling have been tested on STM32F429
>> based Discovery board.
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>
> (...)
>> +config PINCTRL_STM32
>> +       bool "STMicroelectronics STM32 pinctrl driver"
>> +       depends on OF
>> +       depends on ARCH_STM32 || COMPILE_TEST
>> +       select PINMUX
>> +       select PINCONF
>> +       select GPIOLIB_IRQCHIP
>> +       help
>> +         This selects the device tree based generic pinctrl driver for STM32.
>
> Good start! Especially that you use GPIOLIB_IRQCHIP.
>
> But this (as discussed earlier) should select GENERIC_PINCONF
>
> Stopping review here so you can reengineer it a bit using GENERIC_PINCONF
> for next submission.
>
> Also think about pinmux in single registers, whether you want to do this
> with a single value for a register or using strings to identify groups
> and functions.

Thanks for the review.
I will digest all this, and come back with another solution :)

Best regards,
Maxime

>
> Yours,
> Linus Walleij

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-02-20 18:01 ` [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries Maxime Coquelin
  2015-02-20 19:47   ` Uwe Kleine-König
@ 2015-03-09  0:29   ` Stefan Agner
  2015-03-09 17:12     ` Maxime Coquelin
  1 sibling, 1 reply; 65+ messages in thread
From: Stefan Agner @ 2015-03-09  0:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015-02-20 19:01, Maxime Coquelin wrote:
> From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
> So the number of entries in vectors table is up to 256.
> 
> This patch adds a new config flag to specify the number of external interrupts.
> Some ifdeferies are added in order to respect the natural alignment without
> wasting too much space on smaller systems.
> 
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> ---
>  arch/arm/kernel/entry-v7m.S | 13 +++++++++----
>  arch/arm/mm/Kconfig         | 15 +++++++++++++++
>  2 files changed, 24 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
> index 8944f49..68cde36 100644
> --- a/arch/arm/kernel/entry-v7m.S
> +++ b/arch/arm/kernel/entry-v7m.S
> @@ -117,9 +117,14 @@ ENTRY(__switch_to)
>  ENDPROC(__switch_to)
>  
>  	.data
> -	.align	8
> +#if CONFIG_CPUV7M_NUM_IRQ <= 112
> +	.align	9
> +#else
> +	.align	10
> +#endif
> +
>  /*
> - * Vector table (64 words => 256 bytes natural alignment)
> + * Vector table (Natural alignment need to be ensured)
>   */
>  ENTRY(vector_table)
>  	.long	0			@ 0 - Reset stack pointer
> @@ -138,6 +143,6 @@ ENTRY(vector_table)
>  	.long	__invalid_entry		@ 13 - Reserved
>  	.long	__pendsv_entry		@ 14 - PendSV
>  	.long	__invalid_entry		@ 15 - SysTick
> -	.rept	64 - 16
> -	.long	__irq_entry		@ 16..64 - External Interrupts
> +	.rept	CONFIG_CPUV7M_NUM_IRQ
> +	.long	__irq_entry		@ External Interrupts
>  	.endr
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index c43c714..27eb835 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -604,6 +604,21 @@ config CPU_USE_DOMAINS
>  	  This option enables or disables the use of domain switching
>  	  via the set_fs() function.
>  
> +config CPUV7M_NUM_IRQ
> +	int "Number of external interrupts connected to the NVIC"
> +	depends on CPU_V7M
> +	default 90 if ARCH_STM32
> +	default 38 if ARCH_EFM32
> +	default 240
> +	help
> +	  This option indicates the number of interrupts connected to the NVIC.
> +	  The value can be larger than the real number of interrupts supported
> +	  by the system, but must not be lower.
> +	  The default value is 240, corresponding to the maximum number of
> +	  interrupts supported by the NVIC on Cortex-M family.
> +
> +	  If unsure, keep default value.
> +
>  #
>  # CPU supports 36-bit I/O
>  #

I sent a patch which extended that vector table some weeks ago:
https://lkml.org/lkml/2014/12/29/296

But your solution is definitely more flexible, and given that we deal
with small devices here, it's worth saving memory.

Acked-by: Stefan Agner <stefan@agner.ch>

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

* [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU
  2015-02-20 18:01 ` [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU Maxime Coquelin
  2015-03-02 17:42   ` Andreas Färber
@ 2015-03-09 14:39   ` Linus Walleij
  2015-03-09 16:51     ` Maxime Coquelin
  1 sibling, 1 reply; 65+ messages in thread
From: Linus Walleij @ 2015-03-09 14:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
<mcoquelin.stm32@gmail.com> wrote:

> The STMicrolectornics's STM32F419 MCU has the following main features:
>  - Cortex-M4 core running up to @180MHz
>  - 2MB internal flash, 256KBytes internal RAM
>  - FMC controller to connect SDRAM, NOR and NAND memories
>  - SD/MMC/SDIO support
>  - Ethernet controller
>  - USB OTFG FS & HS controllers
>  - I2C, SPI, CAN busses support
>  - Several 16 & 32 bits general purpose timers
>  - Serial Audio interface
>  - LCD controller
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
(...)
> +       soc {
> +               usart1: usart at 40011000 {
> +                       status = "okay";
> +               };
> +
> +               leds {
> +                       compatible = "gpio-leds";
> +                       red {
> +                               #gpio-cells = <2>;
> +                               label = "Front Panel LED";
> +                               gpios = <&gpiog 14 0>;
> +                               linux,default-trigger = "heartbeat";
> +                       };
> +                       green {
> +                               #gpio-cells = <2>;
> +                               gpios = <&gpiog 13 0>;
> +                               default-state = "off";
> +                       };
> +               };
> +       };

The LEDs are mounted on the board not the SoC, right?

So move them outside of the soc node, to the top level
of the DTS file.

Yours,
Linus Walleij

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-02-20 18:01 ` [PATCH v2 04/18] clocksource: Add ARM System timer driver Maxime Coquelin
  2015-02-20 19:54   ` Uwe Kleine-König
@ 2015-03-09 15:50   ` Linus Walleij
  2015-03-09 17:00     ` Maxime Coquelin
  1 sibling, 1 reply; 65+ messages in thread
From: Linus Walleij @ 2015-03-09 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
<mcoquelin.stm32@gmail.com> wrote:

> This patch adds clocksource support for ARMv7-M's System timer,
> also known as SysTick.
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
(...)
> +       /* If no clock found, try to get clock-frequency property */
> +       if (!rate) {
> +               ret = of_property_read_u32(np, "clock-frequency", &rate);
> +               if (ret)
> +                       goto out_unmap;
> +       }

If this driver is only used for this one system, and if on this one system
the clk subsystem will provide the clock rate, then there is no need
to include this hackaround property.

Alternatively there is no point including reading the frequency from
the clk subsystem for this one system.

So which one is it?

Yours,
Linus Walleij

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

* [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU
  2015-03-09 14:39   ` Linus Walleij
@ 2015-03-09 16:51     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-09 16:51 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-09 15:39 GMT+01:00 Linus Walleij <linus.walleij@linaro.org>:
> On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
> <mcoquelin.stm32@gmail.com> wrote:
>
>> The STMicrolectornics's STM32F419 MCU has the following main features:
>>  - Cortex-M4 core running up to @180MHz
>>  - 2MB internal flash, 256KBytes internal RAM
>>  - FMC controller to connect SDRAM, NOR and NAND memories
>>  - SD/MMC/SDIO support
>>  - Ethernet controller
>>  - USB OTFG FS & HS controllers
>>  - I2C, SPI, CAN busses support
>>  - Several 16 & 32 bits general purpose timers
>>  - Serial Audio interface
>>  - LCD controller
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> (...)
>> +       soc {
>> +               usart1: usart at 40011000 {
>> +                       status = "okay";
>> +               };
>> +
>> +               leds {
>> +                       compatible = "gpio-leds";
>> +                       red {
>> +                               #gpio-cells = <2>;
>> +                               label = "Front Panel LED";
>> +                               gpios = <&gpiog 14 0>;
>> +                               linux,default-trigger = "heartbeat";
>> +                       };
>> +                       green {
>> +                               #gpio-cells = <2>;
>> +                               gpios = <&gpiog 13 0>;
>> +                               default-state = "off";
>> +                       };
>> +               };
>> +       };
>
> The LEDs are mounted on the board not the SoC, right?
>
> So move them outside of the soc node, to the top level
> of the DTS file.

Yes, you are right.
Andreas already made the same remark, and the top-level move is
already here in the upcoming v3.

Thanks,
Maxime
>
> Yours,
> Linus Walleij

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-03-09 15:50   ` Linus Walleij
@ 2015-03-09 17:00     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-09 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-09 16:50 GMT+01:00 Linus Walleij <linus.walleij@linaro.org>:
> On Fri, Feb 20, 2015 at 7:01 PM, Maxime Coquelin
> <mcoquelin.stm32@gmail.com> wrote:
>
>> This patch adds clocksource support for ARMv7-M's System timer,
>> also known as SysTick.
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> (...)
>> +       /* If no clock found, try to get clock-frequency property */
>> +       if (!rate) {
>> +               ret = of_property_read_u32(np, "clock-frequency", &rate);
>> +               if (ret)
>> +                       goto out_unmap;
>> +       }
>
> If this driver is only used for this one system, and if on this one system
> the clk subsystem will provide the clock rate, then there is no need
> to include this hackaround property.
>
> Alternatively there is no point including reading the frequency from
> the clk subsystem for this one system.
>
> So which one is it?

In the first version, the "clock-frequency" property handling was not here.
Rob Herring advised me to add its support, as it could be used by
simple systems not selecting CCF.

So, I don't have the name of a system where it could be useful, but I
think Rob's request make sense.

Note that I tested using the clock-frequency property before sending.

Best regards,
Maxime
>
> Yours,
> Linus Walleij

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

* [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries
  2015-03-09  0:29   ` Stefan Agner
@ 2015-03-09 17:12     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-09 17:12 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-09 1:29 GMT+01:00 Stefan Agner <stefan@agner.ch>:
> On 2015-02-20 19:01, Maxime Coquelin wrote:
>> From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
>> So the number of entries in vectors table is up to 256.
>>
>> This patch adds a new config flag to specify the number of external interrupts.
>> Some ifdeferies are added in order to respect the natural alignment without
>> wasting too much space on smaller systems.
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> ---
>>  arch/arm/kernel/entry-v7m.S | 13 +++++++++----
>>  arch/arm/mm/Kconfig         | 15 +++++++++++++++
>>  2 files changed, 24 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
>> index 8944f49..68cde36 100644
>> --- a/arch/arm/kernel/entry-v7m.S
>> +++ b/arch/arm/kernel/entry-v7m.S
>> @@ -117,9 +117,14 @@ ENTRY(__switch_to)
>>  ENDPROC(__switch_to)
>>
>>       .data
>> -     .align  8
>> +#if CONFIG_CPUV7M_NUM_IRQ <= 112
>> +     .align  9
>> +#else
>> +     .align  10
>> +#endif
>> +
>>  /*
>> - * Vector table (64 words => 256 bytes natural alignment)
>> + * Vector table (Natural alignment need to be ensured)
>>   */
>>  ENTRY(vector_table)
>>       .long   0                       @ 0 - Reset stack pointer
>> @@ -138,6 +143,6 @@ ENTRY(vector_table)
>>       .long   __invalid_entry         @ 13 - Reserved
>>       .long   __pendsv_entry          @ 14 - PendSV
>>       .long   __invalid_entry         @ 15 - SysTick
>> -     .rept   64 - 16
>> -     .long   __irq_entry             @ 16..64 - External Interrupts
>> +     .rept   CONFIG_CPUV7M_NUM_IRQ
>> +     .long   __irq_entry             @ External Interrupts
>>       .endr
>> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
>> index c43c714..27eb835 100644
>> --- a/arch/arm/mm/Kconfig
>> +++ b/arch/arm/mm/Kconfig
>> @@ -604,6 +604,21 @@ config CPU_USE_DOMAINS
>>         This option enables or disables the use of domain switching
>>         via the set_fs() function.
>>
>> +config CPUV7M_NUM_IRQ
>> +     int "Number of external interrupts connected to the NVIC"
>> +     depends on CPU_V7M
>> +     default 90 if ARCH_STM32
>> +     default 38 if ARCH_EFM32
>> +     default 240
>> +     help
>> +       This option indicates the number of interrupts connected to the NVIC.
>> +       The value can be larger than the real number of interrupts supported
>> +       by the system, but must not be lower.
>> +       The default value is 240, corresponding to the maximum number of
>> +       interrupts supported by the NVIC on Cortex-M family.
>> +
>> +       If unsure, keep default value.
>> +
>>  #
>>  # CPU supports 36-bit I/O
>>  #
>
> I sent a patch which extended that vector table some weeks ago:
> https://lkml.org/lkml/2014/12/29/296

I did something similar in my first version.

>
> But your solution is definitely more flexible, and given that we deal
> with small devices here, it's worth saving memory.

Yes, it is worth for these small devices.

>
> Acked-by: Stefan Agner <stefan@agner.ch>
>

Thanks for the review,
Maxime

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-03-04 12:08           ` Maxime Coquelin
@ 2015-03-09 21:12             ` Paul Bolle
  2015-03-09 22:17               ` Uwe Kleine-König
  0 siblings, 1 reply; 65+ messages in thread
From: Paul Bolle @ 2015-03-09 21:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 2015-03-04 at 13:08 +0100, Maxime Coquelin wrote:
> This is because I added also support for COMPILE_TEST coverage as per
> Uwe advice,
> and thought it was necessary to have an entry for this.
> Maybe I'm just wrong?

I missed that you added COMPILE_TEST.

A quick scan of your idea doesn't show any obvious issues. (Note that I
don't really know how people actually use COMPILE_TEST. I guess things
like "make allyesconfig" are involved.)


Paul Bolle

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

* [PATCH v2 04/18] clocksource: Add ARM System timer driver
  2015-03-09 21:12             ` Paul Bolle
@ 2015-03-09 22:17               ` Uwe Kleine-König
  0 siblings, 0 replies; 65+ messages in thread
From: Uwe Kleine-König @ 2015-03-09 22:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Mon, Mar 09, 2015 at 10:12:32PM +0100, Paul Bolle wrote:
> On Wed, 2015-03-04 at 13:08 +0100, Maxime Coquelin wrote:
> > This is because I added also support for COMPILE_TEST coverage as per
> > Uwe advice,
> > and thought it was necessary to have an entry for this.
> > Maybe I'm just wrong?
> 
> I missed that you added COMPILE_TEST.
> 
> A quick scan of your idea doesn't show any obvious issues. (Note that I
> don't really know how people actually use COMPILE_TEST. I guess things
> like "make allyesconfig" are involved.)
Maybe this can clearify the purpose of COMPILE_TEST:

diff --git a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -67,6 +67,26 @@ config COMPILE_TEST
 	  here. If you are a user/distributor, say N here to exclude useless
 	  drivers to be distributed.
 
+	# If you are a driver author consider to adjust your driver's
+	# dependencies to make it buildable with minimal preconditions if
+	# COMPILE_TEST is enabled. This helps contributers and maintainers
+	# that might not have the necessary toolchain or kernel config handy and
+	# also increases compile test coverage. It's your advantage if others can
+	# build your driver more easily! So for a device that is only found on the
+	# foo cpu use:
+	#
+	# 	depends on CPU_FOO || COMPILE_TEST
+	#
+	# . You might have to use
+	#
+	# 	depends on CPU_FOO || (COMPILE_TEST && COOKIE)
+	#
+	# or
+	#
+	#	depends on COOKIE && (CPU_FOO || COMPILE_TEST)
+	#
+	# if your driver uses features that are only available if COOKIE is on.
+
 config LOCALVERSION
 	string "Local version - append to kernel release"
 	help

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH v2 05/18] reset: Add reset_controller_of_init() function
  2015-02-20 18:01 ` [PATCH v2 05/18] reset: Add reset_controller_of_init() function Maxime Coquelin
@ 2015-03-10 15:00   ` Arnd Bergmann
  2015-03-10 15:28     ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 February 2015 19:01:04 Maxime Coquelin wrote:
> Some platforms need to initialize the reset controller before the timers.
> 
> This patch introduces a reset_controller_of_init() function that can be
> called before the timers intialization.
> 
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> 

Not sure about this. It seems like the cleanest approach if we get
a lot of these, but then again it is probably very rare, and I'd
like to avoid adding such infrastructure if it's just for one
SoC. Could we add a hack in the machine initialization instead?

I think ideally this would be done in the boot loader before we
even start Linux, but I don't know if that's possible for you.

	Arnd

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-02-20 18:01 ` [PATCH v2 07/18] drivers: reset: Add STM32 reset driver Maxime Coquelin
@ 2015-03-10 15:02   ` Arnd Bergmann
  2015-03-10 15:41     ` Maxime Coquelin
  2015-03-10 15:44     ` Maxime Coquelin
  0 siblings, 2 replies; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
> +/* AHB1 */
> +#define GPIOA_RESET    0
> +#define GPIOB_RESET    1
> +#define GPIOC_RESET    2
> +#define GPIOD_RESET    3
> +#define GPIOE_RESET    4
> +#define GPIOF_RESET    5
> +#define GPIOG_RESET    6
> +#define GPIOH_RESET    7
> +#define GPIOI_RESET    8
> +#define GPIOJ_RESET    9
> +#define GPIOK_RESET    10
> 

As these are just the hardware numbers, it's better to not make them
part of the binding at all. Instead, just document in the binding that
one is supposed to pass the hardware number as the argument.

	Arnd

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

* [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs
  2015-02-20 18:01 ` [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs Maxime Coquelin
  2015-03-06  9:24   ` Linus Walleij
@ 2015-03-10 15:08   ` Arnd Bergmann
  2015-03-18  1:08     ` Linus Walleij
  1 sibling, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 February 2015 19:01:10 Maxime Coquelin wrote:
> --- /dev/null
> +++ b/include/dt-bindings/pinctrl/pinctrl-stm32.h
> @@ -0,0 +1,43 @@
> +#ifndef _DT_BINDINGS_PINCTRL_STM32_H
> +#define _DT_BINDINGS_PINCTRL_STM32_H
> +
> +/* Modes */
> +#define IN             0
> +#define OUT            1
> +#define ALT            2
> +#define ANALOG         3

I think it's better to prefix all the names with a
string to identify what they are for, otherwise these
are way too generic.

> +/* Alternate functions */
> +#define ALT0           ((0 << 2) | ALT)
> +#define ALT1           ((1 << 2) | ALT)
> +#define ALT2           ((2 << 2) | ALT)
> +#define ALT3           ((3 << 2) | ALT)
> +#define ALT4           ((4 << 2) | ALT)
> +#define ALT5           ((5 << 2) | ALT)
> +#define ALT6           ((6 << 2) | ALT)
> +#define ALT7           ((7 << 2) | ALT)
> +#define ALT8           ((8 << 2) | ALT)
> +#define ALT9           ((9 << 2) | ALT)
> +#define ALT10          ((10 << 2) | ALT)
> +#define ALT11          ((11 << 2) | ALT)
> +#define ALT12          ((12 << 2) | ALT)
> +#define ALT13          ((13 << 2) | ALT)
> +#define ALT14          ((14 << 2) | ALT)
> +#define ALT15          ((15 << 2) | ALT)

You can have a single macro for these like

#define STM32_PIN_ALT(x) ((x << 2) | ALT)

> +/* Pull-Up/Down */
> +#define NO_PULL                0
> +#define PULL_UP                1
> +#define PULL_DOWN      2
> +
> +/* Type */
> +#define PUSH_PULL      (0 << 2)
> +#define OPEN_DRAIN     (1 << 2)
> +

These should probably not be stm32 specific at all, they sound
rather generic, so maybe put the definitions into a common file.



	Arnd

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

* [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings
  2015-02-20 18:01 ` [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings Maxime Coquelin
@ 2015-03-10 15:08   ` Arnd Bergmann
  2015-03-10 15:45     ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 February 2015 19:01:11 Maxime Coquelin wrote:
> +
> +Example:
> +usart1: usart at 40011000 {
> +       compatible = "st,stm32-usart";
> 

Please use generic node names everywhere. The standard name for a serial
port is "serial".

	Arnd

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

* [PATCH v2 14/18] ARM: Add STM32 family machine
  2015-02-20 18:01 ` [PATCH v2 14/18] ARM: Add STM32 family machine Maxime Coquelin
  2015-02-20 18:33   ` Peter Meerwald
  2015-02-20 20:00   ` Uwe Kleine-König
@ 2015-03-10 15:10   ` Arnd Bergmann
  2 siblings, 0 replies; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 February 2015 19:01:13 Maxime Coquelin wrote:
> +static void __init stm32_timer_init(void)
> +{
> +       of_clk_init(NULL);
> +       reset_controller_of_init();
> +       clocksource_of_init();
> +
> +}

Don't do that. As I said, I'd rather not introduce reset_controller_of_init()
at all, but if we end up doing it, it should be run by default for
any machine that has an empty timer_init callback.

	Arnd

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

* [PATCH v2 05/18] reset: Add reset_controller_of_init() function
  2015-03-10 15:00   ` Arnd Bergmann
@ 2015-03-10 15:28     ` Maxime Coquelin
  2015-03-10 20:19       ` Arnd Bergmann
  0 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-10 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-10 16:00 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> On Friday 20 February 2015 19:01:04 Maxime Coquelin wrote:
>> Some platforms need to initialize the reset controller before the timers.
>>
>> This patch introduces a reset_controller_of_init() function that can be
>> called before the timers intialization.
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>>
>
> Not sure about this. It seems like the cleanest approach if we get
> a lot of these, but then again it is probably very rare, and I'd
> like to avoid adding such infrastructure if it's just for one
> SoC. Could we add a hack in the machine initialization instead?

Sun6i also need to initialize the reset controller early. Today, they
hack the machine initialization.
With two SoCs having the same need, what should we do?

That said, I'm fine with either way. If reset_controller_of_init gets
accepted, I will send the patch for sun6i.

>
> I think ideally this would be done in the boot loader before we
> even start Linux, but I don't know if that's possible for you.

>From what I understand, the only constraint is to perform it after the
clock is enabled.
So this should be possible to do it in the bootloader, but it means
also adding timers clocks ungating in the bootloader.

Br,
Maxime

>
>         Arnd

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-03-10 15:02   ` Arnd Bergmann
@ 2015-03-10 15:41     ` Maxime Coquelin
  2015-03-10 15:44     ` Maxime Coquelin
  1 sibling, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-10 15:41 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-10 16:02 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
>> +/* AHB1 */
>> +#define GPIOA_RESET    0
>> +#define GPIOB_RESET    1
>> +#define GPIOC_RESET    2
>> +#define GPIOD_RESET    3
>> +#define GPIOE_RESET    4
>> +#define GPIOF_RESET    5
>> +#define GPIOG_RESET    6
>> +#define GPIOH_RESET    7
>> +#define GPIOI_RESET    8
>> +#define GPIOJ_RESET    9
>> +#define GPIOK_RESET    10
>>
>
> As these are just the hardware numbers, it's better to not make them
> part of the binding at all. Instead, just document in the binding that
> one is supposed to pass the hardware number as the argument.

The reset controller is part of the RCC (Reset & Clock Controller) IP.
In this version, I only provided the reset registers to the reset
controller driver, but as per Andrea

>
>         Arnd

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-03-10 15:02   ` Arnd Bergmann
  2015-03-10 15:41     ` Maxime Coquelin
@ 2015-03-10 15:44     ` Maxime Coquelin
  2015-03-10 20:21       ` Arnd Bergmann
  1 sibling, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-10 15:44 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-10 16:02 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
>> +/* AHB1 */
>> +#define GPIOA_RESET    0
>> +#define GPIOB_RESET    1
>> +#define GPIOC_RESET    2
>> +#define GPIOD_RESET    3
>> +#define GPIOE_RESET    4
>> +#define GPIOF_RESET    5
>> +#define GPIOG_RESET    6
>> +#define GPIOH_RESET    7
>> +#define GPIOI_RESET    8
>> +#define GPIOJ_RESET    9
>> +#define GPIOK_RESET    10
>>
>
> As these are just the hardware numbers, it's better to not make them
> part of the binding at all. Instead, just document in the binding that
> one is supposed to pass the hardware number as the argument.

The reset controller is part of the RCC (Reset & Clock Controller) IP.
In this version, I only provided the reset registers to the reset
controller driver, but as per Andreas F?rber remark, I should avec a
single DT node for both the resets and clocks.

In the next version I am preparing, the defines doesn't look as
trivial as in this version, GPIOA_RESET being 128 for instance.

Is it fine for you if I keep the defines part of the binding?

Br,
Maxime
>
>         Arnd

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

* [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings
  2015-03-10 15:08   ` Arnd Bergmann
@ 2015-03-10 15:45     ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-10 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-10 16:08 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> On Friday 20 February 2015 19:01:11 Maxime Coquelin wrote:
>> +
>> +Example:
>> +usart1: usart at 40011000 {
>> +       compatible = "st,stm32-usart";
>>
>
> Please use generic node names everywhere. The standard name for a serial
> port is "serial".

I already had the remark, and it is already fixed in the next version.

Thanks,
Maxime

>
>         Arnd

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

* [PATCH v2 05/18] reset: Add reset_controller_of_init() function
  2015-03-10 15:28     ` Maxime Coquelin
@ 2015-03-10 20:19       ` Arnd Bergmann
  2015-03-10 21:30         ` Rob Herring
  0 siblings, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 20:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 March 2015 16:28:44 Maxime Coquelin wrote:
> 2015-03-10 16:00 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> > On Friday 20 February 2015 19:01:04 Maxime Coquelin wrote:
> >> Some platforms need to initialize the reset controller before the timers.
> >>
> >> This patch introduces a reset_controller_of_init() function that can be
> >> called before the timers intialization.
> >>
> >> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> >>
> >
> > Not sure about this. It seems like the cleanest approach if we get
> > a lot of these, but then again it is probably very rare, and I'd
> > like to avoid adding such infrastructure if it's just for one
> > SoC. Could we add a hack in the machine initialization instead?
> 
> Sun6i also need to initialize the reset controller early. Today, they
> hack the machine initialization.
> With two SoCs having the same need, what should we do?

Good question, I'd like to hear some other opinions on this first.

> > I think ideally this would be done in the boot loader before we
> > even start Linux, but I don't know if that's possible for you.
> 
> From what I understand, the only constraint is to perform it after the
> clock is enabled.
> So this should be possible to do it in the bootloader, but it means
> also adding timers clocks ungating in the bootloader.

Ungating the timer clock input seems like a reasonable thing to
do for the bootloader, I think a lot of platforms rely on this
elsewhere (but enough of them don't, which is why we have the
early clk init).

	Arnd

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-03-10 15:44     ` Maxime Coquelin
@ 2015-03-10 20:21       ` Arnd Bergmann
  2015-03-10 21:20         ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2015-03-10 20:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 10 March 2015 16:44:24 Maxime Coquelin wrote:
> 2015-03-10 16:02 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> > On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
> >> +/* AHB1 */
> >> +#define GPIOA_RESET    0
> >> +#define GPIOB_RESET    1
> >> +#define GPIOC_RESET    2
> >> +#define GPIOD_RESET    3
> >> +#define GPIOE_RESET    4
> >> +#define GPIOF_RESET    5
> >> +#define GPIOG_RESET    6
> >> +#define GPIOH_RESET    7
> >> +#define GPIOI_RESET    8
> >> +#define GPIOJ_RESET    9
> >> +#define GPIOK_RESET    10
> >>
> >
> > As these are just the hardware numbers, it's better to not make them
> > part of the binding at all. Instead, just document in the binding that
> > one is supposed to pass the hardware number as the argument.
> 
> The reset controller is part of the RCC (Reset & Clock Controller) IP.
> In this version, I only provided the reset registers to the reset
> controller driver, but as per Andreas F?rber remark, I should avec a
> single DT node for both the resets and clocks.
> 
> In the next version I am preparing, the defines doesn't look as
> trivial as in this version, GPIOA_RESET being 128 for instance.
> 
> Is it fine for you if I keep the defines part of the binding?
> 
> 

It's always better to avoid these files entirely, as they are
a frequent source of merge dependencies, and they make it less
obvious what's going on than having binary values in the dtb
that make sense.

	Arnd

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-03-10 20:21       ` Arnd Bergmann
@ 2015-03-10 21:20         ` Maxime Coquelin
  2015-03-11 13:08           ` Philipp Zabel
  0 siblings, 1 reply; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-10 21:20 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-10 21:21 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> On Tuesday 10 March 2015 16:44:24 Maxime Coquelin wrote:
>> 2015-03-10 16:02 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
>> > On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
>> >> +/* AHB1 */
>> >> +#define GPIOA_RESET    0
>> >> +#define GPIOB_RESET    1
>> >> +#define GPIOC_RESET    2
>> >> +#define GPIOD_RESET    3
>> >> +#define GPIOE_RESET    4
>> >> +#define GPIOF_RESET    5
>> >> +#define GPIOG_RESET    6
>> >> +#define GPIOH_RESET    7
>> >> +#define GPIOI_RESET    8
>> >> +#define GPIOJ_RESET    9
>> >> +#define GPIOK_RESET    10
>> >>
>> >
>> > As these are just the hardware numbers, it's better to not make them
>> > part of the binding at all. Instead, just document in the binding that
>> > one is supposed to pass the hardware number as the argument.
>>
>> The reset controller is part of the RCC (Reset & Clock Controller) IP.
>> In this version, I only provided the reset registers to the reset
>> controller driver, but as per Andreas F?rber remark, I should avec a
>> single DT node for both the resets and clocks.
>>
>> In the next version I am preparing, the defines doesn't look as
>> trivial as in this version, GPIOA_RESET being 128 for instance.
>>
>> Is it fine for you if I keep the defines part of the binding?
>>
>>
>
> It's always better to avoid these files entirely, as they are
> a frequent source of merge dependencies, and they make it less
> obvious what's going on than having binary values in the dtb
> that make sense.

I agree it is always painful to have to have to manage these merge dependencies.
What I will do, if Philipp agrees, is to list all the values in the
binding documentation.

Doing that, the user of a reset won't have to do the calculation, and
no more merge dependencies.

Maxime
>
>         Arnd

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

* [PATCH v2 05/18] reset: Add reset_controller_of_init() function
  2015-03-10 20:19       ` Arnd Bergmann
@ 2015-03-10 21:30         ` Rob Herring
  2015-03-12 21:08           ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Rob Herring @ 2015-03-10 21:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 10, 2015 at 3:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 10 March 2015 16:28:44 Maxime Coquelin wrote:
>> 2015-03-10 16:00 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
>> > On Friday 20 February 2015 19:01:04 Maxime Coquelin wrote:
>> >> Some platforms need to initialize the reset controller before the timers.
>> >>
>> >> This patch introduces a reset_controller_of_init() function that can be
>> >> called before the timers intialization.
>> >>
>> >> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> >>
>> >
>> > Not sure about this. It seems like the cleanest approach if we get
>> > a lot of these, but then again it is probably very rare, and I'd
>> > like to avoid adding such infrastructure if it's just for one
>> > SoC. Could we add a hack in the machine initialization instead?
>>
>> Sun6i also need to initialize the reset controller early. Today, they
>> hack the machine initialization.
>> With two SoCs having the same need, what should we do?
>
> Good question, I'd like to hear some other opinions on this first.

2 is still far from the common case.

>> > I think ideally this would be done in the boot loader before we
>> > even start Linux, but I don't know if that's possible for you.
>>
>> From what I understand, the only constraint is to perform it after the
>> clock is enabled.
>> So this should be possible to do it in the bootloader, but it means
>> also adding timers clocks ungating in the bootloader.
>
> Ungating the timer clock input seems like a reasonable thing to
> do for the bootloader, I think a lot of platforms rely on this
> elsewhere (but enough of them don't, which is why we have the
> early clk init).

+1

If the bootloader is u-boot, then you need a timer anyway.

Rob

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-03-10 21:20         ` Maxime Coquelin
@ 2015-03-11 13:08           ` Philipp Zabel
  2015-03-12 21:05             ` Maxime Coquelin
  0 siblings, 1 reply; 65+ messages in thread
From: Philipp Zabel @ 2015-03-11 13:08 UTC (permalink / raw)
  To: linux-arm-kernel

Am Dienstag, den 10.03.2015, 22:20 +0100 schrieb Maxime Coquelin:
> 2015-03-10 21:21 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> > On Tuesday 10 March 2015 16:44:24 Maxime Coquelin wrote:
> >> 2015-03-10 16:02 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
> >> > On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
> >> >> +/* AHB1 */
> >> >> +#define GPIOA_RESET    0
> >> >> +#define GPIOB_RESET    1
> >> >> +#define GPIOC_RESET    2
> >> >> +#define GPIOD_RESET    3
> >> >> +#define GPIOE_RESET    4
> >> >> +#define GPIOF_RESET    5
> >> >> +#define GPIOG_RESET    6
> >> >> +#define GPIOH_RESET    7
> >> >> +#define GPIOI_RESET    8
> >> >> +#define GPIOJ_RESET    9
> >> >> +#define GPIOK_RESET    10
> >> >>
> >> >
> >> > As these are just the hardware numbers, it's better to not make them
> >> > part of the binding at all. Instead, just document in the binding that
> >> > one is supposed to pass the hardware number as the argument.
> >>
> >> The reset controller is part of the RCC (Reset & Clock Controller) IP.
> >> In this version, I only provided the reset registers to the reset
> >> controller driver, but as per Andreas F?rber remark, I should avec a
> >> single DT node for both the resets and clocks.
> >>
> >> In the next version I am preparing, the defines doesn't look as
> >> trivial as in this version, GPIOA_RESET being 128 for instance.
> >>
> >> Is it fine for you if I keep the defines part of the binding?
> >>
> >>
> >
> > It's always better to avoid these files entirely, as they are
> > a frequent source of merge dependencies, and they make it less
> > obvious what's going on than having binary values in the dtb
> > that make sense.
> 
> I agree it is always painful to have to have to manage these merge dependencies.
> What I will do, if Philipp agrees, is to list all the values in the
> binding documentation.
> 
> Doing that, the user of a reset won't have to do the calculation, and
> no more merge dependencies.

I'd prefer to have #defines for the reset bits if they are named in the
documentation and use the names in the dts. But if you want to reference
reset bits by number in the device tree instead, I won't insist.

Consider using two cells in the phandle for register and bit offset
instead of a single number that arbitrarily starts at 128.

regards
Philipp

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

* [PATCH v2 07/18] drivers: reset: Add STM32 reset driver
  2015-03-11 13:08           ` Philipp Zabel
@ 2015-03-12 21:05             ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-12 21:05 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-11 14:08 GMT+01:00 Philipp Zabel <p.zabel@pengutronix.de>:
> Am Dienstag, den 10.03.2015, 22:20 +0100 schrieb Maxime Coquelin:
>> 2015-03-10 21:21 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
>> > On Tuesday 10 March 2015 16:44:24 Maxime Coquelin wrote:
>> >> 2015-03-10 16:02 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
>> >> > On Friday 20 February 2015 19:01:06 Maxime Coquelin wrote:
>> >> >> +/* AHB1 */
>> >> >> +#define GPIOA_RESET    0
>> >> >> +#define GPIOB_RESET    1
>> >> >> +#define GPIOC_RESET    2
>> >> >> +#define GPIOD_RESET    3
>> >> >> +#define GPIOE_RESET    4
>> >> >> +#define GPIOF_RESET    5
>> >> >> +#define GPIOG_RESET    6
>> >> >> +#define GPIOH_RESET    7
>> >> >> +#define GPIOI_RESET    8
>> >> >> +#define GPIOJ_RESET    9
>> >> >> +#define GPIOK_RESET    10
>> >> >>
>> >> >
>> >> > As these are just the hardware numbers, it's better to not make them
>> >> > part of the binding at all. Instead, just document in the binding that
>> >> > one is supposed to pass the hardware number as the argument.
>> >>
>> >> The reset controller is part of the RCC (Reset & Clock Controller) IP.
>> >> In this version, I only provided the reset registers to the reset
>> >> controller driver, but as per Andreas F?rber remark, I should avec a
>> >> single DT node for both the resets and clocks.
>> >>
>> >> In the next version I am preparing, the defines doesn't look as
>> >> trivial as in this version, GPIOA_RESET being 128 for instance.
>> >>
>> >> Is it fine for you if I keep the defines part of the binding?
>> >>
>> >>
>> >
>> > It's always better to avoid these files entirely, as they are
>> > a frequent source of merge dependencies, and they make it less
>> > obvious what's going on than having binary values in the dtb
>> > that make sense.
>>
>> I agree it is always painful to have to have to manage these merge dependencies.
>> What I will do, if Philipp agrees, is to list all the values in the
>> binding documentation.
>>
>> Doing that, the user of a reset won't have to do the calculation, and
>> no more merge dependencies.
>
> I'd prefer to have #defines for the reset bits if they are named in the
> documentation and use the names in the dts. But if you want to reference
> reset bits by number in the device tree instead, I won't insist.
>
> Consider using two cells in the phandle for register and bit offset
> instead of a single number that arbitrarily starts at 128.

Thanks for your feedback.

I would prefer using a single cell, which is less error prone in my opinion.
Will you accept this?

Kind regards,
Maxime

>
> regards
> Philipp
>

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

* [PATCH v2 05/18] reset: Add reset_controller_of_init() function
  2015-03-10 21:30         ` Rob Herring
@ 2015-03-12 21:08           ` Maxime Coquelin
  0 siblings, 0 replies; 65+ messages in thread
From: Maxime Coquelin @ 2015-03-12 21:08 UTC (permalink / raw)
  To: linux-arm-kernel

2015-03-10 22:30 GMT+01:00 Rob Herring <robherring2@gmail.com>:
> On Tue, Mar 10, 2015 at 3:19 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Tuesday 10 March 2015 16:28:44 Maxime Coquelin wrote:
>>> 2015-03-10 16:00 GMT+01:00 Arnd Bergmann <arnd@arndb.de>:
>>> > On Friday 20 February 2015 19:01:04 Maxime Coquelin wrote:
>>> >> Some platforms need to initialize the reset controller before the timers.
>>> >>
>>> >> This patch introduces a reset_controller_of_init() function that can be
>>> >> called before the timers intialization.
>>> >>
>>> >> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>>> >>
>>> >
>>> > Not sure about this. It seems like the cleanest approach if we get
>>> > a lot of these, but then again it is probably very rare, and I'd
>>> > like to avoid adding such infrastructure if it's just for one
>>> > SoC. Could we add a hack in the machine initialization instead?
>>>
>>> Sun6i also need to initialize the reset controller early. Today, they
>>> hack the machine initialization.
>>> With two SoCs having the same need, what should we do?
>>
>> Good question, I'd like to hear some other opinions on this first.
>
> 2 is still far from the common case.
>
>>> > I think ideally this would be done in the boot loader before we
>>> > even start Linux, but I don't know if that's possible for you.
>>>
>>> From what I understand, the only constraint is to perform it after the
>>> clock is enabled.
>>> So this should be possible to do it in the bootloader, but it means
>>> also adding timers clocks ungating in the bootloader.
>>
>> Ungating the timer clock input seems like a reasonable thing to
>> do for the bootloader, I think a lot of platforms rely on this
>> elsewhere (but enough of them don't, which is why we have the
>> early clk init).
>
> +1
>
> If the bootloader is u-boot, then you need a timer anyway.

Ok, I moved it to the bootloader, and use the reset as optional in the
timer driver.

Thanks,
Maxime
>
> Rob

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

* [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs
  2015-03-10 15:08   ` Arnd Bergmann
@ 2015-03-18  1:08     ` Linus Walleij
  0 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2015-03-18  1:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 10, 2015 at 4:08 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 20 February 2015 19:01:10 Maxime Coquelin wrote:

>> +/* Pull-Up/Down */
>> +#define NO_PULL                0
>> +#define PULL_UP                1
>> +#define PULL_DOWN      2
>> +
>> +/* Type */
>> +#define PUSH_PULL      (0 << 2)
>> +#define OPEN_DRAIN     (1 << 2)
>> +
>
> These should probably not be stm32 specific at all, they sound
> rather generic, so maybe put the definitions into a common file.

It's part of what GENERIC_PINCONF does and it has bindings
in Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

Yours,
Linus Walleij

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

end of thread, other threads:[~2015-03-18  1:08 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-20 18:00 [PATCH v2 00/18] Add support to STMicroelectronics STM32 family Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 01/18] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 02/18] ARM: ARMv7M: Enlarge vector table to 256 entries Maxime Coquelin
2015-02-20 19:47   ` Uwe Kleine-König
2015-02-23 10:33     ` Maxime Coquelin
2015-02-26 10:29       ` Maxime Coquelin
2015-02-26 10:43         ` Uwe Kleine-König
2015-03-09  0:29   ` Stefan Agner
2015-03-09 17:12     ` Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 03/18] dt-bindings: Document the ARM System timer bindings Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 04/18] clocksource: Add ARM System timer driver Maxime Coquelin
2015-02-20 19:54   ` Uwe Kleine-König
2015-02-20 21:48     ` Paul Bolle
2015-03-02 16:53       ` Maxime Coquelin
2015-03-03 19:43         ` Paul Bolle
2015-03-04 12:08           ` Maxime Coquelin
2015-03-09 21:12             ` Paul Bolle
2015-03-09 22:17               ` Uwe Kleine-König
2015-03-09 15:50   ` Linus Walleij
2015-03-09 17:00     ` Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 05/18] reset: Add reset_controller_of_init() function Maxime Coquelin
2015-03-10 15:00   ` Arnd Bergmann
2015-03-10 15:28     ` Maxime Coquelin
2015-03-10 20:19       ` Arnd Bergmann
2015-03-10 21:30         ` Rob Herring
2015-03-12 21:08           ` Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 06/18] dt-bindings: Document the STM32 reset bindings Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 07/18] drivers: reset: Add STM32 reset driver Maxime Coquelin
2015-03-10 15:02   ` Arnd Bergmann
2015-03-10 15:41     ` Maxime Coquelin
2015-03-10 15:44     ` Maxime Coquelin
2015-03-10 20:21       ` Arnd Bergmann
2015-03-10 21:20         ` Maxime Coquelin
2015-03-11 13:08           ` Philipp Zabel
2015-03-12 21:05             ` Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 08/18] dt-bindings: Document the STM32 timer bindings Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 09/18] clockevent: Add STM32 Timer driver Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 10/18] dt-bindings: Document the STM32 pin controller Maxime Coquelin
2015-03-06  9:12   ` Linus Walleij
2015-03-06  9:35   ` Linus Walleij
2015-02-20 18:01 ` [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs Maxime Coquelin
2015-03-06  9:24   ` Linus Walleij
2015-03-06  9:57     ` Maxime Coquelin
2015-03-10 15:08   ` Arnd Bergmann
2015-03-18  1:08     ` Linus Walleij
2015-02-20 18:01 ` [PATCH v2 12/18] dt-bindings: Document the STM32 USART bindings Maxime Coquelin
2015-03-10 15:08   ` Arnd Bergmann
2015-03-10 15:45     ` Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 13/18] serial: stm32-usart: Add STM32 USART Driver Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 14/18] ARM: Add STM32 family machine Maxime Coquelin
2015-02-20 18:33   ` Peter Meerwald
2015-02-25 11:52     ` Maxime Coquelin
2015-02-20 20:00   ` Uwe Kleine-König
2015-02-20 21:37     ` Paul Bolle
2015-02-25 12:04       ` Maxime Coquelin
2015-02-25 12:03     ` Maxime Coquelin
2015-03-10 15:10   ` Arnd Bergmann
2015-02-20 18:01 ` [PATCH v2 15/18] ARM: dts: Add ARM System timer as clockevent in armv7m Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 16/18] ARM: dts: Introduce STM32F429 MCU Maxime Coquelin
2015-03-02 17:42   ` Andreas Färber
2015-03-03 17:59     ` Maxime Coquelin
2015-03-09 14:39   ` Linus Walleij
2015-03-09 16:51     ` Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 17/18] ARM: configs: Add STM32 defconfig Maxime Coquelin
2015-02-20 18:01 ` [PATCH v2 18/18] MAINTAINERS: Add entry for STM32 MCUs Maxime Coquelin

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).