Add support to STMicroelectronics STM32 family
Subsystems (15)
Maxime Coquelin
maintainerv5 cover Add support to STMicroelectronics STM32 family
This fifth round only contains cosmetic fixes, and add some more Acks.
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 v4:
-----------------
- Cosmetic changes in USART driver (Andy)
- Apply Acks on reset driver & bindings (Philipp & Rob)
Changes since v3:
-----------------
- Fix and simplify error path in ARMv7-M Systick driver (Daniel)
- Improve reset bindings documentation (Philipp)
- Fix trailing lines anf typos in reset driver & doc (Philipp & Chanwoo)
- Fix MODULE_LICENCE in USART driver (Paul)
- Refactor USART baudrate calculation (Peter & Andy)
- Fix error path in USART init (Peter & Russell)
- Fix HW flow control in USART driver (Peter)
- Fix serial port type number to unused one (Peter)
- Applies Chanwoo's Tested-by on the series
Changes since v2:
-----------------
- Remove pinctrl driver from the series.
- Remove reset_controller_of_init(), and reset the timers in the bootloader
- Add HW flow contrl property for serial driver
- Lots of changes in the DTS file, as per Andreas recommendations
- Some Kconfig clean-ups
- Adapt the config to be compatible with Andreas' bootwrapper, except UART port.
- Various fixes in documentation
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 (15):
scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP
Kernel
ARM: ARMv7-M: Enlarge vector table up to 256 entries
dt-bindings: Document the ARM System timer bindings clocksource/drivers: Add ARM System timer driver
dt-bindings: Document the STM32 reset bindings
drivers: reset: Add STM32 reset driver
dt-bindings: Document the STM32 timer bindings clockevents/drivers: Add STM32 Timer driver
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/reset/st,stm32-rcc.txt | 107 +++ .../devicetree/bindings/serial/st,stm32-usart.txt | 32 + .../devicetree/bindings/timer/st,stm32-timer.txt | 22 + MAINTAINERS | 8 + arch/arm/Kconfig | 18 + arch/arm/Makefile | 1 + arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/armv7-m.dtsi | 6 + arch/arm/boot/dts/stm32f429-disco.dts | 71 ++ arch/arm/boot/dts/stm32f429.dtsi | 226 +++++++ arch/arm/configs/stm32_defconfig | 71 ++ arch/arm/kernel/entry-v7m.S | 13 +- arch/arm/mach-stm32/Makefile | 1 + arch/arm/mach-stm32/Makefile.boot | 3 + arch/arm/mach-stm32/board-dt.c | 19 + arch/arm/mm/Kconfig | 15 + drivers/clocksource/Kconfig | 15 + drivers/clocksource/Makefile | 2 + drivers/clocksource/armv7m_systick.c | 79 +++ drivers/clocksource/timer-stm32.c | 184 ++++++ drivers/reset/Makefile | 1 + drivers/reset/reset-stm32.c | 124 ++++ drivers/tty/serial/Kconfig | 17 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/stm32-usart.c | 736 +++++++++++++++++++++ include/uapi/linux/serial_core.h | 3 + scripts/link-vmlinux.sh | 2 +- 30 files changed, 1853 insertions(+), 5 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/reset/st,stm32-rcc.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/reset/reset-stm32.c create mode 100644 drivers/tty/serial/stm32-usart.c
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 1/15 scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel
When Kernel is executed in place from ROM, the symbol addresses can be lower than the page offset.
--- scripts/link-vmlinux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/link-vmlinux.sh +1 -1
@@ -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
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 2/15 ARM: ARMv7-M: Enlarge vector table up to 256 entries
In reply to Maxime CoquelinFrom 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.
--- arch/arm/kernel/entry-v7m.S | 13 +++++++++---- arch/arm/mm/Kconfig | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-)
arch/arm/kernel/entry-v7m.S +9 -4
@@ -117,9 +117,14 @@ ENTRY(__switch_to) ENDPROC(__switch_to) .data - .align 8 +#if CONFIG_CPU_V7M_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_CPU_V7M_NUM_IRQ + .long __irq_entry @ External Interrupts .endr
arch/arm/mm/Kconfig +15 -0
@@ -604,6 +604,21 @@ config CPU_USE_DOMAINS This option enables or disables the use of domain switching via the set_fs() function. +config CPU_V7M_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 #
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 3/15 dt-bindings: Document the ARM System timer bindings
In reply to Maxime CoquelinThis adds documentation of device tree bindings for the ARM System timer.
--- .../devicetree/bindings/arm/armv7m_systick.txt | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt
Documentation/devicetree/bindings/arm/armv7m_systick.txt new file +26 -0
@@ -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@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + clocks = <&clk_systick>; +}; + +systick: timer@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + clock-frequency = <90000000>; +};
Signature · 1 line
1.9.1
Re: [PATCH v5 03/15] dt-bindings: Document the ARM System timer bindings
Quoted 5 lines · Maxime Coquelin
This adds documentation of device tree bindings for the ARM System timer.
Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>
Quoted 40 lines
--- .../devicetree/bindings/arm/armv7m_systick.txt | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txtDocumentation/devicetree/bindings/arm/armv7m_systick.txt new file +26
-1@@ -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@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + clocks = <&clk_systick>; +}; + +systick: timer@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + clock-frequency = <90000000>; +}; --1.9.1
Maxime Coquelin
maintainerPATCH v5 4/15 clocksource/drivers: Add ARM System timer driver
In reply to Maxime CoquelinThis patch adds clocksource support for ARMv7-M's System timer, also known as SysTick.
--- drivers/clocksource/Kconfig | 7 ++++ drivers/clocksource/Makefile | 1 + drivers/clocksource/armv7m_systick.c | 79 ++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 drivers/clocksource/armv7m_systick.c
drivers/clocksource/Kconfig +7 -0
@@ -134,6 +134,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
drivers/clocksource/Makefile +1 -0
@@ -44,6 +44,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
drivers/clocksource/armv7m_systick.c new file +79 -0
79 lines not on this page · raw message
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 5/15 dt-bindings: Document the STM32 reset bindings
In reply to Maxime CoquelinThis adds documentation of device tree bindings for the STM32 reset controller.
--- .../devicetree/bindings/reset/st,stm32-rcc.txt | 107 +++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
Documentation/devicetree/bindings/reset/st,stm32-rcc.txt new file +107 -0
@@ -0,0 +1,107 @@ +STMicroelectronics STM32 Peripheral Reset Controller +==================================================== + +The RCC IP is both a reset and a clock controller. This documentation only +documents the reset part. + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "st,stm32-rcc" +- reg: should be register base and length as documented in the + datasheet +- #reset-cells: 1, see below + +example: + +rcc: reset@40023800 { + #reset-cells = <1>; + compatible = "st,stm32-rcc"; + reg = <0x40023800 0x400>; +}; + +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. +The index is the bit number within the RCC registers bank, starting from RCC +base address. +It is calculated as: index = register_offset / 4 * 32 + bit_offset. +Where bit_offset is the bit offset within the register. +For example, for CRC reset: + crc = AHB1RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x10 / 4 * 32 + 12 = 140 + +example: + + timer2 { + resets = <&rcc 256>; + }; + +List of valid indices for STM32F429: + - gpioa: 128 + - gpiob: 129 + - gpioc: 130 + - gpiod: 131 + - gpioe: 132 + - gpiof: 133 + - gpiog: 134 + - gpioh: 135 + - gpioi: 136 + - gpioj: 137 + - gpiok: 138 + - crc: 140 + - dma1: 149 + - dma2: 150 + - dma2d: 151 + - ethmac: 153 + - otghs: 157 + - dcmi: 160 + - cryp: 164 + - hash: 165 + - rng: 166 + - otgfs: 167 + - fmc: 192 + - tim2: 256 + - tim3: 257 + - tim4: 258 + - tim5: 259 + - tim6: 260 + - tim7: 261 + - tim12: 262 + - tim13: 263 + - tim14: 264 + - wwdg: 267 + - spi2: 270 + - spi3: 271 + - uart2: 273 + - uart3: 274 + - uart4: 275 + - uart5: 276 + - i2c1: 277 + - i2c2: 278 + - i2c3: 279 + - can1: 281 + - can2: 282 + - pwr: 284 + - dac: 285 + - uart7: 286 + - uart8: 287 + - tim1: 288 + - tim8: 289 + - usart1: 292 + - usart6: 293 + - adc: 296 + - sdio: 299 + - spi1: 300 + - spi4: 301 + - syscfg: 302 + - tim9: 304 + - tim10: 305 + - tim11: 306 + - spi5: 308 + - spi6: 309 + - sai1: 310 + - ltdc: 314
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 6/15 drivers: reset: Add STM32 reset driver
In reply to Maxime CoquelinThe STM32 MCUs family IPs can be reset by accessing some registers from the RCC block.
The list of available reset lines is documented in the DT bindings.
--- drivers/reset/Makefile | 1 + drivers/reset/reset-stm32.c | 124 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 drivers/reset/reset-stm32.c
drivers/reset/Makefile +1 -0
@@ -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/
drivers/reset/reset-stm32.c new file +124 -0
124 lines not on this page · raw message
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 7/15 dt-bindings: Document the STM32 timer bindings
In reply to Maxime CoquelinThis adds documentation of device tree bindings for the STM32 timer.
--- .../devicetree/bindings/timer/st,stm32-timer.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txt
Documentation/devicetree/bindings/timer/st,stm32-timer.txt new file +22 -0
@@ -0,0 +1,22 @@ +. 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 + +Optional properties: +- resets: Reference to a reset controller asserting the timer + +Example: + +timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; + resets = <&rrc 259>; + clocks = <&clk_pmtr1>; +};
Signature · 1 line
1.9.1
Re: [PATCH v5 07/15] dt-bindings: Document the STM32 timer bindings
Quoted 5 lines · Maxime Coquelin
This adds documentation of device tree bindings for the STM32 timer.
Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>
One minor thing below, otherwise:
Quoted 11 lines
--- .../devicetree/bindings/timer/st,stm32-timer.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txtDocumentation/devicetree/bindings/timer/st,stm32-timer.txt new file +0
-0
Documentation/devicetree/bindings/timer/st,stm32-timer.txt line 6
Quoted 6 lines
Documentation/devicetree/bindings/timer/st,stm32-timer.txt new file +6
-0@@ -0,0 +1,22 @@ +. STMicroelectronics STM32 timer + +The STM32 MCUs family has several general-purpose 16 and 32 bits timers. + +Required properties: +- compatible : Should be st,stm32-timer"
Missing quote
Quoted 19 lines
Documentation/devicetree/bindings/timer/st,stm32-timer.txt new file +16
-1+- reg : Address and length of the register set +- clocks : Reference on the timer input clock +- interrupts : Reference to the timer interrupt + +Optional properties: +- resets: Reference to a reset controller asserting the timer + +Example: + +timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; + resets = <&rrc 259>; + clocks = <&clk_pmtr1>; +}; --1.9.1
Maxime Coquelin
maintainerPATCH v5 8/15 clockevents/drivers: Add STM32 Timer driver
In reply to Maxime CoquelinSTM32 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.
--- drivers/clocksource/Kconfig | 8 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-stm32.c | 184 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/clocksource/timer-stm32.c
drivers/clocksource/Kconfig +8 -0
@@ -101,6 +101,14 @@ 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 event device. + config ARM_ARCH_TIMER bool select CLKSRC_OF if OF
drivers/clocksource/Makefile +1 -0
@@ -35,6 +35,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
drivers/clocksource/timer-stm32.c new file +184 -0
184 lines not on this page · raw message
Signature · 1 line
1.9.1
Re: [PATCH v5 08/15] clockevents/drivers: Add STM32 Timer driver
Quoted 4 lines · Maxime Coquelin
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.
Few comments below.
Quoted 145 lines
Reviewed-by Linus Walleij <[email protected]>Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>--- drivers/clocksource/Kconfig | 8 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-stm32.c | 184 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/clocksource/timer-stm32.cdrivers/clocksource/Kconfig +8
-0@@ -101,6 +101,14 @@ 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 event device. + config ARM_ARCH_TIMER bool select CLKSRC_OF if OFdrivers/clocksource/Makefile +1
-0@@ -35,6 +35,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.odrivers/clocksource/timer-stm32.c new file +98
-0@@ -0,0 +1,184 @@ +/* +* Copyright (C) Maxime Coquelin 2015 +* Author: Maxime Coquelin <[email protected]> +* 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) +{
drivers/clocksource/timer-stm32.c line 108
Quoted 10 lines
drivers/clocksource/timer-stm32.c new file +10
-0+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);
Why not dev_err(); ?
drivers/clocksource/timer-stm32.c line 115
Quoted 7 lines
drivers/clocksource/timer-stm32.c new file +7
-0+ goto err_clk_get; + } + + ret =clk_prepare_enable (clk); +if (ret) { +pr_err ("failed to enable timer clock for clockevent (%d)\n" , + ret);
Ditto.
Quoted 4 lines
drivers/clocksource/timer-stm32.c new file +4
-0+ goto err_clk_enable; + } + + rate =clk_get_rate (clk);
drivers/clocksource/timer-stm32.c line 129
Quoted 10 lines
drivers/clocksource/timer-stm32.c new file +10
-0+ + rstc =of_reset_control_get (np,NULL ); +if (!IS_ERR (rstc)) { +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" );
Ditto.
drivers/clocksource/timer-stm32.c line 135
Quoted 6 lines
drivers/clocksource/timer-stm32.c new file +6
-0+ goto err_iomap; + } + + irq =irq_of_parse_and_map (np,0 ); +if (!irq) { +pr_err ("%s: failed to get irq.\n" , np->full_name);
Ditto.
Quoted 20 lines
drivers/clocksource/timer-stm32.c new file +20
-0+ 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 ); +
drivers/clocksource/timer-stm32.c line 165
Quoted 10 lines
drivers/clocksource/timer-stm32.c new file +10
-0+ 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);
Ditto.
drivers/clocksource/timer-stm32.c line 170
Quoted 5 lines
drivers/clocksource/timer-stm32.c new file +5
-0+ goto err_get_irq; + } + +pr_info ("%s: STM32 clockevent driver initialized (%d bits)\n" , + np->full_name, bits);
dev_info(); ?
Quoted 17 lines
drivers/clocksource/timer-stm32.c new file +14
-1+ +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
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v5 08/15] clockevents/drivers: Add STM32 Timer driver
Quoted 5 lines · Andy Shevchenko
Quoted 3 lines · Maxime Coquelin
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.
[]
Quoted 3 lines
Quoted 1 line
+
pr_err("failed to get clock for clockevent (%d)\n", ret);Why not
dev_err(); ?
Understood, because it's device tree with lack of something like of_err();
Signature · 2 lines
With Best Regards, Andy Shevchenko
Maxime Coquelin
maintainerPATCH v5 9/15 dt-bindings: Document the STM32 USART bindings
In reply to Maxime CoquelinThis adds documentation of device tree bindings for the STM32 USART
--- .../devicetree/bindings/serial/st,stm32-usart.txt | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
Documentation/devicetree/bindings/serial/st,stm32-usart.txt new file +32 -0
@@ -0,0 +1,32 @@ +* STMicroelectronics STM32 USART + +Required properties: +- compatible: Can be either "st,stm32-usart" or "st,stm32-uart" depending on +whether the device supports synchronous mode. +- 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 + +Optional properties: +- pinctrl: The reference on the pins configuration +- st,hw-flow-ctrl: bool flag to enable hardware flow control. + +Examples: +usart4: serial@40004c00 { + compatible = "st,stm32-uart"; + reg = <0x40004c00 0x400>; + interrupts = <52>; + clocks = <&clk_pclk1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart4>; +}; + +usart2: serial@40004400 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40004400 0x400>; + interrupts = <38>; + clocks = <&clk_pclk1>; + st,hw-flow-ctrl; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>; +};
Signature · 1 line
1.9.1
Re: [PATCH v5 09/15] dt-bindings: Document the STM32 USART bindings
Quoted 18 lines · Maxime Coquelin
This adds documentation of device tree bindings for the STM32 USART
Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>--- .../devicetree/bindings/serial/st,stm32-usart.txt | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txtDocumentation/devicetree/bindings/serial/st,stm32-usart.txt new file +2
-0@@ -0,0 +1,32 @@ +* STMicroelectronics STM32 USART +
Documentation/devicetree/bindings/serial/st,stm32-usart.txt line 12
Quoted 10 lines
Documentation/devicetree/bindings/serial/st,stm32-usart.txt new file +10
-0+Required properties: +- compatible: Can be either "st,stm32-usart" or "st,stm32-uart" depending on +whether the device supports synchronous mode. +- 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 + +Optional properties: +- pinctrl: The reference on the pins configuration +- st,hw-flow-ctrl: bool flag to enable hardware flow control.
We already have "auto-flow-control" for 8250. Does that work for you?
Quoted 21 lines
Documentation/devicetree/bindings/serial/st,stm32-usart.txt new file +20
-1+ +Examples: +usart4: serial@40004c00 { + compatible = "st,stm32-uart"; + reg = <0x40004c00 0x400>; + interrupts = <52>; + clocks = <&clk_pclk1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart4>; +}; + +usart2: serial@40004400 { + compatible = "st,stm32-usart", "st,stm32-uart"; + reg = <0x40004400 0x400>; + interrupts = <38>; + clocks = <&clk_pclk1>; + st,hw-flow-ctrl; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>; +}; --
Quoted 2 lines
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Maxime Coquelin
maintainerRe: [PATCH v5 09/15] dt-bindings: Document the STM32 USART bindings
2015-04-03 19:14 GMT+02:00 Rob Herring <[email protected]>:
Quoted 24 lines
Quoted 22 lines · Maxime Coquelin
This adds documentation of device tree bindings for the STM32 USART
Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>--- .../devicetree/bindings/serial/st,stm32-usart.txt | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txtDocumentation/devicetree/bindings/serial/st,stm32-usart.txt new file +6
-0@@ -0,0 +1,32 @@ +* STMicroelectronics STM32 USART + +Required properties: +- compatible: Can be either "st,stm32-usart" or "st,stm32-uart" depending on +whether the device supports synchronous mode. +- reg: The address and length of the peripheral registers space
Quoted 8 lines
Documentation/devicetree/bindings/serial/st,stm32-usart.txt line 12
Quoted 6 lines
Documentation/devicetree/bindings/serial/st,stm32-usart.txt new file +6
-0+- interrupts: The interrupt line of the USART instance +- clocks: The input clock of the USART instance + +Optional properties: +- pinctrl: The reference on the pins configuration +- st,hw-flow-ctrl: bool flag to enable hardware flow control.We already have "auto-flow-control" for 8250. Does that work for you?
Yes it works, just that I didn't know about it.
I will change to "auto-flow-control" in next version.
Thanks,
Maxime
Maxime Coquelin
maintainerPATCH v5 10/15 serial: stm32-usart: Add STM32 USART Driver
In reply to Maxime CoquelinThis drivers adds support to the STM32 USART controller, which is a standard serial driver.
--- drivers/tty/serial/Kconfig | 17 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/stm32-usart.c | 736 +++++++++++++++++++++++++++++++++++++++ include/uapi/linux/serial_core.h | 3 + 4 files changed, 757 insertions(+) create mode 100644 drivers/tty/serial/stm32-usart.c
drivers/tty/serial/Kconfig +17 -0
@@ -1611,6 +1611,23 @@ config SERIAL_SPRD_CONSOLE with "earlycon" on the kernel command line. The console is enabled when early_param is processed. +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
drivers/tty/serial/Makefile +1 -0
@@ -95,6 +95,7 @@ obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o +obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
drivers/tty/serial/stm32-usart.c new file +736 -0
736 lines not on this page · raw message
include/uapi/linux/serial_core.h +3 -0
@@ -258,4 +258,7 @@/* Cris v10 / v32 SoC */ #define PORT_CRIS 112 +/* STM32 USART */ +#define PORT_STM32 113 +#endif /* _UAPILINUX_SERIAL_CORE_H */
Signature · 1 line
1.9.1
Re: [PATCH v5 10/15] serial: stm32-usart: Add STM32 USART Driver
Quoted 2 lines · Maxime Coquelin
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
PS - I saw Rob's comment about 'hw-flow-ctrl' vs 'auto-flow-control' and I'm ok with either so feel free to and my review comment to a v6 if that's the only change.
Joe Perches
maintainerRe: [PATCH v5 10/15] serial: stm32-usart: Add STM32 USART Driver
In reply to Maxime CoquelinQuoted 2 lines · Maxime Coquelin
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
trivia:
drivers/tty/serial/stm32-usart.c
Quoted 1 line
drivers/tty/serial/stm32-usart.c +0
-0
[]
Quoted 1 line
+static struct
uart_opsstm32_uart_ops= {
could be const
and it could be updated in a separate patch later too.
Joe Perches
maintainerPATCH 1/1 checkpatch: Add uart_ops to normally const structs
Add another struct to the list of normally const struct types
---
Quoted 9 lines · Joe Perches
Quoted 2 lines · Maxime Coquelin
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
trivia:
drivers/tty/serial/stm32-usart.c
Quoted 1 line
drivers/tty/serial/stm32-usart.c +0
-0[]
Quoted 1 line
+static struct
uart_opsstm32_uart_ops= {could be const
and it could be updated in a separate patch later too.
scripts/checkpatch.pl | 1 + 1 file changed, 1 insertion(+)
scripts/checkpatch.pl +1 -0
@@ -5338,6 +5338,7 @@ sub process { stacktrace_ops| sysfs_ops| tty_operations| + uart_ops| usb_mon_operations| wd_ops}x; if ($line !~ /\bconst\b/ &&
Re: [PATCH] checkpatch: Add uart_ops to normally const structs
Hi Joe,
2015-04-04 19:47 GMT+02:00 Joe Perches <[email protected]>:
Quoted 10 lines
Add another struct to the list of normally const struct types
Signed-off-by Joe Perches <[email protected]>---
Quoted 4 lines · Joe Perches
Quoted 2 lines · Maxime Coquelin
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
trivia:
Quoted 9 lines
Quoted 5 lines
drivers/tty/serial/stm32-usart.c
Quoted 1 line
drivers/tty/serial/stm32-usart.c +0
-0[]
Quoted 1 line
+static struct
uart_opsstm32_uart_ops= {could be const
and it could be updated in a separate patch later too.scripts/checkpatch.pl | 1 + 1 file changed, 1 insertion(+)
For what it's worth, you can add:
Regards,
Maxime
Maxime Coquelin
maintainerRe: [PATCH v5 10/15] serial: stm32-usart: Add STM32 USART Driver
In reply to Joe Perches2015-04-03 19:43 GMT+02:00 Joe Perches <[email protected]>:
Quoted 11 lines · Maxime Coquelin
Quoted 2 lines
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
trivia:
drivers/tty/serial/stm32-usart.c
Quoted 1 line
drivers/tty/serial/stm32-usart.c +0
-0[]
Quoted 1 line
+static struct
uart_opsstm32_uart_ops= {could be const
i would even say, should be const.
Quoted 3 lines
and it could be updated in a separate patch later too.
Nope, I will send another version anyway, so it will be part of the v6.
Thanks for the review,
Maxime
Re: [PATCH v5 10/15] serial: stm32-usart: Add STM32 USART Driver
In reply to Maxime CoquelinQuoted 3 lines · Maxime Coquelin
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
Few minor comments.
Quoted 323 lines
Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>--- drivers/tty/serial/Kconfig | 17 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/stm32-usart.c | 736 +++++++++++++++++++++++++++++++++++++++ include/uapi/linux/serial_core.h | 3 + 4 files changed, 757 insertions(+) create mode 100644 drivers/tty/serial/stm32-usart.cdrivers/tty/serial/Kconfig +17
-0@@ -1611,6 +1611,23 @@ config SERIAL_SPRD_CONSOLE with "earlycon" on the kernel command line. The console is enabled when early_param is processed. +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_GPIOdrivers/tty/serial/Makefile +1
-0@@ -95,6 +95,7 @@ obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o +obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o # GPIOLIB helpers for modem control lines obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.odrivers/tty/serial/stm32-usart.c new file +267
-0@@ -0,0 +1,736 @@ +/* +* Copyright (C) Maxime Coquelin 2015 +* Author: Maxime Coquelin <[email protected]> +* 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; +bool hw_flow_control; +}; + +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 inline struct stm32_port *to_stm32_port (struct uart_port *port) +{ + return container_of(port, struct stm32_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) +{ +if ((mctrl &TIOCM_RTS ) && (port->status &UPSTAT_AUTORTS )) +stm32_set_bits (port,USART_CR3 ,USART_CR3_RTSE ); +else +stm32_clr_bits (port,USART_CR3 ,USART_CR3_RTSE ); +} + +static unsigned int stm32_get_mctrl (struct uart_port *port) +{ +/* This routine is used to get signals of: DCD, DSR, RI, and CTS */
drivers/tty/serial/stm32-usart.c line 277
Quoted 10 lines
drivers/tty/serial/stm32-usart.c new file +10
-0+return TIOCM_CAR |TIOCM_DSR |TIOCM_CTS ; +} + +/* Transmit stop */ +static void stm32_stop_tx (struct uart_port *port) +{ +stm32_clr_bits (port,USART_CR1 ,USART_CR1_TXEIE ); +} + +
Unneeded empty line.
Quoted 39 lines
drivers/tty/serial/stm32-usart.c new file +39
-0+/* 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 ); +} + +/* Throttle the remote when input buffer is about to overflow. */ +static void stm32_throttle (struct uart_port *port) +{ +unsigned long flags; + +spin_lock_irqsave (&port->lock, flags); +stm32_clr_bits (port,USART_CR1 ,USART_CR1_RXNEIE ); +spin_unlock_irqrestore (&port->lock, flags); +} + +/* Unthrottle the remote, the input buffer can now accept data. */ +static void stm32_unthrottle (struct uart_port *port) +{ +unsigned long flags; + +spin_lock_irqsave (&port->lock, flags); +stm32_set_bits (port,USART_CR1 ,USART_CR1_RXNEIE ); +spin_unlock_irqrestore (&port->lock, flags); +} + +/* 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)
drivers/tty/serial/stm32-usart.c line 326
Quoted 10 lines
drivers/tty/serial/stm32-usart.c new file +10
-0+{ +} + +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)) {
I think you have to propogate returned value, thus ret = request_irq();
if (ret < 0)
return ret;
Quoted 111 lines
drivers/tty/serial/stm32-usart.c new file +111
-0+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) +{ +struct stm32_port *stm32_port =to_stm32_port (port); +unsigned int baud; +u32 usartdiv, mantissa, fraction, oversampling; +tcflag_t cflag = termios->c_cflag; +u32 cr1, cr2, cr3; +unsigned long flags; + +if (!stm32_port->hw_flow_control) + cflag &= ~CRTSCTS ; + + baud =uart_get_baud_rate (port, termios, old,0 , port->uartclk /8 ); + +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 ; + + port->status &= ~(UPSTAT_AUTOCTS |UPSTAT_AUTORTS ); +if (cflag &CRTSCTS ) { + port->status |=UPSTAT_AUTOCTS |UPSTAT_AUTORTS ; + cr3 =USART_CR3_CTSE ; + } + + usartdiv =DIV_ROUND_CLOSEST (port->uartclk, baud); + +/* +* The USART supports 16 or 8 times oversampling. +* By default we prefer 16 times oversampling, so that the receiver +* has a better tolerance to clock deviations. +* 8 times oversampling is only used to achieve higher speeds. +*/ +if (usartdiv <16 ) { + oversampling =8 ; +stm32_set_bits (port,USART_CR1 ,USART_CR1_OVER8 ); + }else { + oversampling =16 ; +stm32_clr_bits (port,USART_CR1 ,USART_CR1_OVER8 ); + } + + mantissa = (usartdiv / oversampling) <<USART_BRR_DIV_M_SHIFT ; + fraction = usartdiv % oversampling; +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);
drivers/tty/serial/stm32-usart.c line 447
Quoted 10 lines
drivers/tty/serial/stm32-usart.c new file +10
-0+} + +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) +{ +}
Doesn't core handle NULL-functions? If it does, remove such from the driver.
drivers/tty/serial/stm32-usart.c line 452
Quoted 5 lines
drivers/tty/serial/stm32-usart.c new file +5
-0+ +static int stm32_request_port (struct uart_port *port) +{ +return 0 ; +}
Ditto.
Quoted 299 lines
drivers/tty/serial/stm32-usart.c new file +284
-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, + .stop_tx = stm32_stop_tx, + .start_tx = stm32_start_tx, + .throttle = stm32_throttle, + .unthrottle = stm32_unthrottle, + .stop_rx = stm32_stop_rx, + .break_ctl = stm32_break_ctl, + .startup = stm32_startup, + .shutdown = stm32_shutdown, + .set_termios = stm32_set_termios, + .pm = stm32_pm, + .type = stm32_type, + .release_port = stm32_release_port, + .request_port = stm32_request_port, + .config_port = stm32_config_port, + .verify_port = stm32_verify_port, +}; + +static int stm32_init_port (struct stm32_port *stm32port, +struct platform_device *pdev) +{ +struct uart_port *port = &stm32port->port; +struct resource *res; +int ret; + + 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 (IS_ERR (stm32port->clk)) +return PTR_ERR (stm32port->clk); + +/* Ensure that clk rate is correct by enabling the clk */ + ret =clk_prepare_enable (stm32port->clk); +if (ret) +return ret; + + stm32port->port.uartclk =clk_get_rate (stm32port->clk); +if (!stm32port->port.uartclk) + ret = -EINVAL ; + +clk_disable_unprepare (stm32port->clk); + +return ret; +} + +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,"serial" ); +if (id <0 ) + id =0 ; + +if (WARN_ON (id >=STM32_MAX_PORTS )) +return NULL ; + + stm32_ports[id].hw_flow_control =of_property_read_bool (np, +"st,hw-flow-control" ); + stm32_ports[id].port.line = id; +return &stm32_ports[id]; +} + +#ifdef CONFIG_OF +static const struct of_device_id stm32_match[] = { + { .compatible ="st,stm32-usart" , }, + { .compatible ="st,stm32-uart" , }, + {}, +}; + +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 = { + .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 , + .of_match_table =of_match_ptr (stm32_match), + }, +}; + +static int __init usart_init (void ) +{ +static char banner[]__initdata ="STM32 USART driver initialized" ; +int ret; + +pr_info ("%s\n" , 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 v2" );include/uapi/linux/serial_core.h +3
-1@@ -258,4 +258,7 @@/* Cris v10 / v32 SoC */ #define PORT_CRIS 112 +/* STM32 USART */ +#define PORT_STM32 113 +#endif /* _UAPILINUX_SERIAL_CORE_H */ --1.9.1
Signature · 2 lines
With Best Regards, Andy Shevchenko
Maxime Coquelin
maintainerRe: [PATCH v5 10/15] serial: stm32-usart: Add STM32 USART Driver
2015-04-04 0:04 GMT+02:00 Andy Shevchenko <[email protected]>:
Quoted 25 lines
Quoted 3 lines · Maxime Coquelin
This drivers adds support to the STM32 USART controller, which is a standard serial driver.
Few minor comments.
Quoted 17 lines
Tested-by Chanwoo Choi <[email protected]>Signed-off-by Maxime Coquelin <[email protected]>--- drivers/tty/serial/Kconfig | 17 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/stm32-usart.c | 736 +++++++++++++++++++++++++++++++++++++++ include/uapi/linux/serial_core.h | 3 + 4 files changed, 757 insertions(+) create mode 100644 drivers/tty/serial/stm32-usart.cdrivers/tty/serial/stm32-usart.c new file +0
-0@@ -0,0 +1,736 @@
...
Quoted 8 lines
Quoted 8 lines
drivers/tty/serial/stm32-usart.c new file +8
-0+ +static unsigned int stm32_get_mctrl (struct uart_port *port) +{ +/* This routine is used to get signals of: DCD, DSR, RI, and CTS */ +return TIOCM_CAR |TIOCM_DSR |TIOCM_CTS ; +} + +/* Transmit stop */
Quoted 8 lines
drivers/tty/serial/stm32-usart.c line 277
Quoted 6 lines
drivers/tty/serial/stm32-usart.c new file +6
-0+static void stm32_stop_tx (struct uart_port *port) +{ +stm32_clr_bits (port,USART_CR1 ,USART_CR1_TXEIE ); +} + +Unneeded empty line.
Right, will be removed.
Quoted 1 line
...
Quoted 5 lines
Quoted 5 lines
drivers/tty/serial/stm32-usart.c new file +5
-0+ +static int stm32_startup (struct uart_port *port) +{ +const char *name =to_platform_device (port->dev)->name; +u32 val;
Quoted 8 lines
drivers/tty/serial/stm32-usart.c line 326
Quoted 3 lines
drivers/tty/serial/stm32-usart.c new file +3
-0+ +if (request_irq (port->irq, stm32_interrupt,IRQF_NO_SUSPEND , + name, port)) {I think you have to propogate returned value, thus ret =
request_irq();
if (ret < 0)
return ret;
Exact, I will fix this.
Quoted 1 line
...
Quoted 11 lines
drivers/tty/serial/stm32-usart.c line 447
Quoted 9 lines
drivers/tty/serial/stm32-usart.c new file +9
-0+ +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) +{ +}Doesn't core handle NULL-functions? If it does, remove such from the driver.
No it does not.
Quoted 8 lines
drivers/tty/serial/stm32-usart.c line 452
Quoted 6 lines
drivers/tty/serial/stm32-usart.c new file +5
-0+ +static int stm32_request_port (struct uart_port *port) +{ +return 0 ; +}Ditto.
Ditto.
Thanks for the review,
Maxime
Quoted 6 lines
--
With Best Regards,
Andy Shevchenko
Maxime Coquelin
maintainerPATCH v5 11/15 ARM: Add STM32 family machine
In reply to Maxime CoquelinSTMicrolectronics's STM32 series is a family of Cortex-M microcontrollers. It is used in various applications, and proposes a wide range of peripherals.
--- Documentation/arm/stm32/overview.txt | 32 ++++++++++++++++++++++++++ Documentation/arm/stm32/stm32f429-overview.txt | 22 ++++++++++++++++++ arch/arm/Kconfig | 18 +++++++++++++++ arch/arm/Makefile | 1 + arch/arm/mach-stm32/Makefile | 1 + arch/arm/mach-stm32/Makefile.boot | 3 +++ arch/arm/mach-stm32/board-dt.c | 19 +++++++++++++++ 7 files changed, 96 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
Documentation/arm/stm32/overview.txt new file +32 -0
@@ -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 <[email protected]>
Documentation/arm/stm32/stm32f429-overview.txt new file +22 -0
@@ -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 <[email protected]>
arch/arm/Kconfig +18 -0
@@ -776,6 +776,24 @@ config ARCH_OMAP1 help Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx) +config ARCH_STM32 + bool "STMicrolectronics STM32" + depends on !MMU + select ARCH_HAS_RESET_CONTROLLER + select ARM_NVIC + select ARMV7M_SYSTICK + select AUTO_ZRELADDR + select CLKSRC_OF + select COMMON_CLK + select CPU_V7M + select GENERIC_CLOCKEVENTS + select NO_IOPORT_MAP + select RESET_CONTROLLER + select SPARSE_IRQ + select USE_OF + help + Support for STMicroelectronics STM32 processors. + endchoice menu "Multiple platform selection"
arch/arm/Makefile +1 -0
@@ -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
arch/arm/mach-stm32/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-y += board-dt.o
arch/arm/mach-stm32/Makefile.boot new file +3 -0
@@ -0,0 +1,3 @@ +# Empty file waiting for deletion once Makefile.boot isn't needed any more. +# Patch waits for application at +# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
arch/arm/mach-stm32/board-dt.c new file +19 -0
@@ -0,0 +1,19 @@ +/* +* Copyright (C) Maxime Coquelin 2015 +* Author: Maxime Coquelin <[email protected]> +* License terms: GNU General Public License (GPL), version 2 +*/ + +#include <linux/kernel.h> +#include <asm/v7m.h> +#include <asm/mach/arch.h> + +static const char *const stm32_compat[]__initconst = { +"st,stm32f429" , +NULL +}; + +DT_MACHINE_START (STM32DT ,"STM32 (Device Tree Support)" ) + .dt_compat = stm32_compat, + .restart = armv7m_restart, +MACHINE_END
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 12/15 ARM: dts: Add ARM System timer as clockevent in armv7m
In reply to Maxime Coquelin--- arch/arm/boot/dts/armv7-m.dtsi | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/boot/dts/armv7-m.dtsi +6 -0
@@ -8,6 +8,12 @@ reg = <0xe000e100 0xc00>; }; + systick: timer@e000e010 { + compatible = "arm,armv7m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + soc { #address-cells = <1>; #size-cells = <1>;
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 13/15 ARM: dts: Introduce STM32F429 MCU
In reply to Maxime CoquelinThe 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
--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/stm32f429-disco.dts | 71 +++++++++++ arch/arm/boot/dts/stm32f429.dtsi | 226 ++++++++++++++++++++++++++++++++++ 3 files changed, 298 insertions(+) create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
arch/arm/boot/dts/Makefile +1 -0
@@ -509,6 +509,7 @@ dtb-$(CONFIG_ARCH_STI) += \ stih416-b2020.dtb \ stih416-b2020e.dtb \ stih418-b2199.dtb +dtb-$(CONFIG_ARCH_STM32)+= stm32f429-disco.dtb dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-a1000.dtb \ sun4i-a10-ba10-tvbox.dtb \
arch/arm/boot/dts/stm32f429-disco.dts new file +71 -0
71 lines not on this page · raw message
arch/arm/boot/dts/stm32f429.dtsi new file +226 -0
226 lines not on this page · raw message
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 14/15 ARM: configs: Add STM32 defconfig
In reply to Maxime CoquelinThis patch adds a new config for STM32 MCUs.
STM32F429 Discovery board boots successfully with this config applied.
--- arch/arm/configs/stm32_defconfig | 71 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 arch/arm/configs/stm32_defconfig
arch/arm/configs/stm32_defconfig new file +71 -0
@@ -0,0 +1,71 @@ +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=0x90000000 +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=0x08008000 +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_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
Signature · 1 line
1.9.1
Maxime Coquelin
maintainerPATCH v5 15/15 MAINTAINERS: Add entry for STM32 MCUs
In reply to Maxime CoquelinAdd a MAINTAINER entry covering all STM32 machine and drivers files.
--- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+)
MAINTAINERS +8 -0
@@ -1467,6 +1467,14 @@ 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 <[email protected]> +L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers) +S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git +N: stm32 +F: drivers/clocksource/armv7m_systick.c + ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT M: Lennert Buytenhek <kernel-OLH4Qvv75CYX/[email protected]> L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
Signature · 6 lines
1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html