tty/serial: Add helpers to use GPIOs to control modem lines and implement atmel_serial.c
Subsystems (7)
cover tty/serial: Add helpers to use GPIOs to control modem lines and implement atmel_serial.c
This patch series is a leftover of http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts.
The 1st patch may be applied as a fix for 3.15-rc, since it correct a device tree binding documentation example.
Greg, for you to decide if it's worth it or not !
It's based on v3.15-rc2.
Richard Genoud (5):
tty/serial: atmel_serial: Fix device tree documetation
ARM: at91: gpio: implement get_direction tty/serial: Add GPIOLIB helpers for controlling modem lines tty/serial: at91: use mctrl_gpio helpers tty/serial: at91: add interrupts for modem control lines
.../devicetree/bindings/serial/atmel-usart.txt | 12 +- Documentation/serial/driver | 25 +++ arch/arm/mach-at91/at91rm9200_devices.c | 16 +- arch/arm/mach-at91/at91sam9260_devices.c | 7 - arch/arm/mach-at91/at91sam9261_devices.c | 4 - arch/arm/mach-at91/at91sam9263_devices.c | 4 - arch/arm/mach-at91/at91sam9g45_devices.c | 5 - arch/arm/mach-at91/at91sam9rl_devices.c | 5 - arch/arm/mach-at91/gpio.c | 13 ++ drivers/tty/serial/Kconfig | 4 + drivers/tty/serial/Makefile | 3 + drivers/tty/serial/atmel_serial.c | 230 +++++++++++++++++---- drivers/tty/serial/serial_mctrl_gpio.c | 143 +++++++++++++ drivers/tty/serial/serial_mctrl_gpio.h | 110 ++++++++++ include/linux/platform_data/atmel.h | 1 - 15 files changed, 509 insertions(+), 73 deletions(-) create mode 100644 drivers/tty/serial/serial_mctrl_gpio.c create mode 100644 drivers/tty/serial/serial_mctrl_gpio.h
Signature · 1 line
1.8.5.5
PATCH 1/5 tty/serial: atmel_serial: Fix device tree documetation
RTS pin is an active low pin.
For now, this doesn't change anything as the ACTIVE_LOW flag is not handled in atmel_serial, but it will be in 3.16.
--- Documentation/devicetree/bindings/serial/atmel-usart.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
This may be applied as a fix on 3.15-rc, or on 3.16, like the other if this correction is not a big deal.
Documentation/devicetree/bindings/serial/atmel-usart.txt +1 -1
@@ -35,7 +35,7 @@ Example: clock-names = "usart"; atmel,use-dma-rx; atmel,use-dma-tx; - rts-gpios = <&pioD 15 0>; + rts-gpios = <&pioD 15 GPIO_ACTIVE_LOW>; }; - use DMA:
Signature · 1 line
1.8.5.5
PATCH 2/5 ARM: at91: gpio: implement get_direction
In reply to Richard GenoudThis is needed for gpiod_get_direction().
Otherwise, it returns -EINVAL.
--- arch/arm/mach-at91/gpio.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/arm/mach-at91/gpio.c +13 -0
@@ -49,6 +49,7 @@ static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);static void at91_gpiolib_dbg_show (struct seq_file *s,struct gpio_chip *chip);static void at91_gpiolib_set (struct gpio_chip *chip,unsigned offset,int val);static int at91_gpiolib_get (struct gpio_chip *chip,unsigned offset); +static int at91_gpiolib_get_direction (struct gpio_chip *chip,unsigned offset);static int at91_gpiolib_direction_output (struct gpio_chip *chip,unsigned offset,int val); static int at91_gpiolib_direction_input(struct gpio_chip *chip,
@@ -60,6 +61,7 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); .chip = { \ .label = name, \ .request = at91_gpiolib_request, \ + .get_direction = at91_gpiolib_get_direction, \ .direction_input = at91_gpiolib_direction_input, \ .direction_output = at91_gpiolib_direction_output, \ .get = at91_gpiolib_get, \
@@ -799,6 +801,17 @@ static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)return 0 ; } +static int at91_gpiolib_get_direction (struct gpio_chip *chip,unsigned offset) +{ +struct at91_gpio_chip *at91_gpio =to_at91_gpio_chip (chip); +void __iomem *pio = at91_gpio->regbase; +unsigned mask =1 << offset; +u32 osr; + + osr =__raw_readl (pio +PIO_OSR ); +return !(osr & mask); +} +static int at91_gpiolib_direction_input (struct gpio_chip *chip,unsigned offset) {
Signature · 1 line
1.8.5.5
PATCH 3/5 tty/serial: Add GPIOLIB helpers for controlling modem lines
In reply to Richard GenoudThis patch add some helpers to control modem lines (CTS/RTS/DSR...) via GPIO.
This will be useful for many boards which have a serial controller that only handle CTS/RTS pins (or even just RX/TX).
--- Documentation/serial/driver | 25 ++++++ drivers/tty/serial/Kconfig | 3 + drivers/tty/serial/Makefile | 3 + drivers/tty/serial/serial_mctrl_gpio.c | 143 +++++++++++++++++++++++++++++++++ drivers/tty/serial/serial_mctrl_gpio.h | 110 +++++++++++++++++++++++++ 5 files changed, 284 insertions(+) create mode 100644 drivers/tty/serial/serial_mctrl_gpio.c create mode 100644 drivers/tty/serial/serial_mctrl_gpio.h
Documentation/serial/driver +25 -0
@@ -429,3 +429,28 @@ thus: struct uart_port port; int my_stuff; }; + +Modem control lines via GPIO +---------------------------- + +Some helpers are provided in order to set/get modem control lines via GPIO. + +mctrl_gpio_init(dev, idx): + This will get the {cts,rts,...}-gpios from device tree if they are + present and request them, set direction etc, and return an + allocated structure. devm_* functions are used, so there's no need + to call mctrl_gpio_free(). + +mctrl_gpio_free(dev, gpios): + This will free the requested gpios in mctrl_gpio_init(). + As devm_* function are used, there's generally no need to call + this function. + +mctrl_gpio_to_gpiod(gpios, gidx) + This returns the gpio structure associated to the modem line index. + +mctrl_gpio_set(gpios, mctrl): + This will sets the gpios according to the mctrl state. + +mctrl_gpio_get(gpios, mctrl): + This will update mctrl with the gpios values.
drivers/tty/serial/Kconfig +3 -0
@@ -1510,4 +1510,7 @@ config SERIAL_ST_ASC_CONSOLE endmenu +config SERIAL_MCTRL_GPIO + tristate + endif # TTY
drivers/tty/serial/Makefile +3 -0
@@ -87,3 +87,6 @@ obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o obj-$(CONFIG_SERIAL_ARC) += arc_uart.o obj-$(CONFIG_SERIAL_RP2) += rp2.o obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o + +# GPIOLIB helpers for modem control lines +obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
drivers/tty/serial/serial_mctrl_gpio.c new file +143 -0
143 lines not on this page · raw message
drivers/tty/serial/serial_mctrl_gpio.h new file +110 -0
110 lines not on this page · raw message
Signature · 1 line
1.8.5.5
PATCH 3/5 tty/serial: Add GPIOLIB helpers for controlling modem lines
Quoted 7 lines · Richard Genoud
This patch add some helpers to control modem lines (CTS/RTS/DSR...) via GPIO.
This will be useful for many boards which have a serial controller that only handle CTS/RTS pins (or even just RX/TX).Signed-off-by Richard Genoud <[email protected]>
Yegor
PATCH 4/5 tty/serial: at91: use mctrl_gpio helpers
In reply to Richard GenoudOn sam9x5, dedicated CTS (and RTS) pins are unusable together with the LCDC, the EMAC, or the MMC because they share the same line.
Moreover, the USART 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.
--- .../devicetree/bindings/serial/atmel-usart.txt | 10 +- arch/arm/mach-at91/at91rm9200_devices.c | 16 ++-- arch/arm/mach-at91/at91sam9260_devices.c | 7 -- arch/arm/mach-at91/at91sam9261_devices.c | 4 - arch/arm/mach-at91/at91sam9263_devices.c | 4 - arch/arm/mach-at91/at91sam9g45_devices.c | 5 - arch/arm/mach-at91/at91sam9rl_devices.c | 5 - drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/atmel_serial.c | 105 ++++++++++++++------- include/linux/platform_data/atmel.h | 1 - 10 files changed, 89 insertions(+), 69 deletions(-)
Documentation/devicetree/bindings/serial/atmel-usart.txt +8 -2
@@ -13,8 +13,9 @@ Required properties: Optional properties: - atmel,use-dma-rx: use of PDC or DMA for receiving data - atmel,use-dma-tx: use of PDC or DMA for transmitting data -- rts-gpios: specify a GPIO for RTS line. It will use specified PIO instead of the peripheral - function pin for the USART RTS feature. If unsure, don't specify 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 PIO instead of the peripheral function pin for the USART feature. + If unsure, don't specify this property. - add dma bindings for dma transfer: - dmas: DMA specifier, consisting of a phandle to DMA controller node, memory peripheral interface and USART DMA channel ID, FIFO configuration.
@@ -36,6 +37,11 @@ Example: atmel,use-dma-rx; atmel,use-dma-tx; rts-gpios = <&pioD 15 GPIO_ACTIVE_LOW>; + cts-gpios = <&pioD 16 GPIO_ACTIVE_LOW>; + dtr-gpios = <&pioD 17 GPIO_ACTIVE_LOW>; + dsr-gpios = <&pioD 18 GPIO_ACTIVE_LOW>; + dcd-gpios = <&pioD 20 GPIO_ACTIVE_LOW>; + rng-gpios = <&pioD 19 GPIO_ACTIVE_LOW>; }; - use DMA:
arch/arm/mach-at91/at91rm9200_devices.c +10 -6
@@ -15,6 +15,7 @@#include <linux/dma-mapping.h> #include <linux/gpio.h> +#include <linux/gpio/driver.h> #include <linux/platform_device.h> #include <linux/i2c-gpio.h>
@@ -923,7 +924,6 @@ static struct resource dbgu_resources[] = {static struct atmel_uart_data dbgu_data = { .use_dma_tx =0 , .use_dma_rx =0 ,/* DBGU not capable of receive DMA */ - .rts_gpio = -EINVAL , };static u64 dbgu_dmamask =DMA_BIT_MASK (32 );
@@ -962,7 +962,14 @@ static struct resource uart0_resources[] = {static struct atmel_uart_data uart0_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , +}; + +static struct gpiod_lookup_table uart0_gpios_table = { + .dev_id ="atmel_usart" , + .table = { +GPIO_LOOKUP ("pioA" ,21 ,"rts" ,GPIO_ACTIVE_LOW ), + { }, + }, };static u64 uart0_dmamask =DMA_BIT_MASK (32 );
@@ -993,7 +1000,7 @@ static inline void configure_usart0_pins(unsigned pins)* We need to drive the pin manually. The serial driver will driver * this to high when initializing. */ - uart0_data.rts_gpio =AT91_PIN_PA21 ; +gpiod_add_lookup_table (&uart0_gpios_table); } }
@@ -1013,7 +1020,6 @@ static struct resource uart1_resources[] = {static struct atmel_uart_data uart1_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart1_dmamask =DMA_BIT_MASK (32 );
@@ -1065,7 +1071,6 @@ static struct resource uart2_resources[] = {static struct atmel_uart_data uart2_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart2_dmamask =DMA_BIT_MASK (32 );
@@ -1109,7 +1114,6 @@ static struct resource uart3_resources[] = {static struct atmel_uart_data uart3_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart3_dmamask =DMA_BIT_MASK (32 );
arch/arm/mach-at91/at91sam9260_devices.c +0 -7
@@ -820,7 +820,6 @@ static struct resource dbgu_resources[] = {static struct atmel_uart_data dbgu_data = { .use_dma_tx =0 , .use_dma_rx =0 ,/* DBGU not capable of receive DMA */ - .rts_gpio = -EINVAL , };static u64 dbgu_dmamask =DMA_BIT_MASK (32 );
@@ -859,7 +858,6 @@ static struct resource uart0_resources[] = {static struct atmel_uart_data uart0_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart0_dmamask =DMA_BIT_MASK (32 );
@@ -911,7 +909,6 @@ static struct resource uart1_resources[] = {static struct atmel_uart_data uart1_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart1_dmamask =DMA_BIT_MASK (32 );
@@ -955,7 +952,6 @@ static struct resource uart2_resources[] = {static struct atmel_uart_data uart2_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart2_dmamask =DMA_BIT_MASK (32 );
@@ -999,7 +995,6 @@ static struct resource uart3_resources[] = {static struct atmel_uart_data uart3_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart3_dmamask =DMA_BIT_MASK (32 );
@@ -1043,7 +1038,6 @@ static struct resource uart4_resources[] = {static struct atmel_uart_data uart4_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart4_dmamask =DMA_BIT_MASK (32 );
@@ -1082,7 +1076,6 @@ static struct resource uart5_resources[] = {static struct atmel_uart_data uart5_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart5_dmamask =DMA_BIT_MASK (32 );
arch/arm/mach-at91/at91sam9261_devices.c +0 -4
@@ -881,7 +881,6 @@ static struct resource dbgu_resources[] = {static struct atmel_uart_data dbgu_data = { .use_dma_tx =0 , .use_dma_rx =0 ,/* DBGU not capable of receive DMA */ - .rts_gpio = -EINVAL , };static u64 dbgu_dmamask =DMA_BIT_MASK (32 );
@@ -920,7 +919,6 @@ static struct resource uart0_resources[] = {static struct atmel_uart_data uart0_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart0_dmamask =DMA_BIT_MASK (32 );
@@ -964,7 +962,6 @@ static struct resource uart1_resources[] = {static struct atmel_uart_data uart1_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart1_dmamask =DMA_BIT_MASK (32 );
@@ -1008,7 +1005,6 @@ static struct resource uart2_resources[] = {static struct atmel_uart_data uart2_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart2_dmamask =DMA_BIT_MASK (32 );
arch/arm/mach-at91/at91sam9263_devices.c +0 -4
@@ -1325,7 +1325,6 @@ static struct resource dbgu_resources[] = {static struct atmel_uart_data dbgu_data = { .use_dma_tx =0 , .use_dma_rx =0 ,/* DBGU not capable of receive DMA */ - .rts_gpio = -EINVAL , };static u64 dbgu_dmamask =DMA_BIT_MASK (32 );
@@ -1364,7 +1363,6 @@ static struct resource uart0_resources[] = {static struct atmel_uart_data uart0_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart0_dmamask =DMA_BIT_MASK (32 );
@@ -1408,7 +1406,6 @@ static struct resource uart1_resources[] = {static struct atmel_uart_data uart1_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart1_dmamask =DMA_BIT_MASK (32 );
@@ -1452,7 +1449,6 @@ static struct resource uart2_resources[] = {static struct atmel_uart_data uart2_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart2_dmamask =DMA_BIT_MASK (32 );
arch/arm/mach-at91/at91sam9g45_devices.c +0 -5
@@ -1588,7 +1588,6 @@ static struct resource dbgu_resources[] = {static struct atmel_uart_data dbgu_data = { .use_dma_tx =0 , .use_dma_rx =0 , - .rts_gpio = -EINVAL , };static u64 dbgu_dmamask =DMA_BIT_MASK (32 );
@@ -1627,7 +1626,6 @@ static struct resource uart0_resources[] = {static struct atmel_uart_data uart0_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart0_dmamask =DMA_BIT_MASK (32 );
@@ -1671,7 +1669,6 @@ static struct resource uart1_resources[] = {static struct atmel_uart_data uart1_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart1_dmamask =DMA_BIT_MASK (32 );
@@ -1715,7 +1712,6 @@ static struct resource uart2_resources[] = {static struct atmel_uart_data uart2_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart2_dmamask =DMA_BIT_MASK (32 );
@@ -1759,7 +1755,6 @@ static struct resource uart3_resources[] = {static struct atmel_uart_data uart3_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart3_dmamask =DMA_BIT_MASK (32 );
arch/arm/mach-at91/at91sam9rl_devices.c +0 -5
@@ -957,7 +957,6 @@ static struct resource dbgu_resources[] = {static struct atmel_uart_data dbgu_data = { .use_dma_tx =0 , .use_dma_rx =0 ,/* DBGU not capable of receive DMA */ - .rts_gpio = -EINVAL , };static u64 dbgu_dmamask =DMA_BIT_MASK (32 );
@@ -996,7 +995,6 @@ static struct resource uart0_resources[] = {static struct atmel_uart_data uart0_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart0_dmamask =DMA_BIT_MASK (32 );
@@ -1048,7 +1046,6 @@ static struct resource uart1_resources[] = {static struct atmel_uart_data uart1_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart1_dmamask =DMA_BIT_MASK (32 );
@@ -1092,7 +1089,6 @@ static struct resource uart2_resources[] = {static struct atmel_uart_data uart2_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart2_dmamask =DMA_BIT_MASK (32 );
@@ -1136,7 +1132,6 @@ static struct resource uart3_resources[] = {static struct atmel_uart_data uart3_data = { .use_dma_tx =1 , .use_dma_rx =1 , - .rts_gpio = -EINVAL , };static u64 uart3_dmamask =DMA_BIT_MASK (32 );
drivers/tty/serial/Kconfig +1 -0
@@ -97,6 +97,7 @@ config SERIAL_ATMEL bool "AT91 / AT32 on-chip serial port support" depends on ARCH_AT91 || AVR32 select SERIAL_CORE + select SERIAL_MCTRL_GPIO help This enables the driver for the on-chip UARTs of the Atmel AT91 and AT32 processors.
drivers/tty/serial/atmel_serial.c +70 -35
177 lines not on this page · raw message
include/linux/platform_data/atmel.h +0 -1
@@ -84,7 +84,6 @@ struct atmel_uart_data {short use_dma_rx;/* use receive DMA? */ void __iomem *regs;/* virt. base address, if any */ struct serial_rs485 rs485;/* rs485 settings */ -int rts_gpio;/* optional RTS GPIO */ };/* Touchscreen Controller */
Signature · 1 line
1.8.5.5
PATCH 5/5 tty/serial: at91: add interrupts for modem control lines
In reply to Richard GenoudHandle CTS/DSR/RI/DCD GPIO interrupts in atmel_serial.
--- drivers/tty/serial/atmel_serial.c | 125 +++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 3 deletions(-)
drivers/tty/serial/atmel_serial.c +122 -3
@@ -45,6 +45,7 @@#include <linux/gpio.h> #include <linux/gpio/consumer.h> #include <linux/err.h> +#include <linux/irq.h> #include <asm/io.h> #include <asm/ioctls.h>
@@ -167,7 +168,9 @@ struct atmel_uart_port {struct serial_rs485 rs485;/* rs485 settings */ struct mctrl_gpios *gpios; +int gpio_irq[UART_GPIO_MAX ];unsigned int tx_done_mask; +bool ms_irq_enabled;bool is_usart;/* usart or uart */ struct timer_list uart_timer;/* uart timer */ int (*prepare_rx)(struct uart_port *port);
@@ -489,8 +492,38 @@ static void atmel_stop_rx(struct uart_port *port)*/ static void atmel_enable_ms (struct uart_port *port) { -UART_PUT_IER (port,ATMEL_US_RIIC |ATMEL_US_DSRIC - |ATMEL_US_DCDIC |ATMEL_US_CTSIC ); +struct atmel_uart_port *atmel_port =to_atmel_uart_port (port); +uint32_t ier =0 ; + +/* +* Interrupt should not be enabled twice +*/ +if (atmel_port->ms_irq_enabled) +return ; + + atmel_port->ms_irq_enabled = true; + +if (atmel_port->gpio_irq[UART_GPIO_CTS ] >=0 ) +enable_irq (atmel_port->gpio_irq[UART_GPIO_CTS ]); +else + ier |=ATMEL_US_CTSIC ; + +if (atmel_port->gpio_irq[UART_GPIO_DSR ] >=0 ) +enable_irq (atmel_port->gpio_irq[UART_GPIO_DSR ]); +else + ier |=ATMEL_US_DSRIC ; + +if (atmel_port->gpio_irq[UART_GPIO_RI ] >=0 ) +enable_irq (atmel_port->gpio_irq[UART_GPIO_RI ]); +else + ier |=ATMEL_US_RIIC ; + +if (atmel_port->gpio_irq[UART_GPIO_DCD ] >=0 ) +enable_irq (atmel_port->gpio_irq[UART_GPIO_DCD ]); +else + ier |=ATMEL_US_DCDIC ; + +UART_PUT_IER (port, ier); }/*
@@ -1079,11 +1112,31 @@ atmel_handle_status(struct uart_port *port, unsigned int pending,static irqreturn_t atmel_interrupt (int irq,void *dev_id) {struct uart_port *port = dev_id; +struct atmel_uart_port *atmel_port =to_atmel_uart_port (port);unsigned int status, pending, pass_counter =0 ; +bool gpio_handled = false; do { status = atmel_get_lines_status(port); pending = status & UART_GET_IMR(port); + if (!gpio_handled) { + /* + * Dealing with GPIO interrupt + */ + if (irq == atmel_port->gpio_irq[UART_GPIO_CTS]) + pending |= ATMEL_US_CTSIC; + + if (irq == atmel_port->gpio_irq[UART_GPIO_DSR]) + pending |= ATMEL_US_DSRIC; + + if (irq == atmel_port->gpio_irq[UART_GPIO_RI]) + pending |= ATMEL_US_RIIC; + + if (irq == atmel_port->gpio_irq[UART_GPIO_DCD]) + pending |= ATMEL_US_DCDIC; + + gpio_handled = true; + } if (!pending) break;
@@ -1563,6 +1616,45 @@ static void atmel_get_ip_name(struct uart_port *port) } } +static void atmel_free_gpio_irq (struct uart_port *port) +{ +struct atmel_uart_port *atmel_port =to_atmel_uart_port (port); +enum mctrl_gpio_idx i; + +for (i =0 ; i <UART_GPIO_MAX ; i++) +if (atmel_port->gpio_irq[i] >=0 ) +free_irq (atmel_port->gpio_irq[i], port); +} + +static int atmel_request_gpio_irq (struct uart_port *port) +{ +struct atmel_uart_port *atmel_port =to_atmel_uart_port (port); +int *irq = atmel_port->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], atmel_interrupt,IRQ_TYPE_EDGE_BOTH , +"atmel_serial" , port); +if (err) +dev_err (port->dev,"atmel_startup - Can't get %d irq\n" , + irq[i]); + } + +/* +* If something went wrong, rollback. +*/ +while (err && (--i >=0 )) +if (irq[i] >=0 ) +free_irq (irq[i], port); + +return err; +} +/* * Perform initialization and enable port for reception */
@@ -1579,6 +1671,7 @@ static int atmel_startup(struct uart_port *port)* handle an unexpected interrupt */ UART_PUT_IDR (port,-1 ); + atmel_port->ms_irq_enabled = false;/* * Allocate the IRQ
@@ -1591,6 +1684,13 @@ static int atmel_startup(struct uart_port *port) }/* +* Get the GPIO lines IRQ +*/ + retval =atmel_request_gpio_irq (port); +if (retval) + goto free_irq; + +/* * Initialize DMA (if necessary) */ atmel_init_property (atmel_port, pdev);
@@ -1654,6 +1754,11 @@ static int atmel_startup(struct uart_port *port) }return 0 ; + +free_irq: +free_irq (port->irq, port); + +return retval; }/*
@@ -1701,9 +1806,12 @@ static void atmel_shutdown(struct uart_port *port) atmel_port->rx_ring.tail =0 ;/* -* Free the interrupt +* Free the interrupts */ free_irq (port->irq, port); +atmel_free_gpio_irq (port); + + atmel_port->ms_irq_enabled = false; }/*
@@ -2366,10 +2474,21 @@ static int atmel_serial_resume(struct platform_device *pdev)static int atmel_init_gpios (struct atmel_uart_port *p,struct device *dev) { +enum mctrl_gpio_idx i; +struct gpio_desc *gpiod; + p->gpios =mctrl_gpio_init (dev,0 );if (IS_ERR_OR_NULL (p->gpios))return -1 ; +for (i =0 ; i <UART_GPIO_MAX ; i++) { + gpiod =mctrl_gpio_to_gpiod (p->gpios, i); +if (gpiod && (gpiod_get_direction (gpiod) ==GPIOF_DIR_IN )) + p->gpio_irq[i] =gpiod_to_irq (gpiod); +else + p->gpio_irq[i] = -EINVAL ; + } +return 0 ; }
Signature · 1 line
1.8.5.5
Greg Kroah-Hartman
maintainercover tty/serial: Add helpers to use GPIOs to control modem lines and implement atmel_serial.c
In reply to Richard GenoudQuoted 7 lines · Richard Genoud
This patch series is a leftover of http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts.The 1st patch may be applied as a fix for 3.15-rc, since it correct a device tree binding documentation example.
Greg, for you to decide if it's worth it or not !
Why am I the one tho decides if it is worth it? If it's up to me, I'll just say "no", as I sure don't need this for any of my machines...
See, that was easy :)
greg k-h
cover tty/serial: Add helpers to use GPIOs to control modem lines and implement atmel_serial.c
2014-04-25 17:58 GMT+02:00 Greg Kroah-Hartman <[email protected]>:
Quoted 11 lines · Richard Genoud
Quoted 7 lines
This patch series is a leftover of http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts.The 1st patch may be applied as a fix for 3.15-rc, since it correct a device tree binding documentation example.
Greg, for you to decide if it's worth it or not !
Why am I the one tho decides if it is worth it? If it's up to me, I'll just say "no", as I sure don't need this for any of my machines...
Ok, let me reformulate :) :
This patch series is a leftover of
http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts (you acked the series and ask me to resend it during 3.15-rc cycle).
I think that "[PATCH 1/5] tty/serial: atmel_serial: Fix device tree documentation" should be applied on 3.15-rc,
since it corrects a device tree binding documentation example.
The patches 2-5/5 are for 3.16.
cover tty/serial: Add helpers to use GPIOs to control modem lines and implement atmel_serial.c
On 27/04/2014 02:58, Richard Genoud :
Quoted 12 lines
2014-04-25 17:58 GMT+02:00 Greg Kroah-Hartman <[email protected]>:
Quoted 11 lines · Richard Genoud
Quoted 7 lines
This patch series is a leftover of http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts.The 1st patch may be applied as a fix for 3.15-rc, since it correct a device tree binding documentation example.
Greg, for you to decide if it's worth it or not !
Why am I the one tho decides if it is worth it? If it's up to me, I'll just say "no", as I sure don't need this for any of my machines...
Ok, so I need to speak up and say that the patch series is useful for me :-)
Quoted 7 lines
Ok, let me reformulate :) :
This patch series is a leftover of
http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts (you acked the series and ask me to resend it during 3.15-rc cycle).
Quoted 5 lines
I think that "[PATCH 1/5] tty/serial:
atmel_serial: Fix device tree documentation" should be applied on 3.15-rc,
since it corrects a device tree binding documentation example.The patches 2-5/5 are for 3.16.
BTW, patches 4 and 5 were "Acked" by me in v6 revision of this series.
Thanks, bye,
Signature · 1 line
Nicolas Ferre
Greg Kroah-Hartman
maintainercover tty/serial: Add helpers to use GPIOs to control modem lines and implement atmel_serial.c
In reply to Richard GenoudQuoted 20 lines · Richard Genoud
2014-04-25 17:58 GMT+02:00 Greg Kroah-Hartman <[email protected]>:
Quoted 11 lines · Richard Genoud
Quoted 7 lines
This patch series is a leftover of http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts.The 1st patch may be applied as a fix for 3.15-rc, since it correct a device tree binding documentation example.
Greg, for you to decide if it's worth it or not !
Why am I the one tho decides if it is worth it? If it's up to me, I'll just say "no", as I sure don't need this for any of my machines...
Ok, let me reformulate :) :
This patch series is a leftover of
http://www.spinics.net/lists/arm-kernel/msg314242.html
that missed 3.15 because it caused merge conflicts (you acked the series and ask me to resend it during 3.15-rc cycle).
Quoted 5 lines
I think that "[PATCH 1/5] tty/serial:
atmel_serial: Fix device tree documentation" should be applied on 3.15-rc,
since it corrects a device tree binding documentation example.The patches 2-5/5 are for 3.16.
Ok, can you resend these, with a note that the first one should make it to 3.15-final, and I'll queue them up?
thanks,
greg k-h