diff options
Diffstat (limited to 'drivers/mmc/host/tmio_mmc_pio.c')
-rw-r--r-- | drivers/mmc/host/tmio_mmc_pio.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 92467efc4e2c..700567603107 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -336,7 +336,9 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command switch (mmc_resp_type(cmd)) { case MMC_RSP_NONE: c |= RESP_NONE; break; - case MMC_RSP_R1: c |= RESP_R1; break; + case MMC_RSP_R1: + case MMC_RSP_R1_NO_CRC: + c |= RESP_R1; break; case MMC_RSP_R1B: c |= RESP_R1B; break; case MMC_RSP_R2: c |= RESP_R2; break; case MMC_RSP_R3: c |= RESP_R3; break; @@ -730,12 +732,13 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host, pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", data->blksz, data->blocks); - /* Some hardware cannot perform 2 byte requests in 4 bit mode */ - if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) { + /* Some hardware cannot perform 2 byte requests in 4/8 bit mode */ + if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4 || + host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) { int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES; if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) { - pr_err("%s: %d byte block unsupported in 4 bit mode\n", + pr_err("%s: %d byte block unsupported in 4/8 bit mode\n", mmc_hostname(host->mmc), data->blksz); return -EINVAL; } @@ -857,14 +860,16 @@ static void tmio_mmc_power_off(struct tmio_mmc_host *host) static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host, unsigned char bus_width) { - switch (bus_width) { - case MMC_BUS_WIDTH_1: - sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0); - break; - case MMC_BUS_WIDTH_4: - sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); - break; - } + u16 reg = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT) + & ~(CARD_OPT_WIDTH | CARD_OPT_WIDTH8); + + /* reg now applies to MMC_BUS_WIDTH_4 */ + if (bus_width == MMC_BUS_WIDTH_1) + reg |= CARD_OPT_WIDTH; + else if (bus_width == MMC_BUS_WIDTH_8) + reg |= CARD_OPT_WIDTH8; + + sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg); } /* Set MMC clock / power. @@ -960,20 +965,12 @@ static int tmio_multi_io_quirk(struct mmc_card *card, return blk_size; } -static int tmio_mmc_card_busy(struct mmc_host *mmc) -{ - struct tmio_mmc_host *host = mmc_priv(mmc); - - return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_DAT0); -} - static struct mmc_host_ops tmio_mmc_ops = { .request = tmio_mmc_request, .set_ios = tmio_mmc_set_ios, .get_ro = tmio_mmc_get_ro, .get_cd = mmc_gpio_get_cd, .enable_sdio_irq = tmio_mmc_enable_sdio_irq, - .card_busy = tmio_mmc_card_busy, .multi_io_quirk = tmio_multi_io_quirk, }; @@ -1072,6 +1069,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, goto host_free; } + tmio_mmc_ops.card_busy = _host->card_busy; tmio_mmc_ops.start_signal_voltage_switch = _host->start_signal_voltage_switch; mmc->ops = &tmio_mmc_ops; @@ -1089,6 +1087,15 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, !mmc_card_is_removable(mmc) || mmc->slot.cd_irq >= 0); + /* + * On Gen2+, eMMC with NONREMOVABLE currently fails because native + * hotplug gets disabled. It seems RuntimePM related yet we need further + * research. Since we are planning a PM overhaul anyway, let's enforce + * for now the device being active by enabling native hotplug always. + */ + if (pdata->flags & TMIO_MMC_MIN_RCAR2) + _host->native_hotplug = true; + if (tmio_mmc_clk_enable(_host) < 0) { mmc->f_max = pdata->hclk; mmc->f_min = mmc->f_max / 512; |