diff options
Diffstat (limited to 'drivers/mmc')
40 files changed, 423 insertions, 569 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1f552c6e7579..cb9fbc83b090 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 26 | #include <linux/slab.h> | ||
| 26 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
| 27 | #include <linux/hdreg.h> | 28 | #include <linux/hdreg.h> |
| 28 | #include <linux/kdev_t.h> | 29 | #include <linux/kdev_t.h> |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index e7f8027165e6..445d7db2277e 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/mmc/card.h> | 13 | #include <linux/mmc/card.h> |
| 14 | #include <linux/mmc/host.h> | 14 | #include <linux/mmc/host.h> |
| 15 | #include <linux/mmc/mmc.h> | 15 | #include <linux/mmc/mmc.h> |
| 16 | #include <linux/slab.h> | ||
| 16 | 17 | ||
| 17 | #include <linux/scatterlist.h> | 18 | #include <linux/scatterlist.h> |
| 18 | 19 | ||
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 381fe032caa1..d6ded247d941 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| 12 | #include <linux/slab.h> | ||
| 12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 13 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
| 14 | #include <linux/freezer.h> | 15 | #include <linux/freezer.h> |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index f53755533e7e..a0716967b7c8 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
| @@ -34,9 +34,10 @@ | |||
| 34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
| 35 | #include <linux/serial_reg.h> | 35 | #include <linux/serial_reg.h> |
| 36 | #include <linux/circ_buf.h> | 36 | #include <linux/circ_buf.h> |
| 37 | #include <linux/gfp.h> | ||
| 38 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
| 39 | #include <linux/tty_flip.h> | 38 | #include <linux/tty_flip.h> |
| 39 | #include <linux/kfifo.h> | ||
| 40 | #include <linux/slab.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 | |||
| 63 | struct uart_icount { | 54 | struct 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 | ||
| 457 | static void sdio_uart_transmit_chars(struct sdio_uart_port *port) | 451 | static 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 | ||
| @@ -581,7 +575,7 @@ static int uart_carrier_raised(struct tty_port *tport) | |||
| 581 | struct sdio_uart_port *port = | 575 | struct sdio_uart_port *port = |
| 582 | container_of(tport, struct sdio_uart_port, port); | 576 | container_of(tport, struct sdio_uart_port, port); |
| 583 | unsigned int ret = sdio_uart_claim_func(port); | 577 | unsigned int ret = sdio_uart_claim_func(port); |
| 584 | if (ret) /* Missing hardware shoudn't block for carrier */ | 578 | if (ret) /* Missing hardware shouldn't block for carrier */ |
| 585 | return 1; | 579 | return 1; |
| 586 | ret = sdio_uart_get_mctrl(port); | 580 | ret = sdio_uart_get_mctrl(port); |
| 587 | sdio_uart_release_func(port); | 581 | sdio_uart_release_func(port); |
| @@ -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 | ||
| 703 | err3: | ||
| 704 | sdio_disable_func(port->func); | ||
| 705 | err2: | 691 | err2: |
| 706 | sdio_uart_release_func(port); | 692 | sdio_disable_func(port->func); |
| 707 | err1: | 693 | err1: |
| 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 | |||
| 753 | skip: | ||
| 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, | |||
| 859 | static int sdio_uart_write_room(struct tty_struct *tty) | 826 | static 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 | ||
| 865 | static int sdio_uart_chars_in_buffer(struct tty_struct *tty) | 832 | static 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 | ||
| 871 | static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) | 838 | static void sdio_uart_send_xchar(struct tty_struct *tty, char ch) |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index bdb165f93046..49d9dcaeca49 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/slab.h> | ||
| 16 | 17 | ||
| 17 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
| 18 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 30acd5265821..3168ebd616b2 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -1089,6 +1089,7 @@ void mmc_rescan(struct work_struct *work) | |||
| 1089 | mmc_claim_host(host); | 1089 | mmc_claim_host(host); |
| 1090 | 1090 | ||
| 1091 | mmc_power_up(host); | 1091 | mmc_power_up(host); |
| 1092 | sdio_reset(host); | ||
| 1092 | mmc_go_idle(host); | 1093 | mmc_go_idle(host); |
| 1093 | 1094 | ||
| 1094 | mmc_send_if_cond(host, host->ocr_avail); | 1095 | mmc_send_if_cond(host, host->ocr_avail); |
| @@ -1151,6 +1152,9 @@ void mmc_stop_host(struct mmc_host *host) | |||
| 1151 | cancel_delayed_work(&host->detect); | 1152 | cancel_delayed_work(&host->detect); |
| 1152 | mmc_flush_scheduled_work(); | 1153 | mmc_flush_scheduled_work(); |
| 1153 | 1154 | ||
| 1155 | /* clear pm flags now and let card drivers set them as needed */ | ||
| 1156 | host->pm_flags = 0; | ||
| 1157 | |||
| 1154 | mmc_bus_get(host); | 1158 | mmc_bus_get(host); |
| 1155 | if (host->bus_ops && !host->bus_dead) { | 1159 | if (host->bus_ops && !host->bus_dead) { |
| 1156 | if (host->bus_ops->remove) | 1160 | if (host->bus_ops->remove) |
| @@ -1273,12 +1277,13 @@ int mmc_suspend_host(struct mmc_host *host, pm_message_t state) | |||
| 1273 | mmc_claim_host(host); | 1277 | mmc_claim_host(host); |
| 1274 | mmc_detach_bus(host); | 1278 | mmc_detach_bus(host); |
| 1275 | mmc_release_host(host); | 1279 | mmc_release_host(host); |
| 1280 | host->pm_flags = 0; | ||
| 1276 | err = 0; | 1281 | err = 0; |
| 1277 | } | 1282 | } |
| 1278 | } | 1283 | } |
| 1279 | mmc_bus_put(host); | 1284 | mmc_bus_put(host); |
| 1280 | 1285 | ||
| 1281 | if (!err) | 1286 | if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER)) |
| 1282 | mmc_power_off(host); | 1287 | mmc_power_off(host); |
| 1283 | 1288 | ||
| 1284 | return err; | 1289 | return err; |
| @@ -1296,8 +1301,10 @@ int mmc_resume_host(struct mmc_host *host) | |||
| 1296 | 1301 | ||
| 1297 | mmc_bus_get(host); | 1302 | mmc_bus_get(host); |
| 1298 | if (host->bus_ops && !host->bus_dead) { | 1303 | if (host->bus_ops && !host->bus_dead) { |
| 1299 | mmc_power_up(host); | 1304 | if (!(host->pm_flags & MMC_PM_KEEP_POWER)) { |
| 1300 | mmc_select_voltage(host, host->ocr); | 1305 | mmc_power_up(host); |
| 1306 | mmc_select_voltage(host, host->ocr); | ||
| 1307 | } | ||
| 1301 | BUG_ON(!host->bus_ops->resume); | 1308 | BUG_ON(!host->bus_ops->resume); |
| 1302 | err = host->bus_ops->resume(host); | 1309 | err = host->bus_ops->resume(host); |
| 1303 | if (err) { | 1310 | if (err) { |
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 96d10f40fb23..53cb380c0987 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/debugfs.h> | 10 | #include <linux/debugfs.h> |
| 11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
| 12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
| 13 | #include <linux/slab.h> | ||
| 13 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
| 14 | 15 | ||
| 15 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index a268d12f1af0..47353909e345 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/idr.h> | 16 | #include <linux/idr.h> |
| 17 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
| 18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
| 19 | #include <linux/slab.h> | ||
| 19 | 20 | ||
| 20 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
| 21 | 22 | ||
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0eac6c814904..89f7a25b7ac1 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 14 | #include <linux/slab.h> | ||
| 14 | 15 | ||
| 15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
| 16 | #include <linux/mmc/card.h> | 17 | #include <linux/mmc/card.h> |
| @@ -225,7 +226,7 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
| 225 | mmc_card_set_blockaddr(card); | 226 | mmc_card_set_blockaddr(card); |
| 226 | } | 227 | } |
| 227 | 228 | ||
| 228 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | 229 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
| 229 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | 230 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: |
| 230 | card->ext_csd.hs_max_dtr = 52000000; | 231 | card->ext_csd.hs_max_dtr = 52000000; |
| 231 | break; | 232 | break; |
| @@ -237,7 +238,6 @@ static int mmc_read_ext_csd(struct mmc_card *card) | |||
| 237 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " | 238 | printk(KERN_WARNING "%s: card is mmc v4 but doesn't " |
| 238 | "support any high-speed modes.\n", | 239 | "support any high-speed modes.\n", |
| 239 | mmc_hostname(card->host)); | 240 | mmc_hostname(card->host)); |
| 240 | goto out; | ||
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | if (card->ext_csd.rev >= 3) { | 243 | if (card->ext_csd.rev >= 3) { |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index d2cb5c634392..326447c9ede8 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * your option) any later version. | 9 | * your option) any later version. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/slab.h> | ||
| 12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
| 13 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
| 14 | 15 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index fdd414eded09..5eac21df4809 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 14 | #include <linux/slab.h> | ||
| 14 | 15 | ||
| 15 | #include <linux/mmc/host.h> | 16 | #include <linux/mmc/host.h> |
| 16 | #include <linux/mmc/card.h> | 17 | #include <linux/mmc/card.h> |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 06b64085a355..2dd4cfe7ca17 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
| @@ -188,6 +188,40 @@ static int sdio_disable_cd(struct mmc_card *card) | |||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | /* | 190 | /* |
| 191 | * Devices that remain active during a system suspend are | ||
| 192 | * put back into 1-bit mode. | ||
| 193 | */ | ||
| 194 | static int sdio_disable_wide(struct mmc_card *card) | ||
| 195 | { | ||
| 196 | int ret; | ||
| 197 | u8 ctrl; | ||
| 198 | |||
| 199 | if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) | ||
| 200 | return 0; | ||
| 201 | |||
| 202 | if (card->cccr.low_speed && !card->cccr.wide_bus) | ||
| 203 | return 0; | ||
| 204 | |||
| 205 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl); | ||
| 206 | if (ret) | ||
| 207 | return ret; | ||
| 208 | |||
| 209 | if (!(ctrl & SDIO_BUS_WIDTH_4BIT)) | ||
| 210 | return 0; | ||
| 211 | |||
| 212 | ctrl &= ~SDIO_BUS_WIDTH_4BIT; | ||
| 213 | ctrl |= SDIO_BUS_ASYNC_INT; | ||
| 214 | |||
| 215 | ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); | ||
| 216 | if (ret) | ||
| 217 | return ret; | ||
| 218 | |||
| 219 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); | ||
| 220 | |||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 191 | * Test if the card supports high-speed mode and, if so, switch to it. | 225 | * Test if the card supports high-speed mode and, if so, switch to it. |
| 192 | */ | 226 | */ |
| 193 | static int sdio_enable_hs(struct mmc_card *card) | 227 | static int sdio_enable_hs(struct mmc_card *card) |
| @@ -224,7 +258,7 @@ static int sdio_enable_hs(struct mmc_card *card) | |||
| 224 | * we're trying to reinitialise. | 258 | * we're trying to reinitialise. |
| 225 | */ | 259 | */ |
| 226 | static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | 260 | static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, |
| 227 | struct mmc_card *oldcard) | 261 | struct mmc_card *oldcard, int powered_resume) |
| 228 | { | 262 | { |
| 229 | struct mmc_card *card; | 263 | struct mmc_card *card; |
| 230 | int err; | 264 | int err; |
| @@ -235,9 +269,11 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
| 235 | /* | 269 | /* |
| 236 | * Inform the card of the voltage | 270 | * Inform the card of the voltage |
| 237 | */ | 271 | */ |
| 238 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | 272 | if (!powered_resume) { |
| 239 | if (err) | 273 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); |
| 240 | goto err; | 274 | if (err) |
| 275 | goto err; | ||
| 276 | } | ||
| 241 | 277 | ||
| 242 | /* | 278 | /* |
| 243 | * For SPI, enable CRC as appropriate. | 279 | * For SPI, enable CRC as appropriate. |
| @@ -262,7 +298,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
| 262 | /* | 298 | /* |
| 263 | * For native busses: set card RCA and quit open drain mode. | 299 | * For native busses: set card RCA and quit open drain mode. |
| 264 | */ | 300 | */ |
| 265 | if (!mmc_host_is_spi(host)) { | 301 | if (!powered_resume && !mmc_host_is_spi(host)) { |
| 266 | err = mmc_send_relative_addr(host, &card->rca); | 302 | err = mmc_send_relative_addr(host, &card->rca); |
| 267 | if (err) | 303 | if (err) |
| 268 | goto remove; | 304 | goto remove; |
| @@ -273,7 +309,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
| 273 | /* | 309 | /* |
| 274 | * Select card, as all following commands rely on that. | 310 | * Select card, as all following commands rely on that. |
| 275 | */ | 311 | */ |
| 276 | if (!mmc_host_is_spi(host)) { | 312 | if (!powered_resume && !mmc_host_is_spi(host)) { |
| 277 | err = mmc_select_card(card); | 313 | err = mmc_select_card(card); |
| 278 | if (err) | 314 | if (err) |
| 279 | goto remove; | 315 | goto remove; |
| @@ -425,6 +461,12 @@ static int mmc_sdio_suspend(struct mmc_host *host) | |||
| 425 | } | 461 | } |
| 426 | } | 462 | } |
| 427 | 463 | ||
| 464 | if (!err && host->pm_flags & MMC_PM_KEEP_POWER) { | ||
| 465 | mmc_claim_host(host); | ||
| 466 | sdio_disable_wide(host->card); | ||
| 467 | mmc_release_host(host); | ||
| 468 | } | ||
| 469 | |||
| 428 | return err; | 470 | return err; |
| 429 | } | 471 | } |
| 430 | 472 | ||
| @@ -437,7 +479,13 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
| 437 | 479 | ||
| 438 | /* Basic card reinitialization. */ | 480 | /* Basic card reinitialization. */ |
| 439 | mmc_claim_host(host); | 481 | mmc_claim_host(host); |
| 440 | err = mmc_sdio_init_card(host, host->ocr, host->card); | 482 | err = mmc_sdio_init_card(host, host->ocr, host->card, |
| 483 | (host->pm_flags & MMC_PM_KEEP_POWER)); | ||
| 484 | if (!err) | ||
| 485 | /* We may have switched to 1-bit mode during suspend. */ | ||
| 486 | err = sdio_enable_wide(host->card); | ||
| 487 | if (!err && host->sdio_irqs) | ||
| 488 | mmc_signal_sdio_irq(host); | ||
| 441 | mmc_release_host(host); | 489 | mmc_release_host(host); |
| 442 | 490 | ||
| 443 | /* | 491 | /* |
| @@ -507,7 +555,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) | |||
| 507 | /* | 555 | /* |
| 508 | * Detect and init the card. | 556 | * Detect and init the card. |
| 509 | */ | 557 | */ |
| 510 | err = mmc_sdio_init_card(host, host->ocr, NULL); | 558 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); |
| 511 | if (err) | 559 | if (err) |
| 512 | goto err; | 560 | goto err; |
| 513 | card = host->card; | 561 | card = host->card; |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 9e060c87e64d..4a890dcb95ab 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
| 15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
| 16 | #include <linux/slab.h> | ||
| 16 | 17 | ||
| 17 | #include <linux/mmc/card.h> | 18 | #include <linux/mmc/card.h> |
| 18 | #include <linux/mmc/sdio_func.h> | 19 | #include <linux/mmc/sdio_func.h> |
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index 9538389783c1..541bdb89e0c5 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/slab.h> | ||
| 17 | 18 | ||
| 18 | #include <linux/mmc/host.h> | 19 | #include <linux/mmc/host.h> |
| 19 | #include <linux/mmc/card.h> | 20 | #include <linux/mmc/card.h> |
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index f9aa8a7deffa..ff27c8c71355 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c | |||
| @@ -189,7 +189,12 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) | |||
| 189 | { | 189 | { |
| 190 | unsigned mval = min(func->card->host->max_seg_size, | 190 | unsigned mval = min(func->card->host->max_seg_size, |
| 191 | func->card->host->max_blk_size); | 191 | func->card->host->max_blk_size); |
| 192 | mval = min(mval, func->max_blksize); | 192 | |
| 193 | if (mmc_blksz_for_byte_mode(func->card)) | ||
| 194 | mval = min(mval, func->cur_blksize); | ||
| 195 | else | ||
| 196 | mval = min(mval, func->max_blksize); | ||
| 197 | |||
| 193 | return min(mval, 512u); /* maximum size for byte mode */ | 198 | return min(mval, 512u); /* maximum size for byte mode */ |
| 194 | } | 199 | } |
| 195 | 200 | ||
| @@ -635,3 +640,52 @@ void sdio_f0_writeb(struct sdio_func *func, unsigned char b, unsigned int addr, | |||
| 635 | *err_ret = ret; | 640 | *err_ret = ret; |
| 636 | } | 641 | } |
| 637 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); | 642 | EXPORT_SYMBOL_GPL(sdio_f0_writeb); |
| 643 | |||
| 644 | /** | ||
| 645 | * sdio_get_host_pm_caps - get host power management capabilities | ||
| 646 | * @func: SDIO function attached to host | ||
| 647 | * | ||
| 648 | * Returns a capability bitmask corresponding to power management | ||
| 649 | * features supported by the host controller that the card function | ||
| 650 | * might rely upon during a system suspend. The host doesn't need | ||
| 651 | * to be claimed, nor the function active, for this information to be | ||
| 652 | * obtained. | ||
| 653 | */ | ||
| 654 | mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func) | ||
| 655 | { | ||
| 656 | BUG_ON(!func); | ||
| 657 | BUG_ON(!func->card); | ||
| 658 | |||
| 659 | return func->card->host->pm_caps; | ||
| 660 | } | ||
| 661 | EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps); | ||
| 662 | |||
| 663 | /** | ||
| 664 | * sdio_set_host_pm_flags - set wanted host power management capabilities | ||
| 665 | * @func: SDIO function attached to host | ||
| 666 | * | ||
| 667 | * Set a capability bitmask corresponding to wanted host controller | ||
| 668 | * power management features for the upcoming suspend state. | ||
| 669 | * This must be called, if needed, each time the suspend method of | ||
| 670 | * the function driver is called, and must contain only bits that | ||
| 671 | * were returned by sdio_get_host_pm_caps(). | ||
| 672 | * The host doesn't need to be claimed, nor the function active, | ||
| 673 | * for this information to be set. | ||
| 674 | */ | ||
| 675 | int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags) | ||
| 676 | { | ||
| 677 | struct mmc_host *host; | ||
| 678 | |||
| 679 | BUG_ON(!func); | ||
| 680 | BUG_ON(!func->card); | ||
| 681 | |||
| 682 | host = func->card->host; | ||
| 683 | |||
| 684 | if (flags & ~host->pm_caps) | ||
| 685 | return -EINVAL; | ||
| 686 | |||
| 687 | /* function suspend methods are serialized, hence no lock needed */ | ||
| 688 | host->pm_flags |= flags; | ||
| 689 | return 0; | ||
| 690 | } | ||
| 691 | EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags); | ||
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index 4eb7825fd1a7..dea36d9c22e6 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c | |||
| @@ -67,13 +67,13 @@ int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
| 67 | return err; | 67 | return err; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | 70 | static int mmc_io_rw_direct_host(struct mmc_host *host, int write, unsigned fn, |
| 71 | unsigned addr, u8 in, u8* out) | 71 | unsigned addr, u8 in, u8 *out) |
| 72 | { | 72 | { |
| 73 | struct mmc_command cmd; | 73 | struct mmc_command cmd; |
| 74 | int err; | 74 | int err; |
| 75 | 75 | ||
| 76 | BUG_ON(!card); | 76 | BUG_ON(!host); |
| 77 | BUG_ON(fn > 7); | 77 | BUG_ON(fn > 7); |
| 78 | 78 | ||
| 79 | /* sanity check */ | 79 | /* sanity check */ |
| @@ -90,11 +90,11 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
| 90 | cmd.arg |= in; | 90 | cmd.arg |= in; |
| 91 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; | 91 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; |
| 92 | 92 | ||
| 93 | err = mmc_wait_for_cmd(card->host, &cmd, 0); | 93 | err = mmc_wait_for_cmd(host, &cmd, 0); |
| 94 | if (err) | 94 | if (err) |
| 95 | return err; | 95 | return err; |
| 96 | 96 | ||
| 97 | if (mmc_host_is_spi(card->host)) { | 97 | if (mmc_host_is_spi(host)) { |
| 98 | /* host driver already reported errors */ | 98 | /* host driver already reported errors */ |
| 99 | } else { | 99 | } else { |
| 100 | if (cmd.resp[0] & R5_ERROR) | 100 | if (cmd.resp[0] & R5_ERROR) |
| @@ -106,7 +106,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | if (out) { | 108 | if (out) { |
| 109 | if (mmc_host_is_spi(card->host)) | 109 | if (mmc_host_is_spi(host)) |
| 110 | *out = (cmd.resp[0] >> 8) & 0xFF; | 110 | *out = (cmd.resp[0] >> 8) & 0xFF; |
| 111 | else | 111 | else |
| 112 | *out = cmd.resp[0] & 0xFF; | 112 | *out = cmd.resp[0] & 0xFF; |
| @@ -115,6 +115,13 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
| 115 | return 0; | 115 | return 0; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | ||
| 119 | unsigned addr, u8 in, u8 *out) | ||
| 120 | { | ||
| 121 | BUG_ON(!card); | ||
| 122 | return mmc_io_rw_direct_host(card->host, write, fn, addr, in, out); | ||
| 123 | } | ||
| 124 | |||
| 118 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 125 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
| 119 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) | 126 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz) |
| 120 | { | 127 | { |
| @@ -182,3 +189,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
| 182 | return 0; | 189 | return 0; |
| 183 | } | 190 | } |
| 184 | 191 | ||
| 192 | int sdio_reset(struct mmc_host *host) | ||
| 193 | { | ||
| 194 | int ret; | ||
| 195 | u8 abort; | ||
| 196 | |||
| 197 | /* SDIO Simplified Specification V2.0, 4.4 Reset for SDIO */ | ||
| 198 | |||
| 199 | ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); | ||
| 200 | if (ret) | ||
| 201 | abort = 0x08; | ||
| 202 | else | ||
| 203 | abort |= 0x08; | ||
| 204 | |||
| 205 | ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); | ||
| 206 | return ret; | ||
| 207 | } | ||
| 208 | |||
diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index e2e74b0d17d8..12a4d3ab174c 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h | |||
| @@ -17,6 +17,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, | |||
| 17 | unsigned addr, u8 in, u8* out); | 17 | unsigned addr, u8 in, u8* out); |
| 18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | 18 | int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, |
| 19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); | 19 | unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); |
| 20 | int sdio_reset(struct mmc_host *host); | ||
| 20 | 21 | ||
| 21 | #endif | 22 | #endif |
| 22 | 23 | ||
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index ce1d28884e29..2e13b94769fd 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
| @@ -69,20 +69,16 @@ config MMC_SDHCI_PCI | |||
| 69 | If unsure, say N. | 69 | If unsure, say N. |
| 70 | 70 | ||
| 71 | config MMC_RICOH_MMC | 71 | config MMC_RICOH_MMC |
| 72 | tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" | 72 | bool "Ricoh MMC Controller Disabler (EXPERIMENTAL)" |
| 73 | depends on MMC_SDHCI_PCI | 73 | depends on MMC_SDHCI_PCI |
| 74 | help | 74 | help |
| 75 | This selects the disabler for the Ricoh MMC Controller. This | 75 | This adds a pci quirk to disable Ricoh MMC Controller. This |
| 76 | proprietary controller is unnecessary because the SDHCI driver | 76 | proprietary controller is unnecessary because the SDHCI driver |
| 77 | supports MMC cards on the SD controller, but if it is not | 77 | supports MMC cards on the SD controller, but if it is not |
| 78 | disabled, it will steal the MMC cards away - rendering them | 78 | disabled, it will steal the MMC cards away - rendering them |
| 79 | useless. It is safe to select this driver even if you don't | 79 | useless. It is safe to select this even if you don't |
| 80 | have a Ricoh based card reader. | 80 | have a Ricoh based card reader. |
| 81 | 81 | ||
| 82 | |||
| 83 | To compile this driver as a module, choose M here: | ||
| 84 | the module will be called ricoh_mmc. | ||
| 85 | |||
| 86 | If unsure, say Y. | 82 | If unsure, say Y. |
| 87 | 83 | ||
| 88 | config MMC_SDHCI_OF | 84 | config MMC_SDHCI_OF |
| @@ -193,6 +189,7 @@ config MMC_AU1X | |||
| 193 | 189 | ||
| 194 | choice | 190 | choice |
| 195 | prompt "Atmel SD/MMC Driver" | 191 | prompt "Atmel SD/MMC Driver" |
| 192 | depends on AVR32 || ARCH_AT91 | ||
| 196 | default MMC_ATMELMCI if AVR32 | 193 | default MMC_ATMELMCI if AVR32 |
| 197 | help | 194 | help |
| 198 | Choose which driver to use for the Atmel MCI Silicon | 195 | Choose which driver to use for the Atmel MCI Silicon |
| @@ -368,7 +365,7 @@ config MMC_SDRICOH_CS | |||
| 368 | 365 | ||
| 369 | config MMC_TMIO | 366 | config MMC_TMIO |
| 370 | tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" | 367 | tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support" |
| 371 | depends on MFD_TMIO || MFD_ASIC3 || SUPERH | 368 | depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI |
| 372 | help | 369 | help |
| 373 | This provides support for the SD/MMC cell found in TC6393XB, | 370 | This provides support for the SD/MMC cell found in TC6393XB, |
| 374 | T7L66XB and also HTC ASIC3 | 371 | T7L66XB and also HTC ASIC3 |
| @@ -399,7 +396,7 @@ config MMC_VIA_SDMMC | |||
| 399 | 396 | ||
| 400 | config SDH_BFIN | 397 | config SDH_BFIN |
| 401 | tristate "Blackfin Secure Digital Host support" | 398 | tristate "Blackfin Secure Digital Host support" |
| 402 | depends on MMC && ((BF54x && !BF544) || (BF51x && !BF512)) | 399 | depends on (BF54x && !BF544) || (BF51x && !BF512) |
| 403 | help | 400 | help |
| 404 | If you say yes here you will get support for the Blackfin on-chip | 401 | If you say yes here you will get support for the Blackfin on-chip |
| 405 | Secure Digital Host interface. This includes support for MMC and | 402 | Secure Digital Host interface. This includes support for MMC and |
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 3d253dd4240f..f4803977dfce 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
| @@ -12,7 +12,6 @@ obj-$(CONFIG_MMC_IMX) += imxmmc.o | |||
| 12 | obj-$(CONFIG_MMC_MXC) += mxcmmc.o | 12 | obj-$(CONFIG_MMC_MXC) += mxcmmc.o |
| 13 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 13 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
| 14 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 14 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
| 15 | obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o | ||
| 16 | obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o | 15 | obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o |
| 17 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 16 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
| 18 | obj-$(CONFIG_MMC_WBSD) += wbsd.o | 17 | obj-$(CONFIG_MMC_WBSD) += wbsd.o |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 63924e0c7ea9..a6dd7da37357 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
| @@ -65,6 +65,7 @@ | |||
| 65 | #include <linux/dma-mapping.h> | 65 | #include <linux/dma-mapping.h> |
| 66 | #include <linux/clk.h> | 66 | #include <linux/clk.h> |
| 67 | #include <linux/atmel_pdc.h> | 67 | #include <linux/atmel_pdc.h> |
| 68 | #include <linux/gfp.h> | ||
| 68 | 69 | ||
| 69 | #include <linux/mmc/host.h> | 70 | #include <linux/mmc/host.h> |
| 70 | 71 | ||
| @@ -78,6 +79,17 @@ | |||
| 78 | 79 | ||
| 79 | #define DRIVER_NAME "at91_mci" | 80 | #define DRIVER_NAME "at91_mci" |
| 80 | 81 | ||
| 82 | static inline int at91mci_is_mci1rev2xx(void) | ||
| 83 | { | ||
| 84 | return ( cpu_is_at91sam9260() | ||
| 85 | || cpu_is_at91sam9263() | ||
| 86 | || cpu_is_at91cap9() | ||
| 87 | || cpu_is_at91sam9rl() | ||
| 88 | || cpu_is_at91sam9g10() | ||
| 89 | || cpu_is_at91sam9g20() | ||
| 90 | ); | ||
| 91 | } | ||
| 92 | |||
| 81 | #define FL_SENT_COMMAND (1 << 0) | 93 | #define FL_SENT_COMMAND (1 << 0) |
| 82 | #define FL_SENT_STOP (1 << 1) | 94 | #define FL_SENT_STOP (1 << 1) |
| 83 | 95 | ||
| @@ -88,6 +100,10 @@ | |||
| 88 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) | 100 | #define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg)) |
| 89 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) | 101 | #define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg)) |
| 90 | 102 | ||
| 103 | #define MCI_BLKSIZE 512 | ||
| 104 | #define MCI_MAXBLKSIZE 4095 | ||
| 105 | #define MCI_BLKATONCE 256 | ||
| 106 | #define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE) | ||
| 91 | 107 | ||
| 92 | /* | 108 | /* |
| 93 | * Low level type for this driver | 109 | * Low level type for this driver |
| @@ -200,8 +216,8 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 200 | size = data->blksz * data->blocks; | 216 | size = data->blksz * data->blocks; |
| 201 | len = data->sg_len; | 217 | len = data->sg_len; |
| 202 | 218 | ||
| 203 | /* AT91SAM926[0/3] Data Write Operation and number of bytes erratum */ | 219 | /* MCI1 rev2xx Data Write Operation and number of bytes erratum */ |
| 204 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 220 | if (at91mci_is_mci1rev2xx()) |
| 205 | if (host->total_length == 12) | 221 | if (host->total_length == 12) |
| 206 | memset(dmabuf, 0, 12); | 222 | memset(dmabuf, 0, 12); |
| 207 | 223 | ||
| @@ -227,8 +243,10 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 227 | for (index = 0; index < (amount / 4); index++) | 243 | for (index = 0; index < (amount / 4); index++) |
| 228 | *dmabuf++ = swab32(sgbuffer[index]); | 244 | *dmabuf++ = swab32(sgbuffer[index]); |
| 229 | } else { | 245 | } else { |
| 230 | memcpy(dmabuf, sgbuffer, amount); | 246 | char *tmpv = (char *)dmabuf; |
| 231 | dmabuf += amount; | 247 | memcpy(tmpv, sgbuffer, amount); |
| 248 | tmpv += amount; | ||
| 249 | dmabuf = (unsigned *)tmpv; | ||
| 232 | } | 250 | } |
| 233 | 251 | ||
| 234 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 252 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); |
| @@ -245,80 +263,14 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
| 245 | } | 263 | } |
| 246 | 264 | ||
| 247 | /* | 265 | /* |
| 248 | * Prepare a dma read | ||
| 249 | */ | ||
| 250 | static void at91_mci_pre_dma_read(struct at91mci_host *host) | ||
| 251 | { | ||
| 252 | int i; | ||
| 253 | struct scatterlist *sg; | ||
| 254 | struct mmc_command *cmd; | ||
| 255 | struct mmc_data *data; | ||
| 256 | |||
| 257 | pr_debug("pre dma read\n"); | ||
| 258 | |||
| 259 | cmd = host->cmd; | ||
| 260 | if (!cmd) { | ||
| 261 | pr_debug("no command\n"); | ||
| 262 | return; | ||
| 263 | } | ||
| 264 | |||
| 265 | data = cmd->data; | ||
| 266 | if (!data) { | ||
| 267 | pr_debug("no data\n"); | ||
| 268 | return; | ||
| 269 | } | ||
| 270 | |||
| 271 | for (i = 0; i < 2; i++) { | ||
| 272 | /* nothing left to transfer */ | ||
| 273 | if (host->transfer_index >= data->sg_len) { | ||
| 274 | pr_debug("Nothing left to transfer (index = %d)\n", host->transfer_index); | ||
| 275 | break; | ||
| 276 | } | ||
| 277 | |||
| 278 | /* Check to see if this needs filling */ | ||
| 279 | if (i == 0) { | ||
| 280 | if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) { | ||
| 281 | pr_debug("Transfer active in current\n"); | ||
| 282 | continue; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | else { | ||
| 286 | if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) { | ||
| 287 | pr_debug("Transfer active in next\n"); | ||
| 288 | continue; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | /* Setup the next transfer */ | ||
| 293 | pr_debug("Using transfer index %d\n", host->transfer_index); | ||
| 294 | |||
| 295 | sg = &data->sg[host->transfer_index++]; | ||
| 296 | pr_debug("sg = %p\n", sg); | ||
| 297 | |||
| 298 | sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE); | ||
| 299 | |||
| 300 | pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); | ||
| 301 | |||
| 302 | if (i == 0) { | ||
| 303 | at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address); | ||
| 304 | at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); | ||
| 305 | } | ||
| 306 | else { | ||
| 307 | at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address); | ||
| 308 | at91_mci_write(host, ATMEL_PDC_RNCR, (data->blksz & 0x3) ? sg->length : sg->length / 4); | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | pr_debug("pre dma read done\n"); | ||
| 313 | } | ||
| 314 | |||
| 315 | /* | ||
| 316 | * Handle after a dma read | 266 | * Handle after a dma read |
| 317 | */ | 267 | */ |
| 318 | static void at91_mci_post_dma_read(struct at91mci_host *host) | 268 | static void at91_mci_post_dma_read(struct at91mci_host *host) |
| 319 | { | 269 | { |
| 320 | struct mmc_command *cmd; | 270 | struct mmc_command *cmd; |
| 321 | struct mmc_data *data; | 271 | struct mmc_data *data; |
| 272 | unsigned int len, i, size; | ||
| 273 | unsigned *dmabuf = host->buffer; | ||
| 322 | 274 | ||
| 323 | pr_debug("post dma read\n"); | 275 | pr_debug("post dma read\n"); |
| 324 | 276 | ||
| @@ -334,42 +286,39 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
| 334 | return; | 286 | return; |
| 335 | } | 287 | } |
| 336 | 288 | ||
| 337 | while (host->in_use_index < host->transfer_index) { | 289 | size = data->blksz * data->blocks; |
| 338 | struct scatterlist *sg; | 290 | len = data->sg_len; |
| 339 | 291 | ||
| 340 | pr_debug("finishing index %d\n", host->in_use_index); | 292 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); |
| 293 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); | ||
| 341 | 294 | ||
| 342 | sg = &data->sg[host->in_use_index++]; | 295 | for (i = 0; i < len; i++) { |
| 296 | struct scatterlist *sg; | ||
| 297 | int amount; | ||
| 298 | unsigned int *sgbuffer; | ||
| 343 | 299 | ||
| 344 | pr_debug("Unmapping page %08X\n", sg->dma_address); | 300 | sg = &data->sg[i]; |
| 345 | 301 | ||
| 346 | dma_unmap_page(NULL, sg->dma_address, sg->length, DMA_FROM_DEVICE); | 302 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; |
| 303 | amount = min(size, sg->length); | ||
| 304 | size -= amount; | ||
| 347 | 305 | ||
| 348 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ | 306 | if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */ |
| 349 | unsigned int *buffer; | ||
| 350 | int index; | 307 | int index; |
| 351 | 308 | for (index = 0; index < (amount / 4); index++) | |
| 352 | /* Swap the contents of the buffer */ | 309 | sgbuffer[index] = swab32(*dmabuf++); |
| 353 | buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 310 | } else { |
| 354 | pr_debug("buffer = %p, length = %d\n", buffer, sg->length); | 311 | char *tmpv = (char *)dmabuf; |
| 355 | 312 | memcpy(sgbuffer, tmpv, amount); | |
| 356 | for (index = 0; index < (sg->length / 4); index++) | 313 | tmpv += amount; |
| 357 | buffer[index] = swab32(buffer[index]); | 314 | dmabuf = (unsigned *)tmpv; |
| 358 | |||
| 359 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | ||
| 360 | } | 315 | } |
| 361 | 316 | ||
| 362 | flush_dcache_page(sg_page(sg)); | 317 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); |
| 363 | 318 | dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount); | |
| 364 | data->bytes_xfered += sg->length; | 319 | data->bytes_xfered += amount; |
| 365 | } | 320 | if (size == 0) |
| 366 | 321 | break; | |
| 367 | /* Is there another transfer to trigger? */ | ||
| 368 | if (host->transfer_index < data->sg_len) | ||
| 369 | at91_mci_pre_dma_read(host); | ||
| 370 | else { | ||
| 371 | at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX); | ||
| 372 | at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); | ||
| 373 | } | 322 | } |
| 374 | 323 | ||
| 375 | pr_debug("post dma read done\n"); | 324 | pr_debug("post dma read done\n"); |
| @@ -461,7 +410,7 @@ static void at91_mci_enable(struct at91mci_host *host) | |||
| 461 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); | 410 | at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); |
| 462 | mr = AT91_MCI_PDCMODE | 0x34a; | 411 | mr = AT91_MCI_PDCMODE | 0x34a; |
| 463 | 412 | ||
| 464 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 413 | if (at91mci_is_mci1rev2xx()) |
| 465 | mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; | 414 | mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF; |
| 466 | 415 | ||
| 467 | at91_mci_write(host, AT91_MCI_MR, mr); | 416 | at91_mci_write(host, AT91_MCI_MR, mr); |
| @@ -602,10 +551,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
| 602 | /* | 551 | /* |
| 603 | * Handle a read | 552 | * Handle a read |
| 604 | */ | 553 | */ |
| 605 | host->buffer = NULL; | ||
| 606 | host->total_length = 0; | 554 | host->total_length = 0; |
| 607 | 555 | ||
| 608 | at91_mci_pre_dma_read(host); | 556 | at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address); |
| 557 | at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ? | ||
| 558 | (blocks * block_length) : (blocks * block_length) / 4); | ||
| 559 | at91_mci_write(host, ATMEL_PDC_RNPR, 0); | ||
| 560 | at91_mci_write(host, ATMEL_PDC_RNCR, 0); | ||
| 561 | |||
| 609 | ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; | 562 | ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */; |
| 610 | } | 563 | } |
| 611 | else { | 564 | else { |
| @@ -614,27 +567,15 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
| 614 | */ | 567 | */ |
| 615 | host->total_length = block_length * blocks; | 568 | host->total_length = block_length * blocks; |
| 616 | /* | 569 | /* |
| 617 | * AT91SAM926[0/3] Data Write Operation and | 570 | * MCI1 rev2xx Data Write Operation and |
| 618 | * number of bytes erratum | 571 | * number of bytes erratum |
| 619 | */ | 572 | */ |
| 620 | if (cpu_is_at91sam9260 () || cpu_is_at91sam9263()) | 573 | if (at91mci_is_mci1rev2xx()) |
| 621 | if (host->total_length < 12) | 574 | if (host->total_length < 12) |
| 622 | host->total_length = 12; | 575 | host->total_length = 12; |
| 623 | 576 | ||
| 624 | host->buffer = kmalloc(host->total_length, GFP_KERNEL); | ||
| 625 | if (!host->buffer) { | ||
| 626 | pr_debug("Can't alloc tx buffer\n"); | ||
| 627 | cmd->error = -ENOMEM; | ||
| 628 | mmc_request_done(host->mmc, host->request); | ||
| 629 | return; | ||
| 630 | } | ||
| 631 | |||
| 632 | at91_mci_sg_to_dma(host, data); | 577 | at91_mci_sg_to_dma(host, data); |
| 633 | 578 | ||
| 634 | host->physical_address = dma_map_single(NULL, | ||
| 635 | host->buffer, host->total_length, | ||
| 636 | DMA_TO_DEVICE); | ||
| 637 | |||
| 638 | pr_debug("Transmitting %d bytes\n", host->total_length); | 579 | pr_debug("Transmitting %d bytes\n", host->total_length); |
| 639 | 580 | ||
| 640 | at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); | 581 | at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address); |
| @@ -701,14 +642,6 @@ static void at91_mci_completed_command(struct at91mci_host *host, unsigned int s | |||
| 701 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); | 642 | cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2)); |
| 702 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); | 643 | cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3)); |
| 703 | 644 | ||
| 704 | if (host->buffer) { | ||
| 705 | dma_unmap_single(NULL, | ||
| 706 | host->physical_address, host->total_length, | ||
| 707 | DMA_TO_DEVICE); | ||
| 708 | kfree(host->buffer); | ||
| 709 | host->buffer = NULL; | ||
| 710 | } | ||
| 711 | |||
| 712 | pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", | 645 | pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n", |
| 713 | status, at91_mci_read(host, AT91_MCI_SR), | 646 | status, at91_mci_read(host, AT91_MCI_SR), |
| 714 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); | 647 | cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); |
| @@ -754,7 +687,8 @@ static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
| 754 | host->request = mrq; | 687 | host->request = mrq; |
| 755 | host->flags = 0; | 688 | host->flags = 0; |
| 756 | 689 | ||
| 757 | mod_timer(&host->timer, jiffies + HZ); | 690 | /* more than 1s timeout needed with slow SD cards */ |
| 691 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000)); | ||
| 758 | 692 | ||
| 759 | at91_mci_process_next(host); | 693 | at91_mci_process_next(host); |
| 760 | } | 694 | } |
| @@ -942,7 +876,8 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host) | |||
| 942 | pr_debug("****** Resetting SD-card bus width ******\n"); | 876 | pr_debug("****** Resetting SD-card bus width ******\n"); |
| 943 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); | 877 | at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS); |
| 944 | } | 878 | } |
| 945 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); | 879 | /* 0.5s needed because of early card detect switch firing */ |
| 880 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
| 946 | } | 881 | } |
| 947 | return IRQ_HANDLED; | 882 | return IRQ_HANDLED; |
| 948 | } | 883 | } |
| @@ -1006,24 +941,42 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
| 1006 | mmc->f_min = 375000; | 941 | mmc->f_min = 375000; |
| 1007 | mmc->f_max = 25000000; | 942 | mmc->f_max = 25000000; |
| 1008 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 943 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
| 1009 | mmc->caps = MMC_CAP_SDIO_IRQ; | 944 | mmc->caps = 0; |
| 1010 | 945 | ||
| 1011 | mmc->max_blk_size = 4095; | 946 | mmc->max_blk_size = MCI_MAXBLKSIZE; |
| 1012 | mmc->max_blk_count = mmc->max_req_size; | 947 | mmc->max_blk_count = MCI_BLKATONCE; |
| 948 | mmc->max_req_size = MCI_BUFSIZE; | ||
| 949 | mmc->max_phys_segs = MCI_BLKATONCE; | ||
| 950 | mmc->max_hw_segs = MCI_BLKATONCE; | ||
| 951 | mmc->max_seg_size = MCI_BUFSIZE; | ||
| 1013 | 952 | ||
| 1014 | host = mmc_priv(mmc); | 953 | host = mmc_priv(mmc); |
| 1015 | host->mmc = mmc; | 954 | host->mmc = mmc; |
| 1016 | host->buffer = NULL; | ||
| 1017 | host->bus_mode = 0; | 955 | host->bus_mode = 0; |
| 1018 | host->board = pdev->dev.platform_data; | 956 | host->board = pdev->dev.platform_data; |
| 1019 | if (host->board->wire4) { | 957 | if (host->board->wire4) { |
| 1020 | if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) | 958 | if (at91mci_is_mci1rev2xx()) |
| 1021 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 959 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 1022 | else | 960 | else |
| 1023 | dev_warn(&pdev->dev, "4 wire bus mode not supported" | 961 | dev_warn(&pdev->dev, "4 wire bus mode not supported" |
| 1024 | " - using 1 wire\n"); | 962 | " - using 1 wire\n"); |
| 1025 | } | 963 | } |
| 1026 | 964 | ||
| 965 | host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE, | ||
| 966 | &host->physical_address, GFP_KERNEL); | ||
| 967 | if (!host->buffer) { | ||
| 968 | ret = -ENOMEM; | ||
| 969 | dev_err(&pdev->dev, "Can't allocate transmit buffer\n"); | ||
| 970 | goto fail5; | ||
| 971 | } | ||
| 972 | |||
| 973 | /* Add SDIO capability when available */ | ||
| 974 | if (at91mci_is_mci1rev2xx()) { | ||
| 975 | /* at91mci MCI1 rev2xx sdio interrupt erratum */ | ||
| 976 | if (host->board->wire4 || !host->board->slot_b) | ||
| 977 | mmc->caps |= MMC_CAP_SDIO_IRQ; | ||
| 978 | } | ||
| 979 | |||
| 1027 | /* | 980 | /* |
| 1028 | * Reserve GPIOs ... board init code makes sure these pins are set | 981 | * Reserve GPIOs ... board init code makes sure these pins are set |
| 1029 | * up as GPIOs with the right direction (input, except for vcc) | 982 | * up as GPIOs with the right direction (input, except for vcc) |
| @@ -1032,7 +985,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
| 1032 | ret = gpio_request(host->board->det_pin, "mmc_detect"); | 985 | ret = gpio_request(host->board->det_pin, "mmc_detect"); |
| 1033 | if (ret < 0) { | 986 | if (ret < 0) { |
| 1034 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); | 987 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); |
| 1035 | goto fail5; | 988 | goto fail4b; |
| 1036 | } | 989 | } |
| 1037 | } | 990 | } |
| 1038 | if (host->board->wp_pin) { | 991 | if (host->board->wp_pin) { |
| @@ -1132,6 +1085,10 @@ fail3: | |||
| 1132 | fail4: | 1085 | fail4: |
| 1133 | if (host->board->det_pin) | 1086 | if (host->board->det_pin) |
| 1134 | gpio_free(host->board->det_pin); | 1087 | gpio_free(host->board->det_pin); |
| 1088 | fail4b: | ||
| 1089 | if (host->buffer) | ||
| 1090 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | ||
| 1091 | host->buffer, host->physical_address); | ||
| 1135 | fail5: | 1092 | fail5: |
| 1136 | mmc_free_host(mmc); | 1093 | mmc_free_host(mmc); |
| 1137 | fail6: | 1094 | fail6: |
| @@ -1154,6 +1111,10 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
| 1154 | 1111 | ||
| 1155 | host = mmc_priv(mmc); | 1112 | host = mmc_priv(mmc); |
| 1156 | 1113 | ||
| 1114 | if (host->buffer) | ||
| 1115 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | ||
| 1116 | host->buffer, host->physical_address); | ||
| 1117 | |||
| 1157 | if (host->board->det_pin) { | 1118 | if (host->board->det_pin) { |
| 1158 | if (device_can_wakeup(&pdev->dev)) | 1119 | if (device_can_wakeup(&pdev->dev)) |
| 1159 | free_irq(gpio_to_irq(host->board->det_pin), host); | 1120 | free_irq(gpio_to_irq(host->board->det_pin), host); |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8072128e933b..88be37d9e9a5 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
| 24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
| 25 | #include <linux/slab.h> | ||
| 25 | #include <linux/stat.h> | 26 | #include <linux/stat.h> |
| 26 | 27 | ||
| 27 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 57b21198828f..f5834449400e 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
| 42 | #include <linux/leds.h> | 42 | #include <linux/leds.h> |
| 43 | #include <linux/mmc/host.h> | 43 | #include <linux/mmc/host.h> |
| 44 | #include <linux/slab.h> | ||
| 44 | 45 | ||
| 45 | #include <asm/io.h> | 46 | #include <asm/io.h> |
| 46 | #include <asm/mach-au1x00/au1000.h> | 47 | #include <asm/mach-au1x00/au1000.h> |
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 3343a57355cc..6919e844072c 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
| 18 | #include <linux/mmc/host.h> | 18 | #include <linux/mmc/host.h> |
| 19 | #include <linux/proc_fs.h> | 19 | #include <linux/proc_fs.h> |
| 20 | #include <linux/gfp.h> | ||
| 20 | 21 | ||
| 21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
| 22 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
| @@ -115,7 +116,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data) | |||
| 115 | unsigned int length; | 116 | unsigned int length; |
| 116 | unsigned int data_ctl; | 117 | unsigned int data_ctl; |
| 117 | unsigned int dma_cfg; | 118 | unsigned int dma_cfg; |
| 118 | struct scatterlist *sg; | 119 | unsigned int cycle_ns, timeout; |
| 119 | 120 | ||
| 120 | dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags); | 121 | dev_dbg(mmc_dev(host->mmc), "%s enter flags: 0x%x\n", __func__, data->flags); |
| 121 | host->data = data; | 122 | host->data = data; |
| @@ -136,8 +137,11 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data) | |||
| 136 | data_ctl |= ((ffs(data->blksz) - 1) << 4); | 137 | data_ctl |= ((ffs(data->blksz) - 1) << 4); |
| 137 | 138 | ||
| 138 | bfin_write_SDH_DATA_CTL(data_ctl); | 139 | bfin_write_SDH_DATA_CTL(data_ctl); |
| 139 | 140 | /* the time of a host clock period in ns */ | |
| 140 | bfin_write_SDH_DATA_TIMER(0xFFFF); | 141 | cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1))); |
| 142 | timeout = data->timeout_ns / cycle_ns; | ||
| 143 | timeout += data->timeout_clks; | ||
| 144 | bfin_write_SDH_DATA_TIMER(timeout); | ||
| 141 | SSYNC(); | 145 | SSYNC(); |
| 142 | 146 | ||
| 143 | if (data->flags & MMC_DATA_READ) { | 147 | if (data->flags & MMC_DATA_READ) { |
| @@ -151,6 +155,7 @@ static int sdh_setup_data(struct sdh_host *host, struct mmc_data *data) | |||
| 151 | #if defined(CONFIG_BF54x) | 155 | #if defined(CONFIG_BF54x) |
| 152 | dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN; | 156 | dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN; |
| 153 | { | 157 | { |
| 158 | struct scatterlist *sg; | ||
| 154 | int i; | 159 | int i; |
| 155 | for_each_sg(data->sg, sg, host->dma_len, i) { | 160 | for_each_sg(data->sg, sg, host->dma_len, i) { |
| 156 | host->sg_cpu[i].start_addr = sg_dma_address(sg); | 161 | host->sg_cpu[i].start_addr = sg_dma_address(sg); |
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index 4e72964a7b43..92a324f7417c 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | */ | 9 | */ |
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
| 14 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 15 | #include "cb710-mmc.h" | 14 | #include "cb710-mmc.h" |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index dd45e7c3517e..3bd0ba294e9d 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
| @@ -73,6 +73,7 @@ | |||
| 73 | /* DAVINCI_MMCCTL definitions */ | 73 | /* DAVINCI_MMCCTL definitions */ |
| 74 | #define MMCCTL_DATRST (1 << 0) | 74 | #define MMCCTL_DATRST (1 << 0) |
| 75 | #define MMCCTL_CMDRST (1 << 1) | 75 | #define MMCCTL_CMDRST (1 << 1) |
| 76 | #define MMCCTL_WIDTH_8_BIT (1 << 8) | ||
| 76 | #define MMCCTL_WIDTH_4_BIT (1 << 2) | 77 | #define MMCCTL_WIDTH_4_BIT (1 << 2) |
| 77 | #define MMCCTL_DATEG_DISABLED (0 << 6) | 78 | #define MMCCTL_DATEG_DISABLED (0 << 6) |
| 78 | #define MMCCTL_DATEG_RISING (1 << 6) | 79 | #define MMCCTL_DATEG_RISING (1 << 6) |
| @@ -791,22 +792,42 @@ static void calculate_clk_divider(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 791 | 792 | ||
| 792 | static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 793 | static void mmc_davinci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 793 | { | 794 | { |
| 794 | unsigned int mmc_pclk = 0; | ||
| 795 | struct mmc_davinci_host *host = mmc_priv(mmc); | 795 | struct mmc_davinci_host *host = mmc_priv(mmc); |
| 796 | 796 | ||
| 797 | mmc_pclk = host->mmc_input_clk; | ||
| 798 | dev_dbg(mmc_dev(host->mmc), | 797 | dev_dbg(mmc_dev(host->mmc), |
| 799 | "clock %dHz busmode %d powermode %d Vdd %04x\n", | 798 | "clock %dHz busmode %d powermode %d Vdd %04x\n", |
| 800 | ios->clock, ios->bus_mode, ios->power_mode, | 799 | ios->clock, ios->bus_mode, ios->power_mode, |
| 801 | ios->vdd); | 800 | ios->vdd); |
| 802 | if (ios->bus_width == MMC_BUS_WIDTH_4) { | 801 | |
| 803 | dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n"); | 802 | switch (ios->bus_width) { |
| 804 | writel(readl(host->base + DAVINCI_MMCCTL) | MMCCTL_WIDTH_4_BIT, | 803 | case MMC_BUS_WIDTH_8: |
| 805 | host->base + DAVINCI_MMCCTL); | 804 | dev_dbg(mmc_dev(host->mmc), "Enabling 8 bit mode\n"); |
| 806 | } else { | 805 | writel((readl(host->base + DAVINCI_MMCCTL) & |
| 807 | dev_dbg(mmc_dev(host->mmc), "Disabling 4 bit mode\n"); | 806 | ~MMCCTL_WIDTH_4_BIT) | MMCCTL_WIDTH_8_BIT, |
| 808 | writel(readl(host->base + DAVINCI_MMCCTL) & ~MMCCTL_WIDTH_4_BIT, | ||
| 809 | host->base + DAVINCI_MMCCTL); | 807 | host->base + DAVINCI_MMCCTL); |
| 808 | break; | ||
| 809 | case MMC_BUS_WIDTH_4: | ||
| 810 | dev_dbg(mmc_dev(host->mmc), "Enabling 4 bit mode\n"); | ||
| 811 | if (host->version == MMC_CTLR_VERSION_2) | ||
| 812 | writel((readl(host->base + DAVINCI_MMCCTL) & | ||
| 813 | ~MMCCTL_WIDTH_8_BIT) | MMCCTL_WIDTH_4_BIT, | ||
| 814 | host->base + DAVINCI_MMCCTL); | ||
| 815 | else | ||
| 816 | writel(readl(host->base + DAVINCI_MMCCTL) | | ||
| 817 | MMCCTL_WIDTH_4_BIT, | ||
| 818 | host->base + DAVINCI_MMCCTL); | ||
| 819 | break; | ||
| 820 | case MMC_BUS_WIDTH_1: | ||
| 821 | dev_dbg(mmc_dev(host->mmc), "Enabling 1 bit mode\n"); | ||
| 822 | if (host->version == MMC_CTLR_VERSION_2) | ||
| 823 | writel(readl(host->base + DAVINCI_MMCCTL) & | ||
| 824 | ~(MMCCTL_WIDTH_8_BIT | MMCCTL_WIDTH_4_BIT), | ||
| 825 | host->base + DAVINCI_MMCCTL); | ||
| 826 | else | ||
| 827 | writel(readl(host->base + DAVINCI_MMCCTL) & | ||
| 828 | ~MMCCTL_WIDTH_4_BIT, | ||
| 829 | host->base + DAVINCI_MMCCTL); | ||
| 830 | break; | ||
| 810 | } | 831 | } |
| 811 | 832 | ||
| 812 | calculate_clk_divider(mmc, ios); | 833 | calculate_clk_divider(mmc, ios); |
| @@ -1189,10 +1210,14 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) | |||
| 1189 | 1210 | ||
| 1190 | /* REVISIT: someday, support IRQ-driven card detection. */ | 1211 | /* REVISIT: someday, support IRQ-driven card detection. */ |
| 1191 | mmc->caps |= MMC_CAP_NEEDS_POLL; | 1212 | mmc->caps |= MMC_CAP_NEEDS_POLL; |
| 1213 | mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | ||
| 1192 | 1214 | ||
| 1193 | if (!pdata || pdata->wires == 4 || pdata->wires == 0) | 1215 | if (pdata && (pdata->wires == 4 || pdata->wires == 0)) |
| 1194 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 1216 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 1195 | 1217 | ||
| 1218 | if (pdata && (pdata->wires == 8)) | ||
| 1219 | mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA); | ||
| 1220 | |||
| 1196 | host->version = pdata->version; | 1221 | host->version = pdata->version; |
| 1197 | 1222 | ||
| 1198 | mmc->ops = &mmc_davinci_ops; | 1223 | mmc->ops = &mmc_davinci_ops; |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index d55fe4fb7935..ad847a24a675 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | */ | 26 | */ |
| 27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
| 29 | #include <linux/slab.h> | ||
| 29 | #include <linux/bio.h> | 30 | #include <linux/bio.h> |
| 30 | #include <linux/dma-mapping.h> | 31 | #include <linux/dma-mapping.h> |
| 31 | #include <linux/crc7.h> | 32 | #include <linux/crc7.h> |
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index b31946e0b4ca..04ae884383f6 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
| 34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
| 35 | #include <linux/memory.h> | 35 | #include <linux/memory.h> |
| 36 | #include <linux/gfp.h> | ||
| 36 | 37 | ||
| 37 | #include <asm/cacheflush.h> | 38 | #include <asm/cacheflush.h> |
| 38 | #include <asm/div64.h> | 39 | #include <asm/div64.h> |
| @@ -1250,9 +1251,7 @@ msmsdcc_resume(struct platform_device *dev) | |||
| 1250 | 1251 | ||
| 1251 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) | 1252 | if (mmc->card && mmc->card->type != MMC_TYPE_SDIO) |
| 1252 | mmc_resume_host(mmc); | 1253 | mmc_resume_host(mmc); |
| 1253 | if (host->stat_irq) | 1254 | if (host->stat_irq) |
| 1254 | enable_irq(host->stat_irq); | ||
| 1255 | else if (host->stat_irq) | ||
| 1256 | enable_irq(host->stat_irq); | 1255 | enable_irq(host->stat_irq); |
| 1257 | } | 1256 | } |
| 1258 | return 0; | 1257 | return 0; |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 60a2b69e54f5..2df90412abb5 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 | 4 | * This is a driver for the SDHC controller found in Freescale MX2/MX3 |
| 5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). | 5 | * SoCs. It is basically the same hardware as found on MX1 (imxmmc.c). |
| 6 | * Unlike the hardware found on MX1, this hardware just works and does | 6 | * Unlike the hardware found on MX1, this hardware just works and does |
| 7 | * not need all the quirks found in imxmmc.c, hence the seperate driver. | 7 | * not need all the quirks found in imxmmc.c, hence the separate driver. |
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | 9 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |
| 10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> | 10 | * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com> |
| @@ -708,7 +708,7 @@ static int mxcmci_probe(struct platform_device *pdev) | |||
| 708 | mmc->max_blk_size = 2048; | 708 | mmc->max_blk_size = 2048; |
| 709 | mmc->max_blk_count = 65535; | 709 | mmc->max_blk_count = 65535; |
| 710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; | 710 | mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; |
| 711 | mmc->max_seg_size = mmc->max_seg_size; | 711 | mmc->max_seg_size = mmc->max_req_size; |
| 712 | 712 | ||
| 713 | host = mmc_priv(mmc); | 713 | host = mmc_priv(mmc); |
| 714 | host->base = ioremap(r->start, resource_size(r)); | 714 | host->base = ioremap(r->start, resource_size(r)); |
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index 0c7a63c1f12f..bb6cc54b558e 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 17 | #include <linux/slab.h> | ||
| 17 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
| 18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 19 | #include <linux/of_gpio.h> | 20 | #include <linux/of_gpio.h> |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index c6d7e8ecadbf..84d280406341 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
| 27 | #include <linux/scatterlist.h> | 27 | #include <linux/scatterlist.h> |
| 28 | #include <linux/i2c/tps65010.h> | 28 | #include <linux/i2c/tps65010.h> |
| 29 | #include <linux/slab.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
| 31 | #include <asm/irq.h> | 32 | #include <asm/irq.h> |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 83f0affadcae..e9caf694c59e 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
| @@ -1179,15 +1179,10 @@ static void omap_hsmmc_detect(struct work_struct *work) | |||
| 1179 | carddetect = -ENOSYS; | 1179 | carddetect = -ENOSYS; |
| 1180 | } | 1180 | } |
| 1181 | 1181 | ||
| 1182 | if (carddetect) { | 1182 | if (carddetect) |
| 1183 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); | 1183 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); |
| 1184 | } else { | 1184 | else |
| 1185 | mmc_host_enable(host->mmc); | ||
| 1186 | omap_hsmmc_reset_controller_fsm(host, SRD); | ||
| 1187 | mmc_host_lazy_disable(host->mmc); | ||
| 1188 | |||
| 1189 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); | 1185 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); |
| 1190 | } | ||
| 1191 | } | 1186 | } |
| 1192 | 1187 | ||
| 1193 | /* | 1188 | /* |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index 0d783f3e79ed..0ed48959b590 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
| 30 | #include <linux/regulator/consumer.h> | 30 | #include <linux/regulator/consumer.h> |
| 31 | #include <linux/gpio.h> | 31 | #include <linux/gpio.h> |
| 32 | #include <linux/gfp.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/sizes.h> | 34 | #include <asm/sizes.h> |
| 34 | 35 | ||
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c deleted file mode 100644 index f62790513322..000000000000 --- a/drivers/mmc/host/ricoh_mmc.c +++ /dev/null | |||
| @@ -1,262 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ricoh_mmc.c - Dummy driver to disable the Rioch MMC controller. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007 Philip Langdale, All Rights Reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 9 | * your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This is a conceptually ridiculous driver, but it is required by the way | ||
| 14 | * the Ricoh multi-function chips (R5CXXX) work. These chips implement | ||
| 15 | * the four main memory card controllers (SD, MMC, MS, xD) and one or both | ||
| 16 | * of cardbus or firewire. It happens that they implement SD and MMC | ||
| 17 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
| 18 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
| 19 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
| 20 | * them. To get around this, we must disable the useless MMC controller. | ||
| 21 | * At that point, the SDHCI controller will start seeing them. As a bonus, | ||
| 22 | * a detection event occurs immediately, even if the MMC card is already | ||
| 23 | * in the reader. | ||
| 24 | * | ||
| 25 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
| 26 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
| 27 | * or the firewire controller, depending on the particular chip in question. As | ||
| 28 | * such, it makes what this driver has to do unavoidably ugly. Such is life. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #include <linux/pci.h> | ||
| 32 | |||
| 33 | #define DRIVER_NAME "ricoh-mmc" | ||
| 34 | |||
| 35 | static const struct pci_device_id pci_ids[] __devinitdata = { | ||
| 36 | { | ||
| 37 | .vendor = PCI_VENDOR_ID_RICOH, | ||
| 38 | .device = PCI_DEVICE_ID_RICOH_R5C843, | ||
| 39 | .subvendor = PCI_ANY_ID, | ||
| 40 | .subdevice = PCI_ANY_ID, | ||
| 41 | }, | ||
| 42 | { /* end: all zeroes */ }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
| 46 | |||
| 47 | static int ricoh_mmc_disable(struct pci_dev *fw_dev) | ||
| 48 | { | ||
| 49 | u8 write_enable; | ||
| 50 | u8 write_target; | ||
| 51 | u8 disable; | ||
| 52 | |||
| 53 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
| 54 | /* via RL5C476 */ | ||
| 55 | |||
| 56 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
| 57 | if (disable & 0x02) { | ||
| 58 | printk(KERN_INFO DRIVER_NAME | ||
| 59 | ": Controller already disabled. " \ | ||
| 60 | "Nothing to do.\n"); | ||
| 61 | return -ENODEV; | ||
| 62 | } | ||
| 63 | |||
| 64 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
| 65 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
| 66 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
| 67 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
| 68 | pci_write_config_byte(fw_dev, 0xB7, disable | 0x02); | ||
| 69 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
| 70 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
| 71 | } else { | ||
| 72 | /* via R5C832 */ | ||
| 73 | |||
| 74 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
| 75 | if (disable & 0x02) { | ||
| 76 | printk(KERN_INFO DRIVER_NAME | ||
| 77 | ": Controller already disabled. " \ | ||
| 78 | "Nothing to do.\n"); | ||
| 79 | return -ENODEV; | ||
| 80 | } | ||
| 81 | |||
| 82 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
| 83 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
| 84 | pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); | ||
| 85 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
| 86 | } | ||
| 87 | |||
| 88 | printk(KERN_INFO DRIVER_NAME | ||
| 89 | ": Controller is now disabled.\n"); | ||
| 90 | |||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static int ricoh_mmc_enable(struct pci_dev *fw_dev) | ||
| 95 | { | ||
| 96 | u8 write_enable; | ||
| 97 | u8 write_target; | ||
| 98 | u8 disable; | ||
| 99 | |||
| 100 | if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) { | ||
| 101 | /* via RL5C476 */ | ||
| 102 | |||
| 103 | pci_read_config_byte(fw_dev, 0x8E, &write_enable); | ||
| 104 | pci_write_config_byte(fw_dev, 0x8E, 0xAA); | ||
| 105 | pci_read_config_byte(fw_dev, 0x8D, &write_target); | ||
| 106 | pci_write_config_byte(fw_dev, 0x8D, 0xB7); | ||
| 107 | pci_read_config_byte(fw_dev, 0xB7, &disable); | ||
| 108 | pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02); | ||
| 109 | pci_write_config_byte(fw_dev, 0x8E, write_enable); | ||
| 110 | pci_write_config_byte(fw_dev, 0x8D, write_target); | ||
| 111 | } else { | ||
| 112 | /* via R5C832 */ | ||
| 113 | |||
| 114 | pci_read_config_byte(fw_dev, 0xCA, &write_enable); | ||
| 115 | pci_read_config_byte(fw_dev, 0xCB, &disable); | ||
| 116 | pci_write_config_byte(fw_dev, 0xCA, 0x57); | ||
| 117 | pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); | ||
| 118 | pci_write_config_byte(fw_dev, 0xCA, write_enable); | ||
| 119 | } | ||
| 120 | |||
| 121 | printk(KERN_INFO DRIVER_NAME | ||
| 122 | ": Controller is now re-enabled.\n"); | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static int __devinit ricoh_mmc_probe(struct pci_dev *pdev, | ||
| 128 | const struct pci_device_id *ent) | ||
| 129 | { | ||
| 130 | u8 rev; | ||
| 131 | u8 ctrlfound = 0; | ||
| 132 | |||
| 133 | struct pci_dev *fw_dev = NULL; | ||
| 134 | |||
| 135 | BUG_ON(pdev == NULL); | ||
| 136 | BUG_ON(ent == NULL); | ||
| 137 | |||
| 138 | pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev); | ||
| 139 | |||
| 140 | printk(KERN_INFO DRIVER_NAME | ||
| 141 | ": Ricoh MMC controller found at %s [%04x:%04x] (rev %x)\n", | ||
| 142 | pci_name(pdev), (int)pdev->vendor, (int)pdev->device, | ||
| 143 | (int)rev); | ||
| 144 | |||
| 145 | while ((fw_dev = | ||
| 146 | pci_get_device(PCI_VENDOR_ID_RICOH, | ||
| 147 | PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { | ||
| 148 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
| 149 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
| 150 | pdev->bus == fw_dev->bus) { | ||
| 151 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
| 152 | return -ENODEV; | ||
| 153 | |||
| 154 | pci_set_drvdata(pdev, fw_dev); | ||
| 155 | |||
| 156 | ++ctrlfound; | ||
| 157 | break; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | fw_dev = NULL; | ||
| 162 | |||
| 163 | while (!ctrlfound && | ||
| 164 | (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, | ||
| 165 | PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { | ||
| 166 | if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && | ||
| 167 | PCI_FUNC(fw_dev->devfn) == 0 && | ||
| 168 | pdev->bus == fw_dev->bus) { | ||
| 169 | if (ricoh_mmc_disable(fw_dev) != 0) | ||
| 170 | return -ENODEV; | ||
| 171 | |||
| 172 | pci_set_drvdata(pdev, fw_dev); | ||
| 173 | |||
| 174 | ++ctrlfound; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | if (!ctrlfound) { | ||
| 179 | printk(KERN_WARNING DRIVER_NAME | ||
| 180 | ": Main Ricoh function not found. Cannot disable controller.\n"); | ||
| 181 | return -ENODEV; | ||
| 182 | } | ||
| 183 | |||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | |||
| 187 | static void __devexit ricoh_mmc_remove(struct pci_dev *pdev) | ||
| 188 | { | ||
| 189 | struct pci_dev *fw_dev = NULL; | ||
| 190 | |||
| 191 | fw_dev = pci_get_drvdata(pdev); | ||
| 192 | BUG_ON(fw_dev == NULL); | ||
| 193 | |||
| 194 | ricoh_mmc_enable(fw_dev); | ||
| 195 | |||
| 196 | pci_set_drvdata(pdev, NULL); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int ricoh_mmc_suspend_late(struct pci_dev *pdev, pm_message_t state) | ||
| 200 | { | ||
| 201 | struct pci_dev *fw_dev = NULL; | ||
| 202 | |||
| 203 | fw_dev = pci_get_drvdata(pdev); | ||
| 204 | BUG_ON(fw_dev == NULL); | ||
| 205 | |||
| 206 | printk(KERN_INFO DRIVER_NAME ": Suspending.\n"); | ||
| 207 | |||
| 208 | ricoh_mmc_enable(fw_dev); | ||
| 209 | |||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | |||
| 213 | static int ricoh_mmc_resume_early(struct pci_dev *pdev) | ||
| 214 | { | ||
| 215 | struct pci_dev *fw_dev = NULL; | ||
| 216 | |||
| 217 | fw_dev = pci_get_drvdata(pdev); | ||
| 218 | BUG_ON(fw_dev == NULL); | ||
| 219 | |||
| 220 | printk(KERN_INFO DRIVER_NAME ": Resuming.\n"); | ||
| 221 | |||
| 222 | ricoh_mmc_disable(fw_dev); | ||
| 223 | |||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | static struct pci_driver ricoh_mmc_driver = { | ||
| 228 | .name = DRIVER_NAME, | ||
| 229 | .id_table = pci_ids, | ||
| 230 | .probe = ricoh_mmc_probe, | ||
| 231 | .remove = __devexit_p(ricoh_mmc_remove), | ||
| 232 | .suspend_late = ricoh_mmc_suspend_late, | ||
| 233 | .resume_early = ricoh_mmc_resume_early, | ||
| 234 | }; | ||
| 235 | |||
| 236 | /*****************************************************************************\ | ||
| 237 | * * | ||
| 238 | * Driver init/exit * | ||
| 239 | * * | ||
| 240 | \*****************************************************************************/ | ||
| 241 | |||
| 242 | static int __init ricoh_mmc_drv_init(void) | ||
| 243 | { | ||
| 244 | printk(KERN_INFO DRIVER_NAME | ||
| 245 | ": Ricoh MMC Controller disabling driver\n"); | ||
| 246 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Philip Langdale\n"); | ||
| 247 | |||
| 248 | return pci_register_driver(&ricoh_mmc_driver); | ||
| 249 | } | ||
| 250 | |||
| 251 | static void __exit ricoh_mmc_drv_exit(void) | ||
| 252 | { | ||
| 253 | pci_unregister_driver(&ricoh_mmc_driver); | ||
| 254 | } | ||
| 255 | |||
| 256 | module_init(ricoh_mmc_drv_init); | ||
| 257 | module_exit(ricoh_mmc_drv_exit); | ||
| 258 | |||
| 259 | MODULE_AUTHOR("Philip Langdale <philipl@alumni.utexas.net>"); | ||
| 260 | MODULE_DESCRIPTION("Ricoh MMC Controller disabling driver"); | ||
| 261 | MODULE_LICENSE("GPL"); | ||
| 262 | |||
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index d96e1abf2d64..2fdf7689ae6c 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
| @@ -1179,7 +1179,7 @@ static int s3cmci_card_present(struct mmc_host *mmc) | |||
| 1179 | struct s3c24xx_mci_pdata *pdata = host->pdata; | 1179 | struct s3c24xx_mci_pdata *pdata = host->pdata; |
| 1180 | int ret; | 1180 | int ret; |
| 1181 | 1181 | ||
| 1182 | if (pdata->gpio_detect == 0) | 1182 | if (pdata->no_detect) |
| 1183 | return -ENOSYS; | 1183 | return -ENOSYS; |
| 1184 | 1184 | ||
| 1185 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; | 1185 | ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; |
| @@ -1360,6 +1360,8 @@ static struct mmc_host_ops s3cmci_ops = { | |||
| 1360 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { | 1360 | static struct s3c24xx_mci_pdata s3cmci_def_pdata = { |
| 1361 | /* This is currently here to avoid a number of if (host->pdata) | 1361 | /* This is currently here to avoid a number of if (host->pdata) |
| 1362 | * checks. Any zero fields to ensure reasonable defaults are picked. */ | 1362 | * checks. Any zero fields to ensure reasonable defaults are picked. */ |
| 1363 | .no_wprotect = 1, | ||
| 1364 | .no_detect = 1, | ||
| 1363 | }; | 1365 | }; |
| 1364 | 1366 | ||
| 1365 | #ifdef CONFIG_CPU_FREQ | 1367 | #ifdef CONFIG_CPU_FREQ |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 5c3a1767770a..6701af629c30 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/highmem.h> | 16 | #include <linux/highmem.h> |
| 17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
| 18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
| 19 | #include <linux/slab.h> | ||
| 19 | 20 | ||
| 20 | #include <linux/mmc/host.h> | 21 | #include <linux/mmc/host.h> |
| 21 | 22 | ||
| @@ -80,9 +81,6 @@ struct sdhci_pci_chip { | |||
| 80 | 81 | ||
| 81 | static int ricoh_probe(struct sdhci_pci_chip *chip) | 82 | static int ricoh_probe(struct sdhci_pci_chip *chip) |
| 82 | { | 83 | { |
| 83 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) | ||
| 84 | chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET; | ||
| 85 | |||
| 86 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || | 84 | if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || |
| 87 | chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) | 85 | chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) |
| 88 | chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; | 86 | chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; |
| @@ -92,7 +90,9 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) | |||
| 92 | 90 | ||
| 93 | static const struct sdhci_pci_fixes sdhci_ricoh = { | 91 | static const struct sdhci_pci_fixes sdhci_ricoh = { |
| 94 | .probe = ricoh_probe, | 92 | .probe = ricoh_probe, |
| 95 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, | 93 | .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | |
| 94 | SDHCI_QUIRK_FORCE_DMA | | ||
| 95 | SDHCI_QUIRK_CLOCK_BEFORE_RESET, | ||
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { | 98 | static const struct sdhci_pci_fixes sdhci_ene_712 = { |
| @@ -501,6 +501,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
| 501 | { | 501 | { |
| 502 | struct sdhci_pci_chip *chip; | 502 | struct sdhci_pci_chip *chip; |
| 503 | struct sdhci_pci_slot *slot; | 503 | struct sdhci_pci_slot *slot; |
| 504 | mmc_pm_flag_t pm_flags = 0; | ||
| 504 | int i, ret; | 505 | int i, ret; |
| 505 | 506 | ||
| 506 | chip = pci_get_drvdata(pdev); | 507 | chip = pci_get_drvdata(pdev); |
| @@ -519,6 +520,8 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
| 519 | sdhci_resume_host(chip->slots[i]->host); | 520 | sdhci_resume_host(chip->slots[i]->host); |
| 520 | return ret; | 521 | return ret; |
| 521 | } | 522 | } |
| 523 | |||
| 524 | pm_flags |= slot->host->mmc->pm_flags; | ||
| 522 | } | 525 | } |
| 523 | 526 | ||
| 524 | if (chip->fixes && chip->fixes->suspend) { | 527 | if (chip->fixes && chip->fixes->suspend) { |
| @@ -531,9 +534,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) | |||
| 531 | } | 534 | } |
| 532 | 535 | ||
| 533 | pci_save_state(pdev); | 536 | pci_save_state(pdev); |
| 534 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 537 | if (pm_flags & MMC_PM_KEEP_POWER) { |
| 535 | pci_disable_device(pdev); | 538 | if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) |
| 536 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 539 | pci_enable_wake(pdev, PCI_D3hot, 1); |
| 540 | pci_set_power_state(pdev, PCI_D3hot); | ||
| 541 | } else { | ||
| 542 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
| 543 | pci_disable_device(pdev); | ||
| 544 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 545 | } | ||
| 537 | 546 | ||
| 538 | return 0; | 547 | return 0; |
| 539 | } | 548 | } |
| @@ -653,6 +662,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
| 653 | goto unmap; | 662 | goto unmap; |
| 654 | } | 663 | } |
| 655 | 664 | ||
| 665 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; | ||
| 666 | |||
| 656 | ret = sdhci_add_host(host); | 667 | ret = sdhci_add_host(host); |
| 657 | if (ret) | 668 | if (ret) |
| 658 | goto remove; | 669 | goto remove; |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 50997d2a63e7..2136794c0cfa 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/slab.h> | ||
| 18 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
| 19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 20 | 21 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c279fbc4c2e5..9d4fdfa685e5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
| 20 | #include <linux/slab.h> | ||
| 20 | #include <linux/scatterlist.h> | 21 | #include <linux/scatterlist.h> |
| 21 | 22 | ||
| 22 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
| @@ -174,20 +175,31 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
| 174 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); | 175 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); |
| 175 | } | 176 | } |
| 176 | 177 | ||
| 177 | static void sdhci_init(struct sdhci_host *host) | 178 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); |
| 179 | |||
| 180 | static void sdhci_init(struct sdhci_host *host, int soft) | ||
| 178 | { | 181 | { |
| 179 | sdhci_reset(host, SDHCI_RESET_ALL); | 182 | if (soft) |
| 183 | sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); | ||
| 184 | else | ||
| 185 | sdhci_reset(host, SDHCI_RESET_ALL); | ||
| 180 | 186 | ||
| 181 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, | 187 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, |
| 182 | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | | 188 | SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | |
| 183 | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | | 189 | SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | |
| 184 | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | | 190 | SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | |
| 185 | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); | 191 | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); |
| 192 | |||
| 193 | if (soft) { | ||
| 194 | /* force clock reconfiguration */ | ||
| 195 | host->clock = 0; | ||
| 196 | sdhci_set_ios(host->mmc, &host->mmc->ios); | ||
| 197 | } | ||
| 186 | } | 198 | } |
| 187 | 199 | ||
| 188 | static void sdhci_reinit(struct sdhci_host *host) | 200 | static void sdhci_reinit(struct sdhci_host *host) |
| 189 | { | 201 | { |
| 190 | sdhci_init(host); | 202 | sdhci_init(host, 0); |
| 191 | sdhci_enable_card_detection(host); | 203 | sdhci_enable_card_detection(host); |
| 192 | } | 204 | } |
| 193 | 205 | ||
| @@ -376,6 +388,20 @@ static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) | |||
| 376 | local_irq_restore(*flags); | 388 | local_irq_restore(*flags); |
| 377 | } | 389 | } |
| 378 | 390 | ||
| 391 | static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd) | ||
| 392 | { | ||
| 393 | __le32 *dataddr = (__le32 __force *)(desc + 4); | ||
| 394 | __le16 *cmdlen = (__le16 __force *)desc; | ||
| 395 | |||
| 396 | /* SDHCI specification says ADMA descriptors should be 4 byte | ||
| 397 | * aligned, so using 16 or 32bit operations should be safe. */ | ||
| 398 | |||
| 399 | cmdlen[0] = cpu_to_le16(cmd); | ||
| 400 | cmdlen[1] = cpu_to_le16(len); | ||
| 401 | |||
| 402 | dataddr[0] = cpu_to_le32(addr); | ||
| 403 | } | ||
| 404 | |||
| 379 | static int sdhci_adma_table_pre(struct sdhci_host *host, | 405 | static int sdhci_adma_table_pre(struct sdhci_host *host, |
| 380 | struct mmc_data *data) | 406 | struct mmc_data *data) |
| 381 | { | 407 | { |
| @@ -443,19 +469,11 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
| 443 | sdhci_kunmap_atomic(buffer, &flags); | 469 | sdhci_kunmap_atomic(buffer, &flags); |
| 444 | } | 470 | } |
| 445 | 471 | ||
| 446 | desc[7] = (align_addr >> 24) & 0xff; | 472 | /* tran, valid */ |
| 447 | desc[6] = (align_addr >> 16) & 0xff; | 473 | sdhci_set_adma_desc(desc, align_addr, offset, 0x21); |
| 448 | desc[5] = (align_addr >> 8) & 0xff; | ||
| 449 | desc[4] = (align_addr >> 0) & 0xff; | ||
| 450 | 474 | ||
| 451 | BUG_ON(offset > 65536); | 475 | BUG_ON(offset > 65536); |
| 452 | 476 | ||
| 453 | desc[3] = (offset >> 8) & 0xff; | ||
| 454 | desc[2] = (offset >> 0) & 0xff; | ||
| 455 | |||
| 456 | desc[1] = 0x00; | ||
| 457 | desc[0] = 0x21; /* tran, valid */ | ||
| 458 | |||
| 459 | align += 4; | 477 | align += 4; |
| 460 | align_addr += 4; | 478 | align_addr += 4; |
| 461 | 479 | ||
| @@ -465,19 +483,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
| 465 | len -= offset; | 483 | len -= offset; |
| 466 | } | 484 | } |
| 467 | 485 | ||
| 468 | desc[7] = (addr >> 24) & 0xff; | ||
| 469 | desc[6] = (addr >> 16) & 0xff; | ||
| 470 | desc[5] = (addr >> 8) & 0xff; | ||
| 471 | desc[4] = (addr >> 0) & 0xff; | ||
| 472 | |||
| 473 | BUG_ON(len > 65536); | 486 | BUG_ON(len > 65536); |
| 474 | 487 | ||
| 475 | desc[3] = (len >> 8) & 0xff; | 488 | /* tran, valid */ |
| 476 | desc[2] = (len >> 0) & 0xff; | 489 | sdhci_set_adma_desc(desc, addr, len, 0x21); |
| 477 | |||
| 478 | desc[1] = 0x00; | ||
| 479 | desc[0] = 0x21; /* tran, valid */ | ||
| 480 | |||
| 481 | desc += 8; | 490 | desc += 8; |
| 482 | 491 | ||
| 483 | /* | 492 | /* |
| @@ -490,16 +499,9 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, | |||
| 490 | /* | 499 | /* |
| 491 | * Add a terminating entry. | 500 | * Add a terminating entry. |
| 492 | */ | 501 | */ |
| 493 | desc[7] = 0; | ||
| 494 | desc[6] = 0; | ||
| 495 | desc[5] = 0; | ||
| 496 | desc[4] = 0; | ||
| 497 | 502 | ||
| 498 | desc[3] = 0; | 503 | /* nop, end, valid */ |
| 499 | desc[2] = 0; | 504 | sdhci_set_adma_desc(desc, 0, 0, 0x3); |
| 500 | |||
| 501 | desc[1] = 0x00; | ||
| 502 | desc[0] = 0x03; /* nop, end, valid */ | ||
| 503 | 505 | ||
| 504 | /* | 506 | /* |
| 505 | * Resync align buffer as we might have changed it. | 507 | * Resync align buffer as we might have changed it. |
| @@ -1610,16 +1612,13 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
| 1610 | if (ret) | 1612 | if (ret) |
| 1611 | return ret; | 1613 | return ret; |
| 1612 | 1614 | ||
| 1613 | sdhci_init(host); | 1615 | sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); |
| 1614 | mmiowb(); | 1616 | mmiowb(); |
| 1615 | 1617 | ||
| 1616 | ret = mmc_resume_host(host->mmc); | 1618 | ret = mmc_resume_host(host->mmc); |
| 1617 | if (ret) | ||
| 1618 | return ret; | ||
| 1619 | |||
| 1620 | sdhci_enable_card_detection(host); | 1619 | sdhci_enable_card_detection(host); |
| 1621 | 1620 | ||
| 1622 | return 0; | 1621 | return ret; |
| 1623 | } | 1622 | } |
| 1624 | 1623 | ||
| 1625 | EXPORT_SYMBOL_GPL(sdhci_resume_host); | 1624 | EXPORT_SYMBOL_GPL(sdhci_resume_host); |
| @@ -1874,7 +1873,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
| 1874 | if (ret) | 1873 | if (ret) |
| 1875 | goto untasklet; | 1874 | goto untasklet; |
| 1876 | 1875 | ||
| 1877 | sdhci_init(host); | 1876 | sdhci_init(host, 0); |
| 1878 | 1877 | ||
| 1879 | #ifdef CONFIG_MMC_DEBUG | 1878 | #ifdef CONFIG_MMC_DEBUG |
| 1880 | sdhci_dumpregs(host); | 1879 | sdhci_dumpregs(host); |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index e22c3fa3516a..b2b577f6afd4 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
| @@ -323,7 +323,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid) | |||
| 323 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { | 323 | if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { |
| 324 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | | 324 | ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | |
| 325 | TMIO_STAT_CARD_REMOVE); | 325 | TMIO_STAT_CARD_REMOVE); |
| 326 | mmc_detect_change(host->mmc, 0); | 326 | mmc_detect_change(host->mmc, msecs_to_jiffies(100)); |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | /* CRC and other errors */ | 329 | /* CRC and other errors */ |
| @@ -550,6 +550,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
| 550 | 550 | ||
| 551 | mmc->ops = &tmio_mmc_ops; | 551 | mmc->ops = &tmio_mmc_ops; |
| 552 | mmc->caps = MMC_CAP_4_BIT_DATA; | 552 | mmc->caps = MMC_CAP_4_BIT_DATA; |
| 553 | mmc->caps |= pdata->capabilities; | ||
| 553 | mmc->f_max = pdata->hclk; | 554 | mmc->f_max = pdata->hclk; |
| 554 | mmc->f_min = mmc->f_max / 512; | 555 | mmc->f_min = mmc->f_max / 512; |
| 555 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; | 556 | mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
| @@ -568,14 +569,14 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
| 568 | if (ret >= 0) | 569 | if (ret >= 0) |
| 569 | host->irq = ret; | 570 | host->irq = ret; |
| 570 | else | 571 | else |
| 571 | goto unmap_ctl; | 572 | goto cell_disable; |
| 572 | 573 | ||
| 573 | disable_mmc_irqs(host, TMIO_MASK_ALL); | 574 | disable_mmc_irqs(host, TMIO_MASK_ALL); |
| 574 | 575 | ||
| 575 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | | 576 | ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED | |
| 576 | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); | 577 | IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host); |
| 577 | if (ret) | 578 | if (ret) |
| 578 | goto unmap_ctl; | 579 | goto cell_disable; |
| 579 | 580 | ||
| 580 | mmc_add_host(mmc); | 581 | mmc_add_host(mmc); |
| 581 | 582 | ||
| @@ -587,6 +588,9 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev) | |||
| 587 | 588 | ||
| 588 | return 0; | 589 | return 0; |
| 589 | 590 | ||
| 591 | cell_disable: | ||
| 592 | if (cell->disable) | ||
| 593 | cell->disable(dev); | ||
| 590 | unmap_ctl: | 594 | unmap_ctl: |
| 591 | iounmap(host->ctl); | 595 | iounmap(host->ctl); |
| 592 | host_free: | 596 | host_free: |
| @@ -597,6 +601,7 @@ out: | |||
| 597 | 601 | ||
| 598 | static int __devexit tmio_mmc_remove(struct platform_device *dev) | 602 | static int __devexit tmio_mmc_remove(struct platform_device *dev) |
| 599 | { | 603 | { |
| 604 | struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; | ||
| 600 | struct mmc_host *mmc = platform_get_drvdata(dev); | 605 | struct mmc_host *mmc = platform_get_drvdata(dev); |
| 601 | 606 | ||
| 602 | platform_set_drvdata(dev, NULL); | 607 | platform_set_drvdata(dev, NULL); |
| @@ -605,6 +610,8 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev) | |||
| 605 | struct tmio_mmc_host *host = mmc_priv(mmc); | 610 | struct tmio_mmc_host *host = mmc_priv(mmc); |
| 606 | mmc_remove_host(mmc); | 611 | mmc_remove_host(mmc); |
| 607 | free_irq(host->irq, host); | 612 | free_irq(host->irq, host); |
| 613 | if (cell->disable) | ||
| 614 | cell->disable(dev); | ||
| 608 | iounmap(host->ctl); | 615 | iounmap(host->ctl); |
| 609 | mmc_free_host(mmc); | 616 | mmc_free_host(mmc); |
| 610 | } | 617 | } |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 692dc23363b9..dafecfbcd91a 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
| @@ -55,10 +55,8 @@ | |||
| 55 | /* Define some IRQ masks */ | 55 | /* Define some IRQ masks */ |
| 56 | /* This is the mask used at reset by the chip */ | 56 | /* This is the mask used at reset by the chip */ |
| 57 | #define TMIO_MASK_ALL 0x837f031d | 57 | #define TMIO_MASK_ALL 0x837f031d |
| 58 | #define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \ | 58 | #define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND) |
| 59 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 59 | #define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND) |
| 60 | #define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \ | ||
| 61 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | ||
| 62 | #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ | 60 | #define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \ |
| 63 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) | 61 | TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT) |
| 64 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) | 62 | #define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD) |
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 89bf8cd25cac..69efe01eece8 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
| 35 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
| 36 | #include <linux/scatterlist.h> | 36 | #include <linux/scatterlist.h> |
| 37 | #include <linux/slab.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/io.h> | 39 | #include <asm/io.h> |
| 39 | #include <asm/dma.h> | 40 | #include <asm/dma.h> |
