Re: [RFC] tty/serial/8250: use mctrl_gpio helpers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 10, 2016 at 8:43 AM, Uwe Kleine-König
<u.kleine-koenig@xxxxxxxxxxxxxx> wrote:
> Hello,
>
> On Wed, Mar 09, 2016 at 12:07:39PM +0100, Yegor Yefremov wrote:
>> On Wed, Mar 9, 2016 at 12:03 PM,  <yegorslists@xxxxxxxxxxxxxx> wrote:
>> > From: Yegor Yefremov <yegorslists@xxxxxxxxxxxxxx>
>> >
>> > This patch permits the usage fo GPIOs to control the CTS/RTS/DTR/DSR/DCD/RI
>> > signals.
>> >
>> > Signed-off-by: Yegor Yefremov <yegorslists@xxxxxxxxxxxxxx>
>> > ---
>> >  Documentation/devicetree/bindings/serial/8250.txt | 21 +++++++++++++++++++++
>> >  drivers/tty/serial/8250/8250.h                    |  2 ++
>> >  drivers/tty/serial/8250/8250_core.c               |  5 +++++
>> >  drivers/tty/serial/8250/8250_port.c               | 11 ++++++++++-
>> >  drivers/tty/serial/8250/Kconfig                   |  1 +
>> >  include/linux/serial_8250.h                       |  1 +
>> >  6 files changed, 40 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt
>> > index 936ab5b..277e0ee 100644
>> > --- a/Documentation/devicetree/bindings/serial/8250.txt
>> > +++ b/Documentation/devicetree/bindings/serial/8250.txt
>> > @@ -42,6 +42,9 @@ Optional properties:
>> >  - auto-flow-control: one way to enable automatic flow control support. The
>> >    driver is allowed to detect support for the capability even without this
>> >    property.
>> > +- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
>> > +  line respectively. It will use specified GPIO instead of the peripheral
>> > +  function pin for the UART feature. If unsure, don't specify this property.
>> >
>> >  Note:
>> >  * fsl,ns16550:
>> > @@ -63,3 +66,21 @@ Example:
>> >                 interrupts = <10>;
>> >                 reg-shift = <2>;
>> >         };
>> > +
>> > +Example for OMAP UART using GPIO-based modem control signals:
>> > +
>> > +       uart4: serial@49042000 {
>> > +               compatible = "ti,omap3-uart";
>> > +               reg = <0x49042000 0x400>;
>> > +               interrupts = <80>;
>> > +               dmas = <&sdma 81 &sdma 82>;
>> > +               dma-names = "tx", "rx";
>> > +               ti,hwmods = "uart4";
>> > +               clock-frequency = <48000000>;
>> > +               cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
>> > +               rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
>> > +               dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
>> > +               dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
>> > +               dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
>> > +               rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
>> > +       };
>> > diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
>> > index d54dcd8..98ee73c 100644
>> > --- a/drivers/tty/serial/8250/8250.h
>> > +++ b/drivers/tty/serial/8250/8250.h
>> > @@ -15,6 +15,8 @@
>> >  #include <linux/serial_reg.h>
>> >  #include <linux/dmaengine.h>
>> >
>> > +#include "../serial_mctrl_gpio.h"
>> > +
>> >  struct uart_8250_dma {
>> >         int (*tx_dma)(struct uart_8250_port *p);
>> >         int (*rx_dma)(struct uart_8250_port *p, unsigned int iir);
>> > diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
>> > index c9720a9..cadcaa5 100644
>> > --- a/drivers/tty/serial/8250/8250_core.c
>> > +++ b/drivers/tty/serial/8250/8250_core.c
>> > @@ -1004,6 +1004,10 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
>> >                 if (up->port.flags & UPF_FIXED_TYPE)
>> >                         uart->port.type = up->port.type;
>> >
>> > +               uart->gpios = mctrl_gpio_init(&uart->port, 0);
>> > +               if (IS_ERR(uart->gpios))
>> > +                       return PTR_ERR(uart->gpios);
>> > +
>> >                 serial8250_set_defaults(uart);
>> >
>> >                 /* Possibly override default I/O functions.  */
>> > @@ -1049,6 +1053,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
>> >
>> >                         ret = 0;
>> >                 }
>> > +
>
> This hunk should be dropped.

OK

> Otherwise the patch looks good.
>
>> >         }
>> >         mutex_unlock(&serial_mutex);
>> >
>> > diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
>> > index 8d262bc..e7bfeef 100644
>> > --- a/drivers/tty/serial/8250/8250_port.c
>> > +++ b/drivers/tty/serial/8250/8250_port.c
>> > @@ -1393,6 +1393,8 @@ static void serial8250_disable_ms(struct uart_port *port)
>> >         if (up->bugs & UART_BUG_NOMSR)
>> >                 return;
>> >
>> > +       mctrl_gpio_disable_ms(up->gpios);
>> > +
>> >         up->ier &= ~UART_IER_MSI;
>> >         serial_port_out(port, UART_IER, up->ier);
>> >  }
>> > @@ -1405,6 +1407,8 @@ static void serial8250_enable_ms(struct uart_port *port)
>> >         if (up->bugs & UART_BUG_NOMSR)
>> >                 return;
>> >
>> > +       mctrl_gpio_enable_ms(up->gpios);
>> > +
>> >         up->ier |= UART_IER_MSI;
>> >
>> >         serial8250_rpm_get(up);
>> > @@ -1680,7 +1684,8 @@ static unsigned int serial8250_get_mctrl(struct uart_port *port)
>> >                 ret |= TIOCM_DSR;
>> >         if (status & UART_MSR_CTS)
>> >                 ret |= TIOCM_CTS;
>> > -       return ret;
>> > +
>> > +       return mctrl_gpio_get(up->gpios, &ret);
>> >  }
>> >
>> >  void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl)
>> > @@ -1707,10 +1712,14 @@ EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);
>> >
>> >  static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
>> >  {
>> > +       struct uart_8250_port *up = up_to_u8250p(port);
>> > +
>> >         if (port->set_mctrl)
>> >                 port->set_mctrl(port, mctrl);
>> >         else
>> >                 serial8250_do_set_mctrl(port, mctrl);
>> > +
>> > +       mctrl_gpio_set(up->gpios, mctrl);
>> >  }
>> >
>> >  static void serial8250_break_ctl(struct uart_port *port, int break_state)
>> > diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
>> > index b03cb517..997e9a8 100644
>> > --- a/drivers/tty/serial/8250/Kconfig
>> > +++ b/drivers/tty/serial/8250/Kconfig
>> > @@ -6,6 +6,7 @@
>> >  config SERIAL_8250
>> >         tristate "8250/16550 and compatible serial support"
>> >         select SERIAL_CORE
>> > +       select SERIAL_MCTRL_GPIO if GPIOLIB
>> >         ---help---
>> >           This selects whether you want to include the driver for the standard
>> >           serial ports.  The standard answer is Y.  People who might say N
>> > diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
>> > index faa0e03..86a3ef4 100644
>> > --- a/include/linux/serial_8250.h
>> > +++ b/include/linux/serial_8250.h
>> > @@ -104,6 +104,7 @@ struct uart_8250_port {
>> >                                                  *   if no_console_suspend
>> >                                                  */
>> >         unsigned char           probe;
>> > +       struct mctrl_gpios      *gpios;
>> >  #define UART_PROBE_RSA (1 << 0)
>> >
>> >         /*
>>
>> This patch was tested on a am335x based machine. So far everything is
>> working as expected aside from interrupts. As soon as the first CTS
>> interrupt comes I get:
>>
>> ------------[ cut here ]------------
>> WARNING: CPU: 0 PID: 0 at drivers/tty/serial/serial_core.c:2893
>> uart_handle_cts_change+0x9c/0xd8()
>> Modules linked in: musb_dsps musb_am335x
>> CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W       4.5.0-rc6 #37
>> Hardware name: Generic AM33XX (Flattened Device Tree)
>> [<c0017e34>] (unwind_backtrace) from [<c0014088>] (show_stack+0x10/0x14)
>> [<c0014088>] (show_stack) from [<c02c5b24>] (dump_stack+0xb0/0xe4)
>> [<c02c5b24>] (dump_stack) from [<c003bca4>] (warn_slowpath_common+0x7c/0xb8)
>> [<c003bca4>] (warn_slowpath_common) from [<c003bd7c>]
>> (warn_slowpath_null+0x1c/0x24)
>> [<c003bd7c>] (warn_slowpath_null) from [<c0337bc8>]
>> (uart_handle_cts_change+0x9c/0xd8)
>> [<c0337bc8>] (uart_handle_cts_change) from [<c033f430>]
>> (mctrl_gpio_irq_handle+0xb0/0xcc)
>> [<c033f430>] (mctrl_gpio_irq_handle) from [<c0096db4>]
>> (handle_irq_event_percpu+0x50/0x268)
>> [<c0096db4>] (handle_irq_event_percpu) from [<c0097004>]
>> (handle_irq_event+0x38/0x5c)
>> [<c0097004>] (handle_irq_event) from [<c009a3a0>] (handle_edge_irq+0xf0/0x1bc)
>> [<c009a3a0>] (handle_edge_irq) from [<c0096438>] (generic_handle_irq+0x20/0x34)
>> [<c0096438>] (generic_handle_irq) from [<c0302038>]
>> (omap_gpio_irq_handler+0x12c/0x16c)
>> [<c0302038>] (omap_gpio_irq_handler) from [<c0096db4>]
>> (handle_irq_event_percpu+0x50/0x268)
>> [<c0096db4>] (handle_irq_event_percpu) from [<c0097004>]
>> (handle_irq_event+0x38/0x5c)
>> [<c0097004>] (handle_irq_event) from [<c009a070>] (handle_level_irq+0xb8/0x14c)
>> [<c009a070>] (handle_level_irq) from [<c0096438>] (generic_handle_irq+0x20/0x34)
>> [<c0096438>] (generic_handle_irq) from [<c009672c>]
>> (__handle_domain_irq+0x64/0xe0)
>> [<c009672c>] (__handle_domain_irq) from [<c06802f8>] (__irq_svc+0x58/0x78)
>> [<c06802f8>] (__irq_svc) from [<c00103a0>] (arch_cpu_idle+0x20/0x3c)
>> [<c00103a0>] (arch_cpu_idle) from [<c007fea4>] (cpu_startup_entry+0x2d0/0x358)
>> [<c007fea4>] (cpu_startup_entry) from [<c08eac24>] (start_kernel+0x364/0x3e8)
>> ---[ end trace 68b3b5769f257e1c ]---
>>
>> When I toggle on CTS once more I don't get such an error and for both
>> toggle sessions I get the proper CTS value.
>>
>> Any idea?
>
> The warning at line drivers/tty/serial/serial_core.c:2893 is
>
>         lockdep_assert_held_once(&uport->lock);
>
> That means mctrl_gpio_irq_handle lacks some locking.
>
> I think we need to take port->lock (with irqs off) before
>
>         mctrl = gpios->mctrl_prev
>
> and drop it before returning.
>
> Note there is another issue with mctrl-gpio reported with Message-Id:
> 1456225442-27184-1-git-send-email-inguin@xxxxxx.

Could you add me to CC, if you'll answer to this thread? Thanks.

Yegor
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux