diff options
Diffstat (limited to 'target/linux/at91/patches-2.6.25/008-fdl-serial.patch')
-rw-r--r-- | target/linux/at91/patches-2.6.25/008-fdl-serial.patch | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/target/linux/at91/patches-2.6.25/008-fdl-serial.patch b/target/linux/at91/patches-2.6.25/008-fdl-serial.patch new file mode 100644 index 0000000..3cdbec2 --- /dev/null +++ b/target/linux/at91/patches-2.6.25/008-fdl-serial.patch @@ -0,0 +1,161 @@ +--- linux-2.6.25.10.old/drivers/serial/atmel_serial.c 2008-07-04 14:21:12.000000000 +0200 ++++ linux-2.6.25.10/drivers/serial/atmel_serial.c 2008-07-04 14:55:37.000000000 +0200 +@@ -214,6 +214,34 @@ + at91_set_gpio_value(AT91_PIN_PA21, 0); + else + at91_set_gpio_value(AT91_PIN_PA21, 1); ++ ++ /* ++ * FDL VersaLink adds GPIOS to provide full modem ++ * control on USART 0 - Drive DTR and RI pins manually ++ */ ++ if (mctrl & TIOCM_DTR) ++ at91_set_gpio_value(AT91_PIN_PB6, 0); ++ else ++ at91_set_gpio_value(AT91_PIN_PB6, 1); ++ if (mctrl & TIOCM_RI) ++ at91_set_gpio_value(AT91_PIN_PB7, 0); ++ else ++ at91_set_gpio_value(AT91_PIN_PB7, 1); ++ } ++ ++ /* ++ * FDL VersaLink adds GPIOS to provide full modem control on ++ * USART 3 - Drive DTR and RI pins manually ++ */ ++ if (port->mapbase == AT91RM9200_BASE_US3) { ++ if (mctrl & TIOCM_DTR) ++ at91_set_gpio_value(AT91_PIN_PB29, 0); ++ else ++ at91_set_gpio_value(AT91_PIN_PB29, 1); ++ if (mctrl & TIOCM_RI) ++ at91_set_gpio_value(AT91_PIN_PB2, 0); ++ else ++ at91_set_gpio_value(AT91_PIN_PB2, 1); + } + } + #endif +@@ -251,8 +279,10 @@ + /* + * The control signals are active low. + */ +- if (!(status & ATMEL_US_DCD)) +- ret |= TIOCM_CD; ++ ++ if (!(port->mapbase == AT91RM9200_BASE_US0 || port->mapbase == AT91RM9200_BASE_US3)) ++ if (!(status & ATMEL_US_DCD)) ++ ret |= TIOCM_CD; + if (!(status & ATMEL_US_CTS)) + ret |= TIOCM_CTS; + if (!(status & ATMEL_US_DSR)) +@@ -260,6 +290,16 @@ + if (!(status & ATMEL_US_RI)) + ret |= TIOCM_RI; + ++ /* ++ * Read the GPIO's for the FDL VersaLink special case ++ */ ++ if (port->mapbase == AT91RM9200_BASE_US0) ++ if (!(at91_get_gpio_value(AT91_PIN_PA19))) ++ ret |= TIOCM_CD; ++ if (port->mapbase == AT91RM9200_BASE_US3) ++ if (!(at91_get_gpio_value(AT91_PIN_PA24))) ++ ret |= TIOCM_CD; ++ + return ret; + } + +@@ -453,6 +493,34 @@ + } + + /* ++ * USART0 DCD Interrupt handler ++ */ ++ ++static irqreturn_t atmel_u0_DCD_interrupt(int irq, void *dev_id) ++{ ++ struct uart_port *port = dev_id; ++ int status = at91_get_gpio_value(irq); ++ ++ uart_handle_dcd_change(port, !(status)); ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * USART3 DCD Interrupt handler ++ */ ++ ++static irqreturn_t atmel_u3_DCD_interrupt(int irq, void *dev_id) ++{ ++ struct uart_port *port = dev_id; ++ int status = at91_get_gpio_value(irq); ++ ++ uart_handle_dcd_change(port, !(status)); ++ ++ return IRQ_HANDLED; ++} ++ ++/* + * receive interrupt handler. + */ + static void +@@ -815,6 +883,23 @@ + return retval; + } + ++ if (port->mapbase == AT91RM9200_BASE_US0) { ++ retval = request_irq(AT91_PIN_PA19, atmel_u0_DCD_interrupt, 0, "atmel_serial", port); ++ if (retval) { ++ printk("atmel_serial: atmel_startup - Can't get u0DCD irq\n"); ++ free_irq(port->irq, port); ++ return retval; ++ } ++ } ++ if (port->mapbase == AT91RM9200_BASE_US3) { ++ retval = request_irq(AT91_PIN_PA24, atmel_u3_DCD_interrupt, 0, "atmel_serial", port); ++ if (retval) { ++ printk("atmel_serial: atmel_startup - Can't get u3DCD irq\n"); ++ free_irq(port->irq, port); ++ return retval; ++ } ++ } ++ + /* + * Initialize DMA (if necessary) + */ +@@ -834,6 +919,10 @@ + kfree(atmel_port->pdc_rx[0].buf); + } + free_irq(port->irq, port); ++ if (port->mapbase == AT91RM9200_BASE_US0) ++ free_irq(AT91_PIN_PA19, port); ++ if (port->mapbase == AT91RM9200_BASE_US3) ++ free_irq(AT91_PIN_PA24, port); + return -ENOMEM; + } + pdc->dma_addr = dma_map_single(port->dev, +@@ -873,7 +962,11 @@ + retval = atmel_open_hook(port); + if (retval) { + free_irq(port->irq, port); +- return retval; ++ if (port->mapbase == AT91RM9200_BASE_US0) ++ free_irq(AT91_PIN_PA19, port); ++ if (port->mapbase == AT91RM9200_BASE_US3) ++ free_irq(AT91_PIN_PA24, port); ++ return retval; + } + } + +@@ -947,6 +1040,10 @@ + * Free the interrupt + */ + free_irq(port->irq, port); ++ if (port->mapbase == AT91RM9200_BASE_US0) ++ free_irq(AT91_PIN_PA19, port); ++ if (port->mapbase == AT91RM9200_BASE_US3) ++ free_irq(AT91_PIN_PA24, port); + + /* + * If there is a specific "close" function (to unregister |