aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/card/sdio_uart.c93
1 files changed, 30 insertions, 63 deletions
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index f53755533e7e..3fab78ba8952 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -37,6 +37,7 @@
37#include <linux/gfp.h> 37#include <linux/gfp.h>
38#include <linux/tty.h> 38#include <linux/tty.h>
39#include <linux/tty_flip.h> 39#include <linux/tty_flip.h>
40#include <linux/kfifo.h>
40 41
41#include <linux/mmc/core.h> 42#include <linux/mmc/core.h>
42#include <linux/mmc/card.h> 43#include <linux/mmc/card.h>
@@ -47,19 +48,9 @@
47#define UART_NR 8 /* Number of UARTs this driver can handle */ 48#define UART_NR 8 /* Number of UARTs this driver can handle */
48 49
49 50
50#define UART_XMIT_SIZE PAGE_SIZE 51#define FIFO_SIZE PAGE_SIZE
51#define WAKEUP_CHARS 256 52#define WAKEUP_CHARS 256
52 53
53#define circ_empty(circ) ((circ)->head == (circ)->tail)
54#define circ_clear(circ) ((circ)->head = (circ)->tail = 0)
55
56#define circ_chars_pending(circ) \
57 (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
58
59#define circ_chars_free(circ) \
60 (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
61
62
63struct uart_icount { 54struct uart_icount {
64 __u32 cts; 55 __u32 cts;
65 __u32 dsr; 56 __u32 dsr;
@@ -82,7 +73,7 @@ struct sdio_uart_port {
82 struct mutex func_lock; 73 struct mutex func_lock;
83 struct task_struct *in_sdio_uart_irq; 74 struct task_struct *in_sdio_uart_irq;
84 unsigned int regs_offset; 75 unsigned int regs_offset;
85 struct circ_buf xmit; 76 struct kfifo xmit_fifo;
86 spinlock_t write_lock; 77 spinlock_t write_lock;
87 struct uart_icount icount; 78 struct uart_icount icount;
88 unsigned int uartclk; 79 unsigned int uartclk;
@@ -105,6 +96,8 @@ static int sdio_uart_add_port(struct sdio_uart_port *port)
105 kref_init(&port->kref); 96 kref_init(&port->kref);
106 mutex_init(&port->func_lock); 97 mutex_init(&port->func_lock);
107 spin_lock_init(&port->write_lock); 98 spin_lock_init(&port->write_lock);
99 if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
100 return -ENOMEM;
108 101
109 spin_lock(&sdio_uart_table_lock); 102 spin_lock(&sdio_uart_table_lock);
110 for (index = 0; index < UART_NR; index++) { 103 for (index = 0; index < UART_NR; index++) {
@@ -140,6 +133,7 @@ static void sdio_uart_port_destroy(struct kref *kref)
140{ 133{
141 struct sdio_uart_port *port = 134 struct sdio_uart_port *port =
142 container_of(kref, struct sdio_uart_port, kref); 135 container_of(kref, struct sdio_uart_port, kref);
136 kfifo_free(&port->xmit_fifo);
143 kfree(port); 137 kfree(port);
144} 138}
145 139
@@ -456,9 +450,11 @@ static void sdio_uart_receive_chars(struct sdio_uart_port *port,
456 450
457static void sdio_uart_transmit_chars(struct sdio_uart_port *port) 451static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
458{ 452{
459 struct circ_buf *xmit = &port->xmit; 453 struct kfifo *xmit = &port->xmit_fifo;
460 int count; 454 int count;
461 struct tty_struct *tty; 455 struct tty_struct *tty;
456 u8 iobuf[16];
457 int len;
462 458
463 if (port->x_char) { 459 if (port->x_char) {
464 sdio_out(port, UART_TX, port->x_char); 460 sdio_out(port, UART_TX, port->x_char);
@@ -469,27 +465,25 @@ static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
469 465
470 tty = tty_port_tty_get(&port->port); 466 tty = tty_port_tty_get(&port->port);
471 467
472 if (tty == NULL || circ_empty(xmit) || 468 if (tty == NULL || !kfifo_len(xmit) ||
473 tty->stopped || tty->hw_stopped) { 469 tty->stopped || tty->hw_stopped) {
474 sdio_uart_stop_tx(port); 470 sdio_uart_stop_tx(port);
475 tty_kref_put(tty); 471 tty_kref_put(tty);
476 return; 472 return;
477 } 473 }
478 474
479 count = 16; 475 len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock);
480 do { 476 for (count = 0; count < len; count++) {
481 sdio_out(port, UART_TX, xmit->buf[xmit->tail]); 477 sdio_out(port, UART_TX, iobuf[count]);
482 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
483 port->icount.tx++; 478 port->icount.tx++;
484 if (circ_empty(xmit)) 479 }
485 break;
486 } while (--count > 0);
487 480
488 if (circ_chars_pending(xmit) < WAKEUP_CHARS) 481 len = kfifo_len(xmit);
482 if (len < WAKEUP_CHARS) {
489 tty_wakeup(tty); 483 tty_wakeup(tty);
490 484 if (len == 0)
491 if (circ_empty(xmit)) 485 sdio_uart_stop_tx(port);
492 sdio_uart_stop_tx(port); 486 }
493 tty_kref_put(tty); 487 tty_kref_put(tty);
494} 488}
495 489
@@ -632,7 +626,6 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
632{ 626{
633 struct sdio_uart_port *port = 627 struct sdio_uart_port *port =
634 container_of(tport, struct sdio_uart_port, port); 628 container_of(tport, struct sdio_uart_port, port);
635 unsigned long page;
636 int ret; 629 int ret;
637 630
638 /* 631 /*
@@ -641,22 +634,17 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
641 */ 634 */
642 set_bit(TTY_IO_ERROR, &tty->flags); 635 set_bit(TTY_IO_ERROR, &tty->flags);
643 636
644 /* Initialise and allocate the transmit buffer. */ 637 kfifo_reset(&port->xmit_fifo);
645 page = __get_free_page(GFP_KERNEL);
646 if (!page)
647 return -ENOMEM;
648 port->xmit.buf = (unsigned char *)page;
649 circ_clear(&port->xmit);
650 638
651 ret = sdio_uart_claim_func(port); 639 ret = sdio_uart_claim_func(port);
652 if (ret) 640 if (ret)
653 goto err1; 641 return ret;
654 ret = sdio_enable_func(port->func); 642 ret = sdio_enable_func(port->func);
655 if (ret) 643 if (ret)
656 goto err2; 644 goto err1;
657 ret = sdio_claim_irq(port->func, sdio_uart_irq); 645 ret = sdio_claim_irq(port->func, sdio_uart_irq);
658 if (ret) 646 if (ret)
659 goto err3; 647 goto err2;
660 648
661 /* 649 /*
662 * Clear the FIFO buffers and disable them. 650 * Clear the FIFO buffers and disable them.
@@ -700,12 +688,10 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
700 sdio_uart_release_func(port); 688 sdio_uart_release_func(port);
701 return 0; 689 return 0;
702 690
703err3:
704 sdio_disable_func(port->func);
705err2: 691err2:
706 sdio_uart_release_func(port); 692 sdio_disable_func(port->func);
707err1: 693err1:
708 free_page((unsigned long)port->xmit.buf); 694 sdio_uart_release_func(port);
709 return ret; 695 return ret;
710} 696}
711 697
@@ -727,7 +713,7 @@ static void sdio_uart_shutdown(struct tty_port *tport)
727 713
728 ret = sdio_uart_claim_func(port); 714 ret = sdio_uart_claim_func(port);
729 if (ret) 715 if (ret)
730 goto skip; 716 return;
731 717
732 sdio_uart_stop_rx(port); 718 sdio_uart_stop_rx(port);
733 719
@@ -749,10 +735,6 @@ static void sdio_uart_shutdown(struct tty_port *tport)
749 sdio_disable_func(port->func); 735 sdio_disable_func(port->func);
750 736
751 sdio_uart_release_func(port); 737 sdio_uart_release_func(port);
752
753skip:
754 /* Free the transmit buffer page. */
755 free_page((unsigned long)port->xmit.buf);
756} 738}
757 739
758/** 740/**
@@ -822,27 +804,12 @@ static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
822 int count) 804 int count)
823{ 805{
824 struct sdio_uart_port *port = tty->driver_data; 806 struct sdio_uart_port *port = tty->driver_data;
825 struct circ_buf *circ = &port->xmit; 807 int ret;
826 int c, ret = 0;
827 808
828 if (!port->func) 809 if (!port->func)
829 return -ENODEV; 810 return -ENODEV;
830 811
831 spin_lock(&port->write_lock); 812 ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock);
832 while (1) {
833 c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
834 if (count < c)
835 c = count;
836 if (c <= 0)
837 break;
838 memcpy(circ->buf + circ->head, buf, c);
839 circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
840 buf += c;
841 count -= c;
842 ret += c;
843 }
844 spin_unlock(&port->write_lock);
845
846 if (!(port->ier & UART_IER_THRI)) { 813 if (!(port->ier & UART_IER_THRI)) {
847 int err = sdio_uart_claim_func(port); 814 int err = sdio_uart_claim_func(port);
848 if (!err) { 815 if (!err) {
@@ -859,13 +826,13 @@ static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
859static int sdio_uart_write_room(struct tty_struct *tty) 826static int sdio_uart_write_room(struct tty_struct *tty)
860{ 827{
861 struct sdio_uart_port *port = tty->driver_data; 828 struct sdio_uart_port *port = tty->driver_data;
862 return port ? circ_chars_free(&port->xmit) : 0; 829 return FIFO_SIZE - kfifo_len(&port->xmit_fifo);
863} 830}
864 831
865static int sdio_uart_chars_in_buffer(struct tty_struct *tty) 832static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
866{ 833{
867 struct sdio_uart_port *port = tty->driver_data; 834 struct sdio_uart_port *port = tty->driver_data;
868 return port ? circ_chars_pending(&port->xmit) : 0; 835 return kfifo_len(&port->xmit_fifo);
869} 836}
870 837
871static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) 838static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)