Commit 46b5e340 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc: (24 commits)
  MMC: Use timeout values from CSR
  MMC: CSD and CID timeout values
  sdhci: 'scratch' may be used uninitialized
  mmc: explicitly mention SDIO support in Kconfig
  mmc: remove redundant "depends on"
  Fix comment in include/linux/mmc/host.h
  sdio: high-speed support
  mmc_block: hard code 512 byte block size
  sdhci: force high speed capability on some controllers
  mmc_block: filter out PC requests
  mmc_block: indicate strict ordering
  mmc_block: inform block layer about sector count restriction
  sdio: give sdio irq thread a host specific name
  sdio: make sleep on error interruptable
  sdhci: reduce card detection delay
  sdhci: let the controller wait for busy state to end
  atmel-mci: Add missing flush_dcache_page() in PIO transfer code
  atmel-mci: Don't overwrite error bits when NOTBUSY is set
  atmel-mci: Add experimental DMA support
  atmel-mci: support multiple mmc slots
  ...
parents 94a9f8ad 6ee6c6ad
...@@ -53,8 +53,11 @@ static struct spi_board_info spi0_board_info[] __initdata = { ...@@ -53,8 +53,11 @@ static struct spi_board_info spi0_board_info[] __initdata = {
}; };
static struct mci_platform_data __initdata mci0_data = { static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
.detect_pin = GPIO_PIN_PC(25), .detect_pin = GPIO_PIN_PC(25),
.wp_pin = GPIO_PIN_PE(0), .wp_pin = GPIO_PIN_PE(0),
},
}; };
/* /*
......
...@@ -264,16 +264,20 @@ void __init setup_board(void) ...@@ -264,16 +264,20 @@ void __init setup_board(void)
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
/* MMC card detect requires MACB0 *NOT* be used */ /* MMC card detect requires MACB0 *NOT* be used */
#ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM #ifdef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM
static struct mci_platform_data __initdata mci0_data = {
.detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */ .detect_pin = GPIO_PIN_PC(14), /* gpio30/sdcd */
.wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */ .wp_pin = GPIO_PIN_PC(15), /* gpio31/sdwp */
};
#define MCI_PDATA &mci0_data
#else #else
#define MCI_PDATA NULL .detect_pin = -ENODEV,
.wp_pin = -ENODEV,
#endif /* SW6 for sd{cd,wp} routing */ #endif /* SW6 for sd{cd,wp} routing */
},
};
#endif /* SW2 for MMC signal routing */ #endif /* SW2 for MMC signal routing */
...@@ -326,7 +330,7 @@ static int __init atstk1002_init(void) ...@@ -326,7 +330,7 @@ static int __init atstk1002_init(void)
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif #endif
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_mci(0, MCI_PDATA); at32_add_device_mci(0, &mci0_pdata);
#endif #endif
#ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
set_hw_addr(at32_add_device_eth(1, &eth_data[1])); set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
......
...@@ -66,6 +66,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { { ...@@ -66,6 +66,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { {
} }; } };
#endif #endif
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
.detect_pin = -ENODEV,
.wp_pin = -ENODEV,
},
};
#endif
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
static void __init atstk1003_setup_extdac(void) static void __init atstk1003_setup_extdac(void)
{ {
...@@ -154,7 +164,7 @@ static int __init atstk1003_init(void) ...@@ -154,7 +164,7 @@ static int __init atstk1003_init(void)
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif #endif
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_mci(0, NULL); at32_add_device_mci(0, &mci0_data);
#endif #endif
at32_add_device_usba(0, NULL); at32_add_device_usba(0, NULL);
#ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
......
...@@ -71,6 +71,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { { ...@@ -71,6 +71,16 @@ static struct spi_board_info spi1_board_info[] __initdata = { {
} }; } };
#endif #endif
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
.detect_pin = -ENODEV,
.wp_pin = -ENODEV,
},
};
#endif
#ifdef CONFIG_BOARD_ATSTK1000_EXTDAC #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC
static void __init atstk1004_setup_extdac(void) static void __init atstk1004_setup_extdac(void)
{ {
...@@ -137,7 +147,7 @@ static int __init atstk1004_init(void) ...@@ -137,7 +147,7 @@ static int __init atstk1004_init(void)
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
#endif #endif
#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_mci(0, NULL); at32_add_device_mci(0, &mci0_data);
#endif #endif
at32_add_device_lcdc(0, &atstk1000_lcdc_data, at32_add_device_lcdc(0, &atstk1000_lcdc_data,
fbmem_start, fbmem_size, 0); fbmem_start, fbmem_size, 0);
......
#ifndef __ASM_AVR32_ATMEL_MCI_H #ifndef __ASM_AVR32_ATMEL_MCI_H
#define __ASM_AVR32_ATMEL_MCI_H #define __ASM_AVR32_ATMEL_MCI_H
struct mci_platform_data { #define ATMEL_MCI_MAX_NR_SLOTS 2
struct dma_slave;
/**
* struct mci_slot_pdata - board-specific per-slot configuration
* @bus_width: Number of data lines wired up the slot
* @detect_pin: GPIO pin wired to the card detect switch
* @wp_pin: GPIO pin wired to the write protect sensor
*
* If a given slot is not present on the board, @bus_width should be
* set to 0. The other fields are ignored in this case.
*
* Any pins that aren't available should be set to a negative value.
*
* Note that support for multiple slots is experimental -- some cards
* might get upset if we don't get the clock management exactly right.
* But in most cases, it should work just fine.
*/
struct mci_slot_pdata {
unsigned int bus_width;
int detect_pin; int detect_pin;
int wp_pin; int wp_pin;
}; };
/**
* struct mci_platform_data - board-specific MMC/SDcard configuration
* @dma_slave: DMA slave interface to use in data transfers, or NULL.
* @slot: Per-slot configuration data.
*/
struct mci_platform_data {
struct dma_slave *dma_slave;
struct mci_slot_pdata slot[ATMEL_MCI_MAX_NR_SLOTS];
};
#endif /* __ASM_AVR32_ATMEL_MCI_H */ #endif /* __ASM_AVR32_ATMEL_MCI_H */
...@@ -1272,10 +1272,14 @@ static struct clk atmel_mci0_pclk = { ...@@ -1272,10 +1272,14 @@ static struct clk atmel_mci0_pclk = {
struct platform_device *__init struct platform_device *__init
at32_add_device_mci(unsigned int id, struct mci_platform_data *data) at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
{ {
struct mci_platform_data _data;
struct platform_device *pdev; struct platform_device *pdev;
struct dw_dma_slave *dws;
if (id != 0) if (id != 0 || !data)
return NULL;
/* Must have at least one usable slot */
if (!data->slot[0].bus_width && !data->slot[1].bus_width)
return NULL; return NULL;
pdev = platform_device_alloc("atmel_mci", id); pdev = platform_device_alloc("atmel_mci", id);
...@@ -1286,28 +1290,76 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data) ...@@ -1286,28 +1290,76 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
ARRAY_SIZE(atmel_mci0_resource))) ARRAY_SIZE(atmel_mci0_resource)))
goto fail; goto fail;
if (!data) { if (data->dma_slave)
data = &_data; dws = kmemdup(to_dw_dma_slave(data->dma_slave),
memset(data, -1, sizeof(struct mci_platform_data)); sizeof(struct dw_dma_slave), GFP_KERNEL);
data->detect_pin = GPIO_PIN_NONE; else
data->wp_pin = GPIO_PIN_NONE; dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
}
dws->slave.dev = &pdev->dev;
dws->slave.dma_dev = &dw_dmac0_device.dev;
dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT;
dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
| DWC_CFGH_DST_PER(1));
dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
| DWC_CFGL_HS_SRC_POL);
data->dma_slave = &dws->slave;
if (platform_device_add_data(pdev, data, if (platform_device_add_data(pdev, data,
sizeof(struct mci_platform_data))) sizeof(struct mci_platform_data)))
goto fail; goto fail;
select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ /* CLK line is common to both slots */
select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ select_peripheral(PA(10), PERIPH_A, 0);
select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
switch (data->slot[0].bus_width) {
case 4:
select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */ select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
/* fall through */
case 1:
select_peripheral(PA(11), PERIPH_A, 0); /* CMD */
select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
if (gpio_is_valid(data->detect_pin)) if (gpio_is_valid(data->slot[0].detect_pin))
at32_select_gpio(data->detect_pin, 0); at32_select_gpio(data->slot[0].detect_pin, 0);
if (gpio_is_valid(data->wp_pin)) if (gpio_is_valid(data->slot[0].wp_pin))
at32_select_gpio(data->wp_pin, 0); at32_select_gpio(data->slot[0].wp_pin, 0);
break;
case 0:
/* Slot is unused */
break;
default:
goto fail;
}
switch (data->slot[1].bus_width) {
case 4:
select_peripheral(PB(8), PERIPH_B, 0); /* DATA1 */
select_peripheral(PB(9), PERIPH_B, 0); /* DATA2 */
select_peripheral(PB(10), PERIPH_B, 0); /* DATA3 */
/* fall through */
case 1:
select_peripheral(PB(6), PERIPH_B, 0); /* CMD */
select_peripheral(PB(7), PERIPH_B, 0); /* DATA0 */
if (gpio_is_valid(data->slot[1].detect_pin))
at32_select_gpio(data->slot[1].detect_pin, 0);
if (gpio_is_valid(data->slot[1].wp_pin))
at32_select_gpio(data->slot[1].wp_pin, 0);
break;
case 0:
/* Slot is unused */
break;
default:
if (!data->slot[0].bus_width)
goto fail;
data->slot[1].bus_width = 0;
break;
}
atmel_mci0_pclk.dev = &pdev->dev; atmel_mci0_pclk.dev = &pdev->dev;
......
...@@ -3,13 +3,14 @@ ...@@ -3,13 +3,14 @@
# #
menuconfig MMC menuconfig MMC
tristate "MMC/SD card support" tristate "MMC/SD/SDIO card support"
depends on HAS_IOMEM depends on HAS_IOMEM
help help
MMC is the "multi-media card" bus protocol. This selects MultiMediaCard, Secure Digital and Secure
Digital I/O support.
If you want MMC support, you should say Y here and also If you want MMC/SD/SDIO support, you should say Y here and
to the specific driver for your MMC interface. also to your specific host controller driver.
config MMC_DEBUG config MMC_DEBUG
bool "MMC debugging" bool "MMC debugging"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# MMC/SD card drivers # MMC/SD card drivers
# #
comment "MMC/SD Card Drivers" comment "MMC/SD/SDIO Card Drivers"
config MMC_BLOCK config MMC_BLOCK
tristate "MMC block device driver" tristate "MMC block device driver"
...@@ -34,7 +34,6 @@ config MMC_BLOCK_BOUNCE ...@@ -34,7 +34,6 @@ config MMC_BLOCK_BOUNCE
config SDIO_UART config SDIO_UART
tristate "SDIO UART/GPS class support" tristate "SDIO UART/GPS class support"
depends on MMC
help help
SDIO function driver for SDIO cards that implements the UART SDIO function driver for SDIO cards that implements the UART
class, as well as the GPS class which appears like a UART. class, as well as the GPS class which appears like a UART.
......
...@@ -58,7 +58,6 @@ struct mmc_blk_data { ...@@ -58,7 +58,6 @@ struct mmc_blk_data {
struct mmc_queue queue; struct mmc_queue queue;
unsigned int usage; unsigned int usage;
unsigned int block_bits;
unsigned int read_only; unsigned int read_only;
}; };
...@@ -216,8 +215,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -216,8 +215,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
struct mmc_blk_data *md = mq->data; struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card; struct mmc_card *card = md->queue.card;
struct mmc_blk_request brq; struct mmc_blk_request brq;
int ret = 1, data_size, i; int ret = 1;
struct scatterlist *sg;
mmc_claim_host(card->host); mmc_claim_host(card->host);
...@@ -233,13 +231,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -233,13 +231,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
if (!mmc_card_blockaddr(card)) if (!mmc_card_blockaddr(card))
brq.cmd.arg <<= 9; brq.cmd.arg <<= 9;
brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; brq.cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
brq.data.blksz = 1 << md->block_bits; brq.data.blksz = 512;
brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.opcode = MMC_STOP_TRANSMISSION;
brq.stop.arg = 0; brq.stop.arg = 0;
brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; brq.stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); brq.data.blocks = req->nr_sectors;
if (brq.data.blocks > card->host->max_blk_count)
brq.data.blocks = card->host->max_blk_count;
if (brq.data.blocks > 1) { if (brq.data.blocks > 1) {
/* SPI multiblock writes terminate using a special /* SPI multiblock writes terminate using a special
...@@ -271,24 +267,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -271,24 +267,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
mmc_queue_bounce_pre(mq); mmc_queue_bounce_pre(mq);
/*
* Adjust the sg list so it is the same size as the
* request.
*/
if (brq.data.blocks !=
(req->nr_sectors >> (md->block_bits - 9))) {
data_size = brq.data.blocks * brq.data.blksz;
for_each_sg(brq.data.sg, sg, brq.data.sg_len, i) {
data_size -= sg->length;
if (data_size <= 0) {
sg->length += data_size;
i++;
break;
}
}
brq.data.sg_len = i;
}
mmc_wait_for_req(card->host, &brq.mrq); mmc_wait_for_req(card->host, &brq.mrq);
mmc_queue_bounce_post(mq); mmc_queue_bounce_post(mq);
...@@ -373,16 +351,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) ...@@ -373,16 +351,11 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
if (rq_data_dir(req) != READ) { if (rq_data_dir(req) != READ) {
if (mmc_card_sd(card)) { if (mmc_card_sd(card)) {
u32 blocks; u32 blocks;
unsigned int bytes;
blocks = mmc_sd_num_wr_blocks(card); blocks = mmc_sd_num_wr_blocks(card);
if (blocks != (u32)-1) { if (blocks != (u32)-1) {
if (card->csd.write_partial)
bytes = blocks << md->block_bits;
else
bytes = blocks << 9;
spin_lock_irq(&md->lock); spin_lock_irq(&md->lock);
ret = __blk_end_request(req, 0, bytes); ret = __blk_end_request(req, 0, blocks << 9);
spin_unlock_irq(&md->lock); spin_unlock_irq(&md->lock);
} }
} else { } else {
...@@ -432,13 +405,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) ...@@ -432,13 +405,6 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
*/ */
md->read_only = mmc_blk_readonly(card); md->read_only = mmc_blk_readonly(card);
/*
* Both SD and MMC specifications state (although a bit
* unclearly in the MMC case) that a block size of 512
* bytes must always be supported by the card.
*/
md->block_bits = 9;
md->disk = alloc_disk(1 << MMC_SHIFT); md->disk = alloc_disk(1 << MMC_SHIFT);
if (md->disk == NULL) { if (md->disk == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -476,7 +442,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) ...@@ -476,7 +442,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
sprintf(md->disk->disk_name, "mmcblk%d", devidx); sprintf(md->disk->disk_name, "mmcblk%d", devidx);
blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); blk_queue_hardsect_size(md->queue.queue, 512);
if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
/* /*
...@@ -514,7 +480,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) ...@@ -514,7 +480,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
mmc_claim_host(card->host); mmc_claim_host(card->host);
cmd.opcode = MMC_SET_BLOCKLEN; cmd.opcode = MMC_SET_BLOCKLEN;
cmd.arg = 1 << md->block_bits; cmd.arg = 512;
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
err = mmc_wait_for_cmd(card->host, &cmd, 5); err = mmc_wait_for_cmd(card->host, &cmd, 5);
mmc_release_host(card->host); mmc_release_host(card->host);
......
...@@ -31,7 +31,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) ...@@ -31,7 +31,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
/* /*
* We only like normal block requests. * We only like normal block requests.
*/ */
if (!blk_fs_request(req) && !blk_pc_request(req)) { if (!blk_fs_request(req)) {
blk_dump_rq_flags(req, "MMC bad request"); blk_dump_rq_flags(req, "MMC bad request");
return BLKPREP_KILL; return BLKPREP_KILL;
} }
...@@ -131,6 +131,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock ...@@ -131,6 +131,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
mq->req = NULL; mq->req = NULL;
blk_queue_prep_rq(mq->queue, mmc_prep_request); blk_queue_prep_rq(mq->queue, mmc_prep_request);
blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL);
#ifdef CONFIG_MMC_BLOCK_BOUNCE #ifdef CONFIG_MMC_BLOCK_BOUNCE
if (host->max_hw_segs == 1) { if (host->max_hw_segs == 1) {
...@@ -142,12 +143,19 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock ...@@ -142,12 +143,19 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
bouncesz = host->max_req_size; bouncesz = host->max_req_size;
if (bouncesz > host->max_seg_size) if (bouncesz > host->max_seg_size)
bouncesz = host->max_seg_size; bouncesz = host->max_seg_size;
if (bouncesz > (host->max_blk_count * 512))
bouncesz = host->max_blk_count * 512;
if (bouncesz > 512) {
mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL); mq->bounce_buf = kmalloc(bouncesz, GFP_KERNEL);
if (!mq->bounce_buf) { if (!mq->bounce_buf) {
printk(KERN_WARNING "%s: unable to allocate " printk(KERN_WARNING "%s: unable to "
"bounce buffer\n", mmc_card_name(card)); "allocate bounce buffer\n",
} else { mmc_card_name(card));
}
}
if (mq->bounce_buf) {
blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY); blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY);
blk_queue_max_sectors(mq->queue, bouncesz / 512); blk_queue_max_sectors(mq->queue, bouncesz / 512);
blk_queue_max_phys_segments(mq->queue, bouncesz / 512); blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
...@@ -175,7 +183,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock ...@@ -175,7 +183,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
if (!mq->bounce_buf) { if (!mq->bounce_buf) {
blk_queue_bounce_limit(mq->queue, limit); blk_queue_bounce_limit(mq->queue, limit);
blk_queue_max_sectors(mq->queue, host->max_req_size / 512); blk_queue_max_sectors(mq->queue,
min(host->max_blk_count, host->max_req_size / 512));
blk_queue_max_phys_segments(mq->queue, host->max_phys_segs); blk_queue_max_phys_segments(mq->queue, host->max_phys_segs);
blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
blk_queue_max_segment_size(mq->queue, host->max_seg_size); blk_queue_max_segment_size(mq->queue, host->max_seg_size);
......
...@@ -248,8 +248,12 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, ...@@ -248,8 +248,12 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
sg_init_one(&sg, data_buf, len); sg_init_one(&sg, data_buf, len);
if (card) /*
mmc_set_data_timeout(&data, card); * The spec states that CSR and CID accesses have a timeout
* of 64 clock cycles.
*/
data.timeout_ns = 0;
data.timeout_clks = 64;
mmc_wait_for_req(host, &mrq); mmc_wait_for_req(host, &mrq);
......
...@@ -164,6 +164,36 @@ static int sdio_enable_wide(struct mmc_card *card) ...@@ -164,6 +164,36 @@ static int sdio_enable_wide(struct mmc_card *card)
return 0; return 0;
} }
/*
* Test if the card supports high-speed mode and, if so, switch to it.
*/
static int sdio_enable_hs(struct mmc_card *card)
{
int ret;
u8 speed;
if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
return 0;
if (!card->cccr.high_speed)
return 0;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (ret)
return ret;
speed |= SDIO_SPEED_EHS;
ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
if (ret)
return ret;
mmc_card_set_highspeed(card);
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
return 0;
}
/* /*
* Host is being removed. Free up the current card. * Host is being removed. Free up the current card.
*/ */
...@@ -333,10 +363,26 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) ...@@ -333,10 +363,26 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
goto remove; goto remove;
/* /*
* No support for high-speed yet, so just set * Switch to high-speed (if supported).
* the card's maximum speed. */
err = sdio_enable_hs(card);
if (err)
goto remove;
/*
* Change to the card's maximum speed.
*/ */
if (mmc_card_highspeed(card)) {
/*
* The SDIO specification doesn't mention how
* the CIS transfer speed register relates to
* high-speed, but it seems that 50 MHz is
* mandatory.
*/
mmc_set_clock(host, 50000000);
} else {
mmc_set_clock(host, card->cis.max_dtr); mmc_set_clock(host, card->cis.max_dtr);
}
/* /*
* Switch to wider bus (if supported). * Switch to wider bus (if supported).
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* Created: June 18, 2007 * Created: June 18, 2007
* Copyright: MontaVista Software Inc. * Copyright: MontaVista Software Inc.
* *
* Copyright 2008 Pierre Ossman
*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at * the Free Software Foundation; either version 2 of the License, or (at
...@@ -107,11 +109,14 @@ static int sdio_irq_thread(void *_host) ...@@ -107,11 +109,14 @@ static int sdio_irq_thread(void *_host)
/* /*
* Give other threads a chance to run in the presence of * Give other threads a chance to run in the presence of
* errors. FIXME: determine if due to card removal and * errors.
* possibly exit this thread if so.
*/ */
if (ret < 0) if (ret < 0) {
ssleep(1); set_current_state(TASK_INTERRUPTIBLE);
if (!kthread_should_stop())
schedule_timeout(HZ);
set_current_state(TASK_RUNNING);
}
/* /*
* Adaptive polling frequency based on the assumption * Adaptive polling frequency based on the assumption
...@@ -154,7 +159,8 @@ static int sdio_card_irq_get(struct mmc_card *card) ...@@ -154,7 +159,8 @@ static int sdio_card_irq_get(struct mmc_card *card)
if (!host->sdio_irqs++) { if (!host->sdio_irqs++) {
atomic_set(&host->sdio_irq_thread_abort, 0); atomic_set(&host->sdio_irq_thread_abort, 0);
host->sdio_irq_thread = host->sdio_irq_thread =
kthread_run(sdio_irq_thread, host, "ksdiorqd"); kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
mmc_hostname(host));
if (IS_ERR(host->sdio_irq_thread)) { if (IS_ERR(host->sdio_irq_thread)) {
int err = PTR_ERR(host->sdio_irq_thread); int err = PTR_ERR(host->sdio_irq_thread);
host->sdio_irqs--; host->sdio_irqs--;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# MMC/SD host controller drivers # MMC/SD host controller drivers
# #
comment "MMC/SD Host Controller Drivers" comment "MMC/SD/SDIO Host Controller Drivers"
config MMC_ARMMMCI config MMC_ARMMMCI
tristate "ARM AMBA Multimedia Card Interface support" tristate "ARM AMBA Multimedia Card Interface support"
...@@ -114,6 +114,17 @@ config MMC_ATMELMCI ...@@ -114,6 +114,17 @@ config MMC_ATMELMCI
If unsure, say N. If unsure, say N.
config MMC_ATMELMCI_DMA
bool "Atmel MCI DMA support (EXPERIMENTAL)"
depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL
help
Say Y here to have the Atmel MCI driver use a DMA engine to
do data transfers and thus increase the throughput and
reduce the CPU utilization. Note that this is highly
experimental and may cause the driver to lock up.
If unsure, say N.
config MMC_IMX config MMC_IMX
tristate "Motorola i.MX Multimedia Card Interface support" tristate "Motorola i.MX Multimedia Card Interface support"
depends on ARCH_IMX depends on ARCH_IMX
...@@ -141,21 +152,22 @@ config MMC_TIFM_SD ...@@ -141,21 +152,22 @@ config MMC_TIFM_SD
module will be called tifm_sd. module will be called tifm_sd.
config MMC_SPI config MMC_SPI
tristate "MMC/SD over SPI" tristate "MMC/SD/SDIO over SPI"
depends on MMC && SPI_MASTER && !HIGHMEM && HAS_DMA depends on SPI_MASTER && !HIGHMEM && HAS_DMA
select CRC7 select CRC7
select CRC_ITU_T select CRC_ITU_T
help help
Some systems accss MMC/SD cards using a SPI controller instead of Some systems accss MMC/SD/SDIO cards using a SPI controller
using a "native" MMC/SD controller. This has a disadvantage of instead of using a "native" MMC/SD/SDIO controller. This has a
being relatively high overhead, but a compensating advantage of disadvantage of being relatively high overhead, but a compensating
working on many systems without dedicated MMC/SD controllers. advantage of working on many systems without dedicated MMC/SD/SDIO
controllers.
If unsure, or if your system has no SPI master driver, say N. If unsure, or if your system has no SPI master driver, say N.
config MMC_S3C config MMC_S3C
tristate "Samsung S3C SD/MMC Card Interface support" tristate "Samsung S3C SD/MMC Card Interface support"
depends on ARCH_S3C2410 && MMC depends on ARCH_S3C2410
help help
This selects a driver for the MCI interface found in This selects a driver for the MCI interface found in
Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs. Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs.
...@@ -166,7 +178,7 @@ config MMC_S3C ...@@ -166,7 +178,7 @@ config MMC_S3C
config MMC_SDRICOH_CS config MMC_SDRICOH_CS
tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)"
depends on EXPERIMENTAL && MMC && PCI && PCMCIA depends on EXPERIMENTAL && PCI && PCMCIA
help help
Say Y here if your Notebook reports a Ricoh Bay1Controller PCMCIA Say Y here if your Notebook reports a Ricoh Bay1Controller PCMCIA
card whenever you insert a MMC or SD card into the card slot. card whenever you insert a MMC or SD card into the card slot.
......
...@@ -25,8 +25,10 @@ ...@@ -25,8 +25,10 @@
#define MCI_SDCR 0x000c /* SD Card / SDIO */ #define MCI_SDCR 0x000c /* SD Card / SDIO */
# define MCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */ # define MCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */
# define MCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */ # define MCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */
# define MCI_SDCBUS_1BIT ( 0 << 7) /* 1-bit data bus */ # define MCI_SDCSEL_MASK ( 3 << 0)
# define MCI_SDCBUS_4BIT ( 1 << 7) /* 4-bit data bus */ # define MCI_SDCBUS_1BIT ( 0 << 6) /* 1-bit data bus */
# define MCI_SDCBUS_4BIT ( 2 << 6) /* 4-bit data bus */
# define MCI_SDCBUS_MASK ( 3 << 6)
#define MCI_ARGR 0x0010 /* Command Argument */ #define MCI_ARGR 0x0010 /* Command Argument */
#define MCI_CMDR 0x0014 /* Command */ #define MCI_CMDR 0x0014 /* Command */
# define MCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */ # define MCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */
......
This diff is collapsed.
...@@ -95,8 +95,6 @@ ...@@ -95,8 +95,6 @@
* reads which takes nowhere near that long. Older cards may be able to use * reads which takes nowhere near that long. Older cards may be able to use
* shorter timeouts ... but why bother? * shorter timeouts ... but why bother?
*/ */
#define readblock_timeout ktime_set(0, 100 * 1000 * 1000)
#define writeblock_timeout ktime_set(0, 250 * 1000 * 1000)
#define r1b_timeout ktime_set(3, 0) #define r1b_timeout ktime_set(3, 0)
...@@ -220,9 +218,9 @@ mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout) ...@@ -220,9 +218,9 @@ mmc_spi_wait_unbusy(struct mmc_spi_host *host, ktime_t timeout)
return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0); return mmc_spi_skip(host, timeout, sizeof(host->data->status), 0);
} }
static int mmc_spi_readtoken(struct mmc_spi_host *host) static int mmc_spi_readtoken(struct mmc_spi_host *host, ktime_t timeout)
{ {
return mmc_spi_skip(host, readblock_timeout, 1, 0xff); return mmc_spi_skip(host, timeout, 1, 0xff);
} }
...@@ -605,7 +603,8 @@ mmc_spi_setup_data_message( ...@@ -605,7 +603,8 @@ mmc_spi_setup_data_message(
* Return negative errno, else success. * Return negative errno, else success.
*/ */
static int static int
mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
ktime_t timeout)
{ {
struct spi_device *spi = host->spi; struct spi_device *spi = host->spi;
int status, i; int status, i;
...@@ -673,7 +672,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) ...@@ -673,7 +672,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t)
if (scratch->status[i] != 0) if (scratch->status[i] != 0)
return 0; return 0;
} }
return mmc_spi_wait_unbusy(host, writeblock_timeout); return mmc_spi_wait_unbusy(host, timeout);
} }
/* /*
...@@ -693,7 +692,8 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) ...@@ -693,7 +692,8 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t)
* STOP_TRANSMISSION command. * STOP_TRANSMISSION command.
*/ */
static int static int
mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t,
ktime_t timeout)
{ {
struct spi_device *spi = host->spi; struct spi_device *spi = host->spi;
int status; int status;
...@@ -707,7 +707,7 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) ...@@ -707,7 +707,7 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t)
return status; return status;
status = scratch->status[0]; status = scratch->status[0];
if (status == 0xff || status == 0) if (status == 0xff || status == 0)
status = mmc_spi_readtoken(host); status = mmc_spi_readtoken(host, timeout);
if (status == SPI_TOKEN_SINGLE) { if (status == SPI_TOKEN_SINGLE) {
if (host->dma_dev) { if (host->dma_dev) {
...@@ -778,6 +778,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -778,6 +778,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
struct scatterlist *sg; struct scatterlist *sg;
unsigned n_sg; unsigned n_sg;
int multiple = (data->blocks > 1); int multiple = (data->blocks > 1);
u32 clock_rate;
ktime_t timeout;
if (data->flags & MMC_DATA_READ) if (data->flags & MMC_DATA_READ)
direction = DMA_FROM_DEVICE; direction = DMA_FROM_DEVICE;
...@@ -786,6 +788,14 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -786,6 +788,14 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
mmc_spi_setup_data_message(host, multiple, direction); mmc_spi_setup_data_message(host, multiple, direction);
t = &host->t; t = &host->t;
if (t->speed_hz)
clock_rate = t->speed_hz;
else
clock_rate = spi->max_speed_hz;
timeout = ktime_add_ns(ktime_set(0, 0), data->timeout_ns +
data->timeout_clks * 1000000 / clock_rate);
/* Handle scatterlist segments one at a time, with synch for /* Handle scatterlist segments one at a time, with synch for
* each 512-byte block * each 512-byte block
*/ */
...@@ -832,9 +842,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -832,9 +842,9 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
t->len); t->len);
if (direction == DMA_TO_DEVICE) if (direction == DMA_TO_DEVICE)
status = mmc_spi_writeblock(host, t); status = mmc_spi_writeblock(host, t, timeout);
else else
status = mmc_spi_readblock(host, t); status = mmc_spi_readblock(host, t, timeout);
if (status < 0) if (status < 0)
break; break;
...@@ -917,7 +927,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, ...@@ -917,7 +927,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
if (scratch->status[tmp] != 0) if (scratch->status[tmp] != 0)
return; return;
} }
tmp = mmc_spi_wait_unbusy(host, writeblock_timeout); tmp = mmc_spi_wait_unbusy(host, timeout);
if (tmp < 0 && !data->error) if (tmp < 0 && !data->error)
data->error = tmp; data->error = tmp;
} }
......
...@@ -144,7 +144,8 @@ static int jmicron_probe(struct sdhci_pci_chip *chip) ...@@ -144,7 +144,8 @@ static int jmicron_probe(struct sdhci_pci_chip *chip)
SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_DMA_SIZE |
SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE |
SDHCI_QUIRK_RESET_AFTER_REQUEST | SDHCI_QUIRK_RESET_AFTER_REQUEST |
SDHCI_QUIRK_BROKEN_SMALL_PIO; SDHCI_QUIRK_BROKEN_SMALL_PIO |
SDHCI_QUIRK_FORCE_HIGHSPEED;
} }
/* /*
......
...@@ -177,7 +177,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host) ...@@ -177,7 +177,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
{ {
unsigned long flags; unsigned long flags;
size_t blksize, len, chunk; size_t blksize, len, chunk;
u32 scratch; u32 uninitialized_var(scratch);
u8 *buf; u8 *buf;
DBG("PIO reading\n"); DBG("PIO reading\n");
...@@ -1154,7 +1154,7 @@ static void sdhci_tasklet_card(unsigned long param) ...@@ -1154,7 +1154,7 @@ static void sdhci_tasklet_card(unsigned long param)
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
mmc_detect_change(host->mmc, msecs_to_jiffies(500)); mmc_detect_change(host->mmc, msecs_to_jiffies(200));
} }
static void sdhci_tasklet_finish(unsigned long param) static void sdhci_tasklet_finish(unsigned long param)
...@@ -1266,9 +1266,31 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) ...@@ -1266,9 +1266,31 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
SDHCI_INT_INDEX)) SDHCI_INT_INDEX))
host->cmd->error = -EILSEQ; host->cmd->error = -EILSEQ;
if (host->cmd->error) if (host->cmd->error) {
tasklet_schedule(&host->finish_tasklet); tasklet_schedule(&host->finish_tasklet);
else if (intmask & SDHCI_INT_RESPONSE) return;
}
/*
* The host can send and interrupt when the busy state has
* ended, allowing us to wait without wasting CPU cycles.
* Unfortunately this is overloaded on the "data complete"
* interrupt, so we need to take some care when handling
* it.
*
* Note: The 1.0 specification is a bit ambiguous about this
* feature so there might be some problems with older
* controllers.
*/
if (host->cmd->flags & MMC_RSP_BUSY) {
if (host->cmd->data)
DBG("Cannot wait for busy signal when also "
"doing a data transfer");
else
return;
}
if (intmask & SDHCI_INT_RESPONSE)
sdhci_finish_command(host); sdhci_finish_command(host);
} }
...@@ -1278,11 +1300,16 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) ...@@ -1278,11 +1300,16 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
if (!host->data) { if (!host->data) {
/* /*
* A data end interrupt is sent together with the response * The "data complete" interrupt is also used to
* for the stop command. * indicate that a busy state has ended. See comment
* above in sdhci_cmd_irq().
*/ */
if (intmask & SDHCI_INT_DATA_END) if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
if (intmask & SDHCI_INT_DATA_END) {
sdhci_finish_command(host);
return; return;
}
}
printk(KERN_ERR "%s: Got data interrupt 0x%08x even " printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
"though no data operation was in progress.\n", "though no data operation was in progress.\n",
...@@ -1604,7 +1631,8 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1604,7 +1631,8 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->f_max = host->max_clk; mmc->f_max = host->max_clk;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
if (caps & SDHCI_CAN_DO_HISPD) if ((caps & SDHCI_CAN_DO_HISPD) ||
(host->quirks & SDHCI_QUIRK_FORCE_HIGHSPEED))
mmc->caps |= MMC_CAP_SD_HIGHSPEED; mmc->caps |= MMC_CAP_SD_HIGHSPEED;
mmc->ocr_avail = 0; mmc->ocr_avail = 0;
......
...@@ -208,6 +208,8 @@ struct sdhci_host { ...@@ -208,6 +208,8 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12) #define SDHCI_QUIRK_BROKEN_TIMEOUT_VAL (1<<12)
/* Controller has an issue with buffer bits for small transfers */ /* Controller has an issue with buffer bits for small transfers */
#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
/* Controller supports high speed but doesn't have the caps bit set */
#define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14)
int irq; /* Device IRQ */ int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */ void __iomem * ioaddr; /* Mapped address */
......
...@@ -65,7 +65,7 @@ struct mmc_host_ops { ...@@ -65,7 +65,7 @@ struct mmc_host_ops {
* -ENOSYS when not supported (equal to NULL callback) * -ENOSYS when not supported (equal to NULL callback)
* or a negative errno value when something bad happened * or a negative errno value when something bad happened
* *
* Return values for the get_ro callback should be: * Return values for the get_cd callback should be:
* 0 for a absent card * 0 for a absent card
* 1 for a present card * 1 for a present card
* -ENOSYS when not supported (equal to NULL callback) * -ENOSYS when not supported (equal to NULL callback)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment