Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nicolas Pitre and committed by
Pierre Ossman
6e418a9d d1496c39

+1086
+7
drivers/mmc/card/Kconfig
··· 32 32 33 33 If unsure, say Y here. 34 34 35 + config 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 +
+2
drivers/mmc/card/Makefile
··· 9 9 obj-$(CONFIG_MMC_BLOCK) += mmc_block.o 10 10 mmc_block-objs := block.o queue.o 11 11 12 + obj-$(CONFIG_SDIO_UART) += sdio_uart.o 13 +
+1077
drivers/mmc/card/sdio_uart.c
··· 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 + 61 + struct 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 + 74 + struct 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 + 95 + static struct sdio_uart_port *sdio_uart_table[UART_NR]; 96 + static DEFINE_SPINLOCK(sdio_uart_table_lock); 97 + 98 + static 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 + 121 + static 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 + 137 + static 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 + 144 + static void sdio_uart_port_put(struct sdio_uart_port *port) 145 + { 146 + kref_put(&port->kref, sdio_uart_port_destroy); 147 + } 148 + 149 + static 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 + 182 + static 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 + 194 + static inline void sdio_uart_release_func(struct sdio_uart_port *port) 195 + { 196 + sdio_release_host(port->func); 197 + } 198 + 199 + static 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 + 206 + static 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 + 211 + static 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 + 230 + static 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 + 248 + static 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 + 262 + static 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 + 363 + static 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 + 371 + static 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 + 379 + static 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 + 386 + static 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 + 439 + static 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 + 471 + static 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 + */ 509 + static 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 + 525 + static 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 + 595 + err3: 596 + sdio_disable_func(port->func); 597 + err2: 598 + sdio_uart_release_func(port); 599 + err1: 600 + free_page((unsigned long)port->xmit.buf); 601 + return ret; 602 + } 603 + 604 + static 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 + 639 + skip: 640 + /* Free the transmit buffer page. */ 641 + free_page((unsigned long)port->xmit.buf); 642 + } 643 + 644 + static 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 + 682 + static 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 + 714 + static 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 + 752 + static 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 + 758 + static 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 + 764 + static 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 + 778 + static 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 + 800 + static 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 + 826 + static 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 + 871 + static 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 + 887 + static 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 + 901 + static 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 + 916 + static 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 + 931 + static struct tty_driver *sdio_uart_tty_driver; 932 + 933 + static 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 + 1005 + static 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 + 1013 + static 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 + 1019 + MODULE_DEVICE_TABLE(sdio, sdio_uart_ids); 1020 + 1021 + static 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 + 1028 + static 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 + 1059 + err2: 1060 + tty_unregister_driver(tty_drv); 1061 + err1: 1062 + put_tty_driver(tty_drv); 1063 + return ret; 1064 + } 1065 + 1066 + static 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 + 1073 + module_init(sdio_uart_init); 1074 + module_exit(sdio_uart_exit); 1075 + 1076 + MODULE_AUTHOR("Nicolas Pitre"); 1077 + MODULE_LICENSE("GPL");