diff options
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index b032828c6126..4a8776f8afdd 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/mmc/host.h> | 29 | #include <linux/mmc/host.h> |
30 | #include <linux/mmc/core.h> | 30 | #include <linux/mmc/core.h> |
31 | #include <linux/mmc/mmc.h> | ||
31 | #include <linux/io.h> | 32 | #include <linux/io.h> |
32 | #include <linux/semaphore.h> | 33 | #include <linux/semaphore.h> |
33 | #include <linux/gpio.h> | 34 | #include <linux/gpio.h> |
@@ -78,6 +79,7 @@ | |||
78 | #define INT_EN_MASK 0x307F0033 | 79 | #define INT_EN_MASK 0x307F0033 |
79 | #define BWR_ENABLE (1 << 4) | 80 | #define BWR_ENABLE (1 << 4) |
80 | #define BRR_ENABLE (1 << 5) | 81 | #define BRR_ENABLE (1 << 5) |
82 | #define DTO_ENABLE (1 << 20) | ||
81 | #define INIT_STREAM (1 << 1) | 83 | #define INIT_STREAM (1 << 1) |
82 | #define DP_SELECT (1 << 21) | 84 | #define DP_SELECT (1 << 21) |
83 | #define DDIR (1 << 4) | 85 | #define DDIR (1 << 4) |
@@ -523,7 +525,8 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) | |||
523 | dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n"); | 525 | dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n"); |
524 | } | 526 | } |
525 | 527 | ||
526 | static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host) | 528 | static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, |
529 | struct mmc_command *cmd) | ||
527 | { | 530 | { |
528 | unsigned int irq_mask; | 531 | unsigned int irq_mask; |
529 | 532 | ||
@@ -532,6 +535,10 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host) | |||
532 | else | 535 | else |
533 | irq_mask = INT_EN_MASK; | 536 | irq_mask = INT_EN_MASK; |
534 | 537 | ||
538 | /* Disable timeout for erases */ | ||
539 | if (cmd->opcode == MMC_ERASE) | ||
540 | irq_mask &= ~DTO_ENABLE; | ||
541 | |||
535 | OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); | 542 | OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); |
536 | OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); | 543 | OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); |
537 | OMAP_HSMMC_WRITE(host->base, IE, irq_mask); | 544 | OMAP_HSMMC_WRITE(host->base, IE, irq_mask); |
@@ -782,7 +789,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, | |||
782 | mmc_hostname(host->mmc), cmd->opcode, cmd->arg); | 789 | mmc_hostname(host->mmc), cmd->opcode, cmd->arg); |
783 | host->cmd = cmd; | 790 | host->cmd = cmd; |
784 | 791 | ||
785 | omap_hsmmc_enable_irq(host); | 792 | omap_hsmmc_enable_irq(host, cmd); |
786 | 793 | ||
787 | host->response_busy = 0; | 794 | host->response_busy = 0; |
788 | if (cmd->flags & MMC_RSP_PRESENT) { | 795 | if (cmd->flags & MMC_RSP_PRESENT) { |
@@ -1273,8 +1280,11 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) | |||
1273 | struct mmc_data *data = host->mrq->data; | 1280 | struct mmc_data *data = host->mrq->data; |
1274 | int dma_ch, req_in_progress; | 1281 | int dma_ch, req_in_progress; |
1275 | 1282 | ||
1276 | if (ch_status & OMAP2_DMA_MISALIGNED_ERR_IRQ) | 1283 | if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { |
1277 | dev_dbg(mmc_dev(host->mmc), "MISALIGNED_ADRS_ERR\n"); | 1284 | dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n", |
1285 | ch_status); | ||
1286 | return; | ||
1287 | } | ||
1278 | 1288 | ||
1279 | spin_lock(&host->irq_lock); | 1289 | spin_lock(&host->irq_lock); |
1280 | if (host->dma_ch < 0) { | 1290 | if (host->dma_ch < 0) { |
@@ -1598,6 +1608,14 @@ static int omap_hsmmc_get_ro(struct mmc_host *mmc) | |||
1598 | return mmc_slot(host).get_ro(host->dev, 0); | 1608 | return mmc_slot(host).get_ro(host->dev, 0); |
1599 | } | 1609 | } |
1600 | 1610 | ||
1611 | static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) | ||
1612 | { | ||
1613 | struct omap_hsmmc_host *host = mmc_priv(mmc); | ||
1614 | |||
1615 | if (mmc_slot(host).init_card) | ||
1616 | mmc_slot(host).init_card(card); | ||
1617 | } | ||
1618 | |||
1601 | static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) | 1619 | static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) |
1602 | { | 1620 | { |
1603 | u32 hctl, capa, value; | 1621 | u32 hctl, capa, value; |
@@ -1869,6 +1887,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = { | |||
1869 | .set_ios = omap_hsmmc_set_ios, | 1887 | .set_ios = omap_hsmmc_set_ios, |
1870 | .get_cd = omap_hsmmc_get_cd, | 1888 | .get_cd = omap_hsmmc_get_cd, |
1871 | .get_ro = omap_hsmmc_get_ro, | 1889 | .get_ro = omap_hsmmc_get_ro, |
1890 | .init_card = omap_hsmmc_init_card, | ||
1872 | /* NYET -- enable_sdio_irq */ | 1891 | /* NYET -- enable_sdio_irq */ |
1873 | }; | 1892 | }; |
1874 | 1893 | ||
@@ -1879,6 +1898,7 @@ static const struct mmc_host_ops omap_hsmmc_ps_ops = { | |||
1879 | .set_ios = omap_hsmmc_set_ios, | 1898 | .set_ios = omap_hsmmc_set_ios, |
1880 | .get_cd = omap_hsmmc_get_cd, | 1899 | .get_cd = omap_hsmmc_get_cd, |
1881 | .get_ro = omap_hsmmc_get_ro, | 1900 | .get_ro = omap_hsmmc_get_ro, |
1901 | .init_card = omap_hsmmc_init_card, | ||
1882 | /* NYET -- enable_sdio_irq */ | 1902 | /* NYET -- enable_sdio_irq */ |
1883 | }; | 1903 | }; |
1884 | 1904 | ||
@@ -2094,12 +2114,25 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
2094 | mmc->max_seg_size = mmc->max_req_size; | 2114 | mmc->max_seg_size = mmc->max_req_size; |
2095 | 2115 | ||
2096 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | | 2116 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | |
2097 | MMC_CAP_WAIT_WHILE_BUSY; | 2117 | MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; |
2098 | 2118 | ||
2099 | if (mmc_slot(host).wires >= 8) | 2119 | switch (mmc_slot(host).wires) { |
2120 | case 8: | ||
2100 | mmc->caps |= MMC_CAP_8_BIT_DATA; | 2121 | mmc->caps |= MMC_CAP_8_BIT_DATA; |
2101 | else if (mmc_slot(host).wires >= 4) | 2122 | /* Fall through */ |
2123 | case 4: | ||
2102 | mmc->caps |= MMC_CAP_4_BIT_DATA; | 2124 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
2125 | break; | ||
2126 | case 1: | ||
2127 | /* Nothing to crib here */ | ||
2128 | case 0: | ||
2129 | /* Assuming nothing was given by board, Core use's 1-Bit */ | ||
2130 | break; | ||
2131 | default: | ||
2132 | /* Completely unexpected.. Core goes with 1-Bit Width */ | ||
2133 | dev_crit(mmc_dev(host->mmc), "Invalid width %d\n used!" | ||
2134 | "using 1 instead\n", mmc_slot(host).wires); | ||
2135 | } | ||
2103 | 2136 | ||
2104 | if (mmc_slot(host).nonremovable) | 2137 | if (mmc_slot(host).nonremovable) |
2105 | mmc->caps |= MMC_CAP_NONREMOVABLE; | 2138 | mmc->caps |= MMC_CAP_NONREMOVABLE; |