aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2007-06-30 02:04:21 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-09-23 15:02:45 -0400
commit6e418a9d26ab4fd44b3e07dc1158027cbdf0a919 (patch)
tree03f84d7e2518b7a5422fe111da8745c4c3307133
parentd1496c39e500857b8949cdb91af24e0eb8aae4d0 (diff)
sdio: UART/GPS driver
This currently only accepts the GPS class since that's all I have for testing. Tested with a Matsushita GPS and gpsd version 2.34. Signed-off-by: Nicolas Pitre <npitre@mvista.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/card/Kconfig7
-rw-r--r--drivers/mmc/card/Makefile2
-rw-r--r--drivers/mmc/card/sdio_uart.c1077
3 files changed, 1086 insertions, 0 deletions
diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index a49cb9737cd8..aa8a4e461942 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -32,3 +32,10 @@ config MMC_BLOCK_BOUNCE
32 32
33 If unsure, say Y here. 33 If unsure, say Y here.
34 34
35config SDIO_UART
36 tristate "SDIO UART/GPS class support"
37 depends on MMC
38 help
39 SDIO function driver for SDIO cards that implements the UART
40 class, as well as the GPS class which appears like a UART.
41
diff --git a/drivers/mmc/card/Makefile b/drivers/mmc/card/Makefile
index cf8c939867f5..fc5a784cfa1a 100644
--- a/drivers/mmc/card/Makefile
+++ b/drivers/mmc/card/Makefile
@@ -9,3 +9,5 @@ endif
9obj-$(CONFIG_MMC_BLOCK) += mmc_block.o 9obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
10mmc_block-objs := block.o queue.o 10mmc_block-objs := block.o queue.o
11 11
12obj-$(CONFIG_SDIO_UART) += sdio_uart.o
13
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
new file mode 100644
index 000000000000..e4d9e85ff584
--- /dev/null
+++ b/drivers/mmc/card/sdio_uart.c
@@ -0,0 +1,1077 @@
1/*
2 * linux/drivers/mmc/card/sdio_uart.c - SDIO UART/GPS driver
3 *
4 * Based on drivers/serial/8250.c and drivers/serial/serial_core.c
5 * by Russell King.
6 *
7 * Author: Nicolas Pitre
8 * Created: June 15, 2007
9 * Copyright: MontaVista Software, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 */
16
17/*
18 * Note: Although this driver assumes a 16550A-like UART implementation,
19 * it is not possible to leverage the common 8250/16550 driver, nor the
20 * core UART infrastructure, as they assumes direct access to the hardware
21 * registers, often under a spinlock. This is not possible in the SDIO
22 * context as SDIO access functions must be able to sleep.
23 *
24 * Because we need to lock the SDIO host to ensure an exclusive access to
25 * the card, we simply rely on that lock to also prevent and serialize
26 * concurrent access to the same port.
27 */
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/mutex.h>
33#include <linux/serial_reg.h>
34#include <linux/circ_buf.h>
35#include <linux/gfp.h>
36#include <linux/tty.h>
37#include <linux/tty_flip.h>
38
39#include <linux/mmc/core.h>
40#include <linux/mmc/card.h>
41#include <linux/mmc/sdio_func.h>
42#include <linux/mmc/sdio_ids.h>
43
44
45#define UART_NR 8 /* Number of UARTs this driver can handle */
46
47
48#define UART_XMIT_SIZE PAGE_SIZE
49#define WAKEUP_CHARS 256
50
51#define circ_empty(circ) ((circ)->head == (circ)->tail)
52#define circ_clear(circ) ((circ)->head = (circ)->tail = 0)
53
54#define circ_chars_pending(circ) \
55 (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
56
57#define circ_chars_free(circ) \
58 (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
59
60
61struct uart_icount {
62 __u32 cts;
63 __u32 dsr;
64 __u32 rng;
65 __u32 dcd;
66 __u32 rx;
67 __u32 tx;
68 __u32 frame;
69 __u32 overrun;
70 __u32 parity;
71 __u32 brk;
72};
73
74struct sdio_uart_port {
75 struct kref kref;
76 struct tty_struct *tty;
77 unsigned int index;
78 unsigned int opened;
79 struct mutex open_lock;
80 struct sdio_func *func;
81 struct mutex func_lock;
82 unsigned int regs_offset;
83 struct circ_buf xmit;
84 spinlock_t write_lock;
85 struct uart_icount icount;
86 unsigned int uartclk;
87 unsigned int mctrl;
88 unsigned int read_status_mask;
89 unsigned int ignore_status_mask;
90 unsigned char x_char;
91 unsigned char ier;
92 unsigned char lcr;
93};
94
95static struct sdio_uart_port *sdio_uart_table[UART_NR];
96static DEFINE_SPINLOCK(sdio_uart_table_lock);
97
98static int sdio_uart_add_port(struct sdio_uart_port *port)
99{
100 int index, ret = -EBUSY;
101
102 kref_init(&port->kref);
103 mutex_init(&port->open_lock);
104 mutex_init(&port->func_lock);
105 spin_lock_init(&port->write_lock);
106
107 spin_lock(&sdio_uart_table_lock);
108 for (index = 0; index < UART_NR; index++) {
109 if (!sdio_uart_table[index]) {
110 port->index = index;
111 sdio_uart_table[index] = port;
112 ret = 0;
113 break;
114 }
115 }
116 spin_unlock(&sdio_uart_table_lock);
117
118 return ret;
119}
120
121static struct sdio_uart_port *sdio_uart_port_get(unsigned index)
122{
123 struct sdio_uart_port *port;
124
125 if (index >= UART_NR)
126 return NULL;
127
128 spin_lock(&sdio_uart_table_lock);
129 port = sdio_uart_table[index];
130 if (port)
131 kref_get(&port->kref);
132 spin_unlock(&sdio_uart_table_lock);
133
134 return port;
135}
136
137static void sdio_uart_port_destroy(struct kref *kref)
138{
139 struct sdio_uart_port *port =
140 container_of(kref, struct sdio_uart_port, kref);
141 kfree(port);
142}
143
144static void sdio_uart_port_put(struct sdio_uart_port *port)
145{
146 kref_put(&port->kref, sdio_uart_port_destroy);
147}
148
149static void sdio_uart_port_remove(struct sdio_uart_port *port)
150{
151 struct sdio_func *func;
152
153 BUG_ON(sdio_uart_table[port->index] != port);
154
155 spin_lock(&sdio_uart_table_lock);
156 sdio_uart_table[port->index] = NULL;
157 spin_unlock(&sdio_uart_table_lock);
158
159 /*
160 * We're killing a port that potentially still is in use by
161 * the tty layer. Be careful to prevent any further access
162 * to the SDIO function and arrange for the tty layer to
163 * give up on that port ASAP.
164 * Beware: the lock ordering is critical.
165 */
166 mutex_lock(&port->open_lock);
167 mutex_lock(&port->func_lock);
168 func = port->func;
169 sdio_claim_host(func);
170 port->func = NULL;
171 mutex_unlock(&port->func_lock);
172 if (port->opened)
173 tty_hangup(port->tty);
174 mutex_unlock(&port->open_lock);
175 sdio_release_irq(func);
176 sdio_disable_func(func);
177 sdio_release_host(func);
178
179 sdio_uart_port_put(port);
180}
181
182static int sdio_uart_claim_func(struct sdio_uart_port *port)
183{
184 mutex_lock(&port->func_lock);
185 if (unlikely(!port->func)) {
186 mutex_unlock(&port->func_lock);
187 return -ENODEV;
188 }
189 sdio_claim_host(port->func);
190 mutex_unlock(&port->func_lock);
191 return 0;
192}
193
194static inline void sdio_uart_release_func(struct sdio_uart_port *port)
195{
196 sdio_release_host(port->func);
197}
198
199static inline unsigned int sdio_in(struct sdio_uart_port *port, int offset)
200{
201 unsigned char c;
202 c = sdio_readb(port->func, port->regs_offset + offset, NULL);
203 return c;
204}
205
206static inline void sdio_out(struct sdio_uart_port *port, int offset, int value)
207{
208 sdio_writeb(port->func, value, port->regs_offset + offset, NULL);
209}
210
211static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port)
212{
213 unsigned char status;
214 unsigned int ret;
215
216 status = sdio_in(port, UART_MSR);
217
218 ret = 0;
219 if (status & UART_MSR_DCD)
220 ret |= TIOCM_CAR;
221 if (status & UART_MSR_RI)
222 ret |= TIOCM_RNG;
223 if (status & UART_MSR_DSR)
224 ret |= TIOCM_DSR;
225 if (status & UART_MSR_CTS)
226 ret |= TIOCM_CTS;
227 return ret;
228}
229
230static void sdio_uart_write_mctrl(struct sdio_uart_port *port, unsigned int mctrl)
231{
232 unsigned char mcr = 0;
233
234 if (mctrl & TIOCM_RTS)
235 mcr |= UART_MCR_RTS;
236 if (mctrl & TIOCM_DTR)
237 mcr |= UART_MCR_DTR;
238 if (mctrl & TIOCM_OUT1)
239 mcr |= UART_MCR_OUT1;
240 if (mctrl & TIOCM_OUT2)
241 mcr |= UART_MCR_OUT2;
242 if (mctrl & TIOCM_LOOP)
243 mcr |= UART_MCR_LOOP;
244
245 sdio_out(port, UART_MCR, mcr);
246}
247
248static inline void sdio_uart_update_mctrl(struct sdio_uart_port *port,
249 unsigned int set, unsigned int clear)
250{
251 unsigned int old;
252
253 old = port->mctrl;
254 port->mctrl = (old & ~clear) | set;
255 if (old != port->mctrl)
256 sdio_uart_write_mctrl(port, port->mctrl);
257}
258
259#define sdio_uart_set_mctrl(port, x) sdio_uart_update_mctrl(port, x, 0)
260#define sdio_uart_clear_mctrl(port, x) sdio_uart_update_mctrl(port, 0, x)
261
262static void sdio_uart_change_speed(struct sdio_uart_port *port,
263 struct ktermios *termios,
264 struct ktermios *old)
265{
266 unsigned char cval, fcr = 0;
267 unsigned int baud, quot;
268
269 switch (termios->c_cflag & CSIZE) {
270 case CS5:
271 cval = UART_LCR_WLEN5;
272 break;
273 case CS6:
274 cval = UART_LCR_WLEN6;
275 break;
276 case CS7:
277 cval = UART_LCR_WLEN7;
278 break;
279 default:
280 case CS8:
281 cval = UART_LCR_WLEN8;
282 break;
283 }
284
285 if (termios->c_cflag & CSTOPB)
286 cval |= UART_LCR_STOP;
287 if (termios->c_cflag & PARENB)
288 cval |= UART_LCR_PARITY;
289 if (!(termios->c_cflag & PARODD))
290 cval |= UART_LCR_EPAR;
291
292 for (;;) {
293 baud = tty_termios_baud_rate(termios);
294 if (baud == 0)
295 baud = 9600; /* Special case: B0 rate. */
296 if (baud <= port->uartclk)
297 break;
298 /*
299 * Oops, the quotient was zero. Try again with the old
300 * baud rate if possible, otherwise default to 9600.
301 */
302 termios->c_cflag &= ~CBAUD;
303 if (old) {
304 termios->c_cflag |= old->c_cflag & CBAUD;
305 old = NULL;
306 } else
307 termios->c_cflag |= B9600;
308 }
309 quot = (2 * port->uartclk + baud) / (2 * baud);
310
311 if (baud < 2400)
312 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
313 else
314 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
315
316 port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
317 if (termios->c_iflag & INPCK)
318 port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
319 if (termios->c_iflag & (BRKINT | PARMRK))
320 port->read_status_mask |= UART_LSR_BI;
321
322 /*
323 * Characters to ignore
324 */
325 port->ignore_status_mask = 0;
326 if (termios->c_iflag & IGNPAR)
327 port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
328 if (termios->c_iflag & IGNBRK) {
329 port->ignore_status_mask |= UART_LSR_BI;
330 /*
331 * If we're ignoring parity and break indicators,
332 * ignore overruns too (for real raw support).
333 */
334 if (termios->c_iflag & IGNPAR)
335 port->ignore_status_mask |= UART_LSR_OE;
336 }
337
338 /*
339 * ignore all characters if CREAD is not set
340 */
341 if ((termios->c_cflag & CREAD) == 0)
342 port->ignore_status_mask |= UART_LSR_DR;
343
344 /*
345 * CTS flow control flag and modem status interrupts
346 */
347 port->ier &= ~UART_IER_MSI;
348 if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL))
349 port->ier |= UART_IER_MSI;
350
351 port->lcr = cval;
352
353 sdio_out(port, UART_IER, port->ier);
354 sdio_out(port, UART_LCR, cval | UART_LCR_DLAB);
355 sdio_out(port, UART_DLL, quot & 0xff);
356 sdio_out(port, UART_DLM, quot >> 8);
357 sdio_out(port, UART_LCR, cval);
358 sdio_out(port, UART_FCR, fcr);
359
360 sdio_uart_write_mctrl(port, port->mctrl);
361}
362
363static void sdio_uart_start_tx(struct sdio_uart_port *port)
364{
365 if (!(port->ier & UART_IER_THRI)) {
366 port->ier |= UART_IER_THRI;
367 sdio_out(port, UART_IER, port->ier);
368 }
369}
370
371static void sdio_uart_stop_tx(struct sdio_uart_port *port)
372{
373 if (port->ier & UART_IER_THRI) {
374 port->ier &= ~UART_IER_THRI;
375 sdio_out(port, UART_IER, port->ier);
376 }
377}
378
379static void sdio_uart_stop_rx(struct sdio_uart_port *port)
380{
381 port->ier &= ~UART_IER_RLSI;
382 port->read_status_mask &= ~UART_LSR_DR;
383 sdio_out(port, UART_IER, port->ier);
384}
385
386static void sdio_uart_receive_chars(struct sdio_uart_port *port, int *status)
387{
388 struct tty_struct *tty = port->tty;
389 unsigned int ch, flag;
390 int max_count = 256;
391
392 do {
393 ch = sdio_in(port, UART_RX);
394 flag = TTY_NORMAL;
395 port->icount.rx++;
396
397 if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
398 UART_LSR_FE | UART_LSR_OE))) {
399 /*
400 * For statistics only
401 */
402 if (*status & UART_LSR_BI) {
403 *status &= ~(UART_LSR_FE | UART_LSR_PE);
404 port->icount.brk++;
405 } else if (*status & UART_LSR_PE)
406 port->icount.parity++;
407 else if (*status & UART_LSR_FE)
408 port->icount.frame++;
409 if (*status & UART_LSR_OE)
410 port->icount.overrun++;
411
412 /*
413 * Mask off conditions which should be ignored.
414 */
415 *status &= port->read_status_mask;
416 if (*status & UART_LSR_BI) {
417 flag = TTY_BREAK;
418 } else if (*status & UART_LSR_PE)
419 flag = TTY_PARITY;
420 else if (*status & UART_LSR_FE)
421 flag = TTY_FRAME;
422 }
423
424 if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
425 tty_insert_flip_char(tty, ch, flag);
426
427 /*
428 * Overrun is special. Since it's reported immediately,
429 * it doesn't affect the current character.
430 */
431 if (*status & ~port->ignore_status_mask & UART_LSR_OE)
432 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
433
434 *status = sdio_in(port, UART_LSR);
435 } while ((*status & UART_LSR_DR) && (max_count-- > 0));
436 tty_flip_buffer_push(tty);
437}
438
439static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
440{
441 struct circ_buf *xmit = &port->xmit;
442 int count;
443
444 if (port->x_char) {
445 sdio_out(port, UART_TX, port->x_char);
446 port->icount.tx++;
447 port->x_char = 0;
448 return;
449 }
450 if (circ_empty(xmit) || port->tty->stopped || port->tty->hw_stopped) {
451 sdio_uart_stop_tx(port);
452 return;
453 }
454
455 count = 16;
456 do {
457 sdio_out(port, UART_TX, xmit->buf[xmit->tail]);
458 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
459 port->icount.tx++;
460 if (circ_empty(xmit))
461 break;
462 } while (--count > 0);
463
464 if (circ_chars_pending(xmit) < WAKEUP_CHARS)
465 tty_wakeup(port->tty);
466
467 if (circ_empty(xmit))
468 sdio_uart_stop_tx(port);
469}
470
471static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
472{
473 int status;
474
475 status = sdio_in(port, UART_MSR);
476
477 if ((status & UART_MSR_ANY_DELTA) == 0)
478 return;
479
480 if (status & UART_MSR_TERI)
481 port->icount.rng++;
482 if (status & UART_MSR_DDSR)
483 port->icount.dsr++;
484 if (status & UART_MSR_DDCD)
485 port->icount.dcd++;
486 if (status & UART_MSR_DCTS) {
487 port->icount.cts++;
488 if (port->tty->termios->c_cflag & CRTSCTS) {
489 int cts = (status & UART_MSR_CTS);
490 if (port->tty->hw_stopped) {
491 if (cts) {
492 port->tty->hw_stopped = 0;
493 sdio_uart_start_tx(port);
494 tty_wakeup(port->tty);
495 }
496 } else {
497 if (!cts) {
498 port->tty->hw_stopped = 1;
499 sdio_uart_stop_tx(port);
500 }
501 }
502 }
503 }
504}
505
506/*
507 * This handles the interrupt from one port.
508 */
509static void sdio_uart_irq(struct sdio_func *func)
510{
511 struct sdio_uart_port *port = sdio_get_drvdata(func);
512 unsigned int iir, lsr;
513
514 iir = sdio_in(port, UART_IIR);
515 if (iir & UART_IIR_NO_INT)
516 return;
517 lsr = sdio_in(port, UART_LSR);
518 if (lsr & UART_LSR_DR)
519 sdio_uart_receive_chars(port, &lsr);
520 sdio_uart_check_modem_status(port);
521 if (lsr & UART_LSR_THRE)
522 sdio_uart_transmit_chars(port);
523}
524
525static int sdio_uart_startup(struct sdio_uart_port *port)
526{
527 unsigned long page;
528 int ret;
529
530 /*
531 * Set the TTY IO error marker - we will only clear this
532 * once we have successfully opened the port.
533 */
534 set_bit(TTY_IO_ERROR, &port->tty->flags);
535
536 /* Initialise and allocate the transmit buffer. */
537 page = __get_free_page(GFP_KERNEL);
538 if (!page)
539 return -ENOMEM;
540 port->xmit.buf = (unsigned char *)page;
541 circ_clear(&port->xmit);
542
543 ret = sdio_uart_claim_func(port);
544 if (ret)
545 goto err1;
546 ret = sdio_enable_func(port->func);
547 if (ret)
548 goto err2;
549 ret = sdio_claim_irq(port->func, sdio_uart_irq);
550 if (ret)
551 goto err3;
552
553 /*
554 * Clear the FIFO buffers and disable them.
555 * (they will be reenabled in sdio_change_speed())
556 */
557 sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
558 sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
559 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
560 sdio_out(port, UART_FCR, 0);
561
562 /*
563 * Clear the interrupt registers.
564 */
565 (void) sdio_in(port, UART_LSR);
566 (void) sdio_in(port, UART_RX);
567 (void) sdio_in(port, UART_IIR);
568 (void) sdio_in(port, UART_MSR);
569
570 /*
571 * Now, initialize the UART
572 */
573 sdio_out(port, UART_LCR, UART_LCR_WLEN8);
574
575 port->ier = UART_IER_RLSI | UART_IER_RDI | UART_IER_RTOIE | UART_IER_UUE;
576 port->mctrl = TIOCM_OUT2;
577
578 sdio_uart_change_speed(port, port->tty->termios, NULL);
579
580 if (port->tty->termios->c_cflag & CBAUD)
581 sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
582
583 if (port->tty->termios->c_cflag & CRTSCTS)
584 if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
585 port->tty->hw_stopped = 1;
586
587 clear_bit(TTY_IO_ERROR, &port->tty->flags);
588
589 /* Kick the IRQ handler once while we're still holding the host lock */
590 sdio_uart_irq(port->func);
591
592 sdio_uart_release_func(port);
593 return 0;
594
595err3:
596 sdio_disable_func(port->func);
597err2:
598 sdio_uart_release_func(port);
599err1:
600 free_page((unsigned long)port->xmit.buf);
601 return ret;
602}
603
604static void sdio_uart_shutdown(struct sdio_uart_port *port)
605{
606 int ret;
607
608 ret = sdio_uart_claim_func(port);
609 if (ret)
610 goto skip;
611
612 sdio_uart_stop_rx(port);
613
614 /* TODO: wait here for TX FIFO to drain */
615
616 /* Turn off DTR and RTS early. */
617 if (port->tty->termios->c_cflag & HUPCL)
618 sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
619
620 /* Disable interrupts from this port */
621 sdio_release_irq(port->func);
622 port->ier = 0;
623 sdio_out(port, UART_IER, 0);
624
625 sdio_uart_clear_mctrl(port, TIOCM_OUT2);
626
627 /* Disable break condition and FIFOs. */
628 port->lcr &= ~UART_LCR_SBC;
629 sdio_out(port, UART_LCR, port->lcr);
630 sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
631 UART_FCR_CLEAR_RCVR |
632 UART_FCR_CLEAR_XMIT);
633 sdio_out(port, UART_FCR, 0);
634
635 sdio_disable_func(port->func);
636
637 sdio_uart_release_func(port);
638
639skip:
640 /* Free the transmit buffer page. */
641 free_page((unsigned long)port->xmit.buf);
642}
643
644static int sdio_uart_open (struct tty_struct *tty, struct file * filp)
645{
646 struct sdio_uart_port *port;
647 int ret;
648
649 port = sdio_uart_port_get(tty->index);
650 if (!port)
651 return -ENODEV;
652
653 mutex_lock(&port->open_lock);
654
655 /*
656 * Make sure not to mess up with a dead port
657 * which has not been closed yet.
658 */
659 if (tty->driver_data && tty->driver_data != port) {
660 mutex_unlock(&port->open_lock);
661 sdio_uart_port_put(port);
662 return -EBUSY;
663 }
664
665 if (!port->opened) {
666 tty->driver_data = port;
667 port->tty = tty;
668 ret = sdio_uart_startup(port);
669 if (ret) {
670 tty->driver_data = NULL;
671 port->tty = NULL;
672 mutex_unlock(&port->open_lock);
673 sdio_uart_port_put(port);
674 return ret;
675 }
676 }
677 port->opened++;
678 mutex_unlock(&port->open_lock);
679 return 0;
680}
681
682static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
683{
684 struct sdio_uart_port *port = tty->driver_data;
685
686 if (!port)
687 return;
688
689 mutex_lock(&port->open_lock);
690 BUG_ON(!port->opened);
691
692 /*
693 * This is messy. The tty layer calls us even when open()
694 * returned an error. Ignore this close request if tty->count
695 * is larger than port->count.
696 */
697 if (tty->count > port->opened) {
698 mutex_unlock(&port->open_lock);
699 return;
700 }
701
702 if (--port->opened == 0) {
703 tty->closing = 1;
704 sdio_uart_shutdown(port);
705 tty_ldisc_flush(tty);
706 port->tty = NULL;
707 tty->driver_data = NULL;
708 tty->closing = 0;
709 }
710 mutex_unlock(&port->open_lock);
711 sdio_uart_port_put(port);
712}
713
714static int sdio_uart_write(struct tty_struct * tty, const unsigned char *buf,
715 int count)
716{
717 struct sdio_uart_port *port = tty->driver_data;
718 struct circ_buf *circ = &port->xmit;
719 int c, ret = 0;
720
721 if (!port->func)
722 return -ENODEV;
723
724 spin_lock(&port->write_lock);
725 while (1) {
726 c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
727 if (count < c)
728 c = count;
729 if (c <= 0)
730 break;
731 memcpy(circ->buf + circ->head, buf, c);
732 circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
733 buf += c;
734 count -= c;
735 ret += c;
736 }
737 spin_unlock(&port->write_lock);
738
739 if ( !(port->ier & UART_IER_THRI)) {
740 int err = sdio_uart_claim_func(port);
741 if (!err) {
742 sdio_uart_start_tx(port);
743 sdio_uart_irq(port->func);
744 sdio_uart_release_func(port);
745 } else
746 ret = err;
747 }
748
749 return ret;
750}
751
752static int sdio_uart_write_room(struct tty_struct *tty)
753{
754 struct sdio_uart_port *port = tty->driver_data;
755 return port ? circ_chars_free(&port->xmit) : 0;
756}
757
758static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
759{
760 struct sdio_uart_port *port = tty->driver_data;
761 return port ? circ_chars_pending(&port->xmit) : 0;
762}
763
764static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)
765{
766 struct sdio_uart_port *port = tty->driver_data;
767
768 port->x_char = ch;
769 if (ch && !(port->ier & UART_IER_THRI)) {
770 if (sdio_uart_claim_func(port) != 0)
771 return;
772 sdio_uart_start_tx(port);
773 sdio_uart_irq(port->func);
774 sdio_uart_release_func(port);
775 }
776}
777
778static void sdio_uart_throttle(struct tty_struct *tty)
779{
780 struct sdio_uart_port *port = tty->driver_data;
781
782 if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
783 return;
784
785 if (sdio_uart_claim_func(port) != 0)
786 return;
787
788 if (I_IXOFF(tty)) {
789 port->x_char = STOP_CHAR(tty);
790 sdio_uart_start_tx(port);
791 }
792
793 if (tty->termios->c_cflag & CRTSCTS)
794 sdio_uart_clear_mctrl(port, TIOCM_RTS);
795
796 sdio_uart_irq(port->func);
797 sdio_uart_release_func(port);
798}
799
800static void sdio_uart_unthrottle(struct tty_struct *tty)
801{
802 struct sdio_uart_port *port = tty->driver_data;
803
804 if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
805 return;
806
807 if (sdio_uart_claim_func(port) != 0)
808 return;
809
810 if (I_IXOFF(tty)) {
811 if (port->x_char) {
812 port->x_char = 0;
813 } else {
814 port->x_char = START_CHAR(tty);
815 sdio_uart_start_tx(port);
816 }
817 }
818
819 if (tty->termios->c_cflag & CRTSCTS)
820 sdio_uart_set_mctrl(port, TIOCM_RTS);
821
822 sdio_uart_irq(port->func);
823 sdio_uart_release_func(port);
824}
825
826static void sdio_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
827{
828 struct sdio_uart_port *port = tty->driver_data;
829 unsigned int cflag = tty->termios->c_cflag;
830
831#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
832
833 if ((cflag ^ old_termios->c_cflag) == 0 &&
834 RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
835 return;
836
837 if (sdio_uart_claim_func(port) != 0)
838 return;
839
840 sdio_uart_change_speed(port, tty->termios, old_termios);
841
842 /* Handle transition to B0 status */
843 if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
844 sdio_uart_clear_mctrl(port, TIOCM_RTS | TIOCM_DTR);
845
846 /* Handle transition away from B0 status */
847 if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
848 unsigned int mask = TIOCM_DTR;
849 if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))
850 mask |= TIOCM_RTS;
851 sdio_uart_set_mctrl(port, mask);
852 }
853
854 /* Handle turning off CRTSCTS */
855 if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
856 tty->hw_stopped = 0;
857 sdio_uart_start_tx(port);
858 }
859
860 /* Handle turning on CRTSCTS */
861 if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
862 if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) {
863 tty->hw_stopped = 1;
864 sdio_uart_stop_tx(port);
865 }
866 }
867
868 sdio_uart_release_func(port);
869}
870
871static void sdio_uart_break_ctl(struct tty_struct *tty, int break_state)
872{
873 struct sdio_uart_port *port = tty->driver_data;
874
875 if (sdio_uart_claim_func(port) != 0)
876 return;
877
878 if (break_state == -1)
879 port->lcr |= UART_LCR_SBC;
880 else
881 port->lcr &= ~UART_LCR_SBC;
882 sdio_out(port, UART_LCR, port->lcr);
883
884 sdio_uart_release_func(port);
885}
886
887static int sdio_uart_tiocmget(struct tty_struct *tty, struct file *file)
888{
889 struct sdio_uart_port *port = tty->driver_data;
890 int result;
891
892 result = sdio_uart_claim_func(port);
893 if (!result) {
894 result = port->mctrl | sdio_uart_get_mctrl(port);
895 sdio_uart_release_func(port);
896 }
897
898 return result;
899}
900
901static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file,
902 unsigned int set, unsigned int clear)
903{
904 struct sdio_uart_port *port = tty->driver_data;
905 int result;
906
907 result =sdio_uart_claim_func(port);
908 if(!result) {
909 sdio_uart_update_mctrl(port, set, clear);
910 sdio_uart_release_func(port);
911 }
912
913 return result;
914}
915
916static const struct tty_operations sdio_uart_ops = {
917 .open = sdio_uart_open,
918 .close = sdio_uart_close,
919 .write = sdio_uart_write,
920 .write_room = sdio_uart_write_room,
921 .chars_in_buffer = sdio_uart_chars_in_buffer,
922 .send_xchar = sdio_uart_send_xchar,
923 .throttle = sdio_uart_throttle,
924 .unthrottle = sdio_uart_unthrottle,
925 .set_termios = sdio_uart_set_termios,
926 .break_ctl = sdio_uart_break_ctl,
927 .tiocmget = sdio_uart_tiocmget,
928 .tiocmset = sdio_uart_tiocmset,
929};
930
931static struct tty_driver *sdio_uart_tty_driver;
932
933static int sdio_uart_probe(struct sdio_func *func,
934 const struct sdio_device_id *id)
935{
936 struct sdio_uart_port *port;
937 int ret;
938
939 port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL);
940 if (!port)
941 return -ENOMEM;
942
943 if (func->class == SDIO_CLASS_UART) {
944 printk(KERN_WARNING "%s: need info on UART class basic setup\n",
945 sdio_func_id(func));
946 kfree(port);
947 return -ENOSYS;
948 } else if (func->class == SDIO_CLASS_GPS) {
949 /*
950 * We need tuple 0x91. It contains SUBTPL_SIOREG
951 * and SUBTPL_RCVCAPS.
952 */
953 struct sdio_func_tuple *tpl;
954 for (tpl = func->tuples; tpl; tpl = tpl->next) {
955 if (tpl->code != 0x91)
956 continue;
957 if (tpl->size < 10)
958 continue;
959 if (tpl->data[1] == 0) /* SUBTPL_SIOREG */
960 break;
961 }
962 if (!tpl) {
963 printk(KERN_WARNING
964 "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
965 sdio_func_id(func));
966 kfree(port);
967 return -EINVAL;
968 }
969 printk(KERN_DEBUG "%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",
970 sdio_func_id(func), tpl->data[2], tpl->data[3]);
971 port->regs_offset = (tpl->data[4] << 0) |
972 (tpl->data[5] << 8) |
973 (tpl->data[6] << 16);
974 printk(KERN_DEBUG "%s: regs offset = 0x%x\n",
975 sdio_func_id(func), port->regs_offset);
976 port->uartclk = tpl->data[7] * 115200;
977 if (port->uartclk == 0)
978 port->uartclk = 115200;
979 printk(KERN_DEBUG "%s: clk %d baudcode %u 4800-div %u\n",
980 sdio_func_id(func), port->uartclk,
981 tpl->data[7], tpl->data[8] | (tpl->data[9] << 8));
982 } else {
983 kfree(port);
984 return -EINVAL;
985 }
986
987 port->func = func;
988 sdio_set_drvdata(func, port);
989
990 ret = sdio_uart_add_port(port);
991 if (ret) {
992 kfree(port);
993 } else {
994 struct device *dev;
995 dev = tty_register_device(sdio_uart_tty_driver, port->index, &func->dev);
996 if (IS_ERR(dev)) {
997 sdio_uart_port_remove(port);
998 ret = PTR_ERR(dev);
999 }
1000 }
1001
1002 return ret;
1003}
1004
1005static void sdio_uart_remove(struct sdio_func *func)
1006{
1007 struct sdio_uart_port *port = sdio_get_drvdata(func);
1008
1009 tty_unregister_device(sdio_uart_tty_driver, port->index);
1010 sdio_uart_port_remove(port);
1011}
1012
1013static const struct sdio_device_id sdio_uart_ids[] = {
1014 { SDIO_DEVICE_CLASS(SDIO_CLASS_UART) },
1015 { SDIO_DEVICE_CLASS(SDIO_CLASS_GPS) },
1016 { /* end: all zeroes */ },
1017};
1018
1019MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);
1020
1021static struct sdio_driver sdio_uart_driver = {
1022 .probe = sdio_uart_probe,
1023 .remove = sdio_uart_remove,
1024 .name = "sdio_uart",
1025 .id_table = sdio_uart_ids,
1026};
1027
1028static int __init sdio_uart_init(void)
1029{
1030 int ret;
1031 struct tty_driver *tty_drv;
1032
1033 sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);
1034 if (!tty_drv)
1035 return -ENOMEM;
1036
1037 tty_drv->owner = THIS_MODULE;
1038 tty_drv->driver_name = "sdio_uart";
1039 tty_drv->name = "ttySDIO";
1040 tty_drv->major = 0; /* dynamically allocated */
1041 tty_drv->minor_start = 0;
1042 tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
1043 tty_drv->subtype = SERIAL_TYPE_NORMAL;
1044 tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
1045 tty_drv->init_termios = tty_std_termios;
1046 tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
1047 tty_set_operations(tty_drv, &sdio_uart_ops);
1048
1049 ret = tty_register_driver(tty_drv);
1050 if (ret)
1051 goto err1;
1052
1053 ret = sdio_register_driver(&sdio_uart_driver);
1054 if (ret)
1055 goto err2;
1056
1057 return 0;
1058
1059err2:
1060 tty_unregister_driver(tty_drv);
1061err1:
1062 put_tty_driver(tty_drv);
1063 return ret;
1064}
1065
1066static void __exit sdio_uart_exit(void)
1067{
1068 sdio_unregister_driver(&sdio_uart_driver);
1069 tty_unregister_driver(sdio_uart_tty_driver);
1070 put_tty_driver(sdio_uart_tty_driver);
1071}
1072
1073module_init(sdio_uart_init);
1074module_exit(sdio_uart_exit);
1075
1076MODULE_AUTHOR("Nicolas Pitre");
1077MODULE_LICENSE("GPL");