* [PATCH 00/11] STM32 USART: fixes and new MCU support
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
This series adds some fixes for stm32 uart, add DMA support for improve IP
behaviour, and add usart support of STM32F7 MCU.
Regards
Alex
Alexandre TORGUE (11):
serial: stm32: adding support for stm32f7
DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
serial: stm32: header file creation
serial: stm32: disable tx and rx during shutdown
serial: stm32: correct flow control property spelling
serial: stm32: clock disabling management
dt-bindings: Add DMA bindings for STM32 USART
serial: stm32: adding dma support
serial: stm32: fix spin_lock management
serial: stm32: fix uart enable management
ARM: DT: STM32: add dma for usart1 on F429
.../devicetree/bindings/serial/st,stm32-usart.txt | 46 ++
arch/arm/boot/dts/stm32f429.dtsi | 3 +
drivers/tty/serial/stm32-usart.c | 612 ++++++++++++++++-----
drivers/tty/serial/stm32-usart.h | 229 ++++++++
4 files changed, 739 insertions(+), 151 deletions(-)
create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
create mode 100644 drivers/tty/serial/stm32-usart.h
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 00/11] STM32 USART: fixes and new MCU support
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
This series adds some fixes for stm32 uart, add DMA support for improve IP
behaviour, and add usart support of STM32F7 MCU.
Regards
Alex
Alexandre TORGUE (11):
serial: stm32: adding support for stm32f7
DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
serial: stm32: header file creation
serial: stm32: disable tx and rx during shutdown
serial: stm32: correct flow control property spelling
serial: stm32: clock disabling management
dt-bindings: Add DMA bindings for STM32 USART
serial: stm32: adding dma support
serial: stm32: fix spin_lock management
serial: stm32: fix uart enable management
ARM: DT: STM32: add dma for usart1 on F429
.../devicetree/bindings/serial/st,stm32-usart.txt | 46 ++
arch/arm/boot/dts/stm32f429.dtsi | 3 +
drivers/tty/serial/stm32-usart.c | 612 ++++++++++++++++-----
drivers/tty/serial/stm32-usart.h | 229 ++++++++
4 files changed, 739 insertions(+), 151 deletions(-)
create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
create mode 100644 drivers/tty/serial/stm32-usart.h
--
1.9.1
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 01/11] serial: stm32: adding support for stm32f7
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Register offset management rework to support both
stm32f4 (default) and stm32f7. Driver rework to
ensure same functional level on both stm32f4 and
stm32f7: no new feature in this version yet.
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index f89d1f7..e7ffd01 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) Maxime Coquelin 2015
- * Author: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Authors: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
* License terms: GNU General Public License (GPL), version 2
*
* Inspired by st-asc.c from STMicroelectronics (c)
@@ -29,16 +30,74 @@
#define DRIVER_NAME "stm32-usart"
+struct stm32_usart_offsets {
+ u8 cr1;
+ u8 cr2;
+ u8 cr3;
+ u8 brr;
+ u8 gtpr;
+ u8 rtor;
+ u8 rqr;
+ u8 isr;
+ u8 icr;
+ u8 rdr;
+ u8 tdr;
+};
+
+struct stm32_usart_config {
+ u8 uart_enable_bit; /* USART_CR1_UE */
+ bool has_7bits_data;
+};
+
+struct stm32_usart_info {
+ struct stm32_usart_offsets ofs;
+ struct stm32_usart_config cfg;
+};
+
+#define UNDEF_REG ~0
+
/* 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 */
+struct stm32_usart_info stm32f4_info = {
+ .ofs = {
+ .isr = 0x00,
+ .rdr = 0x04,
+ .tdr = 0x04,
+ .brr = 0x08,
+ .cr1 = 0x0c,
+ .cr2 = 0x10,
+ .cr3 = 0x14,
+ .gtpr = 0x18,
+ .rtor = UNDEF_REG,
+ .rqr = UNDEF_REG,
+ .icr = UNDEF_REG,
+ },
+ .cfg = {
+ .uart_enable_bit = 13,
+ .has_7bits_data = false,
+ }
+};
+
+struct stm32_usart_info stm32f7_info = {
+ .ofs = {
+ .cr1 = 0x00,
+ .cr2 = 0x04,
+ .cr3 = 0x08,
+ .brr = 0x0c,
+ .gtpr = 0x10,
+ .rtor = 0x14,
+ .rqr = 0x18,
+ .isr = 0x1c,
+ .icr = 0x20,
+ .rdr = 0x24,
+ .tdr = 0x28,
+ },
+ .cfg = {
+ .uart_enable_bit = 0,
+ .has_7bits_data = true,
+ }
+};
+
+/* USART_SR (F4) / USART_ISR (F7) */
#define USART_SR_PE BIT(0)
#define USART_SR_FE BIT(1)
#define USART_SR_NF BIT(2)
@@ -48,7 +107,16 @@
#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_CTSIF BIT(9)
+#define USART_SR_CTS BIT(10) /* F7 */
+#define USART_SR_RTOF BIT(11) /* F7 */
+#define USART_SR_EOBF BIT(12) /* F7 */
+#define USART_SR_ABRE BIT(14) /* F7 */
+#define USART_SR_ABRF BIT(15) /* F7 */
+#define USART_SR_BUSY BIT(16) /* F7 */
+#define USART_SR_CMF BIT(17) /* F7 */
+#define USART_SR_SBKF BIT(18) /* F7 */
+#define USART_SR_TEACK BIT(21) /* F7 */
#define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \
USART_SR_FE | USART_SR_PE)
/* Dummy bits */
@@ -64,7 +132,7 @@
/* USART_CR1 */
#define USART_CR1_SBK BIT(0)
-#define USART_CR1_RWU BIT(1)
+#define USART_CR1_RWU BIT(1) /* F4 */
#define USART_CR1_RE BIT(2)
#define USART_CR1_TE BIT(3)
#define USART_CR1_IDLEIE BIT(4)
@@ -76,12 +144,20 @@
#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_M0 BIT(12) /* F7 */
+#define USART_CR1_MME BIT(13) /* F7 */
+#define USART_CR1_CMIE BIT(14) /* F7 */
#define USART_CR1_OVER8 BIT(15)
-#define USART_CR1_IE_MASK GENMASK(8, 4)
+#define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */
+#define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */
+#define USART_CR1_RTOIE BIT(26) /* F7 */
+#define USART_CR1_EOBIE BIT(27) /* F7 */
+#define USART_CR1_M1 BIT(28) /* F7 */
+#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
/* USART_CR2 */
-#define USART_CR2_ADD_MASK GENMASK(3, 0)
+#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
+#define USART_CR2_ADDM7 BIT(4) /* F7 */
#define USART_CR2_LBDL BIT(5)
#define USART_CR2_LBDIE BIT(6)
#define USART_CR2_LBCL BIT(8)
@@ -91,6 +167,15 @@
#define USART_CR2_STOP_2B BIT(13)
#define USART_CR2_STOP_MASK GENMASK(13, 12)
#define USART_CR2_LINEN BIT(14)
+#define USART_CR2_SWAP BIT(15) /* F7 */
+#define USART_CR2_RXINV BIT(16) /* F7 */
+#define USART_CR2_TXINV BIT(17) /* F7 */
+#define USART_CR2_DATAINV BIT(18) /* F7 */
+#define USART_CR2_MSBFIRST BIT(19) /* F7 */
+#define USART_CR2_ABREN BIT(20) /* F7 */
+#define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */
+#define USART_CR2_RTOEN BIT(23) /* F7 */
+#define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */
/* USART_CR3 */
#define USART_CR3_EIE BIT(0)
@@ -105,18 +190,47 @@
#define USART_CR3_CTSE BIT(9)
#define USART_CR3_CTSIE BIT(10)
#define USART_CR3_ONEBIT BIT(11)
+#define USART_CR3_OVRDIS BIT(12) /* F7 */
+#define USART_CR3_DDRE BIT(13) /* F7 */
+#define USART_CR3_DEM BIT(14) /* F7 */
+#define USART_CR3_DEP BIT(15) /* F7 */
+#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
/* USART_GTPR */
#define USART_GTPR_PSC_MASK GENMASK(7, 0)
#define USART_GTPR_GT_MASK GENMASK(15, 8)
-#define DRIVER_NAME "stm32-usart"
+/* USART_RTOR */
+#define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */
+#define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */
+
+/* USART_RQR */
+#define USART_RQR_ABRRQ BIT(0) /* F7 */
+#define USART_RQR_SBKRQ BIT(1) /* F7 */
+#define USART_RQR_MMRQ BIT(2) /* F7 */
+#define USART_RQR_RXFRQ BIT(3) /* F7 */
+#define USART_RQR_TXFRQ BIT(4) /* F7 */
+
+/* USART_ICR */
+#define USART_ICR_PECF BIT(0) /* F7 */
+#define USART_ICR_FFECF BIT(1) /* F7 */
+#define USART_ICR_NCF BIT(2) /* F7 */
+#define USART_ICR_ORECF BIT(3) /* F7 */
+#define USART_ICR_IDLECF BIT(4) /* F7 */
+#define USART_ICR_TCCF BIT(6) /* F7 */
+#define USART_ICR_LBDCF BIT(8) /* F7 */
+#define USART_ICR_CTSCF BIT(9) /* F7 */
+#define USART_ICR_RTOCF BIT(11) /* F7 */
+#define USART_ICR_EOBCF BIT(12) /* F7 */
+#define USART_ICR_CMCF BIT(17) /* F7 */
+
#define STM32_SERIAL_NAME "ttyS"
#define STM32_MAX_PORTS 6
struct stm32_port {
struct uart_port port;
struct clk *clk;
+ struct stm32_usart_info *info;
bool hw_flow_control;
};
@@ -151,6 +265,8 @@ static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
static void stm32_receive_chars(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long c;
u32 sr;
char flag;
@@ -158,9 +274,9 @@ static void stm32_receive_chars(struct uart_port *port)
if (port->irq_wake)
pm_wakeup_event(tport->tty->dev, 0);
- while ((sr = readl_relaxed(port->membase + USART_SR)) & USART_SR_RXNE) {
+ while ((sr = readl_relaxed(port->membase + ofs->isr)) & USART_SR_RXNE) {
sr |= USART_SR_DUMMY_RX;
- c = readl_relaxed(port->membase + USART_DR);
+ c = readl_relaxed(port->membase + ofs->rdr);
flag = TTY_NORMAL;
port->icount.rx++;
@@ -170,6 +286,10 @@ static void stm32_receive_chars(struct uart_port *port)
if (uart_handle_break(port))
continue;
} else if (sr & USART_SR_ORE) {
+ if (ofs->icr != UNDEF_REG)
+ writel_relaxed(USART_ICR_ORECF,
+ port->membase +
+ ofs->icr);
port->icount.overrun++;
} else if (sr & USART_SR_PE) {
port->icount.parity++;
@@ -199,10 +319,12 @@ static void stm32_receive_chars(struct uart_port *port)
static void stm32_transmit_chars(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
struct circ_buf *xmit = &port->state->xmit;
if (port->x_char) {
- writel_relaxed(port->x_char, port->membase + USART_DR);
+ writel_relaxed(port->x_char, port->membase + ofs->tdr);
port->x_char = 0;
port->icount.tx++;
return;
@@ -218,7 +340,7 @@ static void stm32_transmit_chars(struct uart_port *port)
return;
}
- writel_relaxed(xmit->buf[xmit->tail], port->membase + USART_DR);
+ writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
@@ -232,11 +354,13 @@ static void stm32_transmit_chars(struct uart_port *port)
static irqreturn_t stm32_interrupt(int irq, void *ptr)
{
struct uart_port *port = ptr;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
spin_lock(&port->lock);
- sr = readl_relaxed(port->membase + USART_SR);
+ sr = readl_relaxed(port->membase + ofs->isr);
if (sr & USART_SR_RXNE)
stm32_receive_chars(port);
@@ -251,15 +375,21 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
static unsigned int stm32_tx_empty(struct uart_port *port)
{
- return readl_relaxed(port->membase + USART_SR) & USART_SR_TXE;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ return readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE;
}
static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
- stm32_set_bits(port, USART_CR3, USART_CR3_RTSE);
+ stm32_set_bits(port, ofs->cr3, USART_CR3_RTSE);
else
- stm32_clr_bits(port, USART_CR3, USART_CR3_RTSE);
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_RTSE);
}
static unsigned int stm32_get_mctrl(struct uart_port *port)
@@ -271,44 +401,56 @@ static unsigned int stm32_get_mctrl(struct uart_port *port)
/* Transmit stop */
static void stm32_stop_tx(struct uart_port *port)
{
- stm32_clr_bits(port, USART_CR1, USART_CR1_TXEIE);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
}
/* There are probably characters waiting to be transmitted. */
static void stm32_start_tx(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
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);
+ stm32_set_bits(port, ofs->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)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE);
+ stm32_clr_bits(port, ofs->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)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- stm32_set_bits(port, USART_CR1, USART_CR1_RXNEIE);
+ stm32_set_bits(port, ofs->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);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_RXNEIE);
}
/* Handle breaks - ignored by us */
@@ -318,6 +460,8 @@ static void stm32_break_ctl(struct uart_port *port, int break_state)
static int stm32_startup(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
const char *name = to_platform_device(port->dev)->name;
u32 val;
int ret;
@@ -327,17 +471,19 @@ static int stm32_startup(struct uart_port *port)
return ret;
val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
- stm32_set_bits(port, USART_CR1, val);
+ stm32_set_bits(port, ofs->cr1, val);
return 0;
}
static void stm32_shutdown(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 val;
val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
- stm32_set_bits(port, USART_CR1, val);
+ stm32_set_bits(port, ofs->cr1, val);
free_irq(port->irq, port);
}
@@ -346,6 +492,8 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
unsigned int baud;
u32 usartdiv, mantissa, fraction, oversampling;
tcflag_t cflag = termios->c_cflag;
@@ -360,9 +508,10 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
spin_lock_irqsave(&port->lock, flags);
/* Stop serial port and reset value */
- writel_relaxed(0, port->membase + USART_CR1);
+ writel_relaxed(0, port->membase + ofs->cr1);
- cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE;
+ cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
+ cr1 |= BIT(cfg->uart_enable_bit);
cr2 = 0;
cr3 = 0;
@@ -371,8 +520,12 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
if (cflag & PARENB) {
cr1 |= USART_CR1_PCE;
- if ((cflag & CSIZE) == CS8)
- cr1 |= USART_CR1_M;
+ if ((cflag & CSIZE) == CS8) {
+ if (cfg->has_7bits_data)
+ cr1 |= USART_CR1_M0;
+ else
+ cr1 |= USART_CR1_M;
+ }
}
if (cflag & PARODD)
@@ -394,15 +547,15 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
*/
if (usartdiv < 16) {
oversampling = 8;
- stm32_set_bits(port, USART_CR1, USART_CR1_OVER8);
+ stm32_set_bits(port, ofs->cr1, USART_CR1_OVER8);
} else {
oversampling = 16;
- stm32_clr_bits(port, USART_CR1, USART_CR1_OVER8);
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_OVER8);
}
mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT;
fraction = usartdiv % oversampling;
- writel_relaxed(mantissa | fraction, port->membase + USART_BRR);
+ writel_relaxed(mantissa | fraction, port->membase + ofs->brr);
uart_update_timeout(port, cflag, baud);
@@ -430,9 +583,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
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);
+ writel_relaxed(cr3, port->membase + ofs->cr3);
+ writel_relaxed(cr2, port->membase + ofs->cr2);
+ writel_relaxed(cr1, port->membase + ofs->cr1);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -469,6 +622,8 @@ static void stm32_pm(struct uart_port *port, unsigned int state,
{
struct stm32_port *stm32port = container_of(port,
struct stm32_port, port);
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32port->info->cfg;
unsigned long flags = 0;
switch (state) {
@@ -477,7 +632,7 @@ static void stm32_pm(struct uart_port *port, unsigned int state,
break;
case UART_PM_STATE_OFF:
spin_lock_irqsave(&port->lock, flags);
- stm32_clr_bits(port, USART_CR1, USART_CR1_UE);
+ stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
spin_unlock_irqrestore(&port->lock, flags);
clk_disable_unprepare(stm32port->clk);
break;
@@ -567,8 +722,10 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id stm32_match[] = {
- { .compatible = "st,stm32-usart", },
- { .compatible = "st,stm32-uart", },
+ { .compatible = "st,stm32-usart", .data = &stm32f4_info},
+ { .compatible = "st,stm32-uart", .data = &stm32f4_info},
+ { .compatible = "st,stm32f7-usart", .data = &stm32f7_info},
+ { .compatible = "st,stm32f7-uart", .data = &stm32f7_info},
{},
};
@@ -577,13 +734,20 @@ MODULE_DEVICE_TABLE(of, stm32_match);
static int stm32_serial_probe(struct platform_device *pdev)
{
- int ret;
+ const struct of_device_id *match;
struct stm32_port *stm32port;
+ int ret;
stm32port = stm32_of_get_stm32_port(pdev);
if (!stm32port)
return -ENODEV;
+ match = of_match_device(stm32_match, &pdev->dev);
+ if (match && match->data)
+ stm32port->info = (struct stm32_usart_info *)match->data;
+ else
+ return -EINVAL;
+
ret = stm32_init_port(stm32port, pdev);
if (ret)
return ret;
@@ -608,15 +772,20 @@ static int stm32_serial_remove(struct platform_device *pdev)
#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))
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
cpu_relax();
- writel_relaxed(ch, port->membase + USART_DR);
+ writel_relaxed(ch, port->membase + ofs->tdr);
}
static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
{
struct uart_port *port = &stm32_ports[co->index].port;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long flags;
u32 old_cr1, new_cr1;
int locked = 1;
@@ -630,14 +799,14 @@ static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
spin_lock(&port->lock);
/* Save and disable interrupts */
- old_cr1 = readl_relaxed(port->membase + USART_CR1);
+ old_cr1 = readl_relaxed(port->membase + ofs->cr1);
new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
- writel_relaxed(new_cr1, port->membase + USART_CR1);
+ writel_relaxed(new_cr1, port->membase + ofs->cr1);
uart_console_write(port, s, cnt, stm32_console_putchar);
/* Restore interrupt state */
- writel_relaxed(old_cr1, port->membase + USART_CR1);
+ writel_relaxed(old_cr1, port->membase + ofs->cr1);
if (locked)
spin_unlock(&port->lock);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 01/11] serial: stm32: adding support for stm32f7
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Register offset management rework to support both
stm32f4 (default) and stm32f7. Driver rework to
ensure same functional level on both stm32f4 and
stm32f7: no new feature in this version yet.
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index f89d1f7..e7ffd01 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) Maxime Coquelin 2015
- * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * Authors: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * Gerald Baeza <gerald.baeza@st.com>
* License terms: GNU General Public License (GPL), version 2
*
* Inspired by st-asc.c from STMicroelectronics (c)
@@ -29,16 +30,74 @@
#define DRIVER_NAME "stm32-usart"
+struct stm32_usart_offsets {
+ u8 cr1;
+ u8 cr2;
+ u8 cr3;
+ u8 brr;
+ u8 gtpr;
+ u8 rtor;
+ u8 rqr;
+ u8 isr;
+ u8 icr;
+ u8 rdr;
+ u8 tdr;
+};
+
+struct stm32_usart_config {
+ u8 uart_enable_bit; /* USART_CR1_UE */
+ bool has_7bits_data;
+};
+
+struct stm32_usart_info {
+ struct stm32_usart_offsets ofs;
+ struct stm32_usart_config cfg;
+};
+
+#define UNDEF_REG ~0
+
/* 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 */
+struct stm32_usart_info stm32f4_info = {
+ .ofs = {
+ .isr = 0x00,
+ .rdr = 0x04,
+ .tdr = 0x04,
+ .brr = 0x08,
+ .cr1 = 0x0c,
+ .cr2 = 0x10,
+ .cr3 = 0x14,
+ .gtpr = 0x18,
+ .rtor = UNDEF_REG,
+ .rqr = UNDEF_REG,
+ .icr = UNDEF_REG,
+ },
+ .cfg = {
+ .uart_enable_bit = 13,
+ .has_7bits_data = false,
+ }
+};
+
+struct stm32_usart_info stm32f7_info = {
+ .ofs = {
+ .cr1 = 0x00,
+ .cr2 = 0x04,
+ .cr3 = 0x08,
+ .brr = 0x0c,
+ .gtpr = 0x10,
+ .rtor = 0x14,
+ .rqr = 0x18,
+ .isr = 0x1c,
+ .icr = 0x20,
+ .rdr = 0x24,
+ .tdr = 0x28,
+ },
+ .cfg = {
+ .uart_enable_bit = 0,
+ .has_7bits_data = true,
+ }
+};
+
+/* USART_SR (F4) / USART_ISR (F7) */
#define USART_SR_PE BIT(0)
#define USART_SR_FE BIT(1)
#define USART_SR_NF BIT(2)
@@ -48,7 +107,16 @@
#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_CTSIF BIT(9)
+#define USART_SR_CTS BIT(10) /* F7 */
+#define USART_SR_RTOF BIT(11) /* F7 */
+#define USART_SR_EOBF BIT(12) /* F7 */
+#define USART_SR_ABRE BIT(14) /* F7 */
+#define USART_SR_ABRF BIT(15) /* F7 */
+#define USART_SR_BUSY BIT(16) /* F7 */
+#define USART_SR_CMF BIT(17) /* F7 */
+#define USART_SR_SBKF BIT(18) /* F7 */
+#define USART_SR_TEACK BIT(21) /* F7 */
#define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \
USART_SR_FE | USART_SR_PE)
/* Dummy bits */
@@ -64,7 +132,7 @@
/* USART_CR1 */
#define USART_CR1_SBK BIT(0)
-#define USART_CR1_RWU BIT(1)
+#define USART_CR1_RWU BIT(1) /* F4 */
#define USART_CR1_RE BIT(2)
#define USART_CR1_TE BIT(3)
#define USART_CR1_IDLEIE BIT(4)
@@ -76,12 +144,20 @@
#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_M0 BIT(12) /* F7 */
+#define USART_CR1_MME BIT(13) /* F7 */
+#define USART_CR1_CMIE BIT(14) /* F7 */
#define USART_CR1_OVER8 BIT(15)
-#define USART_CR1_IE_MASK GENMASK(8, 4)
+#define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */
+#define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */
+#define USART_CR1_RTOIE BIT(26) /* F7 */
+#define USART_CR1_EOBIE BIT(27) /* F7 */
+#define USART_CR1_M1 BIT(28) /* F7 */
+#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
/* USART_CR2 */
-#define USART_CR2_ADD_MASK GENMASK(3, 0)
+#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
+#define USART_CR2_ADDM7 BIT(4) /* F7 */
#define USART_CR2_LBDL BIT(5)
#define USART_CR2_LBDIE BIT(6)
#define USART_CR2_LBCL BIT(8)
@@ -91,6 +167,15 @@
#define USART_CR2_STOP_2B BIT(13)
#define USART_CR2_STOP_MASK GENMASK(13, 12)
#define USART_CR2_LINEN BIT(14)
+#define USART_CR2_SWAP BIT(15) /* F7 */
+#define USART_CR2_RXINV BIT(16) /* F7 */
+#define USART_CR2_TXINV BIT(17) /* F7 */
+#define USART_CR2_DATAINV BIT(18) /* F7 */
+#define USART_CR2_MSBFIRST BIT(19) /* F7 */
+#define USART_CR2_ABREN BIT(20) /* F7 */
+#define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */
+#define USART_CR2_RTOEN BIT(23) /* F7 */
+#define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */
/* USART_CR3 */
#define USART_CR3_EIE BIT(0)
@@ -105,18 +190,47 @@
#define USART_CR3_CTSE BIT(9)
#define USART_CR3_CTSIE BIT(10)
#define USART_CR3_ONEBIT BIT(11)
+#define USART_CR3_OVRDIS BIT(12) /* F7 */
+#define USART_CR3_DDRE BIT(13) /* F7 */
+#define USART_CR3_DEM BIT(14) /* F7 */
+#define USART_CR3_DEP BIT(15) /* F7 */
+#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
/* USART_GTPR */
#define USART_GTPR_PSC_MASK GENMASK(7, 0)
#define USART_GTPR_GT_MASK GENMASK(15, 8)
-#define DRIVER_NAME "stm32-usart"
+/* USART_RTOR */
+#define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */
+#define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */
+
+/* USART_RQR */
+#define USART_RQR_ABRRQ BIT(0) /* F7 */
+#define USART_RQR_SBKRQ BIT(1) /* F7 */
+#define USART_RQR_MMRQ BIT(2) /* F7 */
+#define USART_RQR_RXFRQ BIT(3) /* F7 */
+#define USART_RQR_TXFRQ BIT(4) /* F7 */
+
+/* USART_ICR */
+#define USART_ICR_PECF BIT(0) /* F7 */
+#define USART_ICR_FFECF BIT(1) /* F7 */
+#define USART_ICR_NCF BIT(2) /* F7 */
+#define USART_ICR_ORECF BIT(3) /* F7 */
+#define USART_ICR_IDLECF BIT(4) /* F7 */
+#define USART_ICR_TCCF BIT(6) /* F7 */
+#define USART_ICR_LBDCF BIT(8) /* F7 */
+#define USART_ICR_CTSCF BIT(9) /* F7 */
+#define USART_ICR_RTOCF BIT(11) /* F7 */
+#define USART_ICR_EOBCF BIT(12) /* F7 */
+#define USART_ICR_CMCF BIT(17) /* F7 */
+
#define STM32_SERIAL_NAME "ttyS"
#define STM32_MAX_PORTS 6
struct stm32_port {
struct uart_port port;
struct clk *clk;
+ struct stm32_usart_info *info;
bool hw_flow_control;
};
@@ -151,6 +265,8 @@ static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
static void stm32_receive_chars(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long c;
u32 sr;
char flag;
@@ -158,9 +274,9 @@ static void stm32_receive_chars(struct uart_port *port)
if (port->irq_wake)
pm_wakeup_event(tport->tty->dev, 0);
- while ((sr = readl_relaxed(port->membase + USART_SR)) & USART_SR_RXNE) {
+ while ((sr = readl_relaxed(port->membase + ofs->isr)) & USART_SR_RXNE) {
sr |= USART_SR_DUMMY_RX;
- c = readl_relaxed(port->membase + USART_DR);
+ c = readl_relaxed(port->membase + ofs->rdr);
flag = TTY_NORMAL;
port->icount.rx++;
@@ -170,6 +286,10 @@ static void stm32_receive_chars(struct uart_port *port)
if (uart_handle_break(port))
continue;
} else if (sr & USART_SR_ORE) {
+ if (ofs->icr != UNDEF_REG)
+ writel_relaxed(USART_ICR_ORECF,
+ port->membase +
+ ofs->icr);
port->icount.overrun++;
} else if (sr & USART_SR_PE) {
port->icount.parity++;
@@ -199,10 +319,12 @@ static void stm32_receive_chars(struct uart_port *port)
static void stm32_transmit_chars(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
struct circ_buf *xmit = &port->state->xmit;
if (port->x_char) {
- writel_relaxed(port->x_char, port->membase + USART_DR);
+ writel_relaxed(port->x_char, port->membase + ofs->tdr);
port->x_char = 0;
port->icount.tx++;
return;
@@ -218,7 +340,7 @@ static void stm32_transmit_chars(struct uart_port *port)
return;
}
- writel_relaxed(xmit->buf[xmit->tail], port->membase + USART_DR);
+ writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
port->icount.tx++;
@@ -232,11 +354,13 @@ static void stm32_transmit_chars(struct uart_port *port)
static irqreturn_t stm32_interrupt(int irq, void *ptr)
{
struct uart_port *port = ptr;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
spin_lock(&port->lock);
- sr = readl_relaxed(port->membase + USART_SR);
+ sr = readl_relaxed(port->membase + ofs->isr);
if (sr & USART_SR_RXNE)
stm32_receive_chars(port);
@@ -251,15 +375,21 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
static unsigned int stm32_tx_empty(struct uart_port *port)
{
- return readl_relaxed(port->membase + USART_SR) & USART_SR_TXE;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ return readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE;
}
static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
- stm32_set_bits(port, USART_CR3, USART_CR3_RTSE);
+ stm32_set_bits(port, ofs->cr3, USART_CR3_RTSE);
else
- stm32_clr_bits(port, USART_CR3, USART_CR3_RTSE);
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_RTSE);
}
static unsigned int stm32_get_mctrl(struct uart_port *port)
@@ -271,44 +401,56 @@ static unsigned int stm32_get_mctrl(struct uart_port *port)
/* Transmit stop */
static void stm32_stop_tx(struct uart_port *port)
{
- stm32_clr_bits(port, USART_CR1, USART_CR1_TXEIE);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_TXEIE);
}
/* There are probably characters waiting to be transmitted. */
static void stm32_start_tx(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
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);
+ stm32_set_bits(port, ofs->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)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE);
+ stm32_clr_bits(port, ofs->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)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long flags;
spin_lock_irqsave(&port->lock, flags);
- stm32_set_bits(port, USART_CR1, USART_CR1_RXNEIE);
+ stm32_set_bits(port, ofs->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);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_RXNEIE);
}
/* Handle breaks - ignored by us */
@@ -318,6 +460,8 @@ static void stm32_break_ctl(struct uart_port *port, int break_state)
static int stm32_startup(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
const char *name = to_platform_device(port->dev)->name;
u32 val;
int ret;
@@ -327,17 +471,19 @@ static int stm32_startup(struct uart_port *port)
return ret;
val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
- stm32_set_bits(port, USART_CR1, val);
+ stm32_set_bits(port, ofs->cr1, val);
return 0;
}
static void stm32_shutdown(struct uart_port *port)
{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 val;
val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
- stm32_set_bits(port, USART_CR1, val);
+ stm32_set_bits(port, ofs->cr1, val);
free_irq(port->irq, port);
}
@@ -346,6 +492,8 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
unsigned int baud;
u32 usartdiv, mantissa, fraction, oversampling;
tcflag_t cflag = termios->c_cflag;
@@ -360,9 +508,10 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
spin_lock_irqsave(&port->lock, flags);
/* Stop serial port and reset value */
- writel_relaxed(0, port->membase + USART_CR1);
+ writel_relaxed(0, port->membase + ofs->cr1);
- cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE;
+ cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
+ cr1 |= BIT(cfg->uart_enable_bit);
cr2 = 0;
cr3 = 0;
@@ -371,8 +520,12 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
if (cflag & PARENB) {
cr1 |= USART_CR1_PCE;
- if ((cflag & CSIZE) == CS8)
- cr1 |= USART_CR1_M;
+ if ((cflag & CSIZE) == CS8) {
+ if (cfg->has_7bits_data)
+ cr1 |= USART_CR1_M0;
+ else
+ cr1 |= USART_CR1_M;
+ }
}
if (cflag & PARODD)
@@ -394,15 +547,15 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
*/
if (usartdiv < 16) {
oversampling = 8;
- stm32_set_bits(port, USART_CR1, USART_CR1_OVER8);
+ stm32_set_bits(port, ofs->cr1, USART_CR1_OVER8);
} else {
oversampling = 16;
- stm32_clr_bits(port, USART_CR1, USART_CR1_OVER8);
+ stm32_clr_bits(port, ofs->cr1, USART_CR1_OVER8);
}
mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT;
fraction = usartdiv % oversampling;
- writel_relaxed(mantissa | fraction, port->membase + USART_BRR);
+ writel_relaxed(mantissa | fraction, port->membase + ofs->brr);
uart_update_timeout(port, cflag, baud);
@@ -430,9 +583,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
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);
+ writel_relaxed(cr3, port->membase + ofs->cr3);
+ writel_relaxed(cr2, port->membase + ofs->cr2);
+ writel_relaxed(cr1, port->membase + ofs->cr1);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -469,6 +622,8 @@ static void stm32_pm(struct uart_port *port, unsigned int state,
{
struct stm32_port *stm32port = container_of(port,
struct stm32_port, port);
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32port->info->cfg;
unsigned long flags = 0;
switch (state) {
@@ -477,7 +632,7 @@ static void stm32_pm(struct uart_port *port, unsigned int state,
break;
case UART_PM_STATE_OFF:
spin_lock_irqsave(&port->lock, flags);
- stm32_clr_bits(port, USART_CR1, USART_CR1_UE);
+ stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
spin_unlock_irqrestore(&port->lock, flags);
clk_disable_unprepare(stm32port->clk);
break;
@@ -567,8 +722,10 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id stm32_match[] = {
- { .compatible = "st,stm32-usart", },
- { .compatible = "st,stm32-uart", },
+ { .compatible = "st,stm32-usart", .data = &stm32f4_info},
+ { .compatible = "st,stm32-uart", .data = &stm32f4_info},
+ { .compatible = "st,stm32f7-usart", .data = &stm32f7_info},
+ { .compatible = "st,stm32f7-uart", .data = &stm32f7_info},
{},
};
@@ -577,13 +734,20 @@ MODULE_DEVICE_TABLE(of, stm32_match);
static int stm32_serial_probe(struct platform_device *pdev)
{
- int ret;
+ const struct of_device_id *match;
struct stm32_port *stm32port;
+ int ret;
stm32port = stm32_of_get_stm32_port(pdev);
if (!stm32port)
return -ENODEV;
+ match = of_match_device(stm32_match, &pdev->dev);
+ if (match && match->data)
+ stm32port->info = (struct stm32_usart_info *)match->data;
+ else
+ return -EINVAL;
+
ret = stm32_init_port(stm32port, pdev);
if (ret)
return ret;
@@ -608,15 +772,20 @@ static int stm32_serial_remove(struct platform_device *pdev)
#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))
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE))
cpu_relax();
- writel_relaxed(ch, port->membase + USART_DR);
+ writel_relaxed(ch, port->membase + ofs->tdr);
}
static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
{
struct uart_port *port = &stm32_ports[co->index].port;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
unsigned long flags;
u32 old_cr1, new_cr1;
int locked = 1;
@@ -630,14 +799,14 @@ static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
spin_lock(&port->lock);
/* Save and disable interrupts */
- old_cr1 = readl_relaxed(port->membase + USART_CR1);
+ old_cr1 = readl_relaxed(port->membase + ofs->cr1);
new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
- writel_relaxed(new_cr1, port->membase + USART_CR1);
+ writel_relaxed(new_cr1, port->membase + ofs->cr1);
uart_console_write(port, s, cnt, stm32_console_putchar);
/* Restore interrupt state */
- writel_relaxed(old_cr1, port->membase + USART_CR1);
+ writel_relaxed(old_cr1, port->membase + ofs->cr1);
if (locked)
spin_unlock(&port->lock);
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
This adds documentation of device tree bindings for the
STM32 USART
Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
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..75b1400
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
@@ -0,0 +1,34 @@
+* STMicroelectronics STM32 USART
+
+Required properties:
+- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
+"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
+the device supports synchronous mode and is compatible with
+stm32(f4) or stm32f7.
+- 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>;
+};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 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>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
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..75b1400
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
@@ -0,0 +1,34 @@
+* STMicroelectronics STM32 USART
+
+Required properties:
+- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
+"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
+the device supports synchronous mode and is compatible with
+stm32(f4) or stm32f7.
+- 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 at 40004c00 {
+ compatible = "st,stm32-uart";
+ reg = <0x40004c00 0x400>;
+ interrupts = <52>;
+ clocks = <&clk_pclk1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart4>;
+};
+
+usart2: serial at 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>;
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 03/11] serial: stm32: header file creation
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index e7ffd01..6236deb 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -28,214 +28,7 @@
#include <linux/serial_core.h>
#include <linux/clk.h>
-#define DRIVER_NAME "stm32-usart"
-
-struct stm32_usart_offsets {
- u8 cr1;
- u8 cr2;
- u8 cr3;
- u8 brr;
- u8 gtpr;
- u8 rtor;
- u8 rqr;
- u8 isr;
- u8 icr;
- u8 rdr;
- u8 tdr;
-};
-
-struct stm32_usart_config {
- u8 uart_enable_bit; /* USART_CR1_UE */
- bool has_7bits_data;
-};
-
-struct stm32_usart_info {
- struct stm32_usart_offsets ofs;
- struct stm32_usart_config cfg;
-};
-
-#define UNDEF_REG ~0
-
-/* Register offsets */
-struct stm32_usart_info stm32f4_info = {
- .ofs = {
- .isr = 0x00,
- .rdr = 0x04,
- .tdr = 0x04,
- .brr = 0x08,
- .cr1 = 0x0c,
- .cr2 = 0x10,
- .cr3 = 0x14,
- .gtpr = 0x18,
- .rtor = UNDEF_REG,
- .rqr = UNDEF_REG,
- .icr = UNDEF_REG,
- },
- .cfg = {
- .uart_enable_bit = 13,
- .has_7bits_data = false,
- }
-};
-
-struct stm32_usart_info stm32f7_info = {
- .ofs = {
- .cr1 = 0x00,
- .cr2 = 0x04,
- .cr3 = 0x08,
- .brr = 0x0c,
- .gtpr = 0x10,
- .rtor = 0x14,
- .rqr = 0x18,
- .isr = 0x1c,
- .icr = 0x20,
- .rdr = 0x24,
- .tdr = 0x28,
- },
- .cfg = {
- .uart_enable_bit = 0,
- .has_7bits_data = true,
- }
-};
-
-/* USART_SR (F4) / USART_ISR (F7) */
-#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_CTSIF BIT(9)
-#define USART_SR_CTS BIT(10) /* F7 */
-#define USART_SR_RTOF BIT(11) /* F7 */
-#define USART_SR_EOBF BIT(12) /* F7 */
-#define USART_SR_ABRE BIT(14) /* F7 */
-#define USART_SR_ABRF BIT(15) /* F7 */
-#define USART_SR_BUSY BIT(16) /* F7 */
-#define USART_SR_CMF BIT(17) /* F7 */
-#define USART_SR_SBKF BIT(18) /* F7 */
-#define USART_SR_TEACK BIT(21) /* F7 */
-#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) /* F4 */
-#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_M0 BIT(12) /* F7 */
-#define USART_CR1_MME BIT(13) /* F7 */
-#define USART_CR1_CMIE BIT(14) /* F7 */
-#define USART_CR1_OVER8 BIT(15)
-#define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */
-#define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */
-#define USART_CR1_RTOIE BIT(26) /* F7 */
-#define USART_CR1_EOBIE BIT(27) /* F7 */
-#define USART_CR1_M1 BIT(28) /* F7 */
-#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
-
-/* USART_CR2 */
-#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
-#define USART_CR2_ADDM7 BIT(4) /* F7 */
-#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)
-#define USART_CR2_SWAP BIT(15) /* F7 */
-#define USART_CR2_RXINV BIT(16) /* F7 */
-#define USART_CR2_TXINV BIT(17) /* F7 */
-#define USART_CR2_DATAINV BIT(18) /* F7 */
-#define USART_CR2_MSBFIRST BIT(19) /* F7 */
-#define USART_CR2_ABREN BIT(20) /* F7 */
-#define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */
-#define USART_CR2_RTOEN BIT(23) /* F7 */
-#define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */
-
-/* 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)
-#define USART_CR3_OVRDIS BIT(12) /* F7 */
-#define USART_CR3_DDRE BIT(13) /* F7 */
-#define USART_CR3_DEM BIT(14) /* F7 */
-#define USART_CR3_DEP BIT(15) /* F7 */
-#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
-
-/* USART_GTPR */
-#define USART_GTPR_PSC_MASK GENMASK(7, 0)
-#define USART_GTPR_GT_MASK GENMASK(15, 8)
-
-/* USART_RTOR */
-#define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */
-#define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */
-
-/* USART_RQR */
-#define USART_RQR_ABRRQ BIT(0) /* F7 */
-#define USART_RQR_SBKRQ BIT(1) /* F7 */
-#define USART_RQR_MMRQ BIT(2) /* F7 */
-#define USART_RQR_RXFRQ BIT(3) /* F7 */
-#define USART_RQR_TXFRQ BIT(4) /* F7 */
-
-/* USART_ICR */
-#define USART_ICR_PECF BIT(0) /* F7 */
-#define USART_ICR_FFECF BIT(1) /* F7 */
-#define USART_ICR_NCF BIT(2) /* F7 */
-#define USART_ICR_ORECF BIT(3) /* F7 */
-#define USART_ICR_IDLECF BIT(4) /* F7 */
-#define USART_ICR_TCCF BIT(6) /* F7 */
-#define USART_ICR_LBDCF BIT(8) /* F7 */
-#define USART_ICR_CTSCF BIT(9) /* F7 */
-#define USART_ICR_RTOCF BIT(11) /* F7 */
-#define USART_ICR_EOBCF BIT(12) /* F7 */
-#define USART_ICR_CMCF BIT(17) /* F7 */
-
-#define STM32_SERIAL_NAME "ttyS"
-#define STM32_MAX_PORTS 6
-
-struct stm32_port {
- struct uart_port port;
- struct clk *clk;
- struct stm32_usart_info *info;
- bool hw_flow_control;
-};
-
-static struct stm32_port stm32_ports[STM32_MAX_PORTS];
-static struct uart_driver stm32_usart_driver;
+#include "stm32-usart.h"
static void stm32_stop_tx(struct uart_port *port);
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
new file mode 100644
index 0000000..75f8388
--- /dev/null
+++ b/drivers/tty/serial/stm32-usart.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Authors: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Gerald Baeza <gerald_baeza-Qt13gs6zZMY@public.gmane.org>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#define DRIVER_NAME "stm32-usart"
+
+struct stm32_usart_offsets {
+ u8 cr1;
+ u8 cr2;
+ u8 cr3;
+ u8 brr;
+ u8 gtpr;
+ u8 rtor;
+ u8 rqr;
+ u8 isr;
+ u8 icr;
+ u8 rdr;
+ u8 tdr;
+};
+
+struct stm32_usart_config {
+ u8 uart_enable_bit; /* USART_CR1_UE */
+ bool has_7bits_data;
+};
+
+struct stm32_usart_info {
+ struct stm32_usart_offsets ofs;
+ struct stm32_usart_config cfg;
+};
+
+#define UNDEF_REG ~0
+
+/* Register offsets */
+struct stm32_usart_info stm32f4_info = {
+ .ofs = {
+ .isr = 0x00,
+ .rdr = 0x04,
+ .tdr = 0x04,
+ .brr = 0x08,
+ .cr1 = 0x0c,
+ .cr2 = 0x10,
+ .cr3 = 0x14,
+ .gtpr = 0x18,
+ .rtor = UNDEF_REG,
+ .rqr = UNDEF_REG,
+ .icr = UNDEF_REG,
+ },
+ .cfg = {
+ .uart_enable_bit = 13,
+ .has_7bits_data = false,
+ }
+};
+
+struct stm32_usart_info stm32f7_info = {
+ .ofs = {
+ .cr1 = 0x00,
+ .cr2 = 0x04,
+ .cr3 = 0x08,
+ .brr = 0x0c,
+ .gtpr = 0x10,
+ .rtor = 0x14,
+ .rqr = 0x18,
+ .isr = 0x1c,
+ .icr = 0x20,
+ .rdr = 0x24,
+ .tdr = 0x28,
+ },
+ .cfg = {
+ .uart_enable_bit = 0,
+ .has_7bits_data = true,
+ }
+};
+
+/* USART_SR (F4) / USART_ISR (F7) */
+#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_CTSIF BIT(9)
+#define USART_SR_CTS BIT(10) /* F7 */
+#define USART_SR_RTOF BIT(11) /* F7 */
+#define USART_SR_EOBF BIT(12) /* F7 */
+#define USART_SR_ABRE BIT(14) /* F7 */
+#define USART_SR_ABRF BIT(15) /* F7 */
+#define USART_SR_BUSY BIT(16) /* F7 */
+#define USART_SR_CMF BIT(17) /* F7 */
+#define USART_SR_SBKF BIT(18) /* F7 */
+#define USART_SR_TEACK BIT(21) /* F7 */
+#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) /* F4 */
+#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_M0 BIT(12) /* F7 */
+#define USART_CR1_MME BIT(13) /* F7 */
+#define USART_CR1_CMIE BIT(14) /* F7 */
+#define USART_CR1_OVER8 BIT(15)
+#define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */
+#define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */
+#define USART_CR1_RTOIE BIT(26) /* F7 */
+#define USART_CR1_EOBIE BIT(27) /* F7 */
+#define USART_CR1_M1 BIT(28) /* F7 */
+#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
+
+/* USART_CR2 */
+#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
+#define USART_CR2_ADDM7 BIT(4) /* F7 */
+#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)
+#define USART_CR2_SWAP BIT(15) /* F7 */
+#define USART_CR2_RXINV BIT(16) /* F7 */
+#define USART_CR2_TXINV BIT(17) /* F7 */
+#define USART_CR2_DATAINV BIT(18) /* F7 */
+#define USART_CR2_MSBFIRST BIT(19) /* F7 */
+#define USART_CR2_ABREN BIT(20) /* F7 */
+#define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */
+#define USART_CR2_RTOEN BIT(23) /* F7 */
+#define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */
+
+/* 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)
+#define USART_CR3_OVRDIS BIT(12) /* F7 */
+#define USART_CR3_DDRE BIT(13) /* F7 */
+#define USART_CR3_DEM BIT(14) /* F7 */
+#define USART_CR3_DEP BIT(15) /* F7 */
+#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
+
+/* USART_GTPR */
+#define USART_GTPR_PSC_MASK GENMASK(7, 0)
+#define USART_GTPR_GT_MASK GENMASK(15, 8)
+
+/* USART_RTOR */
+#define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */
+#define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */
+
+/* USART_RQR */
+#define USART_RQR_ABRRQ BIT(0) /* F7 */
+#define USART_RQR_SBKRQ BIT(1) /* F7 */
+#define USART_RQR_MMRQ BIT(2) /* F7 */
+#define USART_RQR_RXFRQ BIT(3) /* F7 */
+#define USART_RQR_TXFRQ BIT(4) /* F7 */
+
+/* USART_ICR */
+#define USART_ICR_PECF BIT(0) /* F7 */
+#define USART_ICR_FFECF BIT(1) /* F7 */
+#define USART_ICR_NCF BIT(2) /* F7 */
+#define USART_ICR_ORECF BIT(3) /* F7 */
+#define USART_ICR_IDLECF BIT(4) /* F7 */
+#define USART_ICR_TCCF BIT(6) /* F7 */
+#define USART_ICR_LBDCF BIT(8) /* F7 */
+#define USART_ICR_CTSCF BIT(9) /* F7 */
+#define USART_ICR_RTOCF BIT(11) /* F7 */
+#define USART_ICR_EOBCF BIT(12) /* F7 */
+#define USART_ICR_CMCF BIT(17) /* F7 */
+
+#define STM32_SERIAL_NAME "ttyS"
+#define STM32_MAX_PORTS 6
+
+struct stm32_port {
+ struct uart_port port;
+ struct clk *clk;
+ struct stm32_usart_info *info;
+ bool hw_flow_control;
+};
+
+static struct stm32_port stm32_ports[STM32_MAX_PORTS];
+static struct uart_driver stm32_usart_driver;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 03/11] serial: stm32: header file creation
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index e7ffd01..6236deb 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -28,214 +28,7 @@
#include <linux/serial_core.h>
#include <linux/clk.h>
-#define DRIVER_NAME "stm32-usart"
-
-struct stm32_usart_offsets {
- u8 cr1;
- u8 cr2;
- u8 cr3;
- u8 brr;
- u8 gtpr;
- u8 rtor;
- u8 rqr;
- u8 isr;
- u8 icr;
- u8 rdr;
- u8 tdr;
-};
-
-struct stm32_usart_config {
- u8 uart_enable_bit; /* USART_CR1_UE */
- bool has_7bits_data;
-};
-
-struct stm32_usart_info {
- struct stm32_usart_offsets ofs;
- struct stm32_usart_config cfg;
-};
-
-#define UNDEF_REG ~0
-
-/* Register offsets */
-struct stm32_usart_info stm32f4_info = {
- .ofs = {
- .isr = 0x00,
- .rdr = 0x04,
- .tdr = 0x04,
- .brr = 0x08,
- .cr1 = 0x0c,
- .cr2 = 0x10,
- .cr3 = 0x14,
- .gtpr = 0x18,
- .rtor = UNDEF_REG,
- .rqr = UNDEF_REG,
- .icr = UNDEF_REG,
- },
- .cfg = {
- .uart_enable_bit = 13,
- .has_7bits_data = false,
- }
-};
-
-struct stm32_usart_info stm32f7_info = {
- .ofs = {
- .cr1 = 0x00,
- .cr2 = 0x04,
- .cr3 = 0x08,
- .brr = 0x0c,
- .gtpr = 0x10,
- .rtor = 0x14,
- .rqr = 0x18,
- .isr = 0x1c,
- .icr = 0x20,
- .rdr = 0x24,
- .tdr = 0x28,
- },
- .cfg = {
- .uart_enable_bit = 0,
- .has_7bits_data = true,
- }
-};
-
-/* USART_SR (F4) / USART_ISR (F7) */
-#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_CTSIF BIT(9)
-#define USART_SR_CTS BIT(10) /* F7 */
-#define USART_SR_RTOF BIT(11) /* F7 */
-#define USART_SR_EOBF BIT(12) /* F7 */
-#define USART_SR_ABRE BIT(14) /* F7 */
-#define USART_SR_ABRF BIT(15) /* F7 */
-#define USART_SR_BUSY BIT(16) /* F7 */
-#define USART_SR_CMF BIT(17) /* F7 */
-#define USART_SR_SBKF BIT(18) /* F7 */
-#define USART_SR_TEACK BIT(21) /* F7 */
-#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) /* F4 */
-#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_M0 BIT(12) /* F7 */
-#define USART_CR1_MME BIT(13) /* F7 */
-#define USART_CR1_CMIE BIT(14) /* F7 */
-#define USART_CR1_OVER8 BIT(15)
-#define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */
-#define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */
-#define USART_CR1_RTOIE BIT(26) /* F7 */
-#define USART_CR1_EOBIE BIT(27) /* F7 */
-#define USART_CR1_M1 BIT(28) /* F7 */
-#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
-
-/* USART_CR2 */
-#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
-#define USART_CR2_ADDM7 BIT(4) /* F7 */
-#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)
-#define USART_CR2_SWAP BIT(15) /* F7 */
-#define USART_CR2_RXINV BIT(16) /* F7 */
-#define USART_CR2_TXINV BIT(17) /* F7 */
-#define USART_CR2_DATAINV BIT(18) /* F7 */
-#define USART_CR2_MSBFIRST BIT(19) /* F7 */
-#define USART_CR2_ABREN BIT(20) /* F7 */
-#define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */
-#define USART_CR2_RTOEN BIT(23) /* F7 */
-#define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */
-
-/* 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)
-#define USART_CR3_OVRDIS BIT(12) /* F7 */
-#define USART_CR3_DDRE BIT(13) /* F7 */
-#define USART_CR3_DEM BIT(14) /* F7 */
-#define USART_CR3_DEP BIT(15) /* F7 */
-#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
-
-/* USART_GTPR */
-#define USART_GTPR_PSC_MASK GENMASK(7, 0)
-#define USART_GTPR_GT_MASK GENMASK(15, 8)
-
-/* USART_RTOR */
-#define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */
-#define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */
-
-/* USART_RQR */
-#define USART_RQR_ABRRQ BIT(0) /* F7 */
-#define USART_RQR_SBKRQ BIT(1) /* F7 */
-#define USART_RQR_MMRQ BIT(2) /* F7 */
-#define USART_RQR_RXFRQ BIT(3) /* F7 */
-#define USART_RQR_TXFRQ BIT(4) /* F7 */
-
-/* USART_ICR */
-#define USART_ICR_PECF BIT(0) /* F7 */
-#define USART_ICR_FFECF BIT(1) /* F7 */
-#define USART_ICR_NCF BIT(2) /* F7 */
-#define USART_ICR_ORECF BIT(3) /* F7 */
-#define USART_ICR_IDLECF BIT(4) /* F7 */
-#define USART_ICR_TCCF BIT(6) /* F7 */
-#define USART_ICR_LBDCF BIT(8) /* F7 */
-#define USART_ICR_CTSCF BIT(9) /* F7 */
-#define USART_ICR_RTOCF BIT(11) /* F7 */
-#define USART_ICR_EOBCF BIT(12) /* F7 */
-#define USART_ICR_CMCF BIT(17) /* F7 */
-
-#define STM32_SERIAL_NAME "ttyS"
-#define STM32_MAX_PORTS 6
-
-struct stm32_port {
- struct uart_port port;
- struct clk *clk;
- struct stm32_usart_info *info;
- bool hw_flow_control;
-};
-
-static struct stm32_port stm32_ports[STM32_MAX_PORTS];
-static struct uart_driver stm32_usart_driver;
+#include "stm32-usart.h"
static void stm32_stop_tx(struct uart_port *port);
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
new file mode 100644
index 0000000..75f8388
--- /dev/null
+++ b/drivers/tty/serial/stm32-usart.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Authors: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * Gerald Baeza <gerald_baeza@yahoo.fr>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#define DRIVER_NAME "stm32-usart"
+
+struct stm32_usart_offsets {
+ u8 cr1;
+ u8 cr2;
+ u8 cr3;
+ u8 brr;
+ u8 gtpr;
+ u8 rtor;
+ u8 rqr;
+ u8 isr;
+ u8 icr;
+ u8 rdr;
+ u8 tdr;
+};
+
+struct stm32_usart_config {
+ u8 uart_enable_bit; /* USART_CR1_UE */
+ bool has_7bits_data;
+};
+
+struct stm32_usart_info {
+ struct stm32_usart_offsets ofs;
+ struct stm32_usart_config cfg;
+};
+
+#define UNDEF_REG ~0
+
+/* Register offsets */
+struct stm32_usart_info stm32f4_info = {
+ .ofs = {
+ .isr = 0x00,
+ .rdr = 0x04,
+ .tdr = 0x04,
+ .brr = 0x08,
+ .cr1 = 0x0c,
+ .cr2 = 0x10,
+ .cr3 = 0x14,
+ .gtpr = 0x18,
+ .rtor = UNDEF_REG,
+ .rqr = UNDEF_REG,
+ .icr = UNDEF_REG,
+ },
+ .cfg = {
+ .uart_enable_bit = 13,
+ .has_7bits_data = false,
+ }
+};
+
+struct stm32_usart_info stm32f7_info = {
+ .ofs = {
+ .cr1 = 0x00,
+ .cr2 = 0x04,
+ .cr3 = 0x08,
+ .brr = 0x0c,
+ .gtpr = 0x10,
+ .rtor = 0x14,
+ .rqr = 0x18,
+ .isr = 0x1c,
+ .icr = 0x20,
+ .rdr = 0x24,
+ .tdr = 0x28,
+ },
+ .cfg = {
+ .uart_enable_bit = 0,
+ .has_7bits_data = true,
+ }
+};
+
+/* USART_SR (F4) / USART_ISR (F7) */
+#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_CTSIF BIT(9)
+#define USART_SR_CTS BIT(10) /* F7 */
+#define USART_SR_RTOF BIT(11) /* F7 */
+#define USART_SR_EOBF BIT(12) /* F7 */
+#define USART_SR_ABRE BIT(14) /* F7 */
+#define USART_SR_ABRF BIT(15) /* F7 */
+#define USART_SR_BUSY BIT(16) /* F7 */
+#define USART_SR_CMF BIT(17) /* F7 */
+#define USART_SR_SBKF BIT(18) /* F7 */
+#define USART_SR_TEACK BIT(21) /* F7 */
+#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) /* F4 */
+#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_M0 BIT(12) /* F7 */
+#define USART_CR1_MME BIT(13) /* F7 */
+#define USART_CR1_CMIE BIT(14) /* F7 */
+#define USART_CR1_OVER8 BIT(15)
+#define USART_CR1_DEDT_MASK GENMASK(20, 16) /* F7 */
+#define USART_CR1_DEAT_MASK GENMASK(25, 21) /* F7 */
+#define USART_CR1_RTOIE BIT(26) /* F7 */
+#define USART_CR1_EOBIE BIT(27) /* F7 */
+#define USART_CR1_M1 BIT(28) /* F7 */
+#define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27))
+
+/* USART_CR2 */
+#define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */
+#define USART_CR2_ADDM7 BIT(4) /* F7 */
+#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)
+#define USART_CR2_SWAP BIT(15) /* F7 */
+#define USART_CR2_RXINV BIT(16) /* F7 */
+#define USART_CR2_TXINV BIT(17) /* F7 */
+#define USART_CR2_DATAINV BIT(18) /* F7 */
+#define USART_CR2_MSBFIRST BIT(19) /* F7 */
+#define USART_CR2_ABREN BIT(20) /* F7 */
+#define USART_CR2_ABRMOD_MASK GENMASK(22, 21) /* F7 */
+#define USART_CR2_RTOEN BIT(23) /* F7 */
+#define USART_CR2_ADD_F7_MASK GENMASK(31, 24) /* F7 */
+
+/* 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)
+#define USART_CR3_OVRDIS BIT(12) /* F7 */
+#define USART_CR3_DDRE BIT(13) /* F7 */
+#define USART_CR3_DEM BIT(14) /* F7 */
+#define USART_CR3_DEP BIT(15) /* F7 */
+#define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */
+
+/* USART_GTPR */
+#define USART_GTPR_PSC_MASK GENMASK(7, 0)
+#define USART_GTPR_GT_MASK GENMASK(15, 8)
+
+/* USART_RTOR */
+#define USART_RTOR_RTO_MASK GENMASK(23, 0) /* F7 */
+#define USART_RTOR_BLEN_MASK GENMASK(31, 24) /* F7 */
+
+/* USART_RQR */
+#define USART_RQR_ABRRQ BIT(0) /* F7 */
+#define USART_RQR_SBKRQ BIT(1) /* F7 */
+#define USART_RQR_MMRQ BIT(2) /* F7 */
+#define USART_RQR_RXFRQ BIT(3) /* F7 */
+#define USART_RQR_TXFRQ BIT(4) /* F7 */
+
+/* USART_ICR */
+#define USART_ICR_PECF BIT(0) /* F7 */
+#define USART_ICR_FFECF BIT(1) /* F7 */
+#define USART_ICR_NCF BIT(2) /* F7 */
+#define USART_ICR_ORECF BIT(3) /* F7 */
+#define USART_ICR_IDLECF BIT(4) /* F7 */
+#define USART_ICR_TCCF BIT(6) /* F7 */
+#define USART_ICR_LBDCF BIT(8) /* F7 */
+#define USART_ICR_CTSCF BIT(9) /* F7 */
+#define USART_ICR_RTOCF BIT(11) /* F7 */
+#define USART_ICR_EOBCF BIT(12) /* F7 */
+#define USART_ICR_CMCF BIT(17) /* F7 */
+
+#define STM32_SERIAL_NAME "ttyS"
+#define STM32_MAX_PORTS 6
+
+struct stm32_port {
+ struct uart_port port;
+ struct clk *clk;
+ struct stm32_usart_info *info;
+ bool hw_flow_control;
+};
+
+static struct stm32_port stm32_ports[STM32_MAX_PORTS];
+static struct uart_driver stm32_usart_driver;
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 04/11] serial: stm32: disable tx and rx during shutdown
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 6236deb..184b018 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -276,7 +276,7 @@ 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, ofs->cr1, val);
+ stm32_clr_bits(port, ofs->cr1, val);
free_irq(port->irq, port);
}
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 04/11] serial: stm32: disable tx and rx during shutdown
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 6236deb..184b018 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -276,7 +276,7 @@ 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, ofs->cr1, val);
+ stm32_clr_bits(port, ofs->cr1, val);
free_irq(port->irq, port);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 05/11] serial: stm32: correct flow control property spelling
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
"st,hw-flow-ctrl" property is documented in device tree
binding whereas "auto-flow-control" was used in the code.
The driver is now aligned with the binding name
"st,hw-flow-ctrl".
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 184b018..ab294b9 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -508,7 +508,7 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
return NULL;
stm32_ports[id].hw_flow_control = of_property_read_bool(np,
- "auto-flow-control");
+ "st,hw-flow-ctrl");
stm32_ports[id].port.line = id;
return &stm32_ports[id];
}
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 05/11] serial: stm32: correct flow control property spelling
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
"st,hw-flow-ctrl" property is documented in device tree
binding whereas "auto-flow-control" was used in the code.
The driver is now aligned with the binding name
"st,hw-flow-ctrl".
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 184b018..ab294b9 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -508,7 +508,7 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
return NULL;
stm32_ports[id].hw_flow_control = of_property_read_bool(np,
- "auto-flow-control");
+ "st,hw-flow-ctrl");
stm32_ports[id].port.line = id;
return &stm32_ports[id];
}
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 06/11] serial: stm32: clock disabling management
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Keep the clock enabled at the end of stm32_init_port
but disable it in stm32_serial_remove.
Note that stm32_pm function is there to manage the
clock at runtime.
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index ab294b9..520e7de 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -487,8 +487,6 @@ static int stm32_init_port(struct stm32_port *stm32port,
if (!stm32port->port.uartclk)
ret = -EINVAL;
- clk_disable_unprepare(stm32port->clk);
-
return ret;
}
@@ -557,6 +555,9 @@ static int stm32_serial_probe(struct platform_device *pdev)
static int stm32_serial_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+
+ clk_disable_unprepare(stm32_port->clk);
return uart_remove_one_port(&stm32_usart_driver, port);
}
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 06/11] serial: stm32: clock disabling management
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Keep the clock enabled at the end of stm32_init_port
but disable it in stm32_serial_remove.
Note that stm32_pm function is there to manage the
clock at runtime.
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index ab294b9..520e7de 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -487,8 +487,6 @@ static int stm32_init_port(struct stm32_port *stm32port,
if (!stm32port->port.uartclk)
ret = -EINVAL;
- clk_disable_unprepare(stm32port->clk);
-
return ret;
}
@@ -557,6 +555,9 @@ static int stm32_serial_probe(struct platform_device *pdev)
static int stm32_serial_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
+ struct stm32_port *stm32_port = to_stm32_port(port);
+
+ clk_disable_unprepare(stm32_port->clk);
return uart_remove_one_port(&stm32_usart_driver, port);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 07/11] dt-bindings: Add DMA bindings for STM32 USART
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
index 75b1400..85ec5f2 100644
--- a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
+++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
@@ -12,6 +12,8 @@ stm32(f4) or stm32f7.
Optional properties:
- pinctrl: The reference on the pins configuration
- st,hw-flow-ctrl: bool flag to enable hardware flow control.
+- dmas: phandle(s) to DMA controller node(s). Refer to stm32-dma.txt
+- dma-names: "rx" and/or "tx"
Examples:
usart4: serial@40004c00 {
@@ -32,3 +34,13 @@ usart2: serial@40004400 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
};
+
+usart1: serial@40011000 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&rcc 0 164>;
+ dmas = <&dma2 2 4 0x414 0x0>,
+ <&dma2 7 4 0x414 0x0>;
+ dma-names = "rx", "tx";
+};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 07/11] dt-bindings: Add DMA bindings for STM32 USART
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
index 75b1400..85ec5f2 100644
--- a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
+++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
@@ -12,6 +12,8 @@ stm32(f4) or stm32f7.
Optional properties:
- pinctrl: The reference on the pins configuration
- st,hw-flow-ctrl: bool flag to enable hardware flow control.
+- dmas: phandle(s) to DMA controller node(s). Refer to stm32-dma.txt
+- dma-names: "rx" and/or "tx"
Examples:
usart4: serial at 40004c00 {
@@ -32,3 +34,13 @@ usart2: serial at 40004400 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
};
+
+usart1: serial at 40011000 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&rcc 0 164>;
+ dmas = <&dma2 2 4 0x414 0x0>,
+ <&dma2 7 4 0x414 0x0>;
+ dma-names = "rx", "tx";
+};
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 08/11] serial: stm32: adding dma support
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
This patch adds dma mode support for rx and tx
with pio mode as fallback in case of dma error.
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 520e7de..24c4d82 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -11,26 +11,31 @@
#define SUPPORT_SYSRQ
#endif
-#include <linux/module.h>
-#include <linux/serial.h>
+#include <linux/clk.h>
#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-direction.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/iopoll.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/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/serial_core.h>
-#include <linux/clk.h>
+#include <linux/serial.h>
+#include <linux/spinlock.h>
+#include <linux/sysrq.h>
+#include <linux/tty_flip.h>
+#include <linux/tty.h>
#include "stm32-usart.h"
static void stm32_stop_tx(struct uart_port *port);
+static void stm32_transmit_chars(struct uart_port *port);
static inline struct stm32_port *to_stm32_port(struct uart_port *port)
{
@@ -55,7 +60,48 @@ static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
writel_relaxed(val, port->membase + reg);
}
-static void stm32_receive_chars(struct uart_port *port)
+int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res,
+ bool threaded)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ enum dma_status status;
+ struct dma_tx_state state;
+
+ *sr = readl_relaxed(port->membase + ofs->isr);
+
+ if (threaded && stm32_port->rx_ch) {
+ status = dmaengine_tx_status(stm32_port->rx_ch,
+ stm32_port->rx_ch->cookie,
+ &state);
+ if ((status == DMA_IN_PROGRESS) &&
+ (*last_res != state.residue))
+ return 1;
+ else
+ return 0;
+ } else if (*sr & USART_SR_RXNE) {
+ return 1;
+ }
+ return 0;
+}
+
+unsigned long stm32_get_char(struct uart_port *port, u32 *sr, int *last_res)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ unsigned long c;
+
+ if (stm32_port->rx_ch) {
+ c = stm32_port->rx_buf[RX_BUF_L - (*last_res)--];
+ if ((*last_res) == 0)
+ *last_res = RX_BUF_L;
+ return c;
+ } else {
+ return readl_relaxed(port->membase + ofs->rdr);
+ }
+}
+
+static void stm32_receive_chars(struct uart_port *port, bool threaded)
{
struct tty_port *tport = &port->state->port;
struct stm32_port *stm32_port = to_stm32_port(port);
@@ -63,13 +109,14 @@ static void stm32_receive_chars(struct uart_port *port)
unsigned long c;
u32 sr;
char flag;
+ static int last_res = RX_BUF_L;
if (port->irq_wake)
pm_wakeup_event(tport->tty->dev, 0);
- while ((sr = readl_relaxed(port->membase + ofs->isr)) & USART_SR_RXNE) {
+ while (stm32_pending_rx(port, &sr, &last_res, threaded)) {
sr |= USART_SR_DUMMY_RX;
- c = readl_relaxed(port->membase + ofs->rdr);
+ c = stm32_get_char(port, &sr, &last_res);
flag = TTY_NORMAL;
port->icount.rx++;
@@ -110,6 +157,124 @@ static void stm32_receive_chars(struct uart_port *port)
spin_lock(&port->lock);
}
+static void stm32_tx_dma_complete(void *arg)
+{
+ struct uart_port *port = arg;
+ struct stm32_port *stm32port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ unsigned int isr;
+ int ret;
+
+ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+ isr,
+ (isr & USART_SR_TC),
+ 10, 100000);
+
+ if (ret)
+ dev_err(port->dev, "terminal count not set\n");
+
+ if (ofs->icr == UNDEF_REG)
+ stm32_clr_bits(port, ofs->isr, USART_SR_TC);
+ else
+ stm32_set_bits(port, ofs->icr, USART_CR_TC);
+
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+ stm32port->tx_dma_busy = false;
+
+ /* Let's see if we have pending data to send */
+ stm32_transmit_chars(port);
+}
+
+static void stm32_transmit_chars_pio(struct uart_port *port)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct circ_buf *xmit = &port->state->xmit;
+ unsigned int isr;
+ int ret;
+
+ if (stm32_port->tx_dma_busy) {
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+ stm32_port->tx_dma_busy = false;
+ }
+
+ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+ isr,
+ (isr & USART_SR_TXE),
+ 10, 100);
+
+ if (ret)
+ dev_err(port->dev, "tx empty not set\n");
+
+ stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
+
+ writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+}
+
+static void stm32_transmit_chars_dma(struct uart_port *port)
+{
+ struct stm32_port *stm32port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct circ_buf *xmit = &port->state->xmit;
+ struct dma_async_tx_descriptor *desc = NULL;
+ dma_cookie_t cookie;
+ unsigned int count, i;
+
+ if (stm32port->tx_dma_busy)
+ return;
+
+ stm32port->tx_dma_busy = true;
+
+ count = uart_circ_chars_pending(xmit);
+
+ if (count > TX_BUF_L)
+ count = TX_BUF_L;
+
+ if (xmit->tail < xmit->head) {
+ memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], count);
+ } else {
+ size_t one = UART_XMIT_SIZE - xmit->tail;
+ size_t two;
+
+ if (one > count)
+ one = count;
+ two = count - one;
+
+ memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], one);
+ if (two)
+ memcpy(&stm32port->tx_buf[one], &xmit->buf[0], two);
+ }
+
+ desc = dmaengine_prep_slave_single(stm32port->tx_ch,
+ stm32port->tx_dma_buf,
+ count,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT);
+
+ if (!desc) {
+ for (i = count; i > 0; i--)
+ stm32_transmit_chars_pio(port);
+ return;
+ }
+
+ desc->callback = stm32_tx_dma_complete;
+ desc->callback_param = port;
+
+ /* Push current DMA TX transaction in the pending queue */
+ cookie = dmaengine_submit(desc);
+
+ /* Issue pending DMA TX requests */
+ dma_async_issue_pending(stm32port->tx_ch);
+
+ stm32_clr_bits(port, ofs->isr, USART_SR_TC);
+ stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT);
+
+ xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+ port->icount.tx += count;
+}
+
static void stm32_transmit_chars(struct uart_port *port)
{
struct stm32_port *stm32_port = to_stm32_port(port);
@@ -117,9 +282,13 @@ static void stm32_transmit_chars(struct uart_port *port)
struct circ_buf *xmit = &port->state->xmit;
if (port->x_char) {
+ if (stm32_port->tx_dma_busy)
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
writel_relaxed(port->x_char, port->membase + ofs->tdr);
port->x_char = 0;
port->icount.tx++;
+ if (stm32_port->tx_dma_busy)
+ stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT);
return;
}
@@ -133,9 +302,10 @@ static void stm32_transmit_chars(struct uart_port *port)
return;
}
- writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- port->icount.tx++;
+ if (stm32_port->tx_ch)
+ stm32_transmit_chars_dma(port);
+ else
+ stm32_transmit_chars_pio(port);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
@@ -151,16 +321,30 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
- spin_lock(&port->lock);
-
sr = readl_relaxed(port->membase + ofs->isr);
- if (sr & USART_SR_RXNE)
- stm32_receive_chars(port);
+ if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch))
+ stm32_receive_chars(port, false);
- if (sr & USART_SR_TXE)
+ if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch))
stm32_transmit_chars(port);
+ if (stm32_port->rx_ch)
+ return IRQ_WAKE_THREAD;
+ else
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t stm32_threaded_interrupt(int irq, void *ptr)
+{
+ struct uart_port *port = ptr;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+
+ spin_lock(&port->lock);
+
+ if (stm32_port->rx_ch)
+ stm32_receive_chars(port, true);
+
spin_unlock(&port->lock);
return IRQ_HANDLED;
@@ -203,14 +387,12 @@ static void stm32_stop_tx(struct uart_port *port)
/* There are probably characters waiting to be transmitted. */
static void stm32_start_tx(struct uart_port *port)
{
- struct stm32_port *stm32_port = to_stm32_port(port);
- struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
struct circ_buf *xmit = &port->state->xmit;
if (uart_circ_empty(xmit))
return;
- stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE | USART_CR1_TE);
+ stm32_transmit_chars(port);
}
/* Throttle the remote when input buffer is about to overflow. */
@@ -259,7 +441,9 @@ static int stm32_startup(struct uart_port *port)
u32 val;
int ret;
- ret = request_irq(port->irq, stm32_interrupt, 0, name, port);
+ ret = request_threaded_irq(port->irq, stm32_interrupt,
+ stm32_threaded_interrupt,
+ IRQF_NO_SUSPEND, name, port);
if (ret)
return ret;
@@ -376,6 +560,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
if ((termios->c_cflag & CREAD) == 0)
port->ignore_status_mask |= USART_SR_DUMMY_RX;
+ if (stm32_port->rx_ch)
+ cr3 |= USART_CR3_DMAR;
+
writel_relaxed(cr3, port->membase + ofs->cr3);
writel_relaxed(cr2, port->membase + ofs->cr2);
writel_relaxed(cr1, port->membase + ofs->cr1);
@@ -523,6 +710,129 @@ static const struct of_device_id stm32_match[] = {
MODULE_DEVICE_TABLE(of, stm32_match);
#endif
+static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,
+ struct platform_device *pdev)
+{
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct uart_port *port = &stm32port->port;
+ struct device *dev = &pdev->dev;
+ struct dma_slave_config config;
+ struct dma_async_tx_descriptor *desc = NULL;
+ dma_cookie_t cookie;
+ int ret;
+
+ /* Request DMA RX channel */
+ stm32port->rx_ch = dma_request_slave_channel(dev, "rx");
+ if (!stm32port->rx_ch) {
+ dev_info(dev, "rx dma alloc failed\n");
+ return -ENODEV;
+ }
+ stm32port->rx_buf = dma_alloc_coherent(&pdev->dev, RX_BUF_L,
+ &stm32port->rx_dma_buf,
+ GFP_KERNEL);
+ if (!stm32port->rx_buf) {
+ ret = -ENOMEM;
+ goto alloc_err;
+ }
+
+ /* Configure DMA channel */
+ memset(&config, 0, sizeof(config));
+ config.src_addr = (dma_addr_t)port->membase + ofs->rdr;
+ config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
+ ret = dmaengine_slave_config(stm32port->rx_ch, &config);
+ if (ret < 0) {
+ dev_err(dev, "rx dma channel config failed\n");
+ ret = -ENODEV;
+ goto config_err;
+ }
+
+ /* Prepare a DMA cyclic transaction */
+ desc = dmaengine_prep_dma_cyclic(stm32port->rx_ch,
+ stm32port->rx_dma_buf,
+ RX_BUF_L, RX_BUF_P, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT);
+ if (!desc) {
+ dev_err(dev, "rx dma prep cyclic failed\n");
+ ret = -ENODEV;
+ goto config_err;
+ }
+
+ /* No callback as dma buffer is drained on usart interrupt */
+ desc->callback = NULL;
+ desc->callback_param = NULL;
+
+ /* Push current DMA transaction in the pending queue */
+ cookie = dmaengine_submit(desc);
+
+ /* Issue pending DMA requests */
+ dma_async_issue_pending(stm32port->rx_ch);
+
+ return 0;
+
+config_err:
+ dma_free_coherent(&pdev->dev,
+ RX_BUF_L, stm32port->rx_buf,
+ stm32port->rx_dma_buf);
+
+alloc_err:
+ dma_release_channel(stm32port->rx_ch);
+ stm32port->rx_ch = NULL;
+
+ return ret;
+}
+
+static int stm32_of_dma_tx_probe(struct stm32_port *stm32port,
+ struct platform_device *pdev)
+{
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct uart_port *port = &stm32port->port;
+ struct device *dev = &pdev->dev;
+ struct dma_slave_config config;
+ int ret;
+
+ stm32port->tx_dma_busy = false;
+
+ /* Request DMA TX channel */
+ stm32port->tx_ch = dma_request_slave_channel(dev, "tx");
+ if (!stm32port->tx_ch) {
+ dev_info(dev, "tx dma alloc failed\n");
+ return -ENODEV;
+ }
+ stm32port->tx_buf = dma_alloc_coherent(&pdev->dev, TX_BUF_L,
+ &stm32port->tx_dma_buf,
+ GFP_KERNEL);
+ if (!stm32port->tx_buf) {
+ ret = -ENOMEM;
+ goto alloc_err;
+ }
+
+ /* Configure DMA channel */
+ memset(&config, 0, sizeof(config));
+ config.dst_addr = (dma_addr_t)port->membase + ofs->tdr;
+ config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
+ ret = dmaengine_slave_config(stm32port->tx_ch, &config);
+ if (ret < 0) {
+ dev_err(dev, "tx dma channel config failed\n");
+ ret = -ENODEV;
+ goto config_err;
+ }
+
+ return 0;
+
+config_err:
+ dma_free_coherent(&pdev->dev,
+ TX_BUF_L, stm32port->tx_buf,
+ stm32port->tx_dma_buf);
+
+alloc_err:
+ dma_release_channel(stm32port->tx_ch);
+ stm32port->tx_ch = NULL;
+
+ return ret;
+}
+
static int stm32_serial_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@@ -547,6 +857,14 @@ static int stm32_serial_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ret = stm32_of_dma_rx_probe(stm32port, pdev);
+ if (ret)
+ dev_info(&pdev->dev, "interrupt mode used for rx (no dma)\n");
+
+ ret = stm32_of_dma_tx_probe(stm32port, pdev);
+ if (ret)
+ dev_info(&pdev->dev, "interrupt mode used for tx (no dma)\n");
+
platform_set_drvdata(pdev, &stm32port->port);
return 0;
@@ -556,6 +874,27 @@ static int stm32_serial_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
+
+ if (stm32_port->rx_ch)
+ dma_release_channel(stm32_port->rx_ch);
+
+ if (stm32_port->rx_dma_buf)
+ dma_free_coherent(&pdev->dev,
+ RX_BUF_L, stm32_port->rx_buf,
+ stm32_port->rx_dma_buf);
+
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+
+ if (stm32_port->tx_ch)
+ dma_release_channel(stm32_port->tx_ch);
+
+ if (stm32_port->tx_dma_buf)
+ dma_free_coherent(&pdev->dev,
+ TX_BUF_L, stm32_port->tx_buf,
+ stm32_port->tx_dma_buf);
clk_disable_unprepare(stm32_port->clk);
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index 75f8388..41d9749 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -99,6 +99,9 @@ struct stm32_usart_info stm32f7_info = {
/* Dummy bits */
#define USART_SR_DUMMY_RX BIT(16)
+/* USART_ICR (F7) */
+#define USART_CR_TC BIT(6)
+
/* USART_DR */
#define USART_DR_MASK GENMASK(8, 0)
@@ -204,10 +207,21 @@ struct stm32_usart_info stm32f7_info = {
#define STM32_SERIAL_NAME "ttyS"
#define STM32_MAX_PORTS 6
+#define RX_BUF_L 200 /* dma rx buffer length */
+#define RX_BUF_P RX_BUF_L /* dma rx buffer period */
+#define TX_BUF_L 200 /* dma tx buffer length */
+
struct stm32_port {
struct uart_port port;
struct clk *clk;
struct stm32_usart_info *info;
+ struct dma_chan *rx_ch; /* dma rx channel */
+ dma_addr_t rx_dma_buf; /* dma rx buffer bus address */
+ unsigned char *rx_buf; /* dma rx buffer cpu address */
+ struct dma_chan *tx_ch; /* dma tx channel */
+ dma_addr_t tx_dma_buf; /* dma tx buffer bus address */
+ unsigned char *tx_buf; /* dma tx buffer cpu address */
+ bool tx_dma_busy; /* dma tx busy */
bool hw_flow_control;
};
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 08/11] serial: stm32: adding dma support
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
This patch adds dma mode support for rx and tx
with pio mode as fallback in case of dma error.
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 520e7de..24c4d82 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -11,26 +11,31 @@
#define SUPPORT_SYSRQ
#endif
-#include <linux/module.h>
-#include <linux/serial.h>
+#include <linux/clk.h>
#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-direction.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
+#include <linux/iopoll.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/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/serial_core.h>
-#include <linux/clk.h>
+#include <linux/serial.h>
+#include <linux/spinlock.h>
+#include <linux/sysrq.h>
+#include <linux/tty_flip.h>
+#include <linux/tty.h>
#include "stm32-usart.h"
static void stm32_stop_tx(struct uart_port *port);
+static void stm32_transmit_chars(struct uart_port *port);
static inline struct stm32_port *to_stm32_port(struct uart_port *port)
{
@@ -55,7 +60,48 @@ static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
writel_relaxed(val, port->membase + reg);
}
-static void stm32_receive_chars(struct uart_port *port)
+int stm32_pending_rx(struct uart_port *port, u32 *sr, int *last_res,
+ bool threaded)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ enum dma_status status;
+ struct dma_tx_state state;
+
+ *sr = readl_relaxed(port->membase + ofs->isr);
+
+ if (threaded && stm32_port->rx_ch) {
+ status = dmaengine_tx_status(stm32_port->rx_ch,
+ stm32_port->rx_ch->cookie,
+ &state);
+ if ((status == DMA_IN_PROGRESS) &&
+ (*last_res != state.residue))
+ return 1;
+ else
+ return 0;
+ } else if (*sr & USART_SR_RXNE) {
+ return 1;
+ }
+ return 0;
+}
+
+unsigned long stm32_get_char(struct uart_port *port, u32 *sr, int *last_res)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ unsigned long c;
+
+ if (stm32_port->rx_ch) {
+ c = stm32_port->rx_buf[RX_BUF_L - (*last_res)--];
+ if ((*last_res) == 0)
+ *last_res = RX_BUF_L;
+ return c;
+ } else {
+ return readl_relaxed(port->membase + ofs->rdr);
+ }
+}
+
+static void stm32_receive_chars(struct uart_port *port, bool threaded)
{
struct tty_port *tport = &port->state->port;
struct stm32_port *stm32_port = to_stm32_port(port);
@@ -63,13 +109,14 @@ static void stm32_receive_chars(struct uart_port *port)
unsigned long c;
u32 sr;
char flag;
+ static int last_res = RX_BUF_L;
if (port->irq_wake)
pm_wakeup_event(tport->tty->dev, 0);
- while ((sr = readl_relaxed(port->membase + ofs->isr)) & USART_SR_RXNE) {
+ while (stm32_pending_rx(port, &sr, &last_res, threaded)) {
sr |= USART_SR_DUMMY_RX;
- c = readl_relaxed(port->membase + ofs->rdr);
+ c = stm32_get_char(port, &sr, &last_res);
flag = TTY_NORMAL;
port->icount.rx++;
@@ -110,6 +157,124 @@ static void stm32_receive_chars(struct uart_port *port)
spin_lock(&port->lock);
}
+static void stm32_tx_dma_complete(void *arg)
+{
+ struct uart_port *port = arg;
+ struct stm32_port *stm32port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ unsigned int isr;
+ int ret;
+
+ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+ isr,
+ (isr & USART_SR_TC),
+ 10, 100000);
+
+ if (ret)
+ dev_err(port->dev, "terminal count not set\n");
+
+ if (ofs->icr == UNDEF_REG)
+ stm32_clr_bits(port, ofs->isr, USART_SR_TC);
+ else
+ stm32_set_bits(port, ofs->icr, USART_CR_TC);
+
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+ stm32port->tx_dma_busy = false;
+
+ /* Let's see if we have pending data to send */
+ stm32_transmit_chars(port);
+}
+
+static void stm32_transmit_chars_pio(struct uart_port *port)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct circ_buf *xmit = &port->state->xmit;
+ unsigned int isr;
+ int ret;
+
+ if (stm32_port->tx_dma_busy) {
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+ stm32_port->tx_dma_busy = false;
+ }
+
+ ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+ isr,
+ (isr & USART_SR_TXE),
+ 10, 100);
+
+ if (ret)
+ dev_err(port->dev, "tx empty not set\n");
+
+ stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE);
+
+ writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+}
+
+static void stm32_transmit_chars_dma(struct uart_port *port)
+{
+ struct stm32_port *stm32port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct circ_buf *xmit = &port->state->xmit;
+ struct dma_async_tx_descriptor *desc = NULL;
+ dma_cookie_t cookie;
+ unsigned int count, i;
+
+ if (stm32port->tx_dma_busy)
+ return;
+
+ stm32port->tx_dma_busy = true;
+
+ count = uart_circ_chars_pending(xmit);
+
+ if (count > TX_BUF_L)
+ count = TX_BUF_L;
+
+ if (xmit->tail < xmit->head) {
+ memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], count);
+ } else {
+ size_t one = UART_XMIT_SIZE - xmit->tail;
+ size_t two;
+
+ if (one > count)
+ one = count;
+ two = count - one;
+
+ memcpy(&stm32port->tx_buf[0], &xmit->buf[xmit->tail], one);
+ if (two)
+ memcpy(&stm32port->tx_buf[one], &xmit->buf[0], two);
+ }
+
+ desc = dmaengine_prep_slave_single(stm32port->tx_ch,
+ stm32port->tx_dma_buf,
+ count,
+ DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT);
+
+ if (!desc) {
+ for (i = count; i > 0; i--)
+ stm32_transmit_chars_pio(port);
+ return;
+ }
+
+ desc->callback = stm32_tx_dma_complete;
+ desc->callback_param = port;
+
+ /* Push current DMA TX transaction in the pending queue */
+ cookie = dmaengine_submit(desc);
+
+ /* Issue pending DMA TX requests */
+ dma_async_issue_pending(stm32port->tx_ch);
+
+ stm32_clr_bits(port, ofs->isr, USART_SR_TC);
+ stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT);
+
+ xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+ port->icount.tx += count;
+}
+
static void stm32_transmit_chars(struct uart_port *port)
{
struct stm32_port *stm32_port = to_stm32_port(port);
@@ -117,9 +282,13 @@ static void stm32_transmit_chars(struct uart_port *port)
struct circ_buf *xmit = &port->state->xmit;
if (port->x_char) {
+ if (stm32_port->tx_dma_busy)
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
writel_relaxed(port->x_char, port->membase + ofs->tdr);
port->x_char = 0;
port->icount.tx++;
+ if (stm32_port->tx_dma_busy)
+ stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT);
return;
}
@@ -133,9 +302,10 @@ static void stm32_transmit_chars(struct uart_port *port)
return;
}
- writel_relaxed(xmit->buf[xmit->tail], port->membase + ofs->tdr);
- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
- port->icount.tx++;
+ if (stm32_port->tx_ch)
+ stm32_transmit_chars_dma(port);
+ else
+ stm32_transmit_chars_pio(port);
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port);
@@ -151,16 +321,30 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
- spin_lock(&port->lock);
-
sr = readl_relaxed(port->membase + ofs->isr);
- if (sr & USART_SR_RXNE)
- stm32_receive_chars(port);
+ if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch))
+ stm32_receive_chars(port, false);
- if (sr & USART_SR_TXE)
+ if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch))
stm32_transmit_chars(port);
+ if (stm32_port->rx_ch)
+ return IRQ_WAKE_THREAD;
+ else
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t stm32_threaded_interrupt(int irq, void *ptr)
+{
+ struct uart_port *port = ptr;
+ struct stm32_port *stm32_port = to_stm32_port(port);
+
+ spin_lock(&port->lock);
+
+ if (stm32_port->rx_ch)
+ stm32_receive_chars(port, true);
+
spin_unlock(&port->lock);
return IRQ_HANDLED;
@@ -203,14 +387,12 @@ static void stm32_stop_tx(struct uart_port *port)
/* There are probably characters waiting to be transmitted. */
static void stm32_start_tx(struct uart_port *port)
{
- struct stm32_port *stm32_port = to_stm32_port(port);
- struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
struct circ_buf *xmit = &port->state->xmit;
if (uart_circ_empty(xmit))
return;
- stm32_set_bits(port, ofs->cr1, USART_CR1_TXEIE | USART_CR1_TE);
+ stm32_transmit_chars(port);
}
/* Throttle the remote when input buffer is about to overflow. */
@@ -259,7 +441,9 @@ static int stm32_startup(struct uart_port *port)
u32 val;
int ret;
- ret = request_irq(port->irq, stm32_interrupt, 0, name, port);
+ ret = request_threaded_irq(port->irq, stm32_interrupt,
+ stm32_threaded_interrupt,
+ IRQF_NO_SUSPEND, name, port);
if (ret)
return ret;
@@ -376,6 +560,9 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
if ((termios->c_cflag & CREAD) == 0)
port->ignore_status_mask |= USART_SR_DUMMY_RX;
+ if (stm32_port->rx_ch)
+ cr3 |= USART_CR3_DMAR;
+
writel_relaxed(cr3, port->membase + ofs->cr3);
writel_relaxed(cr2, port->membase + ofs->cr2);
writel_relaxed(cr1, port->membase + ofs->cr1);
@@ -523,6 +710,129 @@ static const struct of_device_id stm32_match[] = {
MODULE_DEVICE_TABLE(of, stm32_match);
#endif
+static int stm32_of_dma_rx_probe(struct stm32_port *stm32port,
+ struct platform_device *pdev)
+{
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct uart_port *port = &stm32port->port;
+ struct device *dev = &pdev->dev;
+ struct dma_slave_config config;
+ struct dma_async_tx_descriptor *desc = NULL;
+ dma_cookie_t cookie;
+ int ret;
+
+ /* Request DMA RX channel */
+ stm32port->rx_ch = dma_request_slave_channel(dev, "rx");
+ if (!stm32port->rx_ch) {
+ dev_info(dev, "rx dma alloc failed\n");
+ return -ENODEV;
+ }
+ stm32port->rx_buf = dma_alloc_coherent(&pdev->dev, RX_BUF_L,
+ &stm32port->rx_dma_buf,
+ GFP_KERNEL);
+ if (!stm32port->rx_buf) {
+ ret = -ENOMEM;
+ goto alloc_err;
+ }
+
+ /* Configure DMA channel */
+ memset(&config, 0, sizeof(config));
+ config.src_addr = (dma_addr_t)port->membase + ofs->rdr;
+ config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
+ ret = dmaengine_slave_config(stm32port->rx_ch, &config);
+ if (ret < 0) {
+ dev_err(dev, "rx dma channel config failed\n");
+ ret = -ENODEV;
+ goto config_err;
+ }
+
+ /* Prepare a DMA cyclic transaction */
+ desc = dmaengine_prep_dma_cyclic(stm32port->rx_ch,
+ stm32port->rx_dma_buf,
+ RX_BUF_L, RX_BUF_P, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT);
+ if (!desc) {
+ dev_err(dev, "rx dma prep cyclic failed\n");
+ ret = -ENODEV;
+ goto config_err;
+ }
+
+ /* No callback as dma buffer is drained on usart interrupt */
+ desc->callback = NULL;
+ desc->callback_param = NULL;
+
+ /* Push current DMA transaction in the pending queue */
+ cookie = dmaengine_submit(desc);
+
+ /* Issue pending DMA requests */
+ dma_async_issue_pending(stm32port->rx_ch);
+
+ return 0;
+
+config_err:
+ dma_free_coherent(&pdev->dev,
+ RX_BUF_L, stm32port->rx_buf,
+ stm32port->rx_dma_buf);
+
+alloc_err:
+ dma_release_channel(stm32port->rx_ch);
+ stm32port->rx_ch = NULL;
+
+ return ret;
+}
+
+static int stm32_of_dma_tx_probe(struct stm32_port *stm32port,
+ struct platform_device *pdev)
+{
+ struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
+ struct uart_port *port = &stm32port->port;
+ struct device *dev = &pdev->dev;
+ struct dma_slave_config config;
+ int ret;
+
+ stm32port->tx_dma_busy = false;
+
+ /* Request DMA TX channel */
+ stm32port->tx_ch = dma_request_slave_channel(dev, "tx");
+ if (!stm32port->tx_ch) {
+ dev_info(dev, "tx dma alloc failed\n");
+ return -ENODEV;
+ }
+ stm32port->tx_buf = dma_alloc_coherent(&pdev->dev, TX_BUF_L,
+ &stm32port->tx_dma_buf,
+ GFP_KERNEL);
+ if (!stm32port->tx_buf) {
+ ret = -ENOMEM;
+ goto alloc_err;
+ }
+
+ /* Configure DMA channel */
+ memset(&config, 0, sizeof(config));
+ config.dst_addr = (dma_addr_t)port->membase + ofs->tdr;
+ config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+
+ ret = dmaengine_slave_config(stm32port->tx_ch, &config);
+ if (ret < 0) {
+ dev_err(dev, "tx dma channel config failed\n");
+ ret = -ENODEV;
+ goto config_err;
+ }
+
+ return 0;
+
+config_err:
+ dma_free_coherent(&pdev->dev,
+ TX_BUF_L, stm32port->tx_buf,
+ stm32port->tx_dma_buf);
+
+alloc_err:
+ dma_release_channel(stm32port->tx_ch);
+ stm32port->tx_ch = NULL;
+
+ return ret;
+}
+
static int stm32_serial_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@@ -547,6 +857,14 @@ static int stm32_serial_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ret = stm32_of_dma_rx_probe(stm32port, pdev);
+ if (ret)
+ dev_info(&pdev->dev, "interrupt mode used for rx (no dma)\n");
+
+ ret = stm32_of_dma_tx_probe(stm32port, pdev);
+ if (ret)
+ dev_info(&pdev->dev, "interrupt mode used for tx (no dma)\n");
+
platform_set_drvdata(pdev, &stm32port->port);
return 0;
@@ -556,6 +874,27 @@ static int stm32_serial_remove(struct platform_device *pdev)
{
struct uart_port *port = platform_get_drvdata(pdev);
struct stm32_port *stm32_port = to_stm32_port(port);
+ struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR);
+
+ if (stm32_port->rx_ch)
+ dma_release_channel(stm32_port->rx_ch);
+
+ if (stm32_port->rx_dma_buf)
+ dma_free_coherent(&pdev->dev,
+ RX_BUF_L, stm32_port->rx_buf,
+ stm32_port->rx_dma_buf);
+
+ stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+
+ if (stm32_port->tx_ch)
+ dma_release_channel(stm32_port->tx_ch);
+
+ if (stm32_port->tx_dma_buf)
+ dma_free_coherent(&pdev->dev,
+ TX_BUF_L, stm32_port->tx_buf,
+ stm32_port->tx_dma_buf);
clk_disable_unprepare(stm32_port->clk);
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index 75f8388..41d9749 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -99,6 +99,9 @@ struct stm32_usart_info stm32f7_info = {
/* Dummy bits */
#define USART_SR_DUMMY_RX BIT(16)
+/* USART_ICR (F7) */
+#define USART_CR_TC BIT(6)
+
/* USART_DR */
#define USART_DR_MASK GENMASK(8, 0)
@@ -204,10 +207,21 @@ struct stm32_usart_info stm32f7_info = {
#define STM32_SERIAL_NAME "ttyS"
#define STM32_MAX_PORTS 6
+#define RX_BUF_L 200 /* dma rx buffer length */
+#define RX_BUF_P RX_BUF_L /* dma rx buffer period */
+#define TX_BUF_L 200 /* dma tx buffer length */
+
struct stm32_port {
struct uart_port port;
struct clk *clk;
struct stm32_usart_info *info;
+ struct dma_chan *rx_ch; /* dma rx channel */
+ dma_addr_t rx_dma_buf; /* dma rx buffer bus address */
+ unsigned char *rx_buf; /* dma rx buffer cpu address */
+ struct dma_chan *tx_ch; /* dma tx channel */
+ dma_addr_t tx_dma_buf; /* dma tx buffer bus address */
+ unsigned char *tx_buf; /* dma tx buffer cpu address */
+ bool tx_dma_busy; /* dma tx busy */
bool hw_flow_control;
};
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 09/11] serial: stm32: fix spin_lock management
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 24c4d82..3b99d79 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -321,6 +321,8 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
+ spin_lock(&port->lock);
+
sr = readl_relaxed(port->membase + ofs->isr);
if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch))
@@ -329,6 +331,8 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch))
stm32_transmit_chars(port);
+ spin_unlock(&port->lock);
+
if (stm32_port->rx_ch)
return IRQ_WAKE_THREAD;
else
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 09/11] serial: stm32: fix spin_lock management
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 24c4d82..3b99d79 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -321,6 +321,8 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
u32 sr;
+ spin_lock(&port->lock);
+
sr = readl_relaxed(port->membase + ofs->isr);
if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch))
@@ -329,6 +331,8 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr)
if ((sr & USART_SR_TXE) && !(stm32_port->tx_ch))
stm32_transmit_chars(port);
+ spin_unlock(&port->lock);
+
if (stm32_port->rx_ch)
return IRQ_WAKE_THREAD;
else
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 10/11] serial: stm32: fix uart enable management
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 3b99d79..4d3001b 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -461,9 +461,11 @@ static void stm32_shutdown(struct uart_port *port)
{
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
u32 val;
val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ val |= BIT(cfg->uart_enable_bit);
stm32_clr_bits(port, ofs->cr1, val);
free_irq(port->irq, port);
@@ -923,6 +925,7 @@ static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
struct uart_port *port = &stm32_ports[co->index].port;
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
unsigned long flags;
u32 old_cr1, new_cr1;
int locked = 1;
@@ -935,9 +938,10 @@ static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
else
spin_lock(&port->lock);
- /* Save and disable interrupts */
+ /* Save and disable interrupts, enable the transmitter */
old_cr1 = readl_relaxed(port->membase + ofs->cr1);
new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
+ new_cr1 |= USART_CR1_TE | BIT(cfg->uart_enable_bit);
writel_relaxed(new_cr1, port->membase + ofs->cr1);
uart_console_write(port, s, cnt, stm32_console_putchar);
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 10/11] serial: stm32: fix uart enable management
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 3b99d79..4d3001b 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -461,9 +461,11 @@ static void stm32_shutdown(struct uart_port *port)
{
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
u32 val;
val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ val |= BIT(cfg->uart_enable_bit);
stm32_clr_bits(port, ofs->cr1, val);
free_irq(port->irq, port);
@@ -923,6 +925,7 @@ static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
struct uart_port *port = &stm32_ports[co->index].port;
struct stm32_port *stm32_port = to_stm32_port(port);
struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+ struct stm32_usart_config *cfg = &stm32_port->info->cfg;
unsigned long flags;
u32 old_cr1, new_cr1;
int locked = 1;
@@ -935,9 +938,10 @@ static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
else
spin_lock(&port->lock);
- /* Save and disable interrupts */
+ /* Save and disable interrupts, enable the transmitter */
old_cr1 = readl_relaxed(port->membase + ofs->cr1);
new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
+ new_cr1 |= USART_CR1_TE | BIT(cfg->uart_enable_bit);
writel_relaxed(new_cr1, port->membase + ofs->cr1);
uart_console_write(port, s, cnt, stm32_console_putchar);
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 11/11] ARM: DT: STM32: add dma for usart1 on F429
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-15 16:42 ` Alexandre TORGUE
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: Maxime Coquelin, Rob Herring, gerald.baeza-qxv4g6HH51o,
Greg Kroah-Hartman, Jiri Slaby
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 35df462..227376b 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -161,6 +161,9 @@
interrupts = <37>;
clocks = <&rcc 0 164>;
status = "disabled";
+ dmas = <&dma2 2 4 0x414 0x0>,
+ <&dma2 7 4 0x414 0x0>;
+ dma-names = "rx", "tx";
};
usart6: serial@40011400 {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH 11/11] ARM: DT: STM32: add dma for usart1 on F429
@ 2016-09-15 16:42 ` Alexandre TORGUE
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre TORGUE @ 2016-09-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index 35df462..227376b 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -161,6 +161,9 @@
interrupts = <37>;
clocks = <&rcc 0 164>;
status = "disabled";
+ dmas = <&dma2 2 4 0x414 0x0>,
+ <&dma2 7 4 0x414 0x0>;
+ dma-names = "rx", "tx";
};
usart6: serial at 40011400 {
--
1.9.1
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-23 15:29 ` Rob Herring
-1 siblings, 0 replies; 34+ messages in thread
From: Rob Herring @ 2016-09-23 15:29 UTC (permalink / raw)
To: Alexandre TORGUE
Cc: Maxime Coquelin, gerald.baeza-qxv4g6HH51o, Greg Kroah-Hartman,
Jiri Slaby, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
> This adds documentation of device tree bindings for the
> STM32 USART
Please make your subject prefixes consistent and drop "DOCUMENTATION".
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
>
> 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..75b1400
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> @@ -0,0 +1,34 @@
> +* STMicroelectronics STM32 USART
> +
> +Required properties:
> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
> +the device supports synchronous mode and is compatible with
> +stm32(f4) or stm32f7.
Why not put f4 in the compatible string. stm32 is too generic.
What determines sync mode or not? If it is IP configuration fixed in the
design, then this is fine. If it is user choice or board dependent, then
use a separate property.
> +- 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";
What are valid combinations? usart is sync only, not sync and async?
> + reg = <0x40004400 0x400>;
> + interrupts = <38>;
> + clocks = <&clk_pclk1>;
> + st,hw-flow-ctrl;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
> +};
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
@ 2016-09-23 15:29 ` Rob Herring
0 siblings, 0 replies; 34+ messages in thread
From: Rob Herring @ 2016-09-23 15:29 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
> This adds documentation of device tree bindings for the
> STM32 USART
Please make your subject prefixes consistent and drop "DOCUMENTATION".
>
> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
>
> 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..75b1400
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> @@ -0,0 +1,34 @@
> +* STMicroelectronics STM32 USART
> +
> +Required properties:
> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
> +the device supports synchronous mode and is compatible with
> +stm32(f4) or stm32f7.
Why not put f4 in the compatible string. stm32 is too generic.
What determines sync mode or not? If it is IP configuration fixed in the
design, then this is fine. If it is user choice or board dependent, then
use a separate property.
> +- 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 at 40004c00 {
> + compatible = "st,stm32-uart";
> + reg = <0x40004c00 0x400>;
> + interrupts = <52>;
> + clocks = <&clk_pclk1>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usart4>;
> +};
> +
> +usart2: serial at 40004400 {
> + compatible = "st,stm32-usart", "st,stm32-uart";
What are valid combinations? usart is sync only, not sync and async?
> + reg = <0x40004400 0x400>;
> + interrupts = <38>;
> + clocks = <&clk_pclk1>;
> + st,hw-flow-ctrl;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
> +};
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 07/11] dt-bindings: Add DMA bindings for STM32 USART
2016-09-15 16:42 ` Alexandre TORGUE
@ 2016-09-23 15:30 ` Rob Herring
-1 siblings, 0 replies; 34+ messages in thread
From: Rob Herring @ 2016-09-23 15:30 UTC (permalink / raw)
To: Alexandre TORGUE
Cc: Maxime Coquelin, gerald.baeza-qxv4g6HH51o, Greg Kroah-Hartman,
Jiri Slaby, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
On Thu, Sep 15, 2016 at 06:42:39PM +0200, Alexandre TORGUE wrote:
> Signed-off-by: Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
Squash this with the other binding patch. You are describing the h/w
block, do so completely.
>
> diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> index 75b1400..85ec5f2 100644
> --- a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> @@ -12,6 +12,8 @@ stm32(f4) or stm32f7.
> Optional properties:
> - pinctrl: The reference on the pins configuration
> - st,hw-flow-ctrl: bool flag to enable hardware flow control.
> +- dmas: phandle(s) to DMA controller node(s). Refer to stm32-dma.txt
> +- dma-names: "rx" and/or "tx"
>
> Examples:
> usart4: serial@40004c00 {
> @@ -32,3 +34,13 @@ usart2: serial@40004400 {
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
> };
> +
> +usart1: serial@40011000 {
> + compatible = "st,stm32-usart", "st,stm32-uart";
> + reg = <0x40011000 0x400>;
> + interrupts = <37>;
> + clocks = <&rcc 0 164>;
> + dmas = <&dma2 2 4 0x414 0x0>,
> + <&dma2 7 4 0x414 0x0>;
> + dma-names = "rx", "tx";
> +};
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 07/11] dt-bindings: Add DMA bindings for STM32 USART
@ 2016-09-23 15:30 ` Rob Herring
0 siblings, 0 replies; 34+ messages in thread
From: Rob Herring @ 2016-09-23 15:30 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Sep 15, 2016 at 06:42:39PM +0200, Alexandre TORGUE wrote:
> Signed-off-by: Gerald Baeza <gerald.baeza@st.com>
> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
Squash this with the other binding patch. You are describing the h/w
block, do so completely.
>
> diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> index 75b1400..85ec5f2 100644
> --- a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
> @@ -12,6 +12,8 @@ stm32(f4) or stm32f7.
> Optional properties:
> - pinctrl: The reference on the pins configuration
> - st,hw-flow-ctrl: bool flag to enable hardware flow control.
> +- dmas: phandle(s) to DMA controller node(s). Refer to stm32-dma.txt
> +- dma-names: "rx" and/or "tx"
>
> Examples:
> usart4: serial at 40004c00 {
> @@ -32,3 +34,13 @@ usart2: serial at 40004400 {
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
> };
> +
> +usart1: serial at 40011000 {
> + compatible = "st,stm32-usart", "st,stm32-uart";
> + reg = <0x40011000 0x400>;
> + interrupts = <37>;
> + clocks = <&rcc 0 164>;
> + dmas = <&dma2 2 4 0x414 0x0>,
> + <&dma2 7 4 0x414 0x0>;
> + dma-names = "rx", "tx";
> +};
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
2016-09-23 15:29 ` Rob Herring
@ 2016-10-05 14:09 ` Gerald Baeza
-1 siblings, 0 replies; 34+ messages in thread
From: Gerald Baeza @ 2016-10-05 14:09 UTC (permalink / raw)
To: Rob Herring, Alexandre TORGUE
Cc: devicetree, Maxime Coquelin, Greg Kroah-Hartman, linux-serial,
Jiri Slaby, linux-arm-kernel
On 09/23/2016 05:29 PM, Rob Herring wrote:
> On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
>> This adds documentation of device tree bindings for the
>> STM32 USART
>
> Please make your subject prefixes consistent and drop "DOCUMENTATION".
>
Ok, thanks
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
>>
>> 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..75b1400
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>> @@ -0,0 +1,34 @@
>> +* STMicroelectronics STM32 USART
>> +
>> +Required properties:
>> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
>> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
>> +the device supports synchronous mode and is compatible with
>> +stm32(f4) or stm32f7.
>
> Why not put f4 in the compatible string. stm32 is too generic.
The initial binding is not in current kernel so it has been put in this
serie as PATCH 07/11. It will be squashed with this one, as you requested.
But the driver tty/serial/stm32-usart.c was already upstreamed and it
already mentions the "st,stm32-usart" and "st,stm32-uart" for stm32f4 so
I kept this as it for backward compatibility for those who already use
the driver.
I do not have the history to explain this inconsistency but can you
confirm that keeping the existing compatible values from the driver is
the good approach please?
> What determines sync mode or not? If it is IP configuration fixed in the
> design, then this is fine. If it is user choice or board dependent, then
> use a separate property.
This is IP configuration fixed in the design, indeed.
>> +- 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";
>
> What are valid combinations? usart is sync only, not sync and async?
usart (sync and async) is a superset of uart (async).
But the current driver does not use the synchronous mode, so the
distinction is just here to be consistent with the reference manual
instances naming (so configuration).
>> + reg = <0x40004400 0x400>;
>> + interrupts = <38>;
>> + clocks = <&clk_pclk1>;
>> + st,hw-flow-ctrl;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
>> +};
>> --
>> 1.9.1
>>
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
@ 2016-10-05 14:09 ` Gerald Baeza
0 siblings, 0 replies; 34+ messages in thread
From: Gerald Baeza @ 2016-10-05 14:09 UTC (permalink / raw)
To: linux-arm-kernel
On 09/23/2016 05:29 PM, Rob Herring wrote:
> On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
>> This adds documentation of device tree bindings for the
>> STM32 USART
>
> Please make your subject prefixes consistent and drop "DOCUMENTATION".
>
Ok, thanks
>>
>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
>>
>> 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..75b1400
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>> @@ -0,0 +1,34 @@
>> +* STMicroelectronics STM32 USART
>> +
>> +Required properties:
>> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
>> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
>> +the device supports synchronous mode and is compatible with
>> +stm32(f4) or stm32f7.
>
> Why not put f4 in the compatible string. stm32 is too generic.
The initial binding is not in current kernel so it has been put in this
serie as PATCH 07/11. It will be squashed with this one, as you requested.
But the driver tty/serial/stm32-usart.c was already upstreamed and it
already mentions the "st,stm32-usart" and "st,stm32-uart" for stm32f4 so
I kept this as it for backward compatibility for those who already use
the driver.
I do not have the history to explain this inconsistency but can you
confirm that keeping the existing compatible values from the driver is
the good approach please?
> What determines sync mode or not? If it is IP configuration fixed in the
> design, then this is fine. If it is user choice or board dependent, then
> use a separate property.
This is IP configuration fixed in the design, indeed.
>> +- 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 at 40004c00 {
>> + compatible = "st,stm32-uart";
>> + reg = <0x40004c00 0x400>;
>> + interrupts = <52>;
>> + clocks = <&clk_pclk1>;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usart4>;
>> +};
>> +
>> +usart2: serial at 40004400 {
>> + compatible = "st,stm32-usart", "st,stm32-uart";
>
> What are valid combinations? usart is sync only, not sync and async?
usart (sync and async) is a superset of uart (async).
But the current driver does not use the synchronous mode, so the
distinction is just here to be consistent with the reference manual
instances naming (so configuration).
>> + reg = <0x40004400 0x400>;
>> + interrupts = <38>;
>> + clocks = <&clk_pclk1>;
>> + st,hw-flow-ctrl;
>> + pinctrl-names = "default";
>> + pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
>> +};
>> --
>> 1.9.1
>>
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
2016-10-05 14:09 ` Gerald Baeza
@ 2016-10-05 15:13 ` Rob Herring
-1 siblings, 0 replies; 34+ messages in thread
From: Rob Herring @ 2016-10-05 15:13 UTC (permalink / raw)
To: Gerald Baeza
Cc: Alexandre TORGUE, Maxime Coquelin, Greg Kroah-Hartman,
Jiri Slaby, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
On Wed, Oct 5, 2016 at 9:09 AM, Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org> wrote:
> On 09/23/2016 05:29 PM, Rob Herring wrote:
>>
>> On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
>>>
>>> This adds documentation of device tree bindings for the
>>> STM32 USART
>>
>>
>> Please make your subject prefixes consistent and drop "DOCUMENTATION".
>>
>
> Ok, thanks
>
>>>
>>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>> Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
>>>
>>> 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..75b1400
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>>> @@ -0,0 +1,34 @@
>>> +* STMicroelectronics STM32 USART
>>> +
>>> +Required properties:
>>> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
>>> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
>>> +the device supports synchronous mode and is compatible with
>>> +stm32(f4) or stm32f7.
>>
>>
>> Why not put f4 in the compatible string. stm32 is too generic.
>
>
> The initial binding is not in current kernel so it has been put in this
> serie as PATCH 07/11. It will be squashed with this one, as you requested.
>
> But the driver tty/serial/stm32-usart.c was already upstreamed and it
> already mentions the "st,stm32-usart" and "st,stm32-uart" for stm32f4 so I
> kept this as it for backward compatibility for those who already use the
> driver.
>
> I do not have the history to explain this inconsistency but can you confirm
> that keeping the existing compatible values from the driver is the good
> approach please?
Yes, keep it as it. Please reformat 1 valid combination per line.
>> What determines sync mode or not? If it is IP configuration fixed in the
>> design, then this is fine. If it is user choice or board dependent, then
>> use a separate property.
>
>
> This is IP configuration fixed in the design, indeed.
>
>>> +- 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";
>>
>>
>> What are valid combinations? usart is sync only, not sync and async?
>
>
> usart (sync and async) is a superset of uart (async).
> But the current driver does not use the synchronous mode, so the distinction
> is just here to be consistent with the reference manual instances naming (so
> configuration).
Okay, but this point is not clear in the compatible text. The
description should allow me to validate the example or a dts file.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
@ 2016-10-05 15:13 ` Rob Herring
0 siblings, 0 replies; 34+ messages in thread
From: Rob Herring @ 2016-10-05 15:13 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Oct 5, 2016 at 9:09 AM, Gerald Baeza <gerald.baeza@st.com> wrote:
> On 09/23/2016 05:29 PM, Rob Herring wrote:
>>
>> On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
>>>
>>> This adds documentation of device tree bindings for the
>>> STM32 USART
>>
>>
>> Please make your subject prefixes consistent and drop "DOCUMENTATION".
>>
>
> Ok, thanks
>
>>>
>>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>>> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
>>>
>>> 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..75b1400
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>>> @@ -0,0 +1,34 @@
>>> +* STMicroelectronics STM32 USART
>>> +
>>> +Required properties:
>>> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
>>> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
>>> +the device supports synchronous mode and is compatible with
>>> +stm32(f4) or stm32f7.
>>
>>
>> Why not put f4 in the compatible string. stm32 is too generic.
>
>
> The initial binding is not in current kernel so it has been put in this
> serie as PATCH 07/11. It will be squashed with this one, as you requested.
>
> But the driver tty/serial/stm32-usart.c was already upstreamed and it
> already mentions the "st,stm32-usart" and "st,stm32-uart" for stm32f4 so I
> kept this as it for backward compatibility for those who already use the
> driver.
>
> I do not have the history to explain this inconsistency but can you confirm
> that keeping the existing compatible values from the driver is the good
> approach please?
Yes, keep it as it. Please reformat 1 valid combination per line.
>> What determines sync mode or not? If it is IP configuration fixed in the
>> design, then this is fine. If it is user choice or board dependent, then
>> use a separate property.
>
>
> This is IP configuration fixed in the design, indeed.
>
>>> +- 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 at 40004c00 {
>>> + compatible = "st,stm32-uart";
>>> + reg = <0x40004c00 0x400>;
>>> + interrupts = <52>;
>>> + clocks = <&clk_pclk1>;
>>> + pinctrl-names = "default";
>>> + pinctrl-0 = <&pinctrl_usart4>;
>>> +};
>>> +
>>> +usart2: serial at 40004400 {
>>> + compatible = "st,stm32-usart", "st,stm32-uart";
>>
>>
>> What are valid combinations? usart is sync only, not sync and async?
>
>
> usart (sync and async) is a superset of uart (async).
> But the current driver does not use the synchronous mode, so the distinction
> is just here to be consistent with the reference manual instances naming (so
> configuration).
Okay, but this point is not clear in the compatible text. The
description should allow me to validate the example or a dts file.
Rob
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
2016-10-05 15:13 ` Rob Herring
@ 2016-10-06 8:00 ` Alexandre Torgue
-1 siblings, 0 replies; 34+ messages in thread
From: Alexandre Torgue @ 2016-10-06 8:00 UTC (permalink / raw)
To: Rob Herring, Gerald Baeza
Cc: Maxime Coquelin, Greg Kroah-Hartman, Jiri Slaby,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Hi Rob,
On 10/05/2016 05:13 PM, Rob Herring wrote:
> On Wed, Oct 5, 2016 at 9:09 AM, Gerald Baeza <gerald.baeza-qxv4g6HH51o@public.gmane.org> wrote:
>> On 09/23/2016 05:29 PM, Rob Herring wrote:
>>>
>>> On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
>>>>
>>>> This adds documentation of device tree bindings for the
>>>> STM32 USART
>>>
>>>
>>> Please make your subject prefixes consistent and drop "DOCUMENTATION".
>>>
>>
>> Ok, thanks
>>
>>>>
>>>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>>> Signed-off-by: Alexandre TORGUE <alexandre.torgue-qxv4g6HH51o@public.gmane.org>
>>>>
>>>> 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..75b1400
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>>>> @@ -0,0 +1,34 @@
>>>> +* STMicroelectronics STM32 USART
>>>> +
>>>> +Required properties:
>>>> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
>>>> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
>>>> +the device supports synchronous mode and is compatible with
>>>> +stm32(f4) or stm32f7.
>>>
>>>
>>> Why not put f4 in the compatible string. stm32 is too generic.
>>
>>
>> The initial binding is not in current kernel so it has been put in this
>> serie as PATCH 07/11. It will be squashed with this one, as you requested.
>>
>> But the driver tty/serial/stm32-usart.c was already upstreamed and it
>> already mentions the "st,stm32-usart" and "st,stm32-uart" for stm32f4 so I
>> kept this as it for backward compatibility for those who already use the
>> driver.
>>
>> I do not have the history to explain this inconsistency but can you confirm
>> that keeping the existing compatible values from the driver is the good
>> approach please?
>
> Yes, keep it as it. Please reformat 1 valid combination per line.
Ok. Do you mean something like:
- compatible: "st,stm32-usart", "st,stm32-uart" For STM32F4 SOC and if
IP supports synchronous mode.
- compatible: "st,stm32-uart" For STM32F4 SOC.
- compatible: "st,stm32f7-usart", "st,stm32f7-uart": For STM32F7 SOC
and if IP supports synchronous mode.
- compatible: "st,stm32f7-uart" For STM32F7 SOC
If you agree, what do you prefer to send modification ? I mean, those
bindings documentation patches are already in linux-next tree. Do you
want a new patch on top of linux-next or do you prefer I resend only
those ones ?
Regards
Alex
>
>>> What determines sync mode or not? If it is IP configuration fixed in the
>>> design, then this is fine. If it is user choice or board dependent, then
>>> use a separate property.
>>
>>
>> This is IP configuration fixed in the design, indeed.
>>
>>>> +- 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";
>>>
>>>
>>> What are valid combinations? usart is sync only, not sync and async?
>>
>>
>> usart (sync and async) is a superset of uart (async).
>> But the current driver does not use the synchronous mode, so the distinction
>> is just here to be consistent with the reference manual instances naming (so
>> configuration).
>
> Okay, but this point is not clear in the compatible text. The
> description should allow me to validate the example or a dts file.
>
> Rob
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings
@ 2016-10-06 8:00 ` Alexandre Torgue
0 siblings, 0 replies; 34+ messages in thread
From: Alexandre Torgue @ 2016-10-06 8:00 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rob,
On 10/05/2016 05:13 PM, Rob Herring wrote:
> On Wed, Oct 5, 2016 at 9:09 AM, Gerald Baeza <gerald.baeza@st.com> wrote:
>> On 09/23/2016 05:29 PM, Rob Herring wrote:
>>>
>>> On Thu, Sep 15, 2016 at 06:42:34PM +0200, Alexandre TORGUE wrote:
>>>>
>>>> This adds documentation of device tree bindings for the
>>>> STM32 USART
>>>
>>>
>>> Please make your subject prefixes consistent and drop "DOCUMENTATION".
>>>
>>
>> Ok, thanks
>>
>>>>
>>>> Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
>>>> Signed-off-by: Alexandre TORGUE <alexandre.torgue@st.com>
>>>>
>>>> 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..75b1400
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
>>>> @@ -0,0 +1,34 @@
>>>> +* STMicroelectronics STM32 USART
>>>> +
>>>> +Required properties:
>>>> +- compatible: Can be either "st,stm32-usart", "st,stm32-uart",
>>>> +"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether
>>>> +the device supports synchronous mode and is compatible with
>>>> +stm32(f4) or stm32f7.
>>>
>>>
>>> Why not put f4 in the compatible string. stm32 is too generic.
>>
>>
>> The initial binding is not in current kernel so it has been put in this
>> serie as PATCH 07/11. It will be squashed with this one, as you requested.
>>
>> But the driver tty/serial/stm32-usart.c was already upstreamed and it
>> already mentions the "st,stm32-usart" and "st,stm32-uart" for stm32f4 so I
>> kept this as it for backward compatibility for those who already use the
>> driver.
>>
>> I do not have the history to explain this inconsistency but can you confirm
>> that keeping the existing compatible values from the driver is the good
>> approach please?
>
> Yes, keep it as it. Please reformat 1 valid combination per line.
Ok. Do you mean something like:
- compatible: "st,stm32-usart", "st,stm32-uart" For STM32F4 SOC and if
IP supports synchronous mode.
- compatible: "st,stm32-uart" For STM32F4 SOC.
- compatible: "st,stm32f7-usart", "st,stm32f7-uart": For STM32F7 SOC
and if IP supports synchronous mode.
- compatible: "st,stm32f7-uart" For STM32F7 SOC
If you agree, what do you prefer to send modification ? I mean, those
bindings documentation patches are already in linux-next tree. Do you
want a new patch on top of linux-next or do you prefer I resend only
those ones ?
Regards
Alex
>
>>> What determines sync mode or not? If it is IP configuration fixed in the
>>> design, then this is fine. If it is user choice or board dependent, then
>>> use a separate property.
>>
>>
>> This is IP configuration fixed in the design, indeed.
>>
>>>> +- 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 at 40004c00 {
>>>> + compatible = "st,stm32-uart";
>>>> + reg = <0x40004c00 0x400>;
>>>> + interrupts = <52>;
>>>> + clocks = <&clk_pclk1>;
>>>> + pinctrl-names = "default";
>>>> + pinctrl-0 = <&pinctrl_usart4>;
>>>> +};
>>>> +
>>>> +usart2: serial at 40004400 {
>>>> + compatible = "st,stm32-usart", "st,stm32-uart";
>>>
>>>
>>> What are valid combinations? usart is sync only, not sync and async?
>>
>>
>> usart (sync and async) is a superset of uart (async).
>> But the current driver does not use the synchronous mode, so the distinction
>> is just here to be consistent with the reference manual instances naming (so
>> configuration).
>
> Okay, but this point is not clear in the compatible text. The
> description should allow me to validate the example or a dts file.
>
> Rob
>
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2016-10-06 8:00 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-15 16:42 [PATCH 00/11] STM32 USART: fixes and new MCU support Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
[not found] ` <1473957763-30629-1-git-send-email-alexandre.torgue-qxv4g6HH51o@public.gmane.org>
2016-09-15 16:42 ` [PATCH 01/11] serial: stm32: adding support for stm32f7 Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 02/11] DOCUMENTATION: dt-bindings: Document the STM32 USART bindings Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
[not found] ` <1473957763-30629-3-git-send-email-alexandre.torgue-qxv4g6HH51o@public.gmane.org>
2016-09-23 15:29 ` Rob Herring
2016-09-23 15:29 ` Rob Herring
2016-10-05 14:09 ` Gerald Baeza
2016-10-05 14:09 ` Gerald Baeza
[not found] ` <dd28f224-3e3b-0a00-f978-16861b946fd1-qxv4g6HH51o@public.gmane.org>
2016-10-05 15:13 ` Rob Herring
2016-10-05 15:13 ` Rob Herring
[not found] ` <CAL_JsqK=VCHcPbupnwLVEWehqJbXfGD1CSZT++A4+N6DD6VqxA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-06 8:00 ` Alexandre Torgue
2016-10-06 8:00 ` Alexandre Torgue
2016-09-15 16:42 ` [PATCH 03/11] serial: stm32: header file creation Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 04/11] serial: stm32: disable tx and rx during shutdown Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 05/11] serial: stm32: correct flow control property spelling Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 06/11] serial: stm32: clock disabling management Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 07/11] dt-bindings: Add DMA bindings for STM32 USART Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
[not found] ` <1473957763-30629-8-git-send-email-alexandre.torgue-qxv4g6HH51o@public.gmane.org>
2016-09-23 15:30 ` Rob Herring
2016-09-23 15:30 ` Rob Herring
2016-09-15 16:42 ` [PATCH 08/11] serial: stm32: adding dma support Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 09/11] serial: stm32: fix spin_lock management Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 10/11] serial: stm32: fix uart enable management Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
2016-09-15 16:42 ` [PATCH 11/11] ARM: DT: STM32: add dma for usart1 on F429 Alexandre TORGUE
2016-09-15 16:42 ` Alexandre TORGUE
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.