serial: mxs-auart: gpios as modem signals
v4 cover serial: mxs-auart: gpios as modem signals
It contains improved version of the old v3 patchset "[PATCH v3] serial: mxs-auart: gpios as modem signals (dirty)"
v3 -> v4 changelog:
[PATCH 1/4] serial: mxs-auart: clean get_mctrl and set_mctrl
* renamed from "serial: mxs-auart: ctrl removed from mxs_auart_port"
* mxs_auart_get_mctrl() read back RTS line. It is removed too.
[PATCH 2/4] serial: mxs-auart: use mctrl_gpio helpers for handling
modem signals
* RTS_AT_AUART() and CTS_AT_AUART() macro defined
* DMA engine disabled if RTS or CTS is GPIO line
* warn if fsl,uart-has-rtscts and RTS/CTS via GPIO are mixed
* CTSEN can't be enabled for hardware flow control block if CTS is defined as GPIO line
* RTSEN can be enabled for hardware flow control block even if RTS is defined as GPIO line.
RTS pin depends on pinctrl configuration which
selects RTS output from hardware flow control block or GPIO line.
* mxs_auart_settermios(): RTS_AT_AUART() and CTS_AT_AUART() used
* mxs_auart_irq_handle(): CTS_AT_AUART() used
* mxs_auart_init_gpios() returns true(success)/false(failure)
* dev_err() message fixed in mxs_auart_probe()
[PATCH 3/4] serial: mxs-auart: add interrupts for modem control lines
* rebased
[PATCH 4/4] serial: mxs-auart: enable PPS support
* coding style: braces in both branches of condition
v2 -> v3 changelog:
* own patches reordered to apply mainline
* patch "serial: mxs-auart: add sysrq support" removed from the patchset and resent as independent
new [PATCH 1/4] serial: mxs-auart: ctrl removed from mxs_auart_port
* the ctrl variable duplicated mctrl, member of uart_port structure in serial_core.h
* the code duplicated uart_update_mctrl() and uart_tiocmget() in serial_core.c
* mxs_auart_get_mctrl() reads back RTS line. It could be removed too but not sure.
[PATCH 2/4] serial: mxs-auart: use mctrl_gpio helpers for handling
modem signals
* mctrl_gpio_free() removed to simplify:
mctrl_gpio_free() is not necessary in mxs_auart_probe() and mxs_auart_remove() because mctrl_gpio_init() does all allocations with devm_* functions.
(see Documentation/serial/driver since kernel 3.16)
* DMA on HW flow control comment updated, still not sure about the comment
* mxs_auart_modem_status() removed from mxs_auart_get_mctrl():
mctrl_gpio_get() does not clear gpio interrupt pendings like 8250_core.c does with MSR.
* mxs_auart_modem_status() moved to [3/4]
If enable_ms() is not called, uart_handle_cts_change() shouldn't be called.
[PATCH 3/4] serial: mxs-auart: add interrupts for modem control lines
* introduces mctrl_prev instead of removed ctrl
* mxs_auart_modem_status() moved from [3/4]
* mxs_auart_modem_status() interrupt_enabled meant s->ms_irq_enabled
[PATCH 4/4] serial: mxs-auart: enable PPS support
* no changes
Janusz Uzycki (4):
serial: mxs-auart: clean get_mctrl and set_mctrl
serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
serial: mxs-auart: add interrupts for modem control lines
serial: mxs-auart: enable PPS support
.../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 +- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 237 +++++++++++++++++++-- 3 files changed, 233 insertions(+), 15 deletions(-)
Signature · 1 line
1.7.11.3
PATCH v4 1/4 serial: mxs-auart: clean get_mctrl and set_mctrl
Russell King:
The only thing which the .get_mctrl method is supposed to do is to return the state of the /input/ lines, which are CTS, DCD, DSR, RI. The output line state is stored in port->mctrl, and is added to the returned value by serial_core when it's required.
RTS output state should not be returned from the .get_mctrl method.
This patch removes ctrl variable from mxs_auart_port and removes useless reading back RTS line.
The ctrl variable in mxs_auart_port duplicated mctrl, member of uart_port structure in serial_core.h.
The removed code from mxs_auart_set_mctrl() and mxs_auart_get_mctrl duplicated uart_update_mctrl() and uart_tiocmget()
in serial_core.c.
---
v3 -> v4 changelog:
[PATCH 1/4] serial: mxs-auart: clean get_mctrl and set_mctrl
* renamed from "serial: mxs-auart: ctrl removed from mxs_auart_port"
* mxs_auart_get_mctrl() read back RTS line. It is removed too.
v2 -> v3 changelog:
The patch was introduced:
new [PATCH 1/4] serial: mxs-auart: ctrl removed from mxs_auart_port
* the ctrl variable duplicated mctrl, member of uart_port structure in serial_core.h
* the code duplicated uart_update_mctrl() and uart_tiocmget() in serial_core.c
* mxs_auart_get_mctrl() reads back RTS line. It could be removed too but not sure.
--- drivers/tty/serial/mxs-auart.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-)
drivers/tty/serial/mxs-auart.c +1 -13
@@ -143,7 +143,6 @@ struct mxs_auart_port {#define MXS_AUART_DMA_RX_READY 3/* bit 3 */ #define MXS_AUART_RTSCTS 4/* bit 4 */ unsigned long flags; -unsigned int ctrl;enum mxs_auart_type devtype;unsigned int irq;
@@ -406,8 +405,6 @@ static void mxs_auart_release_port(struct uart_port *u)static void mxs_auart_set_mctrl (struct uart_port *u,unsigned mctrl) { -struct mxs_auart_port *s =to_auart_port (u); -u32 ctrl =readl (u->membase +AUART_CTRL2 ); ctrl &= ~(AUART_CTRL2_RTSEN |AUART_CTRL2_RTS );
@@ -418,24 +415,17 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) ctrl |=AUART_CTRL2_RTS ; } - s->ctrl = mctrl;writel (ctrl, u->membase +AUART_CTRL2 ); }static u32 mxs_auart_get_mctrl (struct uart_port *u) { -struct mxs_auart_port *s =to_auart_port (u);u32 stat =readl (u->membase +AUART_STAT ); -int ctrl2 =readl (u->membase +AUART_CTRL2 ); -u32 mctrl = s->ctrl; +u32 mctrl =0 ; - mctrl &= ~TIOCM_CTS ;if (stat &AUART_STAT_CTS ) mctrl |=TIOCM_CTS ; -if (ctrl2 &AUART_CTRL2_RTS ) - mctrl |=TIOCM_RTS ; -return mctrl; }
@@ -1071,8 +1061,6 @@ static int mxs_auart_probe(struct platform_device *pdev) s->port.type =PORT_IMX ; s->port.dev = s->dev = &pdev->dev; - s->ctrl =0 ; - s->irq =platform_get_irq (pdev,0 ); s->port.irq = s->irq; ret =request_irq (s->irq, mxs_auart_irq_handle,0 ,dev_name (&pdev->dev), s);
Signature · 1 line
1.7.11.3
PATCH v4 1/4 serial: mxs-auart: clean get_mctrl and set_mctrl
Quoted 86 lines · Janusz Uzycki
Russell King:
The only thing which the .get_mctrl method is supposed to do is to return the state of the /input/ lines, which are CTS, DCD, DSR, RI. The output line state is stored inport->mctrl, and is added to the returned value byserial_corewhen it's required.
RTS output state should not be returned from the .get_mctrl method.This patch removes ctrl variable from
mxs_auart_portand removes useless reading back RTS line.The ctrl variable in
mxs_auart_portduplicated mctrl, member ofuart_portstructure inserial_core.h.
The removed code frommxs_auart_set_mctrl()andmxs_auart_get_mctrlduplicateduart_update_mctrl()anduart_tiocmget()
inserial_core.c.Signed-off-by Janusz Uzycki <[email protected]>---
v3 -> v4 changelog:
[PATCH 1/4] serial: mxs-auart: cleanget_mctrlandset_mctrl
* renamed from "serial: mxs-auart: ctrl removed frommxs_auart_port"
*mxs_auart_get_mctrl()read back RTS line. It is removed too.v2 -> v3 changelog:
The patch was introduced:
new [PATCH 1/4] serial: mxs-auart: ctrl removed frommxs_auart_port
* the ctrl variable duplicated mctrl, member ofuart_portstructure inserial_core.h
* the code duplicateduart_update_mctrl()anduart_tiocmget()inserial_core.c
*mxs_auart_get_mctrl()reads back RTS line. It could be removed too but not sure.--- drivers/tty/serial/mxs-auart.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-)drivers/tty/serial/mxs-auart.c +1
-11@@ -143,7 +143,6 @@ struct mxs_auart_port {#define MXS_AUART_DMA_RX_READY 3/* bit 3 */ #define MXS_AUART_RTSCTS 4/* bit 4 */ unsigned long flags; -unsigned int ctrl;enum mxs_auart_type devtype;unsigned int irq;@@ -406,8 +405,6 @@ static void mxs_auart_release_port(struct uart_port *u)static void mxs_auart_set_mctrl (struct uart_port *u,unsigned mctrl) { -struct mxs_auart_port *s =to_auart_port (u); -u32 ctrl =readl (u->membase +AUART_CTRL2 ); ctrl &= ~(AUART_CTRL2_RTSEN |AUART_CTRL2_RTS );@@ -418,24 +415,17 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) ctrl |=AUART_CTRL2_RTS ; } - s->ctrl = mctrl;writel (ctrl, u->membase +AUART_CTRL2 ); }static u32 mxs_auart_get_mctrl (struct uart_port *u) { -struct mxs_auart_port *s =to_auart_port (u);u32 stat =readl (u->membase +AUART_STAT ); -int ctrl2 =readl (u->membase +AUART_CTRL2 ); -u32 mctrl = s->ctrl; +u32 mctrl =0 ; - mctrl &= ~TIOCM_CTS ;if (stat &AUART_STAT_CTS ) mctrl |=TIOCM_CTS ; -if (ctrl2 &AUART_CTRL2_RTS ) - mctrl |=TIOCM_RTS ; -return mctrl; }
drivers/tty/serial/mxs-auart.c static int mxs_auart_probe(struct platform_device *pdev) · line 1066
Quoted 8 lines
drivers/tty/serial/mxs-auart.c +0
-2@@ -1071,8 +1061,6 @@ static int mxs_auart_probe(struct platform_device *pdev) s->port.type =PORT_IMX ; s->port.dev = s->dev = &pdev->dev; - s->ctrl =0 ; - s->irq =platform_get_irq (pdev,0 ); s->port.irq = s->irq; ret =request_irq (s->irq, mxs_auart_irq_handle,0 ,dev_name (&pdev->dev), s);
Seems good to me.
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
In reply to Janusz UzyckiDedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited.
Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO.
This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals.
---
v3 -> v4 changelog:
* RTS_AT_AUART() and CTS_AT_AUART() macro defined
* DMA engine disabled if RTS or CTS is GPIO line
* warn if fsl,uart-has-rtscts and RTS/CTS via GPIO are mixed
* CTSEN can't be enabled for hardware flow control block if CTS is defined as GPIO line
* RTSEN can be enabled for hardware flow control block even if RTS is defined as GPIO line.
RTS pin depends on pinctrl configuration which
selects RTS output from hardware flow control block or GPIO line.
* mxs_auart_settermios(): RTS_AT_AUART() and CTS_AT_AUART() used
* mxs_auart_irq_handle(): CTS_AT_AUART() used
* mxs_auart_init_gpios() returns true(success)/false(failure)
* dev_err() message fixed in mxs_auart_probe()
v2 -> v3 changelog:
* mctrl_gpio_free() removed to simplify:
mctrl_gpio_free() is not necessary in mxs_auart_probe() and mxs_auart_remove() because mctrl_gpio_init() does all allocations with devm_* functions.
(see Documentation/serial/driver since kernel 3.16)
* DMA on HW flow control comment updated, still not sure about the comment
* mxs_auart_modem_status() removed from mxs_auart_get_mctrl():
mctrl_gpio_get() does not clear gpio interrupt pendings like 8250_core.c does with MSR.
* mxs_auart_modem_status() moved to [3/4]
If enable_ms() is not called, uart_handle_cts_change() shouldn't be called.
--- .../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 ++++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-)
Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +9 -1
@@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD + line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial@8006a000 {
@@ -21,6 +26,9 @@ auart0: serial@8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in "aliases"
drivers/tty/serial/Kconfig +1 -0
@@ -1357,6 +1357,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port.
drivers/tty/serial/mxs-auart.c +45 -5
120 lines not on this page · raw message
Signature · 1 line
1.7.11.3
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
Quoted 187 lines · Janusz Uzycki
Dedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited.
Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO.
This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals.
Signed-off-by Janusz Uzycki <[email protected]>---
v3 -> v4 changelog:
*RTS_AT_AUART()andCTS_AT_AUART()macro defined
* DMA engine disabled if RTS or CTS is GPIO line
* warn if fsl,uart-has-rtscts and RTS/CTS via GPIO are mixed
* CTSEN can't be enabled for hardware flow control block if CTS is defined as GPIO line
* RTSEN can be enabled for hardware flow control block even if RTS is defined as GPIO line.
RTS pin depends on pinctrl configuration which
selects RTS output from hardware flow control block or GPIO line.
*mxs_auart_settermios():RTS_AT_AUART()andCTS_AT_AUART()used
*mxs_auart_irq_handle():CTS_AT_AUART()used
*mxs_auart_init_gpios()returns true(success)/false(failure)
*dev_err()message fixed inmxs_auart_probe()v2 -> v3 changelog:
*mctrl_gpio_free()removed to simplify:
mctrl_gpio_free()is not necessary inmxs_auart_probe()andmxs_auart_remove()becausemctrl_gpio_init()does all allocations with devm_* functions.
(seeDocumentation/serial/driversince kernel 3.16)
* DMA on HW flow control comment updated, still not sure about the comment
*mxs_auart_modem_status()removed frommxs_auart_get_mctrl():
mctrl_gpio_get()does not clear gpio interrupt pendings like8250_core.cdoes with MSR.
*mxs_auart_modem_status()moved to [3/4]
Ifenable_ms()is not called,uart_handle_cts_change()shouldn't be called.--- .../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 ++++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-)Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +9
-1@@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD + line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial at 8006a000 {@@ -21,6 +26,9 @@ auart0: serial at 8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in "aliases"drivers/tty/serial/Kconfig +1
-0@@ -1357,6 +1357,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port.drivers/tty/serial/mxs-auart.c +24
-5@@ -42,6 +42,9 @@#include <asm/cacheflush.h> +#include <linux/err.h> +#include "serial_mctrl_gpio.h" +#define MXS_AUART_PORTS 5#define MXS_AUART_FIFO_SIZE 16@@ -158,6 +161,8 @@ struct mxs_auart_port {struct scatterlist rx_sgl;struct dma_chan *rx_dma_chan;void *rx_dma_buf; + +struct mctrl_gpios *gpios; };static struct platform_device_id mxs_auart_devtype[] = {@@ -405,6 +410,8 @@ static void mxs_auart_release_port(struct uart_port *u)static void mxs_auart_set_mctrl (struct uart_port *u,unsigned mctrl) { +struct mxs_auart_port *s =to_auart_port (u); +u32 ctrl =readl (u->membase +AUART_CTRL2 ); ctrl &= ~(AUART_CTRL2_RTSEN |AUART_CTRL2_RTS );@@ -416,17 +423,20 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) }writel (ctrl, u->membase +AUART_CTRL2 ); + +mctrl_gpio_set (s->gpios, mctrl); }static u32 mxs_auart_get_mctrl (struct uart_port *u) { +struct mxs_auart_port *s =to_auart_port (u);u32 stat =readl (u->membase +AUART_STAT );u32 mctrl =0 ;if (stat &AUART_STAT_CTS ) mctrl |=TIOCM_CTS ; -return mctrl; +return mctrl_gpio_get (s->gpios, &mctrl); }static int mxs_auart_dma_prep_rx (struct mxs_auart_port *s);@@ -554,6 +564,10 @@ err_out: } +#define RTS_AT_AUART () IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_RTS)) +#define CTS_AT_AUART () IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_CTS))static void mxs_auart_settermios (struct uart_port *u,struct ktermios *termios,struct ktermios *old)@@ -630,6 +644,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |=AUART_LINECTRL_STP2 ;/* figure out the hardware flow control settings */ + ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN );if (cflag &CRTSCTS ) {/* * The DMA has a bug(see errata:2836) in mx23. @@ -644,9 +659,11 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl2 |=AUART_CTRL2_TXDMAE |AUART_CTRL2_RXDMAE |AUART_CTRL2_DMAONERR ; } - ctrl2 |=AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ; - }else { - ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ); +/* Even if RTS is GPIO line RTSEN can be enabled because +* the pinctrl configuration decides about RTS pin function */ + ctrl2 |=AUART_CTRL2_RTSEN ; +if (CTS_AT_AUART ()) + ctrl2 |=AUART_CTRL2_CTSEN ; }/* set baud rate */ @@ -690,7 +707,9 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) s->port.membase + AUART_INTR_CLR);if (istat &AUART_INTR_CTSMIS ) { -uart_handle_cts_change (&s->port, stat &AUART_STAT_CTS ); +if (CTS_AT_AUART ()) +uart_handle_cts_change (&s->port, + stat &AUART_STAT_CTS );writel (AUART_INTR_CTSMIS , s->port.membase +AUART_INTR_CLR ); istat &= ~AUART_INTR_CTSMIS ;
drivers/tty/serial/mxs-auart.c static int serial_mxs_probe_dt(struct mxs_auart_port *s, · line 1042
Quoted 10 lines
drivers/tty/serial/mxs-auart.c +7
-0@@ -1014,6 +1033,23 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,return 0 ; } +static bool mxs_auart_init_gpios (struct mxs_auart_port *s,struct device *dev) +{ + s->gpios =mctrl_gpio_init (dev,0 ); +if (IS_ERR_OR_NULL (s->gpios)) +return false; + +/* Block (enabled before) DMA option if RTS or CTS is GPIO line */
This is confusing, so I think some more comments won't be too much. Something like:
/*
* The DMA only work if the lines CTS/RTS are handled by the controller
* cf. 8418e67d9523 serial: mxs: enable the DMA only when the RTS/CTS is
valid
* So, If the CTS/RTS lines are controlled via GPIO the MXS_AUART_RTSCTS
bit should be
* cleaned to indicate that the RTS/CTS lines are not handled by the
controller.
*/
(If I understood correctly what is done here.)
Quoted 15 lines
drivers/tty/serial/mxs-auart.c +10
-0+if (!RTS_AT_AUART () || !CTS_AT_AUART ()) { +if (test_bit (MXS_AUART_RTSCTS , &s->flags)) +dev_warn (dev, +"DMA and flow control via gpio may cause some problems. DMA disabled!\n" ); +clear_bit (MXS_AUART_RTSCTS , &s->flags); + } + +return true; +} +static int mxs_auart_probe (struct platform_device *pdev) { const struct of_device_id *of_id =
drivers/tty/serial/mxs-auart.c static int mxs_auart_probe(struct platform_device *pdev) · line 1114
Quoted 10 lines
drivers/tty/serial/mxs-auart.c +4
-0@@ -1069,6 +1105,10 @@ static int mxs_auart_probe(struct platform_device *pdev)platform_set_drvdata (pdev, s); +if (!mxs_auart_init_gpios (s, &pdev->dev)) +dev_err (&pdev->dev, +"Failed to initialize GPIOs. The serial port may not work as expected\n" ); + auart_port[s->port.line] = s;mxs_auart_reset (&s->port);
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
W dniu 2014-10-24 o 17:32, Richard Genoud pisze:
Quoted 202 lines · Janusz Uzycki
Quoted 187 lines
Dedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited.
Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO.
This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals.
Signed-off-by Janusz Uzycki <[email protected]>---
v3 -> v4 changelog:
*RTS_AT_AUART()andCTS_AT_AUART()macro defined
* DMA engine disabled if RTS or CTS is GPIO line
* warn if fsl,uart-has-rtscts and RTS/CTS via GPIO are mixed
* CTSEN can't be enabled for hardware flow control block if CTS is defined as GPIO line
* RTSEN can be enabled for hardware flow control block even if RTS is defined as GPIO line.
RTS pin depends on pinctrl configuration which
selects RTS output from hardware flow control block or GPIO line.
*mxs_auart_settermios():RTS_AT_AUART()andCTS_AT_AUART()used
*mxs_auart_irq_handle():CTS_AT_AUART()used
*mxs_auart_init_gpios()returns true(success)/false(failure)
*dev_err()message fixed inmxs_auart_probe()v2 -> v3 changelog:
*mctrl_gpio_free()removed to simplify:
mctrl_gpio_free()is not necessary inmxs_auart_probe()andmxs_auart_remove()becausemctrl_gpio_init()does all allocations with devm_* functions.
(seeDocumentation/serial/driversince kernel 3.16)
* DMA on HW flow control comment updated, still not sure about the comment
*mxs_auart_modem_status()removed frommxs_auart_get_mctrl():
mctrl_gpio_get()does not clear gpio interrupt pendings like8250_core.cdoes with MSR.
*mxs_auart_modem_status()moved to [3/4]
Ifenable_ms()is not called,uart_handle_cts_change()shouldn't be called.--- .../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 ++++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-)Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +9
-1@@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD + line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial@8006a000 {@@ -21,6 +26,9 @@ auart0: serial@8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in "aliases"drivers/tty/serial/Kconfig +1
-0@@ -1357,6 +1357,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port.drivers/tty/serial/mxs-auart.c +24
-5@@ -42,6 +42,9 @@#include <asm/cacheflush.h> +#include <linux/err.h> +#include "serial_mctrl_gpio.h" +#define MXS_AUART_PORTS 5#define MXS_AUART_FIFO_SIZE 16@@ -158,6 +161,8 @@ struct mxs_auart_port {struct scatterlist rx_sgl;struct dma_chan *rx_dma_chan;void *rx_dma_buf; + +struct mctrl_gpios *gpios; };static struct platform_device_id mxs_auart_devtype[] = {@@ -405,6 +410,8 @@ static void mxs_auart_release_port(struct uart_port *u)static void mxs_auart_set_mctrl (struct uart_port *u,unsigned mctrl) { +struct mxs_auart_port *s =to_auart_port (u); +u32 ctrl =readl (u->membase +AUART_CTRL2 ); ctrl &= ~(AUART_CTRL2_RTSEN |AUART_CTRL2_RTS );@@ -416,17 +423,20 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) }writel (ctrl, u->membase +AUART_CTRL2 ); + +mctrl_gpio_set (s->gpios, mctrl); }static u32 mxs_auart_get_mctrl (struct uart_port *u) { +struct mxs_auart_port *s =to_auart_port (u);u32 stat =readl (u->membase +AUART_STAT );u32 mctrl =0 ;if (stat &AUART_STAT_CTS ) mctrl |=TIOCM_CTS ; -return mctrl; +return mctrl_gpio_get (s->gpios, &mctrl); }static int mxs_auart_dma_prep_rx (struct mxs_auart_port *s);@@ -554,6 +564,10 @@ err_out: } +#define RTS_AT_AUART () IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_RTS)) +#define CTS_AT_AUART () IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_CTS))static void mxs_auart_settermios (struct uart_port *u,struct ktermios *termios,struct ktermios *old)@@ -630,6 +644,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |=AUART_LINECTRL_STP2 ;/* figure out the hardware flow control settings */ + ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN );if (cflag &CRTSCTS ) {/* * The DMA has a bug(see errata:2836) in mx23. @@ -644,9 +659,11 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl2 |=AUART_CTRL2_TXDMAE |AUART_CTRL2_RXDMAE |AUART_CTRL2_DMAONERR ; } - ctrl2 |=AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ; - }else { - ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ); +/* Even if RTS is GPIO line RTSEN can be enabled because +* the pinctrl configuration decides about RTS pin function */ + ctrl2 |=AUART_CTRL2_RTSEN ; +if (CTS_AT_AUART ()) + ctrl2 |=AUART_CTRL2_CTSEN ; }/* set baud rate */ @@ -690,7 +707,9 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) s->port.membase + AUART_INTR_CLR);if (istat &AUART_INTR_CTSMIS ) { -uart_handle_cts_change (&s->port, stat &AUART_STAT_CTS ); +if (CTS_AT_AUART ()) +uart_handle_cts_change (&s->port, + stat &AUART_STAT_CTS );writel (AUART_INTR_CTSMIS , s->port.membase +AUART_INTR_CLR ); istat &= ~AUART_INTR_CTSMIS ;drivers/tty/serial/mxs-auart.c static int serial_mxs_probe_dt(struct mxs_auart_port *s, · line 1042
Quoted 10 lines
drivers/tty/serial/mxs-auart.c +7
-0@@ -1014,6 +1033,23 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,return 0 ; } +static bool mxs_auart_init_gpios (struct mxs_auart_port *s,struct device *dev) +{ + s->gpios =mctrl_gpio_init (dev,0 ); +if (IS_ERR_OR_NULL (s->gpios)) +return false; + +/* Block (enabled before) DMA option if RTS or CTS is GPIO line */ This is confusing, so I think some more comments won't be too much. Something like:
/*
* The DMA only work if the lines CTS/RTS are handled by the controller
Quoted 8 lines
* cf.
8418e67d9523serial: mxs: enable the DMA only when the RTS/CTS is
valid
* So, If the CTS/RTS lines are controlled via GPIO theMXS_AUART_RTSCTS
bit should be
* cleaned to indicate that the RTS/CTS lines are not handled by the
controller.
*/
(If I understood correctly what is done here.)
This is not clear in the driver. If hardware RTS/CTS (non-gpio) is not defined in DT only DMA is not used. It is still possible to use hardware RTS/CTS lines if you set hw-flowcontrol in termios. So it is also possible to mix hardware RTS/CTS and gpio RTS/CTS. In mixed or gpio case the code blocks/disables DMA. I know my comment is not clear but the reason is in the earlier code. Can you propose better solution?
After review and small fixes requested new version is required for a patchset or rather patch resend?
kind regards
Janusz
Quoted 26 lines
Quoted 15 lines
drivers/tty/serial/mxs-auart.c +10
-0+if (!RTS_AT_AUART () || !CTS_AT_AUART ()) { +if (test_bit (MXS_AUART_RTSCTS , &s->flags)) +dev_warn (dev, +"DMA and flow control via gpio may cause some problems. DMA disabled!\n" ); +clear_bit (MXS_AUART_RTSCTS , &s->flags); + } + +return true; +} +static int mxs_auart_probe (struct platform_device *pdev) { const struct of_device_id *of_id =drivers/tty/serial/mxs-auart.c static int mxs_auart_probe(struct platform_device *pdev) · line 1114
Quoted 10 lines
drivers/tty/serial/mxs-auart.c +4
-0@@ -1069,6 +1105,10 @@ static int mxs_auart_probe(struct platform_device *pdev)platform_set_drvdata (pdev, s); +if (!mxs_auart_init_gpios (s, &pdev->dev)) +dev_err (&pdev->dev, +"Failed to initialize GPIOs. The serial port may not work as expected\n" ); + auart_port[s->port.line] = s;mxs_auart_reset (&s->port);Reviewed-by Richard Genoud <[email protected]>
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
2014-10-24 17:51 GMT+02:00 Janusz U?ycki <[email protected]>:
Quoted 211 lines
W dniu 2014-10-24 o 17:32, Richard Genoud pisze:
Quoted 198 lines · Janusz Uzycki
Quoted 182 lines
Dedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited.
Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO.
This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals.
Signed-off-by Janusz Uzycki <[email protected]>---
v3 -> v4 changelog:
*RTS_AT_AUART()andCTS_AT_AUART()macro defined
* DMA engine disabled if RTS or CTS is GPIO line
* warn if fsl,uart-has-rtscts and RTS/CTS via GPIO are mixed
* CTSEN can't be enabled for hardware flow control block if CTS is defined as GPIO line
* RTSEN can be enabled for hardware flow control block even if RTS is defined as GPIO line.
RTS pin depends on pinctrl configuration which
selects RTS output from hardware flow control block or GPIO line.
*mxs_auart_settermios():RTS_AT_AUART()andCTS_AT_AUART()used
*mxs_auart_irq_handle():CTS_AT_AUART()used
*mxs_auart_init_gpios()returns true(success)/false(failure)
*dev_err()message fixed inmxs_auart_probe()v2 -> v3 changelog:
*mctrl_gpio_free()removed to simplify:
mctrl_gpio_free()is not necessary inmxs_auart_probe()andmxs_auart_remove()becausemctrl_gpio_init()does all allocations with devm_* functions.
(seeDocumentation/serial/driversince kernel 3.16)
* DMA on HW flow control comment updated, still not sure about the comment
*mxs_auart_modem_status()removed frommxs_auart_get_mctrl():
mctrl_gpio_get()does not clear gpio interrupt pendings like8250_core.cdoes with MSR.
*mxs_auart_modem_status()moved to [3/4]
Ifenable_ms()is not called,uart_handle_cts_change()shouldn't be called.--- .../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 ++++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-)Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +3
-1@@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO forRTS/CTS/DTR/DSR/RI/DCD
Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +6
-0+ line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial at 8006a000 {@@ -21,6 +26,9 @@ auart0: serial at 8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in"aliases"
drivers/tty/serial/Kconfig +1
-0@@ -1357,6 +1357,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port. diff --git a/drivers/tty/serial/mxs-auart.c
b/drivers/tty/serial/mxs-auart.c
index 2d49901..8bbcfd1 100644drivers/tty/serial/mxs-auart.c +14
-0@@ -42,6 +42,9 @@#include <asm/cacheflush.h> +#include <linux/err.h> +#include "serial_mctrl_gpio.h" +#define MXS_AUART_PORTS 5#define MXS_AUART_FIFO_SIZE 16 @@ -158,6 +161,8 @@ struct mxs_auart_port {struct scatterlist rx_sgl;struct dma_chan *rx_dma_chan;void *rx_dma_buf; + +struct mctrl_gpios *gpios; };static struct platform_device_id mxs_auart_devtype[] = {@@ -405,6 +410,8 @@ static void mxs_auart_release_port(struct uart_port *u)static void mxs_auart_set_mctrl (struct uart_port *u,unsigned mctrl) { +struct mxs_auart_port *s =to_auart_port (u); +u32 ctrl =readl (u->membase +AUART_CTRL2 ); ctrl &= ~(AUART_CTRL2_RTSEN |AUART_CTRL2_RTS );@@ -416,17 +423,20 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) }writel (ctrl, u->membase +AUART_CTRL2 ); + +mctrl_gpio_set (s->gpios, mctrl); }static u32 mxs_auart_get_mctrl (struct uart_port *u) { +struct mxs_auart_port *s =to_auart_port (u);u32 stat =readl (u->membase +AUART_STAT );u32 mctrl =0 ;if (stat &AUART_STAT_CTS ) mctrl |=TIOCM_CTS ; - return mctrl; +return mctrl_gpio_get (s->gpios, &mctrl); }static int mxs_auart_dma_prep_rx (struct mxs_auart_port *s);@@ -554,6 +564,10 @@ err_out: } +#define RTS_AT_AUART()IS_ERR_OR_NULL (mctrl_gpio_to_gpiod (s->gpios, \ + UART_GPIO_RTS)) +#define CTS_AT_AUART () IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_CTS))static void mxs_auart_settermios (struct uart_port *u,struct ktermios *termios,struct ktermios *old)@@ -630,6 +644,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |=AUART_LINECTRL_STP2 ;/* figure out the hardware flow control settings */ + ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN );if (cflag &CRTSCTS ) {/* * The DMA has a bug(see errata:2836) in mx23. @@ -644,9 +659,11 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl2 |= AUART_CTRL2_TXDMAE |
AUART_CTRL2_RXDMAE| AUART_CTRL2_DMAONERR; }drivers/tty/serial/mxs-auart.c +2
-3- ctrl2 |=AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ; - }else { - ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ); +/* Even if RTS is GPIO line RTSEN can be enabled because +* the pinctrl configuration decides about RTS pin function */
drivers/tty/serial/mxs-auart.c +6
-1+ ctrl2 |=AUART_CTRL2_RTSEN ; +if (CTS_AT_AUART ()) + ctrl2 |=AUART_CTRL2_CTSEN ; }/* set baud rate */ @@ -690,7 +707,9 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) s->port.membase + AUART_INTR_CLR);if (istat &AUART_INTR_CTSMIS ) { -uart_handle_cts_change (&s->port, stat &AUART_STAT_CTS ); +if (CTS_AT_AUART ()) +uart_handle_cts_change (&s->port, + stat &AUART_STAT_CTS );writel (AUART_INTR_CTSMIS , s->port.membase +AUART_INTR_CLR ); istat &= ~AUART_INTR_CTSMIS ;@@ -1014,6 +1033,23 @@ static int serial_mxs_probe_dt(structmxs_auart_port *s, return 0;drivers/tty/serial/mxs-auart.c static int serial_mxs_probe_dt(struct · line 1044
Quoted 10 lines
drivers/tty/serial/mxs-auart.c +6
-0} +static bool mxs_auart_init_gpios(struct mxs_auart_port *s, structdevice *dev) +{ + s->gpios =mctrl_gpio_init (dev,0 ); +if (IS_ERR_OR_NULL (s->gpios)) +return false; + +/* Block (enabled before) DMA option if RTS or CTS is GPIO line */ This is confusing, so I think some more comments won't be too much. Something like:
/*
* The DMA only work if the lines CTS/RTS are handled by the controllerQuoted 8 lines
* cf.
8418e67d9523serial: mxs: enable the DMA only when the RTS/CTS is
valid
* So, If the CTS/RTS lines are controlled via GPIO theMXS_AUART_RTSCTS
bit should be
* cleaned to indicate that the RTS/CTS lines are not handled by the
controller.
*/
(If I understood correctly what is done here.)
Quoted 8 lines
This is not clear in the driver. If hardware RTS/CTS (non-gpio) is not defined in DT
only DMA is not used. It is still possible to use hardware RTS/CTS lines if you set hw-flowcontrol in termios. So it is also possible to mix hardware RTS/CTS
and gpio RTS/CTS. In mixed or gpio case the code blocks/disables DMA. I know my comment is not clear but the reason is in the earlier code. Can you propose better solution?
Maybe Huang Shijie knows more on this DMA vs RTS/CTS incompatibility. [added Huang Shijie in Cc ]
Quoted 3 lines
After review and small fixes requested new version is required for a patchset
or rather patch resend?
It's better to resend the whole patchset (after giving some time for Huang Shijie to give its thoughts )
Quoted 33 lines
kind regards
JanuszQuoted 26 lines
Quoted 16 lines
drivers/tty/serial/mxs-auart.c +4
-0+if (!RTS_AT_AUART () || !CTS_AT_AUART ()) { +if (test_bit (MXS_AUART_RTSCTS , &s->flags)) + dev_warn(dev, + "DMA and flow control via gpio may causesome problems. DMA disabled!\n");
drivers/tty/serial/mxs-auart.c +6
-0+clear_bit (MXS_AUART_RTSCTS , &s->flags); + } + +return true; +} +static int mxs_auart_probe (struct platform_device *pdev) { const struct of_device_id *of_id =drivers/tty/serial/mxs-auart.c static int mxs_auart_probe(struct platform_device · line 1113
Quoted 9 lines
drivers/tty/serial/mxs-auart.c +3
-0@@ -1069,6 +1105,10 @@ static int mxs_auart_probe(struct platform_device *pdev)platform_set_drvdata (pdev, s); + if (!mxs_auart_init_gpios(s, &pdev->dev)) +dev_err (&pdev->dev, + "Failed to initialize GPIOs. The serial port may not work as expected\n"); + auart_port[s->port.line] = s;mxs_auart_reset (&s->port);Reviewed-by Richard Genoud <[email protected]>
Signature · 1 line
for me, ck means con kolivas and not calvin klein... does it mean I'm a geek ?
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
Any news?
best regards
Janusz
W dniu 2014-10-31 o 09:48, Richard Genoud pisze:
Quoted 258 lines
2014-10-24 17:51 GMT+02:00 Janusz U?ycki <[email protected]>:
Quoted 207 lines
W dniu 2014-10-24 o 17:32, Richard Genoud pisze:
Quoted 196 lines · Janusz Uzycki
Quoted 181 lines
Dedicated CTS and RTS pins are unusable together with a lot of other peripherals because they share the same line. Pinctrl is limited.
Moreover, the AUART controller doesn't handle DTR/DSR/DCD/RI signals, so we have to control them via GPIO.
This patch permits to use GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI signals.
Signed-off-by Janusz Uzycki <[email protected]>---
v3 -> v4 changelog:
*RTS_AT_AUART()andCTS_AT_AUART()macro defined
* DMA engine disabled if RTS or CTS is GPIO line
* warn if fsl,uart-has-rtscts and RTS/CTS via GPIO are mixed
* CTSEN can't be enabled for hardware flow control block if CTS is defined as GPIO line
* RTSEN can be enabled for hardware flow control block even if RTS is defined as GPIO line.
RTS pin depends on pinctrl configuration which
selects RTS output from hardware flow control block or GPIO line.
*mxs_auart_settermios():RTS_AT_AUART()andCTS_AT_AUART()used
*mxs_auart_irq_handle():CTS_AT_AUART()used
*mxs_auart_init_gpios()returns true(success)/false(failure)
*dev_err()message fixed inmxs_auart_probe()v2 -> v3 changelog:
*mctrl_gpio_free()removed to simplify:
mctrl_gpio_free()is not necessary inmxs_auart_probe()andmxs_auart_remove()becausemctrl_gpio_init()does all allocations with devm_* functions.
(seeDocumentation/serial/driversince kernel 3.16)
* DMA on HW flow control comment updated, still not sure about the comment
*mxs_auart_modem_status()removed frommxs_auart_get_mctrl():
mctrl_gpio_get()does not clear gpio interrupt pendings like8250_core.cdoes with MSR.
*mxs_auart_modem_status()moved to [3/4]
Ifenable_ms()is not called,uart_handle_cts_change()shouldn't be called.--- .../devicetree/bindings/serial/fsl-mxs-auart.txt | 10 ++++- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mxs-auart.c | 50 +++++++++++++++++++--- 3 files changed, 55 insertions(+), 6 deletions(-)Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +3
-1@@ -11,8 +11,13 @@ Required properties: - dma-names: "rx" for RX channel, "tx" for TX channel. Optional properties: -- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines, +- fsl,uart-has-rtscts : Indicate the UART has RTS and CTS lines + for hardware flow control, it also means you enable the DMA support for this UART. +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO forRTS/CTS/DTR/DSR/RI/DCD
Documentation/devicetree/bindings/serial/fsl-mxs-auart.txt +6
-0+ line respectively. It will use specified PIO instead of the peripheral + function pin for the USART feature. + If unsure, don't specify this property. Example: auart0: serial at 8006a000 {@@ -21,6 +26,9 @@ auart0: serial at 8006a000 { interrupts = <112>; dmas = <&dma_apbx 8>, <&dma_apbx 9>; dma-names = "rx", "tx"; + cts-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + dsr-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + dcd-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; Note: Each auart port should have an alias correctly numbered in"aliases"
drivers/tty/serial/Kconfig +1
-0@@ -1357,6 +1357,7 @@ config SERIAL_MXS_AUART depends on ARCH_MXS tristate "MXS AUART support" select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB help This driver supports the MXS Application UART (AUART) port. diff --git a/drivers/tty/serial/mxs-auart.c
b/drivers/tty/serial/mxs-auart.c
index 2d49901..8bbcfd1 100644drivers/tty/serial/mxs-auart.c +14
-0@@ -42,6 +42,9 @@#include <asm/cacheflush.h> +#include <linux/err.h> +#include "serial_mctrl_gpio.h" +#define MXS_AUART_PORTS 5#define MXS_AUART_FIFO_SIZE 16 @@ -158,6 +161,8 @@ struct mxs_auart_port {struct scatterlist rx_sgl;struct dma_chan *rx_dma_chan;void *rx_dma_buf; + +struct mctrl_gpios *gpios; };static struct platform_device_id mxs_auart_devtype[] = {@@ -405,6 +410,8 @@ static void mxs_auart_release_port(struct uart_port *u)static void mxs_auart_set_mctrl (struct uart_port *u,unsigned mctrl) { +struct mxs_auart_port *s =to_auart_port (u); +u32 ctrl =readl (u->membase +AUART_CTRL2 ); ctrl &= ~(AUART_CTRL2_RTSEN |AUART_CTRL2_RTS );@@ -416,17 +423,20 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) }writel (ctrl, u->membase +AUART_CTRL2 ); + +mctrl_gpio_set (s->gpios, mctrl); }static u32 mxs_auart_get_mctrl (struct uart_port *u) { +struct mxs_auart_port *s =to_auart_port (u);u32 stat =readl (u->membase +AUART_STAT );u32 mctrl =0 ;if (stat &AUART_STAT_CTS ) mctrl |=TIOCM_CTS ; - return mctrl; +return mctrl_gpio_get (s->gpios, &mctrl); }static int mxs_auart_dma_prep_rx (struct mxs_auart_port *s);@@ -554,6 +564,10 @@ err_out: } +#define RTS_AT_AUART()IS_ERR_OR_NULL (mctrl_gpio_to_gpiod (s->gpios, \ + UART_GPIO_RTS)) +#define CTS_AT_AUART () IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(s->gpios, \ + UART_GPIO_CTS))static void mxs_auart_settermios (struct uart_port *u,struct ktermios *termios,struct ktermios *old)@@ -630,6 +644,7 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |=AUART_LINECTRL_STP2 ;/* figure out the hardware flow control settings */ + ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN );if (cflag &CRTSCTS ) {/* * The DMA has a bug(see errata:2836) in mx23. @@ -644,9 +659,11 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl2 |= AUART_CTRL2_TXDMAE |
AUART_CTRL2_RXDMAE| AUART_CTRL2_DMAONERR; }drivers/tty/serial/mxs-auart.c +2
-3- ctrl2 |=AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ; - }else { - ctrl2 &= ~(AUART_CTRL2_CTSEN |AUART_CTRL2_RTSEN ); +/* Even if RTS is GPIO line RTSEN can be enabled because +* the pinctrl configuration decides about RTS pin function */
drivers/tty/serial/mxs-auart.c +6
-1+ ctrl2 |=AUART_CTRL2_RTSEN ; +if (CTS_AT_AUART ()) + ctrl2 |=AUART_CTRL2_CTSEN ; }/* set baud rate */ @@ -690,7 +707,9 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) s->port.membase + AUART_INTR_CLR);if (istat &AUART_INTR_CTSMIS ) { -uart_handle_cts_change (&s->port, stat &AUART_STAT_CTS ); +if (CTS_AT_AUART ()) +uart_handle_cts_change (&s->port, + stat &AUART_STAT_CTS );writel (AUART_INTR_CTSMIS , s->port.membase +AUART_INTR_CLR ); istat &= ~AUART_INTR_CTSMIS ;@@ -1014,6 +1033,23 @@ static int serial_mxs_probe_dt(structmxs_auart_port *s, return 0;drivers/tty/serial/mxs-auart.c static int serial_mxs_probe_dt(struct · line 1044
Quoted 10 lines
drivers/tty/serial/mxs-auart.c +6
-0} +static bool mxs_auart_init_gpios(struct mxs_auart_port *s, structdevice *dev) +{ + s->gpios =mctrl_gpio_init (dev,0 ); +if (IS_ERR_OR_NULL (s->gpios)) +return false; + +/* Block (enabled before) DMA option if RTS or CTS is GPIO line */ This is confusing, so I think some more comments won't be too much. Something like:
/*
* The DMA only work if the lines CTS/RTS are handled by the controllerQuoted 8 lines
* cf.
8418e67d9523serial: mxs: enable the DMA only when the RTS/CTS is
valid
* So, If the CTS/RTS lines are controlled via GPIO theMXS_AUART_RTSCTS
bit should be
* cleaned to indicate that the RTS/CTS lines are not handled by the
controller.
*/
(If I understood correctly what is done here.)Quoted 8 lines
This is not clear in the driver. If hardware RTS/CTS (non-gpio) is not defined in DT
only DMA is not used. It is still possible to use hardware RTS/CTS lines if you set hw-flowcontrol in termios. So it is also possible to mix hardware RTS/CTS
and gpio RTS/CTS. In mixed or gpio case the code blocks/disables DMA. I know my comment is not clear but the reason is in the earlier code. Can you propose better solution?Maybe Huang Shijie knows more on this DMA vs RTS/CTS incompatibility. [added Huang Shijie in Cc ]
Quoted 3 lines
After review and small fixes requested new version is required for a patchset
or rather patch resend?It's better to resend the whole patchset (after giving some time for Huang Shijie to give its thoughts )
Quoted 31 lines
kind regards
JanuszQuoted 26 lines
Quoted 16 lines
drivers/tty/serial/mxs-auart.c +4
-0+if (!RTS_AT_AUART () || !CTS_AT_AUART ()) { +if (test_bit (MXS_AUART_RTSCTS , &s->flags)) + dev_warn(dev, + "DMA and flow control via gpio may causesome problems. DMA disabled!\n");
drivers/tty/serial/mxs-auart.c +6
-0+clear_bit (MXS_AUART_RTSCTS , &s->flags); + } + +return true; +} +static int mxs_auart_probe (struct platform_device *pdev) { const struct of_device_id *of_id =drivers/tty/serial/mxs-auart.c static int mxs_auart_probe(struct platform_device · line 1113
Quoted 9 lines
drivers/tty/serial/mxs-auart.c +3
-0@@ -1069,6 +1105,10 @@ static int mxs_auart_probe(struct platform_device *pdev)platform_set_drvdata (pdev, s); + if (!mxs_auart_init_gpios(s, &pdev->dev)) +dev_err (&pdev->dev, + "Failed to initialize GPIOs. The serial port may not work as expected\n"); + auart_port[s->port.line] = s;mxs_auart_reset (&s->port);Reviewed-by Richard Genoud <[email protected]>
A message that is not in the archive (sent off-list or not yet received): CAMiH66FKJm8hcgtR=-ZzzpCq+PQ8xkixbUnMzRPVd_cM_6VM1w@mail.gmail.com
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
Quoted 5 lines · Huang Shijie
why change them to gpio? If we change them to gpio. Could the DMA still works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
HTH
[1] http://comments.gmane.org/gmane.linux.serial/6770
[2] http://article.gmane.org/gmane.linux.serial/3619/
Best regards,
Marek Vasut
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
W dniu 2014-11-07 o 09:03, Marek Vasut pisze:
Quoted 2 lines · Huang Shijie
Quoted 1 line
why change them to gpio?
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Quoted 17 lines
Quoted 5 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
Quoted 5 lines
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support in mxs_auart_init_gpios() if RTS or CTS line is set as gpio.
So I didn't test the patch with the DMA - I've just disabled it.
The question is different. The driver supports the cases for RTS/CTS:
1) both RTS/CTS assigned to hardware AUART (pinmux configured by DT, DT sets fsl,uart-has-rtscts)
a) settermios() sets CRTSCTS: DMA enabled, auto RTS/CTS is enabled
b) settermios() doesn't set CRTSCTS: DMA disabled, RTS/CTS
controlled by get/set_mctrl()
2) both RTS/CTS assigned to hardware AUART (pinmux configured by DT, DT doesn't set fsl,uart-has-rtscts)
a) settermios() sets CRTSCTS: DMA disabled, auto RTS/CTS is enabled
b) settermios() doesn't set CRTSCTS: DMA disabled, RTS/CTS
controlled by get/set_mctrl()
and after the patch it is more complex (because of mixed cases):
3) both RTS/CTS assigned to gpios (DT sets or not fsl,uart-has-rtscts):
the patch cancels fsl,uart-has-rtscts flag to disable DMA support, settermios() sets or not CRTSCTS: DMA disabled, RTS/CTS controlled
by get/set_mctrl(),
both lines by gpios. In addition:
a) settermios() doesn't set CRTSCTS: RTS of hardware AUART is also
controlled but
the case assumes it is not selected by pinmux in DT
b) settermios() sets CRTSCTS: auto RTS of hardware AUART is also
enabled but
the case assumes it is not selected by pinmux in DT
4) RTS assigned to hardware AUART (pinmux configured by DT, fsl,uart-has-rtscts set or not),
CTS assigned to gpio: the patch cancels fsl,uart-has-rtscts flag to
disable DMA support,
a) settermios() doesn't set CRTSCTS: DMA disabled, CTS (as gpio)
read by get_mctrl(),
RTS of hardware AUART controlled by set_mctrl()
b) settermios() sets CRTSCTS: DMA disabled, CTS (as gpio) read byget_mctrl(),
auto RTS is enabled
So case 4) is exactly 3) case with just different pinmux
configuration and the patch
threats 3) and 4) as the same case.
5) CTS assigned to hardware AUART (pinmux configured by DT, fsl,uart-has-rtscts set or not),
RTS assigned to gpio: the patch cancels fsl,uart-has-rtscts flag to
disable DMA support,
a) settermios() doesn't set CRTSCTS: DMA disabled, CTS of hardware
AUART read by
get_mctrl(), RTS (as gpio) controlled by set_mctrl(), in
addition RTS of hardware AUART
is also controlled but the case assumes it is not selected by
pinmux in DT
b) settermios() sets CRTSCTS: DMA disabled, auto RTS/CTS is enabled but RTS is controlled by set_mctrl() as gpio because the case
assumes it is not selected
by pinmux in DT
It is not nice description but I hadn't idea how to write it more clear. The mixed cases 4) and 5) are likely not so useful but possible and not so expensive
to support.
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
best regards
Janusz
Quoted 7 lines
HTH
[1] http://comments.gmane.org/gmane.linux.serial/6770
[2] http://article.gmane.org/gmane.linux.serial/3619/Best regards,
Marek Vasut
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
Quoted 3 lines · Janusz U?ycki
W dniu 2014-11-07 o 09:03, Marek Vasut pisze:
Quoted 2 lines · Huang Shijie
Quoted 1 line
why change them to gpio?
+CC Alexandre, since he might be interested :-)
Quoted 3 lines
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Your logic is outright flawed here, the first sentence doesn't implicate the second sentence. In fact, those two are completely unrelated.
Quoted 25 lines
Quoted 25 lines
Quoted 6 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the
same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo
Quoted 7 lines
Quoted 4 lines
of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
You will run into timing problems (see above).
What you're proposing here is a workaround for broken hardware, which was proven to be a bad idea and NAK'd already multiple times in the past (please see the links I posted in my last email).
Quoted 4 lines
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support inmxs_auart_init_gpios()if RTS or CTS line is set as gpio.
DMA has nothing to do with those problems here. DMA can be safely ignored for the purpose of the discussion altogether.
Like I explained already -- the problem is with the GPIO and AUART block not being synchronised by the same clock. It is therefore impossible to predict and control when the GPIO signals and the AUART signals will toggle in relation to one another.
Quoted 1 line
So I didn't test the patch with the DMA - I've just disabled it.
This would break the driver for pretty much everyone using higher baud rates.
Quoted 60 lines
The question is different. The driver supports the cases for RTS/CTS:
1) both RTS/CTS assigned to hardware AUART (pinmux configured by DT, DT sets fsl,uart-has-rtscts)
a)settermios()sets CRTSCTS: DMA enabled, auto RTS/CTS is enabled
b)settermios()doesn't set CRTSCTS: DMA disabled, RTS/CTS
controlled by get/set_mctrl()
2) both RTS/CTS assigned to hardware AUART (pinmux configured by DT, DT doesn't set fsl,uart-has-rtscts)
a)settermios()sets CRTSCTS: DMA disabled, auto RTS/CTS is enabled
b)settermios()doesn't set CRTSCTS: DMA disabled, RTS/CTS
controlled by get/set_mctrl()and after the patch it is more complex (because of mixed cases):
3) both RTS/CTS assigned to gpios (DT sets or not fsl,uart-has-rtscts):
the patch cancels fsl,uart-has-rtscts flag to disable DMA support,settermios()sets or not CRTSCTS: DMA disabled, RTS/CTS controlled
by get/set_mctrl(),
both lines by gpios. In addition:
a)settermios()doesn't set CRTSCTS: RTS of hardware AUART is also
controlled but
the case assumes it is not selected by pinmux in DT
b)settermios()sets CRTSCTS: auto RTS of hardware AUART is also
enabled but
the case assumes it is not selected by pinmux in DT
4) RTS assigned to hardware AUART (pinmux configured by DT, fsl,uart-has-rtscts set or not),
CTS assigned to gpio: the patch cancels fsl,uart-has-rtscts flag to
disable DMA support,
a)settermios()doesn't set CRTSCTS: DMA disabled, CTS (as gpio)
read byget_mctrl(),
RTS of hardware AUART controlled byset_mctrl()
b)settermios()sets CRTSCTS: DMA disabled, CTS (as gpio) read byget_mctrl(),
auto RTS is enabled
So case 4) is exactly 3) case with just different pinmux
configuration and the patch
threats 3) and 4) as the same case.
5) CTS assigned to hardware AUART (pinmux configured by DT, fsl,uart-has-rtscts set or not),
RTS assigned to gpio: the patch cancels fsl,uart-has-rtscts flag to
disable DMA support,
a)settermios()doesn't set CRTSCTS: DMA disabled, CTS of hardware
AUART read by
get_mctrl(), RTS (as gpio) controlled byset_mctrl(), in
addition RTS of hardware AUART
is also controlled but the case assumes it is not selected by
pinmux in DT
b)settermios()sets CRTSCTS: DMA disabled, auto RTS/CTS is enabled
but RTS is controlled byset_mctrl()as gpio because the case assumes it is not selected
by pinmux in DTIt is not nice description but I hadn't idea how to write it more clear. The mixed cases 4) and 5) are likely not so useful but possible and not so expensive
to support.
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
Quoted 1 line
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
The best suggestion I can give you is to fix your hardware early, before you run into nasty deep s.....tuff. These workarounds do not work and they will bit you later on, when it's hard to fix the hardware anymore.
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
W dniu 2014-11-07 o 12:02, Marek Vasut pisze:
Quoted 5 lines · Janusz U?ycki
Quoted 3 lines
W dniu 2014-11-07 o 09:03, Marek Vasut pisze:
Quoted 2 lines · Huang Shijie
Quoted 1 line
why change them to gpio?
+CC Alexandre, since he might be interested :-)
:)
Quoted 6 lines
Quoted 4 lines
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Your logic is outright flawed here, the first sentence doesn't implicate the second sentence. In fact, those two are completely unrelated.
I didn't write MUST but CAN. There is a choice. Is flexibility of the driver disadvantage?
Quoted 24 lines
Quoted 24 lines
Quoted 24 lines
Quoted 6 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the
same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
You will run into timing problems (see above).
A lot of 8250-compatible devices has no hardware flow control and in most cases
they works and it is enough even for 115200 speed if CTS is handled by irq. So it depends on your needs.
Quoted 4 lines
What you're proposing here is a workaround for broken hardware, which was proven to be a bad idea and NAK'd already multiple times in the past (please see the links I posted in my last email).
It is not broken hardware - rather limited to lower speeds but still very useful solution.
Quoted 6 lines
Quoted 4 lines
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support inmxs_auart_init_gpios()if RTS or CTS line is set as gpio.DMA has nothing to do with those problems here. DMA can be safely ignored for the purpose of the discussion altogether.
When gpios are used for RTS/CTS DMA is not used. However DMA is related due to the driver
and "fsl,uart-has-rtscts". If you look into code of the driver you should agree.
Quoted 8 lines
Like I explained already -- the problem is with the GPIO and AUART block not being synchronised by the same clock. It is therefore impossible to predict and control when the GPIO signals and the AUART signals will toggle in relation to one another.
Quoted 1 line
So I didn't test the patch with the DMA - I've just disabled it.
This would break the driver for pretty much everyone using higher baud rates.
NO, there is a choice. If you don't use RTS/CTS as GPIO DMA isn't enabled. It seems you didn't read neither the patch nor the driver's code and analized only the sentence.
Quoted 61 lines
Quoted 61 lines
The question is different. The driver supports the cases for RTS/CTS:
1) both RTS/CTS assigned to hardware AUART (pinmux configured by DT, DT sets fsl,uart-has-rtscts)
a)settermios()sets CRTSCTS: DMA enabled, auto RTS/CTS is enabled
b)settermios()doesn't set CRTSCTS: DMA disabled, RTS/CTS
controlled by get/set_mctrl()
2) both RTS/CTS assigned to hardware AUART (pinmux configured by DT, DT doesn't set fsl,uart-has-rtscts)
a)settermios()sets CRTSCTS: DMA disabled, auto RTS/CTS is enabled
b)settermios()doesn't set CRTSCTS: DMA disabled, RTS/CTS
controlled by get/set_mctrl()and after the patch it is more complex (because of mixed cases):
3) both RTS/CTS assigned to gpios (DT sets or not fsl,uart-has-rtscts):
the patch cancels fsl,uart-has-rtscts flag to disable DMA support,settermios()sets or not CRTSCTS: DMA disabled, RTS/CTS controlled
by get/set_mctrl(),
both lines by gpios. In addition:
a)settermios()doesn't set CRTSCTS: RTS of hardware AUART is also
controlled but
the case assumes it is not selected by pinmux in DT
b)settermios()sets CRTSCTS: auto RTS of hardware AUART is also
enabled but
the case assumes it is not selected by pinmux in DT
4) RTS assigned to hardware AUART (pinmux configured by DT, fsl,uart-has-rtscts set or not),
CTS assigned to gpio: the patch cancels fsl,uart-has-rtscts flag to
disable DMA support,
a)settermios()doesn't set CRTSCTS: DMA disabled, CTS (as gpio)
read byget_mctrl(),
RTS of hardware AUART controlled byset_mctrl()
b)settermios()sets CRTSCTS: DMA disabled, CTS (as gpio) read byget_mctrl(),
auto RTS is enabled
So case 4) is exactly 3) case with just different pinmux
configuration and the patch
threats 3) and 4) as the same case.
5) CTS assigned to hardware AUART (pinmux configured by DT, fsl,uart-has-rtscts set or not),
RTS assigned to gpio: the patch cancels fsl,uart-has-rtscts flag to
disable DMA support,
a)settermios()doesn't set CRTSCTS: DMA disabled, CTS of hardware
AUART read by
get_mctrl(), RTS (as gpio) controlled byset_mctrl(), in
addition RTS of hardware AUART
is also controlled but the case assumes it is not selected by
pinmux in DT
b)settermios()sets CRTSCTS: DMA disabled, auto RTS/CTS is enabled
but RTS is controlled byset_mctrl()as gpio because the case assumes it is not selected
by pinmux in DTIt is not nice description but I hadn't idea how to write it more clear. The mixed cases 4) and 5) are likely not so useful but possible and not so expensive
to support.
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
Quoted 4 lines
Quoted 1 line
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
The best suggestion I can give you is to fix your hardware early, before you run into nasty deep s.....tuff. These workarounds do not work and they will bit you later on, when it's hard to fix the hardware anymore.
The speed is limited but why don't you accept SW-HW mixed solutions? Exactly the same method is accepted for 8250.
It is good to have choice than not. We can comment that speed is limited for gpio-based hardware flow control. So please, rethink again.
best regards
Janusz
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
On Friday, November 07, 2014 at 02:23:23 PM, Janusz U?ycki wrote:
[...]
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Your logic is outright flawed here, the first sentence doesn't implicate the second sentence. In fact, those two are completely unrelated.
I didn't write MUST but CAN. There is a choice. Is flexibility of the driver disadvantage?
If the flexibility brings in known problems, then yes, it is a problem. Not because of the flexibility, but because it brings in bugs.
Quoted 33 lines
Quoted 33 lines
Quoted 32 lines
Quoted 22 lines
Quoted 6 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the
same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
Quoted 7 lines
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo
of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
Quoted 6 lines
Quoted 1 line
You will run into timing problems (see above).
A lot of 8250-compatible devices has no hardware flow control and in most cases
they works and it is enough even for 115200 speed if CTS is handled by irq. So it depends on your needs.
I presume that in such a case , the 8250 still handles the CTS line, not some external GPIO block, yes ?
Quoted 6 lines
Quoted 3 lines
What you're proposing here is a workaround for broken hardware, which was proven to be a bad idea and NAK'd already multiple times in the past (please see the links I posted in my last email).
It is not broken hardware - rather limited to lower speeds but still very useful solution.
What exact "lower speed" are you talking about here and why ?
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support inmxs_auart_init_gpios()if RTS or CTS line is set as gpio.
Quoted 7 lines
Quoted 2 lines
DMA has nothing to do with those problems here. DMA can be safely ignored for the purpose of the discussion altogether.
When gpios are used for RTS/CTS DMA is not used. However DMA is related due to the driver
and "fsl,uart-has-rtscts". If you look into code of the driver you should agree.
This makes me believe that the DMA introduces too many timing fluctuations, so it's really not possible for you to keep toggling the GPIOs such that the bus would work. Is that the case ?
[...]
Quoted 11 lines
Quoted 9 lines
Quoted 5 lines
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
The best suggestion I can give you is to fix your hardware early, before you run into nasty deep s.....tuff. These workarounds do not work and they will bit you later on, when it's hard to fix the hardware anymore.
The speed is limited but why don't you accept SW-HW mixed solutions?
Did you read up on the RS485 timing problems and why that solution was never accepted for any driver ? I believe the threads explained that quite clearly.
Quoted 1 line
Exactly the same method is accepted for 8250.
Can you point out this code please ?
Quoted 2 lines
It is good to have choice than not. We can comment that speed is limited for gpio-based hardware flow control. So please, rethink again.
[...]
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
W dniu 2014-11-07 o 15:48, Marek Vasut pisze:
Quoted 6 lines · Janusz U?ycki
[...]
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Your logic is outright flawed here, the first sentence doesn't implicate the second sentence. In fact, those two are completely unrelated.
I didn't write MUST but CAN. There is a choice. Is flexibility of the driver disadvantage?
If the flexibility brings in known problems, then yes, it is a problem. Not because of the flexibility, but because it brings in bugs.
New features new bugs :) Does it mean to stop development?
Quoted 31 lines
Quoted 31 lines
Quoted 31 lines
Quoted 31 lines
Quoted 22 lines
Quoted 7 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the
same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
Quoted 7 lines
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo
of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
You will run into timing problems (see above).
A lot of 8250-compatible devices has no hardware flow control and in most cases
they works and it is enough even for 115200 speed if CTS is handled by irq. So it depends on your needs.I presume that in such a case , the 8250 still handles the CTS line, not some external GPIO block, yes ?
Yes. However mxs includes both GPIO and AUART. Clocks differs but it is still the same silicon.
External GPIO block is extreme example highly not recommended here.
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
What you're proposing here is a workaround for broken hardware, which was proven to be a bad idea and NAK'd already multiple times in the past (please see the links I posted in my last email).
It is not broken hardware - rather limited to lower speeds but still very useful solution.
What exact "lower speed" are you talking about here and why ?
For example not more than 115200 but it depends on CPU load of course, FIFO size
and device on the opposite site. RTS/CTS via GPIO require to know the limit in an application.
I googled even so exotic thing like:
"8250: add support for DTR/DSR hardware flow control"
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support inmxs_auart_init_gpios()if RTS or CTS line is set as gpio.DMA has nothing to do with those problems here. DMA can be safely ignored for the purpose of the discussion altogether.
Quoted 7 lines
Quoted 4 lines
When gpios are used for RTS/CTS DMA is not used. However DMA is related due to the driver
and "fsl,uart-has-rtscts". If you look into code of the driver you should agree.This makes me believe that the DMA introduces too many timing fluctuations, so it's really not possible for you to keep toggling the GPIOs such that the bus would work. Is that the case ?
Yes, for RTS/CTS based on gpio DMA is not used. They are just toggled. So you probably misunderstood me.
Quoted 6 lines
[...]
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
Quoted 7 lines
Quoted 5 lines
Quoted 4 lines
Quoted 1 line
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
The best suggestion I can give you is to fix your hardware early, before you run into nasty deep s.....tuff. These workarounds do not work and they will bit you later on, when it's hard to fix the hardware anymore.
The speed is limited but why don't you accept SW-HW mixed solutions?
Did you read up on the RS485 timing problems and why that solution was never accepted for any driver ? I believe the threads explained that quite clearly.
Example of RS485 implementation where RTS is toggled by software:
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/tty/serial/omap-serial.c?id=4a0ac0f55b18dc297a87a85417fcf068658bf103
https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/tty/serial/omap-serial.c
Quoted 3 lines
Quoted 2 lines
Exactly the same method is accepted for 8250.
Can you point out this code please ?
If 8250 doesn't support auto flow control RTS/CTS are also toggled by software,uart_trottle(), uart_untrothle(), uart_handle_cts_change():
http://lxr.free-electrons.com/source/drivers/tty/serial/serial_core.c#L635
http://lxr.free-electrons.com/source/drivers/tty/serial/serial_core.c#L2796
Detected by irq (ms enabled when CRTSCTS) CTS change stops tx because UPF_HARD_FLOW flag is not set by the mxs-auart driver.
Of course timing problem exists but in many cases it is not critical - the toggle method was implemented many years ago and it seems to work.
Quoted 4 lines
Quoted 3 lines
It is good to have choice than not. We can comment that speed is limited for gpio-based hardware flow control. So please, rethink again.
[...]
The only problem for me is misleading "fsl,uart-has-rtscts" name because the flag
only enables DMA if CRTSCTS is set and hardware flow control of AUART block is used.
best regards
Janusz
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
Quoted 12 lines · Janusz U?ycki
W dniu 2014-11-07 o 15:48, Marek Vasut pisze:
Quoted 11 lines · Janusz U?ycki
[...]
Quoted 8 lines
Quoted 7 lines
Quoted 3 lines
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Your logic is outright flawed here, the first sentence doesn't implicate the second sentence. In fact, those two are completely unrelated.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
I didn't write MUST but CAN. There is a choice. Is flexibility of the driver disadvantage?
If the flexibility brings in known problems, then yes, it is a problem. Not because of the flexibility, but because it brings in bugs.
New features new bugs :) Does it mean to stop development?
You shouldn't push code which is known to be defective by design into mainline.
Quoted 41 lines
Quoted 41 lines
Quoted 40 lines
Quoted 28 lines
Quoted 28 lines
Quoted 28 lines
Quoted 6 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the
same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo
of UART+GPIO toggling.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
You will run into timing problems (see above).
A lot of 8250-compatible devices has no hardware flow control and in most cases
they works and it is enough even for 115200 speed if CTS is handled by irq. So it depends on your needs.
Quoted 6 lines
Quoted 2 lines
I presume that in such a case , the 8250 still handles the CTS line, not some external GPIO block, yes ?
Yes. However mxs includes both GPIO and AUART. Clocks differs but it is still the same silicon.
External GPIO block is extreme example highly not recommended here.
The way you implemented this particular change, it is possible to use arbitrary GPIO pin. There is no way you can guarantee anything about the latency of the GPIO toggling (I am repeating myself).
Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
What you're proposing here is a workaround for broken hardware, which was proven to be a bad idea and NAK'd already multiple times in the past (please see the links I posted in my last email).
It is not broken hardware - rather limited to lower speeds but still very useful solution.
Quoted 6 lines
Quoted 1 line
What exact "lower speed" are you talking about here and why ?
For example not more than 115200 but it depends on CPU load of course, FIFO size
and device on the opposite site. RTS/CTS via GPIO require to know the limit in an application.
OK, this is completely unreliable solution, which works just by sheer luck.
Quoted 2 lines
I googled even so exotic thing like:
"8250: add support for DTR/DSR hardware flow control"
The fact that those perversions exists doesn't make them right. It doesn't even make them mainlinable.
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
Quoted 7 lines
Quoted 4 lines
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support inmxs_auart_init_gpios()if RTS or CTS line is set as gpio.DMA has nothing to do with those problems here. DMA can be safely ignored for the purpose of the discussion altogether.
When gpios are used for RTS/CTS DMA is not used. However DMA is related due to the driver
and "fsl,uart-has-rtscts". If you look into code of the driver you should agree.
Quoted 6 lines
Quoted 3 lines
This makes me believe that the DMA introduces too many timing fluctuations, so it's really not possible for you to keep toggling the GPIOs such that the bus would work. Is that the case ?
Yes, for RTS/CTS based on gpio DMA is not used. They are just toggled. So you probably misunderstood me.
I understand you -- in case DMA is enabled on the AUART block, your hack is no longer capable to working correctly, so everything falls apart.
Quoted 19 lines
Quoted 13 lines
[...]
Quoted 11 lines
Quoted 10 lines
Quoted 5 lines
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
The best suggestion I can give you is to fix your hardware early, before you run into nasty deep s.....tuff. These workarounds do not work and they will bit you later on, when it's hard to fix the hardware anymore.
Quoted 5 lines
Quoted 1 line
The speed is limited but why don't you accept SW-HW mixed solutions?
Did you read up on the RS485 timing problems and why that solution was never accepted for any driver ? I believe the threads explained that quite clearly.
Quoted 5 lines
Example of RS485 implementation where RTS is toggled by software:
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/dri
vers/tty/serial/omap-serial.c?id=4a0ac0f55b18dc297a87a85417fcf068658bf103
https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/tty/serial/omap-serial.c
This is a question for Greg. I checked the discussion about this patch [1] and I see this timing issue was brought up, but the patch was applied anyway. I cannot tell you why , I just know that this GPIO approach has problems and I wrestled those a couple of days ago (without success, it's not possible to get correct timing).
[1] http://www.spinics.net/lists/linux-serial/msg10574.html
Quoted 11 lines
Quoted 3 lines
Quoted 1 line
Exactly the same method is accepted for 8250.
Can you point out this code please ?
If 8250 doesn't support auto flow control RTS/CTS are also toggled by software,
uart_trottle(),uart_untrothle(),uart_handle_cts_change():
http://lxr.free-electrons.com/source/drivers/tty/serial/serial_core.c#L635
http://lxr.free-electrons.com/source/drivers/tty/serial/serial_core.c#L2796
Detected by irq (ms enabled when CRTSCTS) CTS change stops tx becauseUPF_HARD_FLOWflag is not set by the mxs-auart driver.
This doesn't use GPIO to toggle the RTS/CTS pins, it does toggle then via the 8250 IP block registers, right ?
Quoted 2 lines
Of course timing problem exists but in many cases it is not critical - the toggle method was implemented many years ago and it seems to work.
Yes, it does seem to work initially, that's why so many hardware people implement it, thinking the software people can fix those flubs. Problem is, this is one of those nasty problems, which cannot be fixed in software.
Quoted 12 lines
Quoted 4 lines
Quoted 2 lines
It is good to have choice than not. We can comment that speed is limited for gpio-based hardware flow control. So please, rethink again.
[...]
The only problem for me is misleading "fsl,uart-has-rtscts" name because the flag
only enables DMA if CRTSCTS is set and hardware flow control of AUART block is used.best regards
Janusz
PATCH v4 2/4 serial: mxs-auart: use mctrl_gpio helpers for handling modem signals
W dniu 2014-11-08 o 12:22, Marek Vasut pisze:
Quoted 11 lines · Janusz U?ycki
Quoted 10 lines
W dniu 2014-11-07 o 15:48, Marek Vasut pisze:
Quoted 9 lines · Janusz U?ycki
[...]
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
Hardware RTS/CTS lines can be occupied by RX/TX of other AUART port in order to obtain as much uarts as possible using i.mx283. Therefore gpios can be used for "hardware" flow control.
Your logic is outright flawed here, the first sentence doesn't implicate the second sentence. In fact, those two are completely unrelated.
Quoted 6 lines
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
I didn't write MUST but CAN. There is a choice. Is flexibility of the driver disadvantage?
If the flexibility brings in known problems, then yes, it is a problem. Not because of the flexibility, but because it brings in bugs.
New features new bugs :) Does it mean to stop development?
You shouldn't push code which is known to be defective by design into mainline.
I've written in general. The patch is not defective and it has been discussed before (V4).
Did you read the code and the patch?
Quoted 36 lines
Quoted 36 lines
Quoted 36 lines
Quoted 36 lines
Quoted 25 lines
Quoted 25 lines
Quoted 25 lines
Quoted 6 lines
If we change them to gpio. Could the DMA still
works fine?
did you test the DMA with this patch?Add Marek for this patch too.
I didn't look too deep into the patch, so here's just my experience:
1) The AUART block signals and GPIO block signals are not sychronised using the
same clock. Therefore, the latency between toggling of the AUART lines and the GPIO-driven pins will not be deterministic and will vary. There might be a way to approximate that, but that's definitelly not a reliable solution.
This is very bad for example if you drive RS485 DIR line with the RTS pin as a GPIO ; the RTS pin will toggle at non-deterministic time compared to the end of UART transmission. This will trigger bit-loss on the RS485 line and you just don't want that.
2) Speaking of RS485, there's [1] and [2]. which I believe apply to any combo
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
of UART+GPIO toggling.
So I hate to bring the bad news , but UART+GPIO combo toggling is really a bad bad idea.
Unfortunately if hardware is limited there is no choice and UART+GPIO is necessary.
You will run into timing problems (see above).
A lot of 8250-compatible devices has no hardware flow control and in most cases
they works and it is enough even for 115200 speed if CTS is handled by irq. So it depends on your needs.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I presume that in such a case , the 8250 still handles the CTS line, not some external GPIO block, yes ?
Yes. However mxs includes both GPIO and AUART. Clocks differs but it is still the same silicon.
External GPIO block is extreme example highly not recommended here.The way you implemented this particular change, it is possible to use arbitrary GPIO pin. There is no way you can guarantee anything about the latency of the GPIO toggling (I am repeating myself).
GPIO latency in SoC is usually smaller than any pin toggled in 8250 chip. You can write some gpio-limiter patch for Richard's GPIO patch but in my opinion
it has no sense. DTB maker has to know what he is doing and why. My patch concerns the mxs-auart driver so I can't understand why your notes are addressed to me. You complain on much more patches in mainline,
not mine.
Quoted 11 lines
Quoted 11 lines
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
What you're proposing here is a workaround for broken hardware, which was proven to be a bad idea and NAK'd already multiple times in the past (please see the links I posted in my last email).
It is not broken hardware - rather limited to lower speeds but still very useful solution.
What exact "lower speed" are you talking about here and why ?
For example not more than 115200 but it depends on CPU load of course, FIFO size
and device on the opposite site. RTS/CTS via GPIO require to know the limit in an application.
Quoted 6 lines
OK, this is completely unreliable solution, which works just by sheer luck.
Quoted 2 lines
I googled even so exotic thing like:
"8250: add support for DTR/DSR hardware flow control"The fact that those perversions exists doesn't make them right. It doesn't even make them mainlinable.
Again, not addressed to me. The world has accepted them.
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 7 lines
Quoted 5 lines
Your experience confirms the discussion [3] with Russell King. DMA should be disabled and
the patch disables DMA support inmxs_auart_init_gpios()if RTS or CTS line is set as gpio.DMA has nothing to do with those problems here. DMA can be safely ignored for the purpose of the discussion altogether.
When gpios are used for RTS/CTS DMA is not used. However DMA is related due to the driver
and "fsl,uart-has-rtscts". If you look into code of the driver you should agree.
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
This makes me believe that the DMA introduces too many timing fluctuations, so it's really not possible for you to keep toggling the GPIOs such that the bus would work. Is that the case ?
Yes, for RTS/CTS based on gpio DMA is not used. They are just toggled. So you probably misunderstood me.
I understand you -- in case DMA is enabled on the AUART block, your hack is no longer capable to working correctly, so everything falls apart.
You still didn't read the code or not carefully :)
If RTS/CTS aren't set as gpio it will work exactly as before - including DMA.
Otherwise I wouldn't push the patchset.
Quoted 21 lines
Quoted 13 lines
Quoted 13 lines
[...]
Quoted 10 lines
Quoted 9 lines
Quoted 5 lines
Now the question: "fsl,uart-has-rtscts" name seems to be misleading now, do you agree? It rather should include "dma" word in the name. Any suggestion?
[3] http://thread.gmane.org/gmane.linux.serial/16069/focus=16077
The best suggestion I can give you is to fix your hardware early, before you run into nasty deep s.....tuff. These workarounds do not work and they will bit you later on, when it's hard to fix the hardware anymore.
The speed is limited but why don't you accept SW-HW mixed solutions?
Quoted 8 lines
Quoted 3 lines
Did you read up on the RS485 timing problems and why that solution was never accepted for any driver ? I believe the threads explained that quite clearly.
Example of RS485 implementation where RTS is toggled by software:
https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/dri
vers/tty/serial/omap-serial.c?id=4a0ac0f55b18dc297a87a85417fcf068658bf103
https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/drivers/tty/serial/omap-serial.c
Quoted 7 lines
This is a question for Greg. I checked the discussion about this patch [1] and I see this timing issue was brought up, but the patch was applied anyway. I cannot tell you why , I just know that this GPIO approach has problems and I wrestled those a couple of days ago (without success, it's not possible to get correct timing).
Yes, this is the question for others - tty/serial's guru. The timming isn't great but your opinion makes impossible to work most RS485 devices,
especially older but not only. You want to change the world here I think. In practive
costs usually have higher value than perfect timming if a solution works great without.
In the past hardware RS485 support even didn't exist. It is changing but slowly.
Quoted 11 lines
Quoted 9 lines
Quoted 2 lines
Quoted 1 line
Exactly the same method is accepted for 8250.
Can you point out this code please ?
If 8250 doesn't support auto flow control RTS/CTS are also toggled by software,
uart_trottle(),uart_untrothle(),uart_handle_cts_change():
http://lxr.free-electrons.com/source/drivers/tty/serial/serial_core.c#L635
http://lxr.free-electrons.com/source/drivers/tty/serial/serial_core.c#L2796
Detected by irq (ms enabled when CRTSCTS) CTS change stops tx becauseUPF_HARD_FLOWflag is not set by the mxs-auart driver.This doesn't use GPIO to toggle the RTS/CTS pins, it does toggle then via the 8250 IP block registers, right ?
Right. My patch allows to toggle the pins via SoC's pins - there is a choice in DT.
About latency I've written above.
Quoted 5 lines
Quoted 2 lines
Of course timing problem exists but in many cases it is not critical - the toggle method was implemented many years ago and it seems to work.
Yes, it does seem to work initially, that's why so many hardware people implement it, thinking the software people can fix those flubs. Problem is, this is one of those nasty problems, which cannot be fixed in software.
Look into the past. And, not each application needs perfect things. Hardware people do
not expect of magic things - they must know reality better than you assume. It seems you have young people's approach. The real world is not perfect. There are
costs, limited set of available chips, limited PCB's space, habits, etc.
The thread doesn't concern my patchset at all now :)
thanks for the nice discussion
Janusz
Quoted 7 lines
Quoted 7 lines
The only problem for me is misleading "fsl,uart-has-rtscts" name because the flag
only enables DMA if CRTSCTS is set and hardware flow control of AUART block is used.best regards
Janusz
PATCH v4 3/4 serial: mxs-auart: add interrupts for modem control lines
In reply to Janusz UzyckiHandle CTS/DSR/RI/DCD GPIO interrupts in mxs-auart.
---
v3 -> v4 changelog:
* rebased
v2 -> v3 changelog:
* introduces mctrl_prev instead of removed ctrl
* mxs_auart_modem_status() moved from [3/4]
* mxs_auart_modem_status() interrupt_enabled meant s->ms_irq_enabled
--- drivers/tty/serial/mxs-auart.c | 174 ++++++++++++++++++++++++++- 1 file changed, 172 insertions(+), 2 deletions(-)
drivers/tty/serial/mxs-auart.c +172 -2
@@ -42,7 +42,10 @@#include <asm/cacheflush.h> +#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/err.h> +#include <linux/irq.h> #include "serial_mctrl_gpio.h" #define MXS_AUART_PORTS 5
@@ -146,6 +149,7 @@ struct mxs_auart_port {#define MXS_AUART_DMA_RX_READY 3/* bit 3 */ #define MXS_AUART_RTSCTS 4/* bit 4 */ unsigned long flags; +unsigned int mctrl_prev;enum mxs_auart_type devtype;unsigned int irq;
@@ -163,6 +167,8 @@ struct mxs_auart_port {void *rx_dma_buf;struct mctrl_gpios *gpios; +int gpio_irq[UART_GPIO_MAX ]; +bool ms_irq_enabled; };static struct platform_device_id mxs_auart_devtype[] = {
@@ -427,6 +433,29 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl)mctrl_gpio_set (s->gpios, mctrl); } +#define MCTRL_ANY_DELTA (TIOCM_RI | TIOCM_DSR | TIOCM_CD | TIOCM_CTS) +static u32 mxs_auart_modem_status (struct mxs_auart_port *s,u32 mctrl) +{ +u32 mctrl_diff; + + mctrl_diff = mctrl ^ s->mctrl_prev; + s->mctrl_prev = mctrl; +if (mctrl_diff &MCTRL_ANY_DELTA && s->ms_irq_enabled && + s->port.state !=NULL ) { +if (mctrl_diff &TIOCM_RI ) + s->port.icount.rng++; +if (mctrl_diff &TIOCM_DSR ) + s->port.icount.dsr++; +if (mctrl_diff &TIOCM_CD ) +uart_handle_dcd_change (&s->port, mctrl &TIOCM_CD ); +if (mctrl_diff &TIOCM_CTS ) +uart_handle_cts_change (&s->port, mctrl &TIOCM_CTS ); + +wake_up_interruptible (&s->port.state->port.delta_msr_wait); + } +return mctrl; +} +static u32 mxs_auart_get_mctrl (struct uart_port *u) {struct mxs_auart_port *s =to_auart_port (u);
@@ -439,6 +468,64 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u)return mctrl_gpio_get (s->gpios, &mctrl); } +/* +* Enable modem status interrupts +*/ +static void mxs_auart_enable_ms (struct uart_port *port) +{ +struct mxs_auart_port *s =to_auart_port (port); + +/* +* Interrupt should not be enabled twice +*/ +if (s->ms_irq_enabled) +return ; + + s->ms_irq_enabled = true; + +if (s->gpio_irq[UART_GPIO_CTS ] >=0 ) +enable_irq (s->gpio_irq[UART_GPIO_CTS ]); +/* TODO: enable AUART_INTR_CTSMIEN otherwise */ + +if (s->gpio_irq[UART_GPIO_DSR ] >=0 ) +enable_irq (s->gpio_irq[UART_GPIO_DSR ]); + +if (s->gpio_irq[UART_GPIO_RI ] >=0 ) +enable_irq (s->gpio_irq[UART_GPIO_RI ]); + +if (s->gpio_irq[UART_GPIO_DCD ] >=0 ) +enable_irq (s->gpio_irq[UART_GPIO_DCD ]); +} + +/* +* Disable modem status interrupts +*/ +static void mxs_auart_disable_ms (struct uart_port *port) +{ +struct mxs_auart_port *s =to_auart_port (port); + +/* +* Interrupt should not be disabled twice +*/ +if (!s->ms_irq_enabled) +return ; + + s->ms_irq_enabled = false; + +if (s->gpio_irq[UART_GPIO_CTS ] >=0 ) +disable_irq (s->gpio_irq[UART_GPIO_CTS ]); +/* TODO: disable AUART_INTR_CTSMIEN otherwise */ + +if (s->gpio_irq[UART_GPIO_DSR ] >=0 ) +disable_irq (s->gpio_irq[UART_GPIO_DSR ]); + +if (s->gpio_irq[UART_GPIO_RI ] >=0 ) +disable_irq (s->gpio_irq[UART_GPIO_RI ]); + +if (s->gpio_irq[UART_GPIO_DCD ] >=0 ) +disable_irq (s->gpio_irq[UART_GPIO_DCD ]); +} +static int mxs_auart_dma_prep_rx (struct mxs_auart_port *s);static void dma_rx_callback (void *arg) {
@@ -689,6 +776,12 @@ static void mxs_auart_settermios(struct uart_port *u,dev_err (s->dev,"We can not start up the DMA.\n" ); } } + +/* CTS flow-control and modem-status interrupts */ +if (UART_ENABLE_MS (u, termios->c_cflag)) +mxs_auart_enable_ms (u); +else +mxs_auart_disable_ms (u); }static irqreturn_t mxs_auart_irq_handle (int irq,void *context)
@@ -706,8 +799,18 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | AUART_INTR_CTSMIS), s->port.membase + AUART_INTR_CLR); +/* +* Dealing with GPIO interrupt +*/ +if (irq == s->gpio_irq[UART_GPIO_CTS ] || + irq == s->gpio_irq[UART_GPIO_DCD ] || + irq == s->gpio_irq[UART_GPIO_DSR ] || + irq == s->gpio_irq[UART_GPIO_RI ]) +mxs_auart_modem_status (s, +mctrl_gpio_get (s->gpios, &s->mctrl_prev)); +if (istat &AUART_INTR_CTSMIS ) { -if (CTS_AT_AUART ()) +if (CTS_AT_AUART () && s->ms_irq_enabled)uart_handle_cts_change (&s->port, stat &AUART_STAT_CTS ); writel(AUART_INTR_CTSMIS,
@@ -770,6 +873,10 @@ static int mxs_auart_startup(struct uart_port *u)*/ writel (AUART_LINECTRL_FEN , u->membase +AUART_LINECTRL_SET ); +/* get initial status of modem lines */ +mctrl_gpio_get (s->gpios, &s->mctrl_prev); + + s->ms_irq_enabled = false;return 0 ; }
@@ -777,6 +884,8 @@ static void mxs_auart_shutdown(struct uart_port *u) {struct mxs_auart_port *s =to_auart_port (u); +mxs_auart_disable_ms (u); +if (auart_dma_enabled (s))mxs_auart_dma_exit (s);
@@ -833,6 +942,7 @@ static struct uart_ops mxs_auart_ops = { .start_tx = mxs_auart_start_tx, .stop_tx = mxs_auart_stop_tx, .stop_rx = mxs_auart_stop_rx, + .enable_ms = mxs_auart_enable_ms, .break_ctl = mxs_auart_break_ctl, .set_mctrl = mxs_auart_set_mctrl, .get_mctrl = mxs_auart_get_mctrl,
@@ -1035,6 +1145,9 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,static bool mxs_auart_init_gpios (struct mxs_auart_port *s,struct device *dev) { +enum mctrl_gpio_idx i; +struct gpio_desc *gpiod; + s->gpios =mctrl_gpio_init (dev,0 );if (IS_ERR_OR_NULL (s->gpios))return false;
@@ -1047,9 +1160,54 @@ static bool mxs_auart_init_gpios(struct mxs_auart_port *s, struct device *dev)clear_bit (MXS_AUART_RTSCTS , &s->flags); } +for (i =0 ; i <UART_GPIO_MAX ; i++) { + gpiod =mctrl_gpio_to_gpiod (s->gpios, i); +if (gpiod && (gpiod_get_direction (gpiod) ==GPIOF_DIR_IN )) + s->gpio_irq[i] =gpiod_to_irq (gpiod); +else + s->gpio_irq[i] = -EINVAL ; + } +return true; } +static void mxs_auart_free_gpio_irq (struct mxs_auart_port *s) +{ +enum mctrl_gpio_idx i; + +for (i =0 ; i <UART_GPIO_MAX ; i++) +if (s->gpio_irq[i] >=0 ) +free_irq (s->gpio_irq[i], s); +} + +static int mxs_auart_request_gpio_irq (struct mxs_auart_port *s) +{ +int *irq = s->gpio_irq; +enum mctrl_gpio_idx i; +int err =0 ; + +for (i =0 ; (i <UART_GPIO_MAX ) && !err; i++) { +if (irq[i] <0 ) +continue ; + +irq_set_status_flags (irq[i],IRQ_NOAUTOEN ); + err =request_irq (irq[i], mxs_auart_irq_handle, +IRQ_TYPE_EDGE_BOTH ,dev_name (s->dev), s); +if (err) +dev_err (s->dev,"%s - Can't get %d irq\n" , + __func__, irq[i]); + } + +/* +* If something went wrong, rollback. +*/ +while (err && (--i >=0 )) +if (irq[i] >=0 ) +free_irq (irq[i], s); + +return err; +} +static int mxs_auart_probe (struct platform_device *pdev) { const struct of_device_id *of_id =
@@ -1097,6 +1255,8 @@ static int mxs_auart_probe(struct platform_device *pdev) s->port.type =PORT_IMX ; s->port.dev = s->dev = &pdev->dev; + s->mctrl_prev =0 ; + s->irq =platform_get_irq (pdev,0 ); s->port.irq = s->irq; ret =request_irq (s->irq, mxs_auart_irq_handle,0 ,dev_name (&pdev->dev), s);
@@ -1109,13 +1269,20 @@ static int mxs_auart_probe(struct platform_device *pdev)dev_err (&pdev->dev,"Failed to initialize GPIOs. The serial port may not work as expected\n" ); +/* +* Get the GPIO lines IRQ +*/ + ret =mxs_auart_request_gpio_irq (s); +if (ret) + goto out_free_irq; + auart_port[s->port.line] = s;mxs_auart_reset (&s->port); ret =uart_add_one_port (&auart_driver, &s->port);if (ret) - goto out_free_irq; + goto out_free_gpio_irq; version =readl (s->port.membase +AUART_VERSION ); dev_info(&pdev->dev, "Found APPUART %d.%d.%d\n",
@@ -1124,6 +1291,8 @@ static int mxs_auart_probe(struct platform_device *pdev)return 0 ; +out_free_gpio_irq: +mxs_auart_free_gpio_irq (s); out_free_irq: auart_port[pdev->id] =NULL ;free_irq (s->irq, s);
@@ -1143,6 +1312,7 @@ static int mxs_auart_remove(struct platform_device *pdev) auart_port[pdev->id] =NULL ; +mxs_auart_free_gpio_irq (s);clk_put (s->clk);free_irq (s->irq, s);kfree (s);
Signature · 1 line
1.7.11.3
PATCH v4 4/4 serial: mxs-auart: enable PPS support
In reply to Janusz UzyckiEnables PPS support in mxs-auart serial driver to make PPS API working.
---
v3 -> v4 changelog:
* coding style: braces in both branches of condition
v2 -> v3 changelog:
* no changes
--- drivers/tty/serial/mxs-auart.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/tty/serial/mxs-auart.c +11 -0
@@ -784,6 +784,16 @@ static void mxs_auart_settermios(struct uart_port *u,mxs_auart_disable_ms (u); } +static void mxs_auart_set_ldisc (struct uart_port *port,int new) +{ +if (new ==N_PPS ) { + port->flags |=UPF_HARDPPS_CD ; +mxs_auart_enable_ms (port); + }else { + port->flags &= ~UPF_HARDPPS_CD ; + } +} +static irqreturn_t mxs_auart_irq_handle (int irq,void *context) {u32 istat;
@@ -949,6 +959,7 @@ static struct uart_ops mxs_auart_ops = { .startup = mxs_auart_startup, .shutdown = mxs_auart_shutdown, .set_termios = mxs_auart_settermios, + .set_ldisc = mxs_auart_set_ldisc, .type = mxs_auart_type, .release_port = mxs_auart_release_port, .request_port = mxs_auart_request_port,
Signature · 1 line
1.7.11.3