Added in sub endpoint size patch
[openwrt-10.03/.git] / target / linux / at91 / patches-2.6.25 / 008-fdl-serial.patch
1 --- linux-2.6.25.10.old/drivers/serial/atmel_serial.c   2008-07-04 14:21:12.000000000 +0200
2 +++ linux-2.6.25.10/drivers/serial/atmel_serial.c       2008-07-04 14:55:37.000000000 +0200
3 @@ -214,6 +214,34 @@
4                                 at91_set_gpio_value(AT91_PIN_PA21, 0);
5                         else
6                                 at91_set_gpio_value(AT91_PIN_PA21, 1);
7 +
8 +                       /*
9 +                        * FDL VersaLink adds GPIOS to provide full modem 
10 +                        * control on USART 0 - Drive DTR and RI pins manually
11 +                        */
12 +                       if (mctrl & TIOCM_DTR)
13 +                               at91_set_gpio_value(AT91_PIN_PB6, 0);
14 +                       else
15 +                               at91_set_gpio_value(AT91_PIN_PB6, 1);
16 +                       if (mctrl & TIOCM_RI)
17 +                               at91_set_gpio_value(AT91_PIN_PB7, 0);
18 +                       else
19 +                               at91_set_gpio_value(AT91_PIN_PB7, 1);
20 +               }
21 +
22 +               /*
23 +                * FDL VersaLink adds GPIOS to provide full modem control on
24 +                * USART 3 - Drive DTR and RI pins manually
25 +                */
26 +               if (port->mapbase == AT91RM9200_BASE_US3) {
27 +                       if (mctrl & TIOCM_DTR)
28 +                               at91_set_gpio_value(AT91_PIN_PB29, 0);
29 +                       else
30 +                               at91_set_gpio_value(AT91_PIN_PB29, 1);
31 +                       if (mctrl & TIOCM_RI)
32 +                               at91_set_gpio_value(AT91_PIN_PB2, 0);
33 +                       else
34 +                               at91_set_gpio_value(AT91_PIN_PB2, 1);
35                 }
36         }
37  #endif
38 @@ -251,8 +279,10 @@
39         /*
40          * The control signals are active low.
41          */
42 -       if (!(status & ATMEL_US_DCD))
43 -               ret |= TIOCM_CD;
44 +
45 +       if (!(port->mapbase == AT91RM9200_BASE_US0 || port->mapbase == AT91RM9200_BASE_US3))
46 +               if (!(status & ATMEL_US_DCD))
47 +                       ret |= TIOCM_CD;
48         if (!(status & ATMEL_US_CTS))
49                 ret |= TIOCM_CTS;
50         if (!(status & ATMEL_US_DSR))
51 @@ -260,6 +290,16 @@
52         if (!(status & ATMEL_US_RI))
53                 ret |= TIOCM_RI;
54  
55 +       /*
56 +        * Read the GPIO's for the FDL VersaLink special case
57 +        */
58 +       if (port->mapbase == AT91RM9200_BASE_US0)
59 +               if (!(at91_get_gpio_value(AT91_PIN_PA19)))
60 +                       ret |= TIOCM_CD;
61 +       if (port->mapbase == AT91RM9200_BASE_US3)
62 +               if (!(at91_get_gpio_value(AT91_PIN_PA24)))
63 +                       ret |= TIOCM_CD;
64 +
65         return ret;
66  }
67  
68 @@ -453,6 +493,34 @@
69  }
70  
71  /*
72 + * USART0 DCD Interrupt handler
73 + */
74 +
75 +static irqreturn_t atmel_u0_DCD_interrupt(int irq, void *dev_id)
76 +{
77 +       struct uart_port *port = dev_id;
78 +       int status = at91_get_gpio_value(irq);
79 +
80 +       uart_handle_dcd_change(port, !(status));
81 +
82 +       return IRQ_HANDLED;
83 +}
84 +
85 +/*
86 + * USART3 DCD Interrupt handler
87 + */
88 +
89 +static irqreturn_t atmel_u3_DCD_interrupt(int irq, void *dev_id)
90 +{
91 +       struct uart_port *port = dev_id;
92 +       int status = at91_get_gpio_value(irq);
93 +
94 +       uart_handle_dcd_change(port, !(status));
95 +
96 +       return IRQ_HANDLED;
97 +}
98 +
99 +/*
100   * receive interrupt handler.
101   */
102  static void
103 @@ -815,6 +883,23 @@
104                 return retval;
105         }
106  
107 +        if (port->mapbase == AT91RM9200_BASE_US0) {
108 +                retval = request_irq(AT91_PIN_PA19, atmel_u0_DCD_interrupt, 0, "atmel_serial", port);
109 +                if (retval) {
110 +                        printk("atmel_serial: atmel_startup - Can't get u0DCD irq\n");
111 +                        free_irq(port->irq, port);
112 +                        return retval;
113 +                }
114 +        }
115 +        if (port->mapbase == AT91RM9200_BASE_US3) {
116 +                retval = request_irq(AT91_PIN_PA24, atmel_u3_DCD_interrupt, 0, "atmel_serial", port);
117 +                if (retval) {
118 +                        printk("atmel_serial: atmel_startup - Can't get u3DCD irq\n");
119 +                        free_irq(port->irq, port);
120 +                        return retval;
121 +                }
122 +        }
123 +
124         /*
125          * Initialize DMA (if necessary)
126          */
127 @@ -834,6 +919,10 @@
128                                         kfree(atmel_port->pdc_rx[0].buf);
129                                 }
130                                 free_irq(port->irq, port);
131 +                               if (port->mapbase == AT91RM9200_BASE_US0)
132 +                                       free_irq(AT91_PIN_PA19, port);
133 +                               if (port->mapbase == AT91RM9200_BASE_US3)
134 +                                       free_irq(AT91_PIN_PA24, port);
135                                 return -ENOMEM;
136                         }
137                         pdc->dma_addr = dma_map_single(port->dev,
138 @@ -873,7 +962,11 @@
139                 retval = atmel_open_hook(port);
140                 if (retval) {
141                         free_irq(port->irq, port);
142 -                       return retval;
143 +                       if (port->mapbase == AT91RM9200_BASE_US0)
144 +                               free_irq(AT91_PIN_PA19, port);
145 +                       if (port->mapbase == AT91RM9200_BASE_US3)
146 +                               free_irq(AT91_PIN_PA24, port);
147 +                       return retval;
148                 }
149         }
150  
151 @@ -947,6 +1040,10 @@
152          * Free the interrupt
153          */
154         free_irq(port->irq, port);
155 +       if (port->mapbase == AT91RM9200_BASE_US0)
156 +               free_irq(AT91_PIN_PA19, port);
157 +       if (port->mapbase == AT91RM9200_BASE_US3)
158 +               free_irq(AT91_PIN_PA24, port);
159  
160         /*
161          * If there is a specific "close" function (to unregister