Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/serial/sc26xx.c (Version 2.6.25) and /linux/drivers/serial/sc26xx.c (Version 2.6.31.13)


  1 /*                                                  1 /*
  2  * SC268xx.c: Serial driver for Philiphs SC268      2  * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices.
  3  *                                                  3  *
  4  * Copyright (C) 2006,2007 Thomas Bogendörfer      4  * Copyright (C) 2006,2007 Thomas Bogendörfer (tsbogend@alpha.franken.de)
  5  */                                                 5  */
  6                                                     6 
  7 #include <linux/module.h>                           7 #include <linux/module.h>
  8 #include <linux/kernel.h>                           8 #include <linux/kernel.h>
  9 #include <linux/errno.h>                            9 #include <linux/errno.h>
 10 #include <linux/tty.h>                             10 #include <linux/tty.h>
 11 #include <linux/tty_flip.h>                        11 #include <linux/tty_flip.h>
 12 #include <linux/major.h>                           12 #include <linux/major.h>
 13 #include <linux/circ_buf.h>                        13 #include <linux/circ_buf.h>
 14 #include <linux/serial.h>                          14 #include <linux/serial.h>
 15 #include <linux/sysrq.h>                           15 #include <linux/sysrq.h>
 16 #include <linux/console.h>                         16 #include <linux/console.h>
 17 #include <linux/spinlock.h>                        17 #include <linux/spinlock.h>
 18 #include <linux/slab.h>                            18 #include <linux/slab.h>
 19 #include <linux/delay.h>                           19 #include <linux/delay.h>
 20 #include <linux/init.h>                            20 #include <linux/init.h>
 21 #include <linux/platform_device.h>                 21 #include <linux/platform_device.h>
 22 #include <linux/irq.h>                             22 #include <linux/irq.h>
 23                                                    23 
 24 #if defined(CONFIG_MAGIC_SYSRQ)                    24 #if defined(CONFIG_MAGIC_SYSRQ)
 25 #define SUPPORT_SYSRQ                              25 #define SUPPORT_SYSRQ
 26 #endif                                             26 #endif
 27                                                    27 
 28 #include <linux/serial_core.h>                     28 #include <linux/serial_core.h>
 29                                                    29 
 30 #define SC26XX_MAJOR         204                   30 #define SC26XX_MAJOR         204
 31 #define SC26XX_MINOR_START   205                   31 #define SC26XX_MINOR_START   205
 32 #define SC26XX_NR            2                     32 #define SC26XX_NR            2
 33                                                    33 
 34 struct uart_sc26xx_port {                          34 struct uart_sc26xx_port {
 35         struct uart_port      port[2];             35         struct uart_port      port[2];
 36         u8     dsr_mask[2];                        36         u8     dsr_mask[2];
 37         u8     cts_mask[2];                        37         u8     cts_mask[2];
 38         u8     dcd_mask[2];                        38         u8     dcd_mask[2];
 39         u8     ri_mask[2];                         39         u8     ri_mask[2];
 40         u8     dtr_mask[2];                        40         u8     dtr_mask[2];
 41         u8     rts_mask[2];                        41         u8     rts_mask[2];
 42         u8     imr;                                42         u8     imr;
 43 };                                                 43 };
 44                                                    44 
 45 /* register common to both ports */                45 /* register common to both ports */
 46 #define RD_ISR      0x14                           46 #define RD_ISR      0x14
 47 #define RD_IPR      0x34                           47 #define RD_IPR      0x34
 48                                                    48 
 49 #define WR_ACR      0x10                           49 #define WR_ACR      0x10
 50 #define WR_IMR      0x14                           50 #define WR_IMR      0x14
 51 #define WR_OPCR     0x34                           51 #define WR_OPCR     0x34
 52 #define WR_OPR_SET  0x38                           52 #define WR_OPR_SET  0x38
 53 #define WR_OPR_CLR  0x3C                           53 #define WR_OPR_CLR  0x3C
 54                                                    54 
 55 /* access common register */                       55 /* access common register */
 56 #define READ_SC(p, r)        readb((p)->membas     56 #define READ_SC(p, r)        readb((p)->membase + RD_##r)
 57 #define WRITE_SC(p, r, v)    writeb((v), (p)->     57 #define WRITE_SC(p, r, v)    writeb((v), (p)->membase + WR_##r)
 58                                                    58 
 59 /* register per port */                            59 /* register per port */
 60 #define RD_PORT_MRx 0x00                           60 #define RD_PORT_MRx 0x00
 61 #define RD_PORT_SR  0x04                           61 #define RD_PORT_SR  0x04
 62 #define RD_PORT_RHR 0x0c                           62 #define RD_PORT_RHR 0x0c
 63                                                    63 
 64 #define WR_PORT_MRx 0x00                           64 #define WR_PORT_MRx 0x00
 65 #define WR_PORT_CSR 0x04                           65 #define WR_PORT_CSR 0x04
 66 #define WR_PORT_CR  0x08                           66 #define WR_PORT_CR  0x08
 67 #define WR_PORT_THR 0x0c                           67 #define WR_PORT_THR 0x0c
 68                                                    68 
 69 /* SR bits */                                      69 /* SR bits */
 70 #define SR_BREAK    (1 << 7)                       70 #define SR_BREAK    (1 << 7)
 71 #define SR_FRAME    (1 << 6)                       71 #define SR_FRAME    (1 << 6)
 72 #define SR_PARITY   (1 << 5)                       72 #define SR_PARITY   (1 << 5)
 73 #define SR_OVERRUN  (1 << 4)                       73 #define SR_OVERRUN  (1 << 4)
 74 #define SR_TXRDY    (1 << 2)                       74 #define SR_TXRDY    (1 << 2)
 75 #define SR_RXRDY    (1 << 0)                       75 #define SR_RXRDY    (1 << 0)
 76                                                    76 
 77 #define CR_RES_MR   (1 << 4)                       77 #define CR_RES_MR   (1 << 4)
 78 #define CR_RES_RX   (2 << 4)                       78 #define CR_RES_RX   (2 << 4)
 79 #define CR_RES_TX   (3 << 4)                       79 #define CR_RES_TX   (3 << 4)
 80 #define CR_STRT_BRK (6 << 4)                       80 #define CR_STRT_BRK (6 << 4)
 81 #define CR_STOP_BRK (7 << 4)                       81 #define CR_STOP_BRK (7 << 4)
 82 #define CR_DIS_TX   (1 << 3)                       82 #define CR_DIS_TX   (1 << 3)
 83 #define CR_ENA_TX   (1 << 2)                       83 #define CR_ENA_TX   (1 << 2)
 84 #define CR_DIS_RX   (1 << 1)                       84 #define CR_DIS_RX   (1 << 1)
 85 #define CR_ENA_RX   (1 << 0)                       85 #define CR_ENA_RX   (1 << 0)
 86                                                    86 
 87 /* ISR bits */                                     87 /* ISR bits */
 88 #define ISR_RXRDYB  (1 << 5)                       88 #define ISR_RXRDYB  (1 << 5)
 89 #define ISR_TXRDYB  (1 << 4)                       89 #define ISR_TXRDYB  (1 << 4)
 90 #define ISR_RXRDYA  (1 << 1)                       90 #define ISR_RXRDYA  (1 << 1)
 91 #define ISR_TXRDYA  (1 << 0)                       91 #define ISR_TXRDYA  (1 << 0)
 92                                                    92 
 93 /* IMR bits */                                     93 /* IMR bits */
 94 #define IMR_RXRDY   (1 << 1)                       94 #define IMR_RXRDY   (1 << 1)
 95 #define IMR_TXRDY   (1 << 0)                       95 #define IMR_TXRDY   (1 << 0)
 96                                                    96 
 97 /* access port register */                         97 /* access port register */
 98 static inline u8 read_sc_port(struct uart_port     98 static inline u8 read_sc_port(struct uart_port *p, u8 reg)
 99 {                                                  99 {
100         return readb(p->membase + p->line * 0x    100         return readb(p->membase + p->line * 0x20 + reg);
101 }                                                 101 }
102                                                   102 
103 static inline void write_sc_port(struct uart_p    103 static inline void write_sc_port(struct uart_port *p, u8 reg, u8 val)
104 {                                                 104 {
105         writeb(val, p->membase + p->line * 0x2    105         writeb(val, p->membase + p->line * 0x20 + reg);
106 }                                                 106 }
107                                                   107 
108 #define READ_SC_PORT(p, r)     read_sc_port(p,    108 #define READ_SC_PORT(p, r)     read_sc_port(p, RD_PORT_##r)
109 #define WRITE_SC_PORT(p, r, v) write_sc_port(p    109 #define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v)
110                                                   110 
111 static void sc26xx_enable_irq(struct uart_port    111 static void sc26xx_enable_irq(struct uart_port *port, int mask)
112 {                                                 112 {
113         struct uart_sc26xx_port *up;              113         struct uart_sc26xx_port *up;
114         int line = port->line;                    114         int line = port->line;
115                                                   115 
116         port -= line;                             116         port -= line;
117         up = container_of(port, struct uart_sc    117         up = container_of(port, struct uart_sc26xx_port, port[0]);
118                                                   118 
119         up->imr |= mask << (line * 4);            119         up->imr |= mask << (line * 4);
120         WRITE_SC(port, IMR, up->imr);             120         WRITE_SC(port, IMR, up->imr);
121 }                                                 121 }
122                                                   122 
123 static void sc26xx_disable_irq(struct uart_por    123 static void sc26xx_disable_irq(struct uart_port *port, int mask)
124 {                                                 124 {
125         struct uart_sc26xx_port *up;              125         struct uart_sc26xx_port *up;
126         int line = port->line;                    126         int line = port->line;
127                                                   127 
128         port -= line;                             128         port -= line;
129         up = container_of(port, struct uart_sc    129         up = container_of(port, struct uart_sc26xx_port, port[0]);
130                                                   130 
131         up->imr &= ~(mask << (line * 4));         131         up->imr &= ~(mask << (line * 4));
132         WRITE_SC(port, IMR, up->imr);             132         WRITE_SC(port, IMR, up->imr);
133 }                                                 133 }
134                                                   134 
135 static struct tty_struct *receive_chars(struct    135 static struct tty_struct *receive_chars(struct uart_port *port)
136 {                                                 136 {
137         struct tty_struct *tty = NULL;            137         struct tty_struct *tty = NULL;
138         int limit = 10000;                        138         int limit = 10000;
139         unsigned char ch;                         139         unsigned char ch;
140         char flag;                                140         char flag;
141         u8 status;                                141         u8 status;
142                                                   142 
143         if (port->info != NULL)         /* Uno    143         if (port->info != NULL)         /* Unopened serial console */
144                 tty = port->info->tty;         !! 144                 tty = port->info->port.tty;
145                                                   145 
146         while (limit-- > 0) {                     146         while (limit-- > 0) {
147                 status = READ_SC_PORT(port, SR    147                 status = READ_SC_PORT(port, SR);
148                 if (!(status & SR_RXRDY))         148                 if (!(status & SR_RXRDY))
149                         break;                    149                         break;
150                 ch = READ_SC_PORT(port, RHR);     150                 ch = READ_SC_PORT(port, RHR);
151                                                   151 
152                 flag = TTY_NORMAL;                152                 flag = TTY_NORMAL;
153                 port->icount.rx++;                153                 port->icount.rx++;
154                                                   154 
155                 if (unlikely(status & (SR_BREA    155                 if (unlikely(status & (SR_BREAK | SR_FRAME |
156                                        SR_PARI    156                                        SR_PARITY | SR_OVERRUN))) {
157                         if (status & SR_BREAK)    157                         if (status & SR_BREAK) {
158                                 status &= ~(SR    158                                 status &= ~(SR_PARITY | SR_FRAME);
159                                 port->icount.b    159                                 port->icount.brk++;
160                                 if (uart_handl    160                                 if (uart_handle_break(port))
161                                         contin    161                                         continue;
162                         } else if (status & SR    162                         } else if (status & SR_PARITY)
163                                 port->icount.p    163                                 port->icount.parity++;
164                         else if (status & SR_F    164                         else if (status & SR_FRAME)
165                                 port->icount.f    165                                 port->icount.frame++;
166                         if (status & SR_OVERRU    166                         if (status & SR_OVERRUN)
167                                 port->icount.o    167                                 port->icount.overrun++;
168                                                   168 
169                         status &= port->read_s    169                         status &= port->read_status_mask;
170                         if (status & SR_BREAK)    170                         if (status & SR_BREAK)
171                                 flag = TTY_BRE    171                                 flag = TTY_BREAK;
172                         else if (status & SR_P    172                         else if (status & SR_PARITY)
173                                 flag = TTY_PAR    173                                 flag = TTY_PARITY;
174                         else if (status & SR_F    174                         else if (status & SR_FRAME)
175                                 flag = TTY_FRA    175                                 flag = TTY_FRAME;
176                 }                                 176                 }
177                                                   177 
178                 if (uart_handle_sysrq_char(por    178                 if (uart_handle_sysrq_char(port, ch))
179                         continue;                 179                         continue;
180                                                   180 
181                 if (status & port->ignore_stat    181                 if (status & port->ignore_status_mask)
182                         continue;                 182                         continue;
183                                                   183 
184                 tty_insert_flip_char(tty, ch,     184                 tty_insert_flip_char(tty, ch, flag);
185         }                                         185         }
186         return tty;                               186         return tty;
187 }                                                 187 }
188                                                   188 
189 static void transmit_chars(struct uart_port *p    189 static void transmit_chars(struct uart_port *port)
190 {                                                 190 {
191         struct circ_buf *xmit;                    191         struct circ_buf *xmit;
192                                                   192 
193         if (!port->info)                          193         if (!port->info)
194                 return;                           194                 return;
195                                                   195 
196         xmit = &port->info->xmit;                 196         xmit = &port->info->xmit;
197         if (uart_circ_empty(xmit) || uart_tx_s    197         if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
198                 sc26xx_disable_irq(port, IMR_T    198                 sc26xx_disable_irq(port, IMR_TXRDY);
199                 return;                           199                 return;
200         }                                         200         }
201         while (!uart_circ_empty(xmit)) {          201         while (!uart_circ_empty(xmit)) {
202                 if (!(READ_SC_PORT(port, SR) &    202                 if (!(READ_SC_PORT(port, SR) & SR_TXRDY))
203                         break;                    203                         break;
204                                                   204 
205                 WRITE_SC_PORT(port, THR, xmit-    205                 WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]);
206                 xmit->tail = (xmit->tail + 1)     206                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
207                 port->icount.tx++;                207                 port->icount.tx++;
208         }                                         208         }
209         if (uart_circ_chars_pending(xmit) < WA    209         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
210                 uart_write_wakeup(port);          210                 uart_write_wakeup(port);
211 }                                                 211 }
212                                                   212 
213 static irqreturn_t sc26xx_interrupt(int irq, v    213 static irqreturn_t sc26xx_interrupt(int irq, void *dev_id)
214 {                                                 214 {
215         struct uart_sc26xx_port *up = dev_id;     215         struct uart_sc26xx_port *up = dev_id;
216         struct tty_struct *tty;                   216         struct tty_struct *tty;
217         unsigned long flags;                      217         unsigned long flags;
218         u8 isr;                                   218         u8 isr;
219                                                   219 
220         spin_lock_irqsave(&up->port[0].lock, f    220         spin_lock_irqsave(&up->port[0].lock, flags);
221                                                   221 
222         tty = NULL;                               222         tty = NULL;
223         isr = READ_SC(&up->port[0], ISR);         223         isr = READ_SC(&up->port[0], ISR);
224         if (isr & ISR_TXRDYA)                     224         if (isr & ISR_TXRDYA)
225             transmit_chars(&up->port[0]);         225             transmit_chars(&up->port[0]);
226         if (isr & ISR_RXRDYA)                     226         if (isr & ISR_RXRDYA)
227             tty = receive_chars(&up->port[0]);    227             tty = receive_chars(&up->port[0]);
228                                                   228 
229         spin_unlock(&up->port[0].lock);           229         spin_unlock(&up->port[0].lock);
230                                                   230 
231         if (tty)                                  231         if (tty)
232                 tty_flip_buffer_push(tty);        232                 tty_flip_buffer_push(tty);
233                                                   233 
234         spin_lock(&up->port[1].lock);             234         spin_lock(&up->port[1].lock);
235                                                   235 
236         tty = NULL;                               236         tty = NULL;
237         if (isr & ISR_TXRDYB)                     237         if (isr & ISR_TXRDYB)
238             transmit_chars(&up->port[1]);         238             transmit_chars(&up->port[1]);
239         if (isr & ISR_RXRDYB)                     239         if (isr & ISR_RXRDYB)
240             tty = receive_chars(&up->port[1]);    240             tty = receive_chars(&up->port[1]);
241                                                   241 
242         spin_unlock_irqrestore(&up->port[1].lo    242         spin_unlock_irqrestore(&up->port[1].lock, flags);
243                                                   243 
244         if (tty)                                  244         if (tty)
245                 tty_flip_buffer_push(tty);        245                 tty_flip_buffer_push(tty);
246                                                   246 
247         return IRQ_HANDLED;                       247         return IRQ_HANDLED;
248 }                                                 248 }
249                                                   249 
250 /* port->lock is not held.  */                    250 /* port->lock is not held.  */
251 static unsigned int sc26xx_tx_empty(struct uar    251 static unsigned int sc26xx_tx_empty(struct uart_port *port)
252 {                                                 252 {
253         return (READ_SC_PORT(port, SR) & SR_TX    253         return (READ_SC_PORT(port, SR) & SR_TXRDY) ? TIOCSER_TEMT : 0;
254 }                                                 254 }
255                                                   255 
256 /* port->lock held by caller.  */                 256 /* port->lock held by caller.  */
257 static void sc26xx_set_mctrl(struct uart_port     257 static void sc26xx_set_mctrl(struct uart_port *port, unsigned int mctrl)
258 {                                                 258 {
259         struct uart_sc26xx_port *up;              259         struct uart_sc26xx_port *up;
260         int line = port->line;                    260         int line = port->line;
261                                                   261 
262         port -= line;                             262         port -= line;
263         up = container_of(port, struct uart_sc    263         up = container_of(port, struct uart_sc26xx_port, port[0]);
264                                                   264 
265         if (up->dtr_mask[line]) {                 265         if (up->dtr_mask[line]) {
266                 if (mctrl & TIOCM_DTR)            266                 if (mctrl & TIOCM_DTR)
267                         WRITE_SC(port, OPR_SET    267                         WRITE_SC(port, OPR_SET, up->dtr_mask[line]);
268                 else                              268                 else
269                         WRITE_SC(port, OPR_CLR    269                         WRITE_SC(port, OPR_CLR, up->dtr_mask[line]);
270         }                                         270         }
271         if (up->rts_mask[line]) {                 271         if (up->rts_mask[line]) {
272                 if (mctrl & TIOCM_RTS)            272                 if (mctrl & TIOCM_RTS)
273                         WRITE_SC(port, OPR_SET    273                         WRITE_SC(port, OPR_SET, up->rts_mask[line]);
274                 else                              274                 else
275                         WRITE_SC(port, OPR_CLR    275                         WRITE_SC(port, OPR_CLR, up->rts_mask[line]);
276         }                                         276         }
277 }                                                 277 }
278                                                   278 
279 /* port->lock is held by caller and interrupts    279 /* port->lock is held by caller and interrupts are disabled.  */
280 static unsigned int sc26xx_get_mctrl(struct ua    280 static unsigned int sc26xx_get_mctrl(struct uart_port *port)
281 {                                                 281 {
282         struct uart_sc26xx_port *up;              282         struct uart_sc26xx_port *up;
283         int line = port->line;                    283         int line = port->line;
284         unsigned int mctrl = TIOCM_DSR | TIOCM    284         unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR;
285         u8 ipr;                                   285         u8 ipr;
286                                                   286 
287         port -= line;                             287         port -= line;
288         up = container_of(port, struct uart_sc    288         up = container_of(port, struct uart_sc26xx_port, port[0]);
289         ipr = READ_SC(port, IPR) ^ 0xff;          289         ipr = READ_SC(port, IPR) ^ 0xff;
290                                                   290 
291         if (up->dsr_mask[line]) {                 291         if (up->dsr_mask[line]) {
292                 mctrl &= ~TIOCM_DSR;              292                 mctrl &= ~TIOCM_DSR;
293                 mctrl |= ipr & up->dsr_mask[li    293                 mctrl |= ipr & up->dsr_mask[line] ? TIOCM_DSR : 0;
294         }                                         294         }
295         if (up->cts_mask[line]) {                 295         if (up->cts_mask[line]) {
296                 mctrl &= ~TIOCM_CTS;              296                 mctrl &= ~TIOCM_CTS;
297                 mctrl |= ipr & up->cts_mask[li    297                 mctrl |= ipr & up->cts_mask[line] ? TIOCM_CTS : 0;
298         }                                         298         }
299         if (up->dcd_mask[line]) {                 299         if (up->dcd_mask[line]) {
300                 mctrl &= ~TIOCM_CAR;              300                 mctrl &= ~TIOCM_CAR;
301                 mctrl |= ipr & up->dcd_mask[li    301                 mctrl |= ipr & up->dcd_mask[line] ? TIOCM_CAR : 0;
302         }                                         302         }
303         if (up->ri_mask[line]) {                  303         if (up->ri_mask[line]) {
304                 mctrl &= ~TIOCM_RNG;              304                 mctrl &= ~TIOCM_RNG;
305                 mctrl |= ipr & up->ri_mask[lin    305                 mctrl |= ipr & up->ri_mask[line] ? TIOCM_RNG : 0;
306         }                                         306         }
307         return mctrl;                             307         return mctrl;
308 }                                                 308 }
309                                                   309 
310 /* port->lock held by caller.  */                 310 /* port->lock held by caller.  */
311 static void sc26xx_stop_tx(struct uart_port *p    311 static void sc26xx_stop_tx(struct uart_port *port)
312 {                                                 312 {
313         return;                                   313         return;
314 }                                                 314 }
315                                                   315 
316 /* port->lock held by caller.  */                 316 /* port->lock held by caller.  */
317 static void sc26xx_start_tx(struct uart_port *    317 static void sc26xx_start_tx(struct uart_port *port)
318 {                                                 318 {
319         struct circ_buf *xmit = &port->info->x    319         struct circ_buf *xmit = &port->info->xmit;
320                                                   320 
321         while (!uart_circ_empty(xmit)) {          321         while (!uart_circ_empty(xmit)) {
322                 if (!(READ_SC_PORT(port, SR) &    322                 if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) {
323                         sc26xx_enable_irq(port    323                         sc26xx_enable_irq(port, IMR_TXRDY);
324                         break;                    324                         break;
325                 }                                 325                 }
326                 WRITE_SC_PORT(port, THR, xmit-    326                 WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]);
327                 xmit->tail = (xmit->tail + 1)     327                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
328                 port->icount.tx++;                328                 port->icount.tx++;
329         }                                         329         }
330 }                                                 330 }
331                                                   331 
332 /* port->lock held by caller.  */                 332 /* port->lock held by caller.  */
333 static void sc26xx_stop_rx(struct uart_port *p    333 static void sc26xx_stop_rx(struct uart_port *port)
334 {                                                 334 {
335 }                                                 335 }
336                                                   336 
337 /* port->lock held by caller.  */                 337 /* port->lock held by caller.  */
338 static void sc26xx_enable_ms(struct uart_port     338 static void sc26xx_enable_ms(struct uart_port *port)
339 {                                                 339 {
340 }                                                 340 }
341                                                   341 
342 /* port->lock is not held.  */                    342 /* port->lock is not held.  */
343 static void sc26xx_break_ctl(struct uart_port     343 static void sc26xx_break_ctl(struct uart_port *port, int break_state)
344 {                                                 344 {
345         if (break_state == -1)                    345         if (break_state == -1)
346                 WRITE_SC_PORT(port, CR, CR_STR    346                 WRITE_SC_PORT(port, CR, CR_STRT_BRK);
347         else                                      347         else
348                 WRITE_SC_PORT(port, CR, CR_STO    348                 WRITE_SC_PORT(port, CR, CR_STOP_BRK);
349 }                                                 349 }
350                                                   350 
351 /* port->lock is not held.  */                    351 /* port->lock is not held.  */
352 static int sc26xx_startup(struct uart_port *po    352 static int sc26xx_startup(struct uart_port *port)
353 {                                                 353 {
354         sc26xx_disable_irq(port, IMR_TXRDY | I    354         sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
355         WRITE_SC(port, OPCR, 0);                  355         WRITE_SC(port, OPCR, 0);
356                                                   356 
357         /* reset tx and rx */                     357         /* reset tx and rx */
358         WRITE_SC_PORT(port, CR, CR_RES_RX);       358         WRITE_SC_PORT(port, CR, CR_RES_RX);
359         WRITE_SC_PORT(port, CR, CR_RES_TX);       359         WRITE_SC_PORT(port, CR, CR_RES_TX);
360                                                   360 
361         /* start rx/tx */                         361         /* start rx/tx */
362         WRITE_SC_PORT(port, CR, CR_ENA_TX | CR    362         WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);
363                                                   363 
364         /* enable irqs */                         364         /* enable irqs */
365         sc26xx_enable_irq(port, IMR_RXRDY);       365         sc26xx_enable_irq(port, IMR_RXRDY);
366         return 0;                                 366         return 0;
367 }                                                 367 }
368                                                   368 
369 /* port->lock is not held.  */                    369 /* port->lock is not held.  */
370 static void sc26xx_shutdown(struct uart_port *    370 static void sc26xx_shutdown(struct uart_port *port)
371 {                                                 371 {
372         /* disable interrupst */                  372         /* disable interrupst */
373         sc26xx_disable_irq(port, IMR_TXRDY | I    373         sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY);
374                                                   374 
375         /* stop tx/rx */                          375         /* stop tx/rx */
376         WRITE_SC_PORT(port, CR, CR_DIS_TX | CR    376         WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);
377 }                                                 377 }
378                                                   378 
379 /* port->lock is not held.  */                    379 /* port->lock is not held.  */
380 static void sc26xx_set_termios(struct uart_por    380 static void sc26xx_set_termios(struct uart_port *port, struct ktermios *termios,
381                               struct ktermios     381                               struct ktermios *old)
382 {                                                 382 {
383         unsigned int baud = uart_get_baud_rate    383         unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
384         unsigned int quot = uart_get_divisor(p    384         unsigned int quot = uart_get_divisor(port, baud);
385         unsigned int iflag, cflag;                385         unsigned int iflag, cflag;
386         unsigned long flags;                      386         unsigned long flags;
387         u8 mr1, mr2, csr;                         387         u8 mr1, mr2, csr;
388                                                   388 
389         spin_lock_irqsave(&port->lock, flags);    389         spin_lock_irqsave(&port->lock, flags);
390                                                   390 
391         while ((READ_SC_PORT(port, SR) & ((1 <    391         while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc)
392                 udelay(2);                        392                 udelay(2);
393                                                   393 
394         WRITE_SC_PORT(port, CR, CR_DIS_TX | CR    394         WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX);
395                                                   395 
396         iflag = termios->c_iflag;                 396         iflag = termios->c_iflag;
397         cflag = termios->c_cflag;                 397         cflag = termios->c_cflag;
398                                                   398 
399         port->read_status_mask = SR_OVERRUN;      399         port->read_status_mask = SR_OVERRUN;
400         if (iflag & INPCK)                        400         if (iflag & INPCK)
401                 port->read_status_mask |= SR_P    401                 port->read_status_mask |= SR_PARITY | SR_FRAME;
402         if (iflag & (BRKINT | PARMRK))            402         if (iflag & (BRKINT | PARMRK))
403                 port->read_status_mask |= SR_B    403                 port->read_status_mask |= SR_BREAK;
404                                                   404 
405         port->ignore_status_mask = 0;             405         port->ignore_status_mask = 0;
406         if (iflag & IGNBRK)                       406         if (iflag & IGNBRK)
407                 port->ignore_status_mask |= SR    407                 port->ignore_status_mask |= SR_BREAK;
408         if ((cflag & CREAD) == 0)                 408         if ((cflag & CREAD) == 0)
409                 port->ignore_status_mask |= SR    409                 port->ignore_status_mask |= SR_BREAK | SR_FRAME |
410                                             SR    410                                             SR_PARITY | SR_OVERRUN;
411                                                   411 
412         switch (cflag & CSIZE) {                  412         switch (cflag & CSIZE) {
413         case CS5:                                 413         case CS5:
414                 mr1 = 0x00;                       414                 mr1 = 0x00;
415                 break;                            415                 break;
416         case CS6:                                 416         case CS6:
417                 mr1 = 0x01;                       417                 mr1 = 0x01;
418                 break;                            418                 break;
419         case CS7:                                 419         case CS7:
420                 mr1 = 0x02;                       420                 mr1 = 0x02;
421                 break;                            421                 break;
422         default:                                  422         default:
423         case CS8:                                 423         case CS8:
424                 mr1 = 0x03;                       424                 mr1 = 0x03;
425                 break;                            425                 break;
426         }                                         426         }
427         mr2 = 0x07;                               427         mr2 = 0x07;
428         if (cflag & CSTOPB)                       428         if (cflag & CSTOPB)
429                 mr2 = 0x0f;                       429                 mr2 = 0x0f;
430         if (cflag & PARENB) {                     430         if (cflag & PARENB) {
431                 if (cflag & PARODD)               431                 if (cflag & PARODD)
432                         mr1 |= (1 << 2);          432                         mr1 |= (1 << 2);
433         } else                                    433         } else
434                 mr1 |= (2 << 3);                  434                 mr1 |= (2 << 3);
435                                                   435 
436         switch (baud) {                           436         switch (baud) {
437         case 50:                                  437         case 50:
438                 csr = 0x00;                       438                 csr = 0x00;
439                 break;                            439                 break;
440         case 110:                                 440         case 110:
441                 csr = 0x11;                       441                 csr = 0x11;
442                 break;                            442                 break;
443         case 134:                                 443         case 134:
444                 csr = 0x22;                       444                 csr = 0x22;
445                 break;                            445                 break;
446         case 200:                                 446         case 200:
447                 csr = 0x33;                       447                 csr = 0x33;
448                 break;                            448                 break;
449         case 300:                                 449         case 300:
450                 csr = 0x44;                       450                 csr = 0x44;
451                 break;                            451                 break;
452         case 600:                                 452         case 600:
453                 csr = 0x55;                       453                 csr = 0x55;
454                 break;                            454                 break;
455         case 1200:                                455         case 1200:
456                 csr = 0x66;                       456                 csr = 0x66;
457                 break;                            457                 break;
458         case 2400:                                458         case 2400:
459                 csr = 0x88;                       459                 csr = 0x88;
460                 break;                            460                 break;
461         case 4800:                                461         case 4800:
462                 csr = 0x99;                       462                 csr = 0x99;
463                 break;                            463                 break;
464         default:                                  464         default:
465         case 9600:                                465         case 9600:
466                 csr = 0xbb;                       466                 csr = 0xbb;
467                 break;                            467                 break;
468         case 19200:                               468         case 19200:
469                 csr = 0xcc;                       469                 csr = 0xcc;
470                 break;                            470                 break;
471         }                                         471         }
472                                                   472 
473         WRITE_SC_PORT(port, CR, CR_RES_MR);       473         WRITE_SC_PORT(port, CR, CR_RES_MR);
474         WRITE_SC_PORT(port, MRx, mr1);            474         WRITE_SC_PORT(port, MRx, mr1);
475         WRITE_SC_PORT(port, MRx, mr2);            475         WRITE_SC_PORT(port, MRx, mr2);
476                                                   476 
477         WRITE_SC(port, ACR, 0x80);                477         WRITE_SC(port, ACR, 0x80);
478         WRITE_SC_PORT(port, CSR, csr);            478         WRITE_SC_PORT(port, CSR, csr);
479                                                   479 
480         /* reset tx and rx */                     480         /* reset tx and rx */
481         WRITE_SC_PORT(port, CR, CR_RES_RX);       481         WRITE_SC_PORT(port, CR, CR_RES_RX);
482         WRITE_SC_PORT(port, CR, CR_RES_TX);       482         WRITE_SC_PORT(port, CR, CR_RES_TX);
483                                                   483 
484         WRITE_SC_PORT(port, CR, CR_ENA_TX | CR    484         WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX);
485         while ((READ_SC_PORT(port, SR) & ((1 <    485         while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc)
486                 udelay(2);                        486                 udelay(2);
487                                                   487 
488         /* XXX */                                 488         /* XXX */
489         uart_update_timeout(port, cflag,          489         uart_update_timeout(port, cflag,
490                             (port->uartclk / (    490                             (port->uartclk / (16 * quot)));
491                                                   491 
492         spin_unlock_irqrestore(&port->lock, fl    492         spin_unlock_irqrestore(&port->lock, flags);
493 }                                                 493 }
494                                                   494 
495 static const char *sc26xx_type(struct uart_por    495 static const char *sc26xx_type(struct uart_port *port)
496 {                                                 496 {
497         return "SC26XX";                          497         return "SC26XX";
498 }                                                 498 }
499                                                   499 
500 static void sc26xx_release_port(struct uart_po    500 static void sc26xx_release_port(struct uart_port *port)
501 {                                                 501 {
502 }                                                 502 }
503                                                   503 
504 static int sc26xx_request_port(struct uart_por    504 static int sc26xx_request_port(struct uart_port *port)
505 {                                                 505 {
506         return 0;                                 506         return 0;
507 }                                                 507 }
508                                                   508 
509 static void sc26xx_config_port(struct uart_por    509 static void sc26xx_config_port(struct uart_port *port, int flags)
510 {                                                 510 {
511 }                                                 511 }
512                                                   512 
513 static int sc26xx_verify_port(struct uart_port    513 static int sc26xx_verify_port(struct uart_port *port, struct serial_struct *ser)
514 {                                                 514 {
515         return -EINVAL;                           515         return -EINVAL;
516 }                                                 516 }
517                                                   517 
518 static struct uart_ops sc26xx_ops = {             518 static struct uart_ops sc26xx_ops = {
519         .tx_empty       = sc26xx_tx_empty,        519         .tx_empty       = sc26xx_tx_empty,
520         .set_mctrl      = sc26xx_set_mctrl,       520         .set_mctrl      = sc26xx_set_mctrl,
521         .get_mctrl      = sc26xx_get_mctrl,       521         .get_mctrl      = sc26xx_get_mctrl,
522         .stop_tx        = sc26xx_stop_tx,         522         .stop_tx        = sc26xx_stop_tx,
523         .start_tx       = sc26xx_start_tx,        523         .start_tx       = sc26xx_start_tx,
524         .stop_rx        = sc26xx_stop_rx,         524         .stop_rx        = sc26xx_stop_rx,
525         .enable_ms      = sc26xx_enable_ms,       525         .enable_ms      = sc26xx_enable_ms,
526         .break_ctl      = sc26xx_break_ctl,       526         .break_ctl      = sc26xx_break_ctl,
527         .startup        = sc26xx_startup,         527         .startup        = sc26xx_startup,
528         .shutdown       = sc26xx_shutdown,        528         .shutdown       = sc26xx_shutdown,
529         .set_termios    = sc26xx_set_termios,     529         .set_termios    = sc26xx_set_termios,
530         .type           = sc26xx_type,            530         .type           = sc26xx_type,
531         .release_port   = sc26xx_release_port,    531         .release_port   = sc26xx_release_port,
532         .request_port   = sc26xx_request_port,    532         .request_port   = sc26xx_request_port,
533         .config_port    = sc26xx_config_port,     533         .config_port    = sc26xx_config_port,
534         .verify_port    = sc26xx_verify_port,     534         .verify_port    = sc26xx_verify_port,
535 };                                                535 };
536                                                   536 
537 static struct uart_port *sc26xx_port;             537 static struct uart_port *sc26xx_port;
538                                                   538 
539 #ifdef CONFIG_SERIAL_SC26XX_CONSOLE               539 #ifdef CONFIG_SERIAL_SC26XX_CONSOLE
540 static void sc26xx_console_putchar(struct uart    540 static void sc26xx_console_putchar(struct uart_port *port, char c)
541 {                                                 541 {
542         unsigned long flags;                      542         unsigned long flags;
543         int limit = 1000000;                      543         int limit = 1000000;
544                                                   544 
545         spin_lock_irqsave(&port->lock, flags);    545         spin_lock_irqsave(&port->lock, flags);
546                                                   546 
547         while (limit-- > 0) {                     547         while (limit-- > 0) {
548                 if (READ_SC_PORT(port, SR) & S    548                 if (READ_SC_PORT(port, SR) & SR_TXRDY) {
549                         WRITE_SC_PORT(port, TH    549                         WRITE_SC_PORT(port, THR, c);
550                         break;                    550                         break;
551                 }                                 551                 }
552                 udelay(2);                        552                 udelay(2);
553         }                                         553         }
554                                                   554 
555         spin_unlock_irqrestore(&port->lock, fl    555         spin_unlock_irqrestore(&port->lock, flags);
556 }                                                 556 }
557                                                   557 
558 static void sc26xx_console_write(struct consol    558 static void sc26xx_console_write(struct console *con, const char *s, unsigned n)
559 {                                                 559 {
560         struct uart_port *port = sc26xx_port;     560         struct uart_port *port = sc26xx_port;
561         int i;                                    561         int i;
562                                                   562 
563         for (i = 0; i < n; i++) {                 563         for (i = 0; i < n; i++) {
564                 if (*s == '\n')                   564                 if (*s == '\n')
565                         sc26xx_console_putchar    565                         sc26xx_console_putchar(port, '\r');
566                 sc26xx_console_putchar(port, *    566                 sc26xx_console_putchar(port, *s++);
567         }                                         567         }
568 }                                                 568 }
569                                                   569 
570 static int __init sc26xx_console_setup(struct     570 static int __init sc26xx_console_setup(struct console *con, char *options)
571 {                                                 571 {
572         struct uart_port *port = sc26xx_port;     572         struct uart_port *port = sc26xx_port;
573         int baud = 9600;                          573         int baud = 9600;
574         int bits = 8;                             574         int bits = 8;
575         int parity = 'n';                         575         int parity = 'n';
576         int flow = 'n';                           576         int flow = 'n';
577                                                   577 
578         if (port->type != PORT_SC26XX)            578         if (port->type != PORT_SC26XX)
579                 return -1;                        579                 return -1;
580                                                   580 
581         printk(KERN_INFO "Console: ttySC%d (SC    581         printk(KERN_INFO "Console: ttySC%d (SC26XX)\n", con->index);
582         if (options)                              582         if (options)
583                 uart_parse_options(options, &b    583                 uart_parse_options(options, &baud, &parity, &bits, &flow);
584                                                   584 
585         return uart_set_options(port, con, bau    585         return uart_set_options(port, con, baud, parity, bits, flow);
586 }                                                 586 }
587                                                   587 
588 static struct uart_driver sc26xx_reg;             588 static struct uart_driver sc26xx_reg;
589 static struct console sc26xx_console = {          589 static struct console sc26xx_console = {
590         .name   =       "ttySC",                  590         .name   =       "ttySC",
591         .write  =       sc26xx_console_write,     591         .write  =       sc26xx_console_write,
592         .device =       uart_console_device,      592         .device =       uart_console_device,
593         .setup  =       sc26xx_console_setup,     593         .setup  =       sc26xx_console_setup,
594         .flags  =       CON_PRINTBUFFER,          594         .flags  =       CON_PRINTBUFFER,
595         .index  =       -1,                       595         .index  =       -1,
596         .data   =       &sc26xx_reg,              596         .data   =       &sc26xx_reg,
597 };                                                597 };
598 #define SC26XX_CONSOLE   &sc26xx_console          598 #define SC26XX_CONSOLE   &sc26xx_console
599 #else                                             599 #else
600 #define SC26XX_CONSOLE   NULL                     600 #define SC26XX_CONSOLE   NULL
601 #endif                                            601 #endif
602                                                   602 
603 static struct uart_driver sc26xx_reg = {          603 static struct uart_driver sc26xx_reg = {
604         .owner                  = THIS_MODULE,    604         .owner                  = THIS_MODULE,
605         .driver_name            = "SC26xx",       605         .driver_name            = "SC26xx",
606         .dev_name               = "ttySC",        606         .dev_name               = "ttySC",
607         .major                  = SC26XX_MAJOR    607         .major                  = SC26XX_MAJOR,
608         .minor                  = SC26XX_MINOR    608         .minor                  = SC26XX_MINOR_START,
609         .nr                     = SC26XX_NR,      609         .nr                     = SC26XX_NR,
610         .cons                   = SC26XX_CONSO    610         .cons                   = SC26XX_CONSOLE,
611 };                                                611 };
612                                                   612 
613 static u8 sc26xx_flags2mask(unsigned int flags    613 static u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos)
614 {                                                 614 {
615         unsigned int bit = (flags >> bitpos) &    615         unsigned int bit = (flags >> bitpos) & 15;
616                                                   616 
617         return bit ? (1 << (bit - 1)) : 0;        617         return bit ? (1 << (bit - 1)) : 0;
618 }                                                 618 }
619                                                   619 
620 static void __devinit sc26xx_init_masks(struct    620 static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up,
621                                         int li    621                                         int line, unsigned int data)
622 {                                                 622 {
623         up->dtr_mask[line] = sc26xx_flags2mask    623         up->dtr_mask[line] = sc26xx_flags2mask(data,  0);
624         up->rts_mask[line] = sc26xx_flags2mask    624         up->rts_mask[line] = sc26xx_flags2mask(data,  4);
625         up->dsr_mask[line] = sc26xx_flags2mask    625         up->dsr_mask[line] = sc26xx_flags2mask(data,  8);
626         up->cts_mask[line] = sc26xx_flags2mask    626         up->cts_mask[line] = sc26xx_flags2mask(data, 12);
627         up->dcd_mask[line] = sc26xx_flags2mask    627         up->dcd_mask[line] = sc26xx_flags2mask(data, 16);
628         up->ri_mask[line]  = sc26xx_flags2mask    628         up->ri_mask[line]  = sc26xx_flags2mask(data, 20);
629 }                                                 629 }
630                                                   630 
631 static int __devinit sc26xx_probe(struct platf    631 static int __devinit sc26xx_probe(struct platform_device *dev)
632 {                                                 632 {
633         struct resource *res;                     633         struct resource *res;
634         struct uart_sc26xx_port *up;              634         struct uart_sc26xx_port *up;
635         unsigned int *sc26xx_data = dev->dev.p    635         unsigned int *sc26xx_data = dev->dev.platform_data;
636         int err;                                  636         int err;
637                                                   637 
638         res = platform_get_resource(dev, IORES    638         res = platform_get_resource(dev, IORESOURCE_MEM, 0);
639         if (!res)                                 639         if (!res)
640                 return -ENODEV;                   640                 return -ENODEV;
641                                                   641 
642         up = kzalloc(sizeof *up, GFP_KERNEL);     642         up = kzalloc(sizeof *up, GFP_KERNEL);
643         if (unlikely(!up))                        643         if (unlikely(!up))
644                 return -ENOMEM;                   644                 return -ENOMEM;
645                                                   645 
646         up->port[0].line = 0;                     646         up->port[0].line = 0;
647         up->port[0].ops = &sc26xx_ops;            647         up->port[0].ops = &sc26xx_ops;
648         up->port[0].type = PORT_SC26XX;           648         up->port[0].type = PORT_SC26XX;
649         up->port[0].uartclk = (29491200 / 16);    649         up->port[0].uartclk = (29491200 / 16); /* arbitrary */
650                                                   650 
651         up->port[0].mapbase = res->start;         651         up->port[0].mapbase = res->start;
652         up->port[0].membase = ioremap_nocache(    652         up->port[0].membase = ioremap_nocache(up->port[0].mapbase, 0x40);
653         up->port[0].iotype = UPIO_MEM;            653         up->port[0].iotype = UPIO_MEM;
654         up->port[0].irq = platform_get_irq(dev    654         up->port[0].irq = platform_get_irq(dev, 0);
655                                                   655 
656         up->port[0].dev = &dev->dev;              656         up->port[0].dev = &dev->dev;
657                                                   657 
658         sc26xx_init_masks(up, 0, sc26xx_data[0    658         sc26xx_init_masks(up, 0, sc26xx_data[0]);
659                                                   659 
660         sc26xx_port = &up->port[0];               660         sc26xx_port = &up->port[0];
661                                                   661 
662         up->port[1].line = 1;                     662         up->port[1].line = 1;
663         up->port[1].ops = &sc26xx_ops;            663         up->port[1].ops = &sc26xx_ops;
664         up->port[1].type = PORT_SC26XX;           664         up->port[1].type = PORT_SC26XX;
665         up->port[1].uartclk = (29491200 / 16);    665         up->port[1].uartclk = (29491200 / 16); /* arbitrary */
666                                                   666 
667         up->port[1].mapbase = up->port[0].mapb    667         up->port[1].mapbase = up->port[0].mapbase;
668         up->port[1].membase = up->port[0].memb    668         up->port[1].membase = up->port[0].membase;
669         up->port[1].iotype = UPIO_MEM;            669         up->port[1].iotype = UPIO_MEM;
670         up->port[1].irq = up->port[0].irq;        670         up->port[1].irq = up->port[0].irq;
671                                                   671 
672         up->port[1].dev = &dev->dev;              672         up->port[1].dev = &dev->dev;
673                                                   673 
674         sc26xx_init_masks(up, 1, sc26xx_data[1    674         sc26xx_init_masks(up, 1, sc26xx_data[1]);
675                                                   675 
676         err = uart_register_driver(&sc26xx_reg    676         err = uart_register_driver(&sc26xx_reg);
677         if (err)                                  677         if (err)
678                 goto out_free_port;               678                 goto out_free_port;
679                                                   679 
680         sc26xx_reg.tty_driver->name_base = sc2    680         sc26xx_reg.tty_driver->name_base = sc26xx_reg.minor;
681                                                   681 
682         err = uart_add_one_port(&sc26xx_reg, &    682         err = uart_add_one_port(&sc26xx_reg, &up->port[0]);
683         if (err)                                  683         if (err)
684                 goto out_unregister_driver;       684                 goto out_unregister_driver;
685                                                   685 
686         err = uart_add_one_port(&sc26xx_reg, &    686         err = uart_add_one_port(&sc26xx_reg, &up->port[1]);
687         if (err)                                  687         if (err)
688                 goto out_remove_port0;            688                 goto out_remove_port0;
689                                                   689 
690         err = request_irq(up->port[0].irq, sc2    690         err = request_irq(up->port[0].irq, sc26xx_interrupt, 0, "sc26xx", up);
691         if (err)                                  691         if (err)
692                 goto out_remove_ports;            692                 goto out_remove_ports;
693                                                   693 
694         dev_set_drvdata(&dev->dev, up);           694         dev_set_drvdata(&dev->dev, up);
695         return 0;                                 695         return 0;
696                                                   696 
697 out_remove_ports:                                 697 out_remove_ports:
698         uart_remove_one_port(&sc26xx_reg, &up-    698         uart_remove_one_port(&sc26xx_reg, &up->port[1]);
699 out_remove_port0:                                 699 out_remove_port0:
700         uart_remove_one_port(&sc26xx_reg, &up-    700         uart_remove_one_port(&sc26xx_reg, &up->port[0]);
701                                                   701 
702 out_unregister_driver:                            702 out_unregister_driver:
703         uart_unregister_driver(&sc26xx_reg);      703         uart_unregister_driver(&sc26xx_reg);
704                                                   704 
705 out_free_port:                                    705 out_free_port:
706         kfree(up);                                706         kfree(up);
707         sc26xx_port = NULL;                       707         sc26xx_port = NULL;
708         return err;                               708         return err;
709 }                                                 709 }
710                                                   710 
711                                                   711 
712 static int __exit sc26xx_driver_remove(struct     712 static int __exit sc26xx_driver_remove(struct platform_device *dev)
713 {                                                 713 {
714         struct uart_sc26xx_port *up = dev_get_    714         struct uart_sc26xx_port *up = dev_get_drvdata(&dev->dev);
715                                                   715 
716         free_irq(up->port[0].irq, up);            716         free_irq(up->port[0].irq, up);
717                                                   717 
718         uart_remove_one_port(&sc26xx_reg, &up-    718         uart_remove_one_port(&sc26xx_reg, &up->port[0]);
719         uart_remove_one_port(&sc26xx_reg, &up-    719         uart_remove_one_port(&sc26xx_reg, &up->port[1]);
720                                                   720 
721         uart_unregister_driver(&sc26xx_reg);      721         uart_unregister_driver(&sc26xx_reg);
722                                                   722 
723         kfree(up);                                723         kfree(up);
724         sc26xx_port = NULL;                       724         sc26xx_port = NULL;
725                                                   725 
726         dev_set_drvdata(&dev->dev, NULL);         726         dev_set_drvdata(&dev->dev, NULL);
727         return 0;                                 727         return 0;
728 }                                                 728 }
729                                                   729 
730 static struct platform_driver sc26xx_driver =     730 static struct platform_driver sc26xx_driver = {
731         .probe  = sc26xx_probe,                   731         .probe  = sc26xx_probe,
732         .remove = __devexit_p(sc26xx_driver_re    732         .remove = __devexit_p(sc26xx_driver_remove),
733         .driver = {                               733         .driver = {
734                 .name   = "SC26xx",               734                 .name   = "SC26xx",
735                 .owner  = THIS_MODULE,            735                 .owner  = THIS_MODULE,
736         },                                        736         },
737 };                                                737 };
738                                                   738 
739 static int __init sc26xx_init(void)               739 static int __init sc26xx_init(void)
740 {                                                 740 {
741         return platform_driver_register(&sc26x    741         return platform_driver_register(&sc26xx_driver);
742 }                                                 742 }
743                                                   743 
744 static void __exit sc26xx_exit(void)              744 static void __exit sc26xx_exit(void)
745 {                                                 745 {
746         platform_driver_unregister(&sc26xx_dri    746         platform_driver_unregister(&sc26xx_driver);
747 }                                                 747 }
748                                                   748 
749 module_init(sc26xx_init);                         749 module_init(sc26xx_init);
750 module_exit(sc26xx_exit);                         750 module_exit(sc26xx_exit);
751                                                   751 
752                                                   752 
753 MODULE_AUTHOR("Thomas Bogendörfer");             753 MODULE_AUTHOR("Thomas Bogendörfer");
754 MODULE_DESCRIPTION("SC681/SC2692 serial driver    754 MODULE_DESCRIPTION("SC681/SC2692 serial driver");
755 MODULE_VERSION("1.0");                            755 MODULE_VERSION("1.0");
756 MODULE_LICENSE("GPL");                            756 MODULE_LICENSE("GPL");
757 MODULE_ALIAS("platform:SC26xx");                  757 MODULE_ALIAS("platform:SC26xx");
758                                                   758 
  This page was automatically generated by the LXR engine.