aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-09-05 22:41:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-09-05 22:41:58 -0400
commit080909503664641432cc8adf2ee2084775fd992a (patch)
tree115dc3c1c3ac5772dfd3c8b88c66c198cd84eb9e
parentbc6c83641e1df61cff67748987f95ca62953565e (diff)
parent75b53aee2f4fe6375c6007226bf68d75b5c4a929 (diff)
Merge tag 'mmc-fixes-for-3.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC fixes from Chris Ball: - a firmware bug on several Samsung MoviNAND eMMC models causes permanent corruption on the device when secure erase and secure trim requests are made, so we disable those requests on these eMMC devices. - atmel-mci: fix a hang with some SD cards by waiting for not-busy flag. - dw_mmc: low-power mode breaks SDIO interrupts; fix PIO error handling; fix handling of error interrupts. - mxs-mmc: fix deadlocks; fix compile error due to dma.h arch change. - omap: fix broken PIO mode causing memory corruption. - sdhci-esdhc: fix card detection. * tag 'mmc-fixes-for-3.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: mmc: omap: fix broken PIO mode mmc: card: Skip secure erase on MoviNAND; causes unrecoverable corruption. mmc: dw_mmc: Disable low power mode if SDIO interrupts are used mmc: dw_mmc: fix error handling in PIO mode mmc: dw_mmc: correct mishandling error interrupt mmc: dw_mmc: amend using error interrupt status mmc: atmel-mci: not busy flag has also to be used for read operations mmc: sdhci-esdhc: break out early if clock is 0 mmc: mxs-mmc: fix deadlock caused by recursion loop mmc: mxs-mmc: fix deadlock in SDIO IRQ case mmc: bfin_sdh: fix dma_desc_array build error
-rw-r--r--drivers/mmc/card/block.c26
-rw-r--r--drivers/mmc/host/atmel-mci.c6
-rw-r--r--drivers/mmc/host/bfin_sdh.c7
-rw-r--r--drivers/mmc/host/dw_mmc.c85
-rw-r--r--drivers/mmc/host/mxs-mmc.c14
-rw-r--r--drivers/mmc/host/omap.c14
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h6
-rw-r--r--include/linux/mmc/card.h1
8 files changed, 98 insertions, 61 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index f1c84decb192..172a768036d8 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1411,7 +1411,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
1411 /* complete ongoing async transfer before issuing discard */ 1411 /* complete ongoing async transfer before issuing discard */
1412 if (card->host->areq) 1412 if (card->host->areq)
1413 mmc_blk_issue_rw_rq(mq, NULL); 1413 mmc_blk_issue_rw_rq(mq, NULL);
1414 if (req->cmd_flags & REQ_SECURE) 1414 if (req->cmd_flags & REQ_SECURE &&
1415 !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN))
1415 ret = mmc_blk_issue_secdiscard_rq(mq, req); 1416 ret = mmc_blk_issue_secdiscard_rq(mq, req);
1416 else 1417 else
1417 ret = mmc_blk_issue_discard_rq(mq, req); 1418 ret = mmc_blk_issue_discard_rq(mq, req);
@@ -1716,6 +1717,7 @@ force_ro_fail:
1716#define CID_MANFID_SANDISK 0x2 1717#define CID_MANFID_SANDISK 0x2
1717#define CID_MANFID_TOSHIBA 0x11 1718#define CID_MANFID_TOSHIBA 0x11
1718#define CID_MANFID_MICRON 0x13 1719#define CID_MANFID_MICRON 0x13
1720#define CID_MANFID_SAMSUNG 0x15
1719 1721
1720static const struct mmc_fixup blk_fixups[] = 1722static const struct mmc_fixup blk_fixups[] =
1721{ 1723{
@@ -1752,6 +1754,28 @@ static const struct mmc_fixup blk_fixups[] =
1752 MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, 1754 MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
1753 MMC_QUIRK_LONG_READ_TIME), 1755 MMC_QUIRK_LONG_READ_TIME),
1754 1756
1757 /*
1758 * On these Samsung MoviNAND parts, performing secure erase or
1759 * secure trim can result in unrecoverable corruption due to a
1760 * firmware bug.
1761 */
1762 MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1763 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1764 MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1765 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1766 MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1767 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1768 MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1769 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1770 MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1771 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1772 MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1773 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1774 MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1775 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1776 MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
1777 MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
1778
1755 END_FIXUP 1779 END_FIXUP
1756}; 1780};
1757 1781
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 322412cec4ee..a53c7c478e05 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -81,6 +81,7 @@ struct atmel_mci_caps {
81 bool has_bad_data_ordering; 81 bool has_bad_data_ordering;
82 bool need_reset_after_xfer; 82 bool need_reset_after_xfer;
83 bool need_blksz_mul_4; 83 bool need_blksz_mul_4;
84 bool need_notbusy_for_read_ops;
84}; 85};
85 86
86struct atmel_mci_dma { 87struct atmel_mci_dma {
@@ -1625,7 +1626,8 @@ static void atmci_tasklet_func(unsigned long priv)
1625 __func__); 1626 __func__);
1626 atmci_set_completed(host, EVENT_XFER_COMPLETE); 1627 atmci_set_completed(host, EVENT_XFER_COMPLETE);
1627 1628
1628 if (host->data->flags & MMC_DATA_WRITE) { 1629 if (host->caps.need_notbusy_for_read_ops ||
1630 (host->data->flags & MMC_DATA_WRITE)) {
1629 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); 1631 atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY);
1630 state = STATE_WAITING_NOTBUSY; 1632 state = STATE_WAITING_NOTBUSY;
1631 } else if (host->mrq->stop) { 1633 } else if (host->mrq->stop) {
@@ -2218,6 +2220,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)
2218 host->caps.has_bad_data_ordering = 1; 2220 host->caps.has_bad_data_ordering = 1;
2219 host->caps.need_reset_after_xfer = 1; 2221 host->caps.need_reset_after_xfer = 1;
2220 host->caps.need_blksz_mul_4 = 1; 2222 host->caps.need_blksz_mul_4 = 1;
2223 host->caps.need_notbusy_for_read_ops = 0;
2221 2224
2222 /* keep only major version number */ 2225 /* keep only major version number */
2223 switch (version & 0xf00) { 2226 switch (version & 0xf00) {
@@ -2238,6 +2241,7 @@ static void __init atmci_get_cap(struct atmel_mci *host)
2238 case 0x200: 2241 case 0x200:
2239 host->caps.has_rwproof = 1; 2242 host->caps.has_rwproof = 1;
2240 host->caps.need_blksz_mul_4 = 0; 2243 host->caps.need_blksz_mul_4 = 0;
2244 host->caps.need_notbusy_for_read_ops = 1;
2241 case 0x100: 2245 case 0x100:
2242 host->caps.has_bad_data_ordering = 0; 2246 host->caps.has_bad_data_ordering = 0;
2243 host->caps.need_reset_after_xfer = 0; 2247 host->caps.need_reset_after_xfer = 0;
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index 03666174ca48..a17dd7363ceb 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -49,13 +49,6 @@
49#define bfin_write_SDH_CFG bfin_write_RSI_CFG 49#define bfin_write_SDH_CFG bfin_write_RSI_CFG
50#endif 50#endif
51 51
52struct dma_desc_array {
53 unsigned long start_addr;
54 unsigned short cfg;
55 unsigned short x_count;
56 short x_modify;
57} __packed;
58
59struct sdh_host { 52struct sdh_host {
60 struct mmc_host *mmc; 53 struct mmc_host *mmc;
61 spinlock_t lock; 54 spinlock_t lock;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 72dc3cde646d..af40d227bece 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -627,6 +627,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
627{ 627{
628 struct dw_mci *host = slot->host; 628 struct dw_mci *host = slot->host;
629 u32 div; 629 u32 div;
630 u32 clk_en_a;
630 631
631 if (slot->clock != host->current_speed) { 632 if (slot->clock != host->current_speed) {
632 div = host->bus_hz / slot->clock; 633 div = host->bus_hz / slot->clock;
@@ -659,9 +660,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
659 mci_send_cmd(slot, 660 mci_send_cmd(slot,
660 SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); 661 SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0);
661 662
662 /* enable clock */ 663 /* enable clock; only low power if no SDIO */
663 mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE | 664 clk_en_a = SDMMC_CLKEN_ENABLE << slot->id;
664 SDMMC_CLKEN_LOW_PWR) << slot->id)); 665 if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id)))
666 clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id;
667 mci_writel(host, CLKENA, clk_en_a);
665 668
666 /* inform CIU */ 669 /* inform CIU */
667 mci_send_cmd(slot, 670 mci_send_cmd(slot,
@@ -862,6 +865,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc)
862 return present; 865 return present;
863} 866}
864 867
868/*
869 * Disable lower power mode.
870 *
871 * Low power mode will stop the card clock when idle. According to the
872 * description of the CLKENA register we should disable low power mode
873 * for SDIO cards if we need SDIO interrupts to work.
874 *
875 * This function is fast if low power mode is already disabled.
876 */
877static void dw_mci_disable_low_power(struct dw_mci_slot *slot)
878{
879 struct dw_mci *host = slot->host;
880 u32 clk_en_a;
881 const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
882
883 clk_en_a = mci_readl(host, CLKENA);
884
885 if (clk_en_a & clken_low_pwr) {
886 mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr);
887 mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
888 SDMMC_CMD_PRV_DAT_WAIT, 0);
889 }
890}
891
865static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) 892static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
866{ 893{
867 struct dw_mci_slot *slot = mmc_priv(mmc); 894 struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -871,6 +898,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
871 /* Enable/disable Slot Specific SDIO interrupt */ 898 /* Enable/disable Slot Specific SDIO interrupt */
872 int_mask = mci_readl(host, INTMASK); 899 int_mask = mci_readl(host, INTMASK);
873 if (enb) { 900 if (enb) {
901 /*
902 * Turn off low power mode if it was enabled. This is a bit of
903 * a heavy operation and we disable / enable IRQs a lot, so
904 * we'll leave low power mode disabled and it will get
905 * re-enabled again in dw_mci_setup_bus().
906 */
907 dw_mci_disable_low_power(slot);
908
874 mci_writel(host, INTMASK, 909 mci_writel(host, INTMASK,
875 (int_mask | SDMMC_INT_SDIO(slot->id))); 910 (int_mask | SDMMC_INT_SDIO(slot->id)));
876 } else { 911 } else {
@@ -1429,22 +1464,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host)
1429 nbytes += len; 1464 nbytes += len;
1430 remain -= len; 1465 remain -= len;
1431 } while (remain); 1466 } while (remain);
1432 sg_miter->consumed = offset;
1433 1467
1468 sg_miter->consumed = offset;
1434 status = mci_readl(host, MINTSTS); 1469 status = mci_readl(host, MINTSTS);
1435 mci_writel(host, RINTSTS, SDMMC_INT_RXDR); 1470 mci_writel(host, RINTSTS, SDMMC_INT_RXDR);
1436 if (status & DW_MCI_DATA_ERROR_FLAGS) {
1437 host->data_status = status;
1438 data->bytes_xfered += nbytes;
1439 sg_miter_stop(sg_miter);
1440 host->sg = NULL;
1441 smp_wmb();
1442
1443 set_bit(EVENT_DATA_ERROR, &host->pending_events);
1444
1445 tasklet_schedule(&host->tasklet);
1446 return;
1447 }
1448 } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ 1471 } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/
1449 data->bytes_xfered += nbytes; 1472 data->bytes_xfered += nbytes;
1450 1473
@@ -1497,23 +1520,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host)
1497 nbytes += len; 1520 nbytes += len;
1498 remain -= len; 1521 remain -= len;
1499 } while (remain); 1522 } while (remain);
1500 sg_miter->consumed = offset;
1501 1523
1524 sg_miter->consumed = offset;
1502 status = mci_readl(host, MINTSTS); 1525 status = mci_readl(host, MINTSTS);
1503 mci_writel(host, RINTSTS, SDMMC_INT_TXDR); 1526 mci_writel(host, RINTSTS, SDMMC_INT_TXDR);
1504 if (status & DW_MCI_DATA_ERROR_FLAGS) {
1505 host->data_status = status;
1506 data->bytes_xfered += nbytes;
1507 sg_miter_stop(sg_miter);
1508 host->sg = NULL;
1509
1510 smp_wmb();
1511
1512 set_bit(EVENT_DATA_ERROR, &host->pending_events);
1513
1514 tasklet_schedule(&host->tasklet);
1515 return;
1516 }
1517 } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ 1527 } while (status & SDMMC_INT_TXDR); /* if TXDR write again */
1518 data->bytes_xfered += nbytes; 1528 data->bytes_xfered += nbytes;
1519 1529
@@ -1547,12 +1557,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)
1547static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) 1557static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
1548{ 1558{
1549 struct dw_mci *host = dev_id; 1559 struct dw_mci *host = dev_id;
1550 u32 status, pending; 1560 u32 pending;
1551 unsigned int pass_count = 0; 1561 unsigned int pass_count = 0;
1552 int i; 1562 int i;
1553 1563
1554 do { 1564 do {
1555 status = mci_readl(host, RINTSTS);
1556 pending = mci_readl(host, MINTSTS); /* read-only mask reg */ 1565 pending = mci_readl(host, MINTSTS); /* read-only mask reg */
1557 1566
1558 /* 1567 /*
@@ -1570,7 +1579,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
1570 1579
1571 if (pending & DW_MCI_CMD_ERROR_FLAGS) { 1580 if (pending & DW_MCI_CMD_ERROR_FLAGS) {
1572 mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); 1581 mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
1573 host->cmd_status = status; 1582 host->cmd_status = pending;
1574 smp_wmb(); 1583 smp_wmb();
1575 set_bit(EVENT_CMD_COMPLETE, &host->pending_events); 1584 set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
1576 } 1585 }
@@ -1578,18 +1587,16 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
1578 if (pending & DW_MCI_DATA_ERROR_FLAGS) { 1587 if (pending & DW_MCI_DATA_ERROR_FLAGS) {
1579 /* if there is an error report DATA_ERROR */ 1588 /* if there is an error report DATA_ERROR */
1580 mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); 1589 mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS);
1581 host->data_status = status; 1590 host->data_status = pending;
1582 smp_wmb(); 1591 smp_wmb();
1583 set_bit(EVENT_DATA_ERROR, &host->pending_events); 1592 set_bit(EVENT_DATA_ERROR, &host->pending_events);
1584 if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | 1593 tasklet_schedule(&host->tasklet);
1585 SDMMC_INT_SBE | SDMMC_INT_EBE)))
1586 tasklet_schedule(&host->tasklet);
1587 } 1594 }
1588 1595
1589 if (pending & SDMMC_INT_DATA_OVER) { 1596 if (pending & SDMMC_INT_DATA_OVER) {
1590 mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); 1597 mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);
1591 if (!host->data_status) 1598 if (!host->data_status)
1592 host->data_status = status; 1599 host->data_status = pending;
1593 smp_wmb(); 1600 smp_wmb();
1594 if (host->dir_status == DW_MCI_RECV_STATUS) { 1601 if (host->dir_status == DW_MCI_RECV_STATUS) {
1595 if (host->sg != NULL) 1602 if (host->sg != NULL)
@@ -1613,7 +1620,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
1613 1620
1614 if (pending & SDMMC_INT_CMD_DONE) { 1621 if (pending & SDMMC_INT_CMD_DONE) {
1615 mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); 1622 mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE);
1616 dw_mci_cmd_interrupt(host, status); 1623 dw_mci_cmd_interrupt(host, pending);
1617 } 1624 }
1618 1625
1619 if (pending & SDMMC_INT_CD) { 1626 if (pending & SDMMC_INT_CD) {
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index a51f9309ffbb..ad3fcea1269e 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -285,11 +285,11 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
285 writel(stat & MXS_MMC_IRQ_BITS, 285 writel(stat & MXS_MMC_IRQ_BITS,
286 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); 286 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
287 287
288 spin_unlock(&host->lock);
289
288 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) 290 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
289 mmc_signal_sdio_irq(host->mmc); 291 mmc_signal_sdio_irq(host->mmc);
290 292
291 spin_unlock(&host->lock);
292
293 if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) 293 if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ)
294 cmd->error = -ETIMEDOUT; 294 cmd->error = -ETIMEDOUT;
295 else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) 295 else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ)
@@ -644,11 +644,6 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
644 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); 644 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
645 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 645 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
646 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); 646 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
647
648 if (readl(host->base + HW_SSP_STATUS(host)) &
649 BM_SSP_STATUS_SDIO_IRQ)
650 mmc_signal_sdio_irq(host->mmc);
651
652 } else { 647 } else {
653 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 648 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
654 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); 649 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
@@ -657,6 +652,11 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
657 } 652 }
658 653
659 spin_unlock_irqrestore(&host->lock, flags); 654 spin_unlock_irqrestore(&host->lock, flags);
655
656 if (enable && readl(host->base + HW_SSP_STATUS(host)) &
657 BM_SSP_STATUS_SDIO_IRQ)
658 mmc_signal_sdio_irq(host->mmc);
659
660} 660}
661 661
662static const struct mmc_host_ops mxs_mmc_ops = { 662static const struct mmc_host_ops mxs_mmc_ops = {
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 50e08f03aa65..a5999a74496a 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -668,7 +668,7 @@ mmc_omap_clk_timer(unsigned long data)
668static void 668static void
669mmc_omap_xfer_data(struct mmc_omap_host *host, int write) 669mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
670{ 670{
671 int n; 671 int n, nwords;
672 672
673 if (host->buffer_bytes_left == 0) { 673 if (host->buffer_bytes_left == 0) {
674 host->sg_idx++; 674 host->sg_idx++;
@@ -678,15 +678,23 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
678 n = 64; 678 n = 64;
679 if (n > host->buffer_bytes_left) 679 if (n > host->buffer_bytes_left)
680 n = host->buffer_bytes_left; 680 n = host->buffer_bytes_left;
681
682 nwords = n / 2;
683 nwords += n & 1; /* handle odd number of bytes to transfer */
684
681 host->buffer_bytes_left -= n; 685 host->buffer_bytes_left -= n;
682 host->total_bytes_left -= n; 686 host->total_bytes_left -= n;
683 host->data->bytes_xfered += n; 687 host->data->bytes_xfered += n;
684 688
685 if (write) { 689 if (write) {
686 __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); 690 __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA),
691 host->buffer, nwords);
687 } else { 692 } else {
688 __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); 693 __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA),
694 host->buffer, nwords);
689 } 695 }
696
697 host->buffer += nwords;
690} 698}
691 699
692static inline void mmc_omap_report_irq(u16 status) 700static inline void mmc_omap_report_irq(u16 status)
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index b97b2f5dafdb..d25f9ab9a54d 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
48 int div = 1; 48 int div = 1;
49 u32 temp; 49 u32 temp;
50 50
51 if (clock == 0)
52 goto out;
53
51 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); 54 temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
52 temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN 55 temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
53 | ESDHC_CLOCK_MASK); 56 | ESDHC_CLOCK_MASK);
54 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); 57 sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
55 58
56 if (clock == 0)
57 goto out;
58
59 while (host->max_clk / pre_div / 16 > clock && pre_div < 256) 59 while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
60 pre_div *= 2; 60 pre_div *= 2;
61 61
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 111aca5e97f3..4b27f9f503e4 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -239,6 +239,7 @@ struct mmc_card {
239#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ 239#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
240#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ 240#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
241#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ 241#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
242#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
242 /* byte mode */ 243 /* byte mode */
243 unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ 244 unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */
244#define MMC_NO_POWER_NOTIFICATION 0 245#define MMC_NO_POWER_NOTIFICATION 0