mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 01:51:53 +00:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: mmc: core: Fix deadlock when the CONFIG_MMC_UNSAFE_RESUME is not defined mmc: sdhci-s3c: Remove old and misprototyped suspend operations mmc: tmio: fix clock gating on platforms with a .set_pwr() method mmc: sh_mmcif: fix clock gating on platforms with a .down_pwr() method mmc: core: Fix typo at mmc_card_sleep mmc: core: Fix power_off_notify during suspend mmc: core: Fix setting power notify state variable for non-eMMC mmc: core: Add quirk for long data read time mmc: Add module.h include to sdhci-cns3xxx.c mmc: mxcmmc: fix falling back to PIO mmc: omap_hsmmc: DMA unmap only once in case of MMC error
This commit is contained in:
commit
71fe5ccac7
@ -1606,6 +1606,14 @@ static const struct mmc_fixup blk_fixups[] =
|
||||
MMC_QUIRK_BLK_NO_CMD23),
|
||||
MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
|
||||
MMC_QUIRK_BLK_NO_CMD23),
|
||||
|
||||
/*
|
||||
* Some Micron MMC cards needs longer data read timeout than
|
||||
* indicated in CSD.
|
||||
*/
|
||||
MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc,
|
||||
MMC_QUIRK_LONG_READ_TIME),
|
||||
|
||||
END_FIXUP
|
||||
};
|
||||
|
||||
|
@ -529,6 +529,18 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
|
||||
data->timeout_clks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some cards require longer data read timeout than indicated in CSD.
|
||||
* Address this by setting the read timeout to a "reasonably high"
|
||||
* value. For the cards tested, 300ms has proven enough. If necessary,
|
||||
* this value can be increased if other problematic cards require this.
|
||||
*/
|
||||
if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) {
|
||||
data->timeout_ns = 300000000;
|
||||
data->timeout_clks = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some cards need very high timeouts if driven in SPI mode.
|
||||
* The worst observed timeout was 900ms after writing a
|
||||
@ -1213,6 +1225,46 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
|
||||
mmc_host_clk_release(host);
|
||||
}
|
||||
|
||||
static void mmc_poweroff_notify(struct mmc_host *host)
|
||||
{
|
||||
struct mmc_card *card;
|
||||
unsigned int timeout;
|
||||
unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
|
||||
int err = 0;
|
||||
|
||||
card = host->card;
|
||||
|
||||
/*
|
||||
* Send power notify command only if card
|
||||
* is mmc and notify state is powered ON
|
||||
*/
|
||||
if (card && mmc_card_mmc(card) &&
|
||||
(card->poweroff_notify_state == MMC_POWERED_ON)) {
|
||||
|
||||
if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
|
||||
notify_type = EXT_CSD_POWER_OFF_SHORT;
|
||||
timeout = card->ext_csd.generic_cmd6_time;
|
||||
card->poweroff_notify_state = MMC_POWEROFF_SHORT;
|
||||
} else {
|
||||
notify_type = EXT_CSD_POWER_OFF_LONG;
|
||||
timeout = card->ext_csd.power_off_longtime;
|
||||
card->poweroff_notify_state = MMC_POWEROFF_LONG;
|
||||
}
|
||||
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_POWER_OFF_NOTIFICATION,
|
||||
notify_type, timeout);
|
||||
|
||||
if (err && err != -EBADMSG)
|
||||
pr_err("Device failed to respond within %d poweroff "
|
||||
"time. Forcefully powering down the device\n",
|
||||
timeout);
|
||||
|
||||
/* Set the card state to no notification after the poweroff */
|
||||
card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply power to the MMC stack. This is a two-stage process.
|
||||
* First, we enable power to the card without the clock running.
|
||||
@ -1269,42 +1321,12 @@ static void mmc_power_up(struct mmc_host *host)
|
||||
|
||||
void mmc_power_off(struct mmc_host *host)
|
||||
{
|
||||
struct mmc_card *card;
|
||||
unsigned int notify_type;
|
||||
unsigned int timeout;
|
||||
int err;
|
||||
|
||||
mmc_host_clk_hold(host);
|
||||
|
||||
card = host->card;
|
||||
host->ios.clock = 0;
|
||||
host->ios.vdd = 0;
|
||||
|
||||
if (card && mmc_card_mmc(card) &&
|
||||
(card->poweroff_notify_state == MMC_POWERED_ON)) {
|
||||
|
||||
if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
|
||||
notify_type = EXT_CSD_POWER_OFF_SHORT;
|
||||
timeout = card->ext_csd.generic_cmd6_time;
|
||||
card->poweroff_notify_state = MMC_POWEROFF_SHORT;
|
||||
} else {
|
||||
notify_type = EXT_CSD_POWER_OFF_LONG;
|
||||
timeout = card->ext_csd.power_off_longtime;
|
||||
card->poweroff_notify_state = MMC_POWEROFF_LONG;
|
||||
}
|
||||
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_POWER_OFF_NOTIFICATION,
|
||||
notify_type, timeout);
|
||||
|
||||
if (err && err != -EBADMSG)
|
||||
pr_err("Device failed to respond within %d poweroff "
|
||||
"time. Forcefully powering down the device\n",
|
||||
timeout);
|
||||
|
||||
/* Set the card state to no notification after the poweroff */
|
||||
card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
|
||||
}
|
||||
mmc_poweroff_notify(host);
|
||||
|
||||
/*
|
||||
* Reset ocr mask to be the highest possible voltage supported for
|
||||
@ -2196,7 +2218,7 @@ int mmc_card_sleep(struct mmc_host *host)
|
||||
|
||||
mmc_bus_get(host);
|
||||
|
||||
if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
|
||||
if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
|
||||
err = host->bus_ops->sleep(host);
|
||||
|
||||
mmc_bus_put(host);
|
||||
@ -2302,8 +2324,17 @@ int mmc_suspend_host(struct mmc_host *host)
|
||||
* pre-claim the host.
|
||||
*/
|
||||
if (mmc_try_claim_host(host)) {
|
||||
if (host->bus_ops->suspend)
|
||||
if (host->bus_ops->suspend) {
|
||||
/*
|
||||
* For eMMC 4.5 device send notify command
|
||||
* before sleep, because in sleep state eMMC 4.5
|
||||
* devices respond to only RESET and AWAKE cmd
|
||||
*/
|
||||
mmc_poweroff_notify(host);
|
||||
err = host->bus_ops->suspend(host);
|
||||
}
|
||||
mmc_do_release_host(host);
|
||||
|
||||
if (err == -ENOSYS || !host->bus_ops->resume) {
|
||||
/*
|
||||
* We simply "remove" the card in this case.
|
||||
@ -2318,7 +2349,6 @@ int mmc_suspend_host(struct mmc_host *host)
|
||||
host->pm_flags = 0;
|
||||
err = 0;
|
||||
}
|
||||
mmc_do_release_host(host);
|
||||
} else {
|
||||
err = -EBUSY;
|
||||
}
|
||||
|
@ -876,17 +876,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
||||
* set the notification byte in the ext_csd register of device
|
||||
*/
|
||||
if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) &&
|
||||
(card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) {
|
||||
(card->ext_csd.rev >= 6)) {
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_POWER_OFF_NOTIFICATION,
|
||||
EXT_CSD_POWER_ON,
|
||||
card->ext_csd.generic_cmd6_time);
|
||||
if (err && err != -EBADMSG)
|
||||
goto free_card;
|
||||
}
|
||||
|
||||
if (!err)
|
||||
card->poweroff_notify_state = MMC_POWERED_ON;
|
||||
/*
|
||||
* The err can be -EBADMSG or 0,
|
||||
* so check for success and update the flag
|
||||
*/
|
||||
if (!err)
|
||||
card->poweroff_notify_state = MMC_POWERED_ON;
|
||||
}
|
||||
|
||||
/*
|
||||
* Activate high speed (if supported)
|
||||
|
@ -732,6 +732,7 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
"failed to config DMA channel. Falling back to PIO\n");
|
||||
dma_release_channel(host->dma);
|
||||
host->do_dma = 0;
|
||||
host->dma = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1010,6 +1010,7 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
|
||||
host->data->sg_len,
|
||||
omap_hsmmc_get_dma_dir(host, host->data));
|
||||
omap_free_dma(dma_ch);
|
||||
host->data->host_cookie = 0;
|
||||
}
|
||||
host->data = NULL;
|
||||
}
|
||||
@ -1575,8 +1576,10 @@ static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
|
||||
struct mmc_data *data = mrq->data;
|
||||
|
||||
if (host->use_dma) {
|
||||
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
|
||||
omap_hsmmc_get_dma_dir(host, data));
|
||||
if (data->host_cookie)
|
||||
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
|
||||
data->sg_len,
|
||||
omap_hsmmc_get_dma_dir(host, data));
|
||||
data->host_cookie = 0;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/module.h>
|
||||
#include <mach/cns3xxx.h>
|
||||
#include "sdhci-pltfm.h"
|
||||
|
||||
|
@ -644,8 +644,6 @@ static int sdhci_s3c_resume(struct platform_device *dev)
|
||||
static struct platform_driver sdhci_s3c_driver = {
|
||||
.probe = sdhci_s3c_probe,
|
||||
.remove = __devexit_p(sdhci_s3c_remove),
|
||||
.suspend = sdhci_s3c_suspend,
|
||||
.resume = sdhci_s3c_resume,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "s3c-sdhci",
|
||||
|
@ -908,7 +908,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
if (host->power) {
|
||||
pm_runtime_put(&host->pd->dev);
|
||||
host->power = false;
|
||||
if (p->down_pwr)
|
||||
if (p->down_pwr && ios->power_mode == MMC_POWER_OFF)
|
||||
p->down_pwr(host->pd);
|
||||
}
|
||||
host->state = STATE_IDLE;
|
||||
|
@ -798,7 +798,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
/* start bus clock */
|
||||
tmio_mmc_clk_start(host);
|
||||
} else if (ios->power_mode != MMC_POWER_UP) {
|
||||
if (host->set_pwr)
|
||||
if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
|
||||
host->set_pwr(host->pdev, 0);
|
||||
if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
|
||||
pdata->power) {
|
||||
|
@ -218,6 +218,7 @@ struct mmc_card {
|
||||
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
|
||||
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
|
||||
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
|
||||
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
|
||||
/* byte mode */
|
||||
unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */
|
||||
#define MMC_NO_POWER_NOTIFICATION 0
|
||||
@ -433,6 +434,11 @@ static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c)
|
||||
return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512;
|
||||
}
|
||||
|
||||
static inline int mmc_card_long_read_time(const struct mmc_card *c)
|
||||
{
|
||||
return c->quirks & MMC_QUIRK_LONG_READ_TIME;
|
||||
}
|
||||
|
||||
#define mmc_card_name(c) ((c)->cid.prod_name)
|
||||
#define mmc_card_id(c) (dev_name(&(c)->dev))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user