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: remove unused "ddr" parameter in struct mmc_ios mmc: dw_mmc: Fix DDR mode support. mmc: core: use defined R1_STATE_PRG macro for card status mmc: sdhci: use f_max instead of host->clock for timeouts mmc: sdhci: move timeout_clk calculation farther down mmc: sdhci: check host->clock before using it as a denominator mmc: Revert "mmc: sdhci: Fix SDHCI_QUIRK_TIMEOUT_USES_SDCLK" mmc: tmio: eliminate unused variable 'mmc' warning mmc: esdhc-imx: fix card interrupt loss on freescale eSDHC mmc: sdhci-s3c: Fix build for header change mmc: dw_mmc: Fix mask in IDMAC_SET_BUFFER1_SIZE macro mmc: cb710: fix possible pci_dev leak in cb710_pci_configure() mmc: core: Detect eMMC v4.5 ext_csd entries mmc: mmc_test: avoid stalled file in debugfs mmc: sdhci-s3c: add BROKEN_ADMA_ZEROLEN_DESC quirk mmc: sdhci: pxav3: controller needs 32 bit ADMA addressing mmc: sdhci: fix retuning timer wrongly deleted in sdhci_tasklet_finish
This commit is contained in:
commit
97c24d1d45
12 changed files with 99 additions and 76 deletions
|
@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(cb710_pci_update_config_reg);
|
||||||
static int __devinit cb710_pci_configure(struct pci_dev *pdev)
|
static int __devinit cb710_pci_configure(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
unsigned int devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
|
unsigned int devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
|
||||||
struct pci_dev *pdev0 = pci_get_slot(pdev->bus, devfn);
|
struct pci_dev *pdev0;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
cb710_pci_update_config_reg(pdev, 0x48,
|
cb710_pci_update_config_reg(pdev, 0x48,
|
||||||
|
@ -43,6 +43,7 @@ static int __devinit cb710_pci_configure(struct pci_dev *pdev)
|
||||||
if (val & 0x80000000)
|
if (val & 0x80000000)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
pdev0 = pci_get_slot(pdev->bus, devfn);
|
||||||
if (!pdev0)
|
if (!pdev0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,7 @@ static void mmc_test_prepare_mrq(struct mmc_test_card *test,
|
||||||
static int mmc_test_busy(struct mmc_command *cmd)
|
static int mmc_test_busy(struct mmc_command *cmd)
|
||||||
{
|
{
|
||||||
return !(cmd->resp[0] & R1_READY_FOR_DATA) ||
|
return !(cmd->resp[0] & R1_READY_FOR_DATA) ||
|
||||||
(R1_CURRENT_STATE(cmd->resp[0]) == 7);
|
(R1_CURRENT_STATE(cmd->resp[0]) == R1_STATE_PRG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2900,7 +2900,7 @@ static const struct file_operations mmc_test_fops_testlist = {
|
||||||
.release = single_release,
|
.release = single_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mmc_test_free_file_test(struct mmc_card *card)
|
static void mmc_test_free_dbgfs_file(struct mmc_card *card)
|
||||||
{
|
{
|
||||||
struct mmc_test_dbgfs_file *df, *dfs;
|
struct mmc_test_dbgfs_file *df, *dfs;
|
||||||
|
|
||||||
|
@ -2917,34 +2917,21 @@ static void mmc_test_free_file_test(struct mmc_card *card)
|
||||||
mutex_unlock(&mmc_test_lock);
|
mutex_unlock(&mmc_test_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mmc_test_register_file_test(struct mmc_card *card)
|
static int __mmc_test_register_dbgfs_file(struct mmc_card *card,
|
||||||
|
const char *name, mode_t mode, const struct file_operations *fops)
|
||||||
{
|
{
|
||||||
struct dentry *file = NULL;
|
struct dentry *file = NULL;
|
||||||
struct mmc_test_dbgfs_file *df;
|
struct mmc_test_dbgfs_file *df;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
mutex_lock(&mmc_test_lock);
|
|
||||||
|
|
||||||
if (card->debugfs_root)
|
if (card->debugfs_root)
|
||||||
file = debugfs_create_file("test", S_IWUSR | S_IRUGO,
|
file = debugfs_create_file(name, mode, card->debugfs_root,
|
||||||
card->debugfs_root, card, &mmc_test_fops_test);
|
card, fops);
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(file)) {
|
if (IS_ERR_OR_NULL(file)) {
|
||||||
dev_err(&card->dev,
|
dev_err(&card->dev,
|
||||||
"Can't create test. Perhaps debugfs is disabled.\n");
|
"Can't create %s. Perhaps debugfs is disabled.\n",
|
||||||
ret = -ENODEV;
|
name);
|
||||||
goto err;
|
return -ENODEV;
|
||||||
}
|
|
||||||
|
|
||||||
if (card->debugfs_root)
|
|
||||||
file = debugfs_create_file("testlist", S_IRUGO,
|
|
||||||
card->debugfs_root, card, &mmc_test_fops_testlist);
|
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(file)) {
|
|
||||||
dev_err(&card->dev,
|
|
||||||
"Can't create testlist. Perhaps debugfs is disabled.\n");
|
|
||||||
ret = -ENODEV;
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
df = kmalloc(sizeof(struct mmc_test_dbgfs_file), GFP_KERNEL);
|
df = kmalloc(sizeof(struct mmc_test_dbgfs_file), GFP_KERNEL);
|
||||||
|
@ -2952,14 +2939,31 @@ static int mmc_test_register_file_test(struct mmc_card *card)
|
||||||
debugfs_remove(file);
|
debugfs_remove(file);
|
||||||
dev_err(&card->dev,
|
dev_err(&card->dev,
|
||||||
"Can't allocate memory for internal usage.\n");
|
"Can't allocate memory for internal usage.\n");
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
df->card = card;
|
df->card = card;
|
||||||
df->file = file;
|
df->file = file;
|
||||||
|
|
||||||
list_add(&df->link, &mmc_test_file_test);
|
list_add(&df->link, &mmc_test_file_test);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mmc_test_register_dbgfs_file(struct mmc_card *card)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&mmc_test_lock);
|
||||||
|
|
||||||
|
ret = __mmc_test_register_dbgfs_file(card, "test", S_IWUSR | S_IRUGO,
|
||||||
|
&mmc_test_fops_test);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ret = __mmc_test_register_dbgfs_file(card, "testlist", S_IRUGO,
|
||||||
|
&mmc_test_fops_testlist);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
mutex_unlock(&mmc_test_lock);
|
mutex_unlock(&mmc_test_lock);
|
||||||
|
@ -2974,7 +2978,7 @@ static int mmc_test_probe(struct mmc_card *card)
|
||||||
if (!mmc_card_mmc(card) && !mmc_card_sd(card))
|
if (!mmc_card_mmc(card) && !mmc_card_sd(card))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
ret = mmc_test_register_file_test(card);
|
ret = mmc_test_register_dbgfs_file(card);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -2986,7 +2990,7 @@ static int mmc_test_probe(struct mmc_card *card)
|
||||||
static void mmc_test_remove(struct mmc_card *card)
|
static void mmc_test_remove(struct mmc_card *card)
|
||||||
{
|
{
|
||||||
mmc_test_free_result(card);
|
mmc_test_free_result(card);
|
||||||
mmc_test_free_file_test(card);
|
mmc_test_free_dbgfs_file(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mmc_driver mmc_driver = {
|
static struct mmc_driver mmc_driver = {
|
||||||
|
@ -3006,7 +3010,7 @@ static void __exit mmc_test_exit(void)
|
||||||
{
|
{
|
||||||
/* Clear stalled data if card is still plugged */
|
/* Clear stalled data if card is still plugged */
|
||||||
mmc_test_free_result(NULL);
|
mmc_test_free_result(NULL);
|
||||||
mmc_test_free_file_test(NULL);
|
mmc_test_free_dbgfs_file(NULL);
|
||||||
|
|
||||||
mmc_unregister_driver(&mmc_driver);
|
mmc_unregister_driver(&mmc_driver);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1502,7 +1502,7 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
|
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
|
||||||
R1_CURRENT_STATE(cmd.resp[0]) == 7);
|
R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,7 +259,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
||||||
}
|
}
|
||||||
|
|
||||||
card->ext_csd.rev = ext_csd[EXT_CSD_REV];
|
card->ext_csd.rev = ext_csd[EXT_CSD_REV];
|
||||||
if (card->ext_csd.rev > 5) {
|
if (card->ext_csd.rev > 6) {
|
||||||
printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n",
|
printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n",
|
||||||
mmc_hostname(card->host), card->ext_csd.rev);
|
mmc_hostname(card->host), card->ext_csd.rev);
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
|
@ -407,7 +407,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
|
||||||
break;
|
break;
|
||||||
if (mmc_host_is_spi(card->host))
|
if (mmc_host_is_spi(card->host))
|
||||||
break;
|
break;
|
||||||
} while (R1_CURRENT_STATE(status) == 7);
|
} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
|
||||||
|
|
||||||
if (mmc_host_is_spi(card->host)) {
|
if (mmc_host_is_spi(card->host)) {
|
||||||
if (status & R1_SPI_ILLEGAL_COMMAND)
|
if (status & R1_SPI_ILLEGAL_COMMAND)
|
||||||
|
|
|
@ -62,7 +62,7 @@ struct idmac_desc {
|
||||||
|
|
||||||
u32 des1; /* Buffer sizes */
|
u32 des1; /* Buffer sizes */
|
||||||
#define IDMAC_SET_BUFFER1_SIZE(d, s) \
|
#define IDMAC_SET_BUFFER1_SIZE(d, s) \
|
||||||
((d)->des1 = ((d)->des1 & 0x03ffc000) | ((s) & 0x3fff))
|
((d)->des1 = ((d)->des1 & 0x03ffe000) | ((s) & 0x1fff))
|
||||||
|
|
||||||
u32 des2; /* buffer 1 physical address */
|
u32 des2; /* buffer 1 physical address */
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DDR mode set */
|
/* DDR mode set */
|
||||||
if (ios->ddr) {
|
if (ios->timing == MMC_TIMING_UHS_DDR50) {
|
||||||
regs = mci_readl(slot->host, UHS_REG);
|
regs = mci_readl(slot->host, UHS_REG);
|
||||||
regs |= (0x1 << slot->id) << 16;
|
regs |= (0x1 << slot->id) << 16;
|
||||||
mci_writel(slot->host, UHS_REG, regs);
|
mci_writel(slot->host, UHS_REG, regs);
|
||||||
|
@ -1646,7 +1646,7 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||||
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
mmc->caps |= MMC_CAP_4_BIT_DATA;
|
||||||
|
|
||||||
if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
|
if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
|
||||||
mmc->caps |= MMC_CAP_SD_HIGHSPEED;
|
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||||
|
|
||||||
#ifdef CONFIG_MMC_DW_IDMAC
|
#ifdef CONFIG_MMC_DW_IDMAC
|
||||||
mmc->max_segs = host->ring_size;
|
mmc->max_segs = host->ring_size;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "sdhci-pltfm.h"
|
#include "sdhci-pltfm.h"
|
||||||
#include "sdhci-esdhc.h"
|
#include "sdhci-esdhc.h"
|
||||||
|
|
||||||
|
#define SDHCI_CTRL_D3CD 0x08
|
||||||
/* VENDOR SPEC register */
|
/* VENDOR SPEC register */
|
||||||
#define SDHCI_VENDOR_SPEC 0xC0
|
#define SDHCI_VENDOR_SPEC 0xC0
|
||||||
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
|
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
|
||||||
|
@ -141,14 +142,33 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
|
||||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||||
struct pltfm_imx_data *imx_data = pltfm_host->priv;
|
struct pltfm_imx_data *imx_data = pltfm_host->priv;
|
||||||
struct esdhc_platform_data *boarddata = &imx_data->boarddata;
|
struct esdhc_platform_data *boarddata = &imx_data->boarddata;
|
||||||
|
u32 data;
|
||||||
|
|
||||||
if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
|
if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
|
||||||
&& (boarddata->cd_type == ESDHC_CD_GPIO)))
|
if (boarddata->cd_type == ESDHC_CD_GPIO)
|
||||||
/*
|
/*
|
||||||
* these interrupts won't work with a custom card_detect gpio
|
* These interrupts won't work with a custom
|
||||||
|
* card_detect gpio (only applied to mx25/35)
|
||||||
*/
|
*/
|
||||||
val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
|
val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
|
||||||
|
|
||||||
|
if (val & SDHCI_INT_CARD_INT) {
|
||||||
|
/*
|
||||||
|
* Clear and then set D3CD bit to avoid missing the
|
||||||
|
* card interrupt. This is a eSDHC controller problem
|
||||||
|
* so we need to apply the following workaround: clear
|
||||||
|
* and set D3CD bit will make eSDHC re-sample the card
|
||||||
|
* interrupt. In case a card interrupt was lost,
|
||||||
|
* re-sample it by the following steps.
|
||||||
|
*/
|
||||||
|
data = readl(host->ioaddr + SDHCI_HOST_CONTROL);
|
||||||
|
data &= ~SDHCI_CTRL_D3CD;
|
||||||
|
writel(data, host->ioaddr + SDHCI_HOST_CONTROL);
|
||||||
|
data |= SDHCI_CTRL_D3CD;
|
||||||
|
writel(data, host->ioaddr + SDHCI_HOST_CONTROL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
|
if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
|
||||||
&& (reg == SDHCI_INT_STATUS)
|
&& (reg == SDHCI_INT_STATUS)
|
||||||
&& (val & SDHCI_INT_DATA_END))) {
|
&& (val & SDHCI_INT_DATA_END))) {
|
||||||
|
@ -217,8 +237,10 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
case SDHCI_HOST_CONTROL:
|
case SDHCI_HOST_CONTROL:
|
||||||
/* FSL messed up here, so we can just keep those two */
|
/* FSL messed up here, so we can just keep those three */
|
||||||
new_val = val & (SDHCI_CTRL_LED | SDHCI_CTRL_4BITBUS);
|
new_val = val & (SDHCI_CTRL_LED | \
|
||||||
|
SDHCI_CTRL_4BITBUS | \
|
||||||
|
SDHCI_CTRL_D3CD);
|
||||||
/* ensure the endianess */
|
/* ensure the endianess */
|
||||||
new_val |= ESDHC_HOST_CONTROL_LE;
|
new_val |= ESDHC_HOST_CONTROL_LE;
|
||||||
/* DMA mode bits are shifted */
|
/* DMA mode bits are shifted */
|
||||||
|
|
|
@ -195,7 +195,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev)
|
||||||
clk_enable(clk);
|
clk_enable(clk);
|
||||||
|
|
||||||
host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
|
host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
|
||||||
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
|
| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
|
||||||
|
| SDHCI_QUIRK_32BIT_ADMA_SIZE;
|
||||||
|
|
||||||
/* enable 1/8V DDR capable */
|
/* enable 1/8V DDR capable */
|
||||||
host->mmc->caps |= MMC_CAP_1_8V_DDR;
|
host->mmc->caps |= MMC_CAP_1_8V_DDR;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
|
|
||||||
|
@ -502,6 +503,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
|
||||||
/* This host supports the Auto CMD12 */
|
/* This host supports the Auto CMD12 */
|
||||||
host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
|
host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
|
||||||
|
|
||||||
|
/* Samsung SoCs need BROKEN_ADMA_ZEROLEN_DESC */
|
||||||
|
host->quirks |= SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC;
|
||||||
|
|
||||||
if (pdata->cd_type == S3C_SDHCI_CD_NONE ||
|
if (pdata->cd_type == S3C_SDHCI_CD_NONE ||
|
||||||
pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
|
pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
|
||||||
host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
|
host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
|
||||||
|
|
|
@ -628,12 +628,11 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
|
||||||
/* timeout in us */
|
/* timeout in us */
|
||||||
if (!data)
|
if (!data)
|
||||||
target_timeout = cmd->cmd_timeout_ms * 1000;
|
target_timeout = cmd->cmd_timeout_ms * 1000;
|
||||||
else
|
else {
|
||||||
target_timeout = data->timeout_ns / 1000 +
|
target_timeout = data->timeout_ns / 1000;
|
||||||
data->timeout_clks / host->clock;
|
if (host->clock)
|
||||||
|
target_timeout += data->timeout_clks / host->clock;
|
||||||
if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
|
}
|
||||||
host->timeout_clk = host->clock / 1000;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Figure out needed cycles.
|
* Figure out needed cycles.
|
||||||
|
@ -645,7 +644,6 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
|
||||||
* =>
|
* =>
|
||||||
* (1) / (2) > 2^6
|
* (1) / (2) > 2^6
|
||||||
*/
|
*/
|
||||||
BUG_ON(!host->timeout_clk);
|
|
||||||
count = 0;
|
count = 0;
|
||||||
current_timeout = (1 << 13) * 1000 / host->timeout_clk;
|
current_timeout = (1 << 13) * 1000 / host->timeout_clk;
|
||||||
while (current_timeout < target_timeout) {
|
while (current_timeout < target_timeout) {
|
||||||
|
@ -1867,9 +1865,6 @@ static void sdhci_tasklet_finish(unsigned long param)
|
||||||
|
|
||||||
del_timer(&host->timer);
|
del_timer(&host->timer);
|
||||||
|
|
||||||
if (host->version >= SDHCI_SPEC_300)
|
|
||||||
del_timer(&host->tuning_timer);
|
|
||||||
|
|
||||||
mrq = host->mrq;
|
mrq = host->mrq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2461,22 +2456,6 @@ int sdhci_add_host(struct sdhci_host *host)
|
||||||
host->max_clk = host->ops->get_max_clock(host);
|
host->max_clk = host->ops->get_max_clock(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
host->timeout_clk =
|
|
||||||
(caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
|
|
||||||
if (host->timeout_clk == 0) {
|
|
||||||
if (host->ops->get_timeout_clock) {
|
|
||||||
host->timeout_clk = host->ops->get_timeout_clock(host);
|
|
||||||
} else if (!(host->quirks &
|
|
||||||
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
|
|
||||||
printk(KERN_ERR
|
|
||||||
"%s: Hardware doesn't specify timeout clock "
|
|
||||||
"frequency.\n", mmc_hostname(mmc));
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
|
|
||||||
host->timeout_clk *= 1000;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In case of Host Controller v3.00, find out whether clock
|
* In case of Host Controller v3.00, find out whether clock
|
||||||
* multiplier is supported.
|
* multiplier is supported.
|
||||||
|
@ -2509,9 +2488,25 @@ int sdhci_add_host(struct sdhci_host *host)
|
||||||
} else
|
} else
|
||||||
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
|
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
|
||||||
|
|
||||||
|
host->timeout_clk =
|
||||||
|
(caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
|
||||||
|
if (host->timeout_clk == 0) {
|
||||||
|
if (host->ops->get_timeout_clock) {
|
||||||
|
host->timeout_clk = host->ops->get_timeout_clock(host);
|
||||||
|
} else if (!(host->quirks &
|
||||||
|
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"%s: Hardware doesn't specify timeout clock "
|
||||||
|
"frequency.\n", mmc_hostname(mmc));
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
|
||||||
|
host->timeout_clk *= 1000;
|
||||||
|
|
||||||
if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
|
if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
|
||||||
mmc->max_discard_to = (1 << 27) / (mmc->f_max / 1000);
|
host->timeout_clk = mmc->f_max / 1000;
|
||||||
else
|
|
||||||
mmc->max_discard_to = (1 << 27) / host->timeout_clk;
|
mmc->max_discard_to = (1 << 27) / host->timeout_clk;
|
||||||
|
|
||||||
mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
|
mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
|
static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
|
||||||
{
|
{
|
||||||
const struct mfd_cell *cell = mfd_get_cell(dev);
|
const struct mfd_cell *cell = mfd_get_cell(dev);
|
||||||
struct mmc_host *mmc = platform_get_drvdata(dev);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = tmio_mmc_host_suspend(&dev->dev);
|
ret = tmio_mmc_host_suspend(&dev->dev);
|
||||||
|
@ -42,7 +41,6 @@ static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
|
||||||
static int tmio_mmc_resume(struct platform_device *dev)
|
static int tmio_mmc_resume(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
const struct mfd_cell *cell = mfd_get_cell(dev);
|
const struct mfd_cell *cell = mfd_get_cell(dev);
|
||||||
struct mmc_host *mmc = platform_get_drvdata(dev);
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Tell the MFD core we are ready to be enabled */
|
/* Tell the MFD core we are ready to be enabled */
|
||||||
|
|
|
@ -56,8 +56,6 @@ struct mmc_ios {
|
||||||
#define MMC_TIMING_UHS_SDR104 4
|
#define MMC_TIMING_UHS_SDR104 4
|
||||||
#define MMC_TIMING_UHS_DDR50 5
|
#define MMC_TIMING_UHS_DDR50 5
|
||||||
|
|
||||||
unsigned char ddr; /* dual data rate used */
|
|
||||||
|
|
||||||
#define MMC_SDR_MODE 0
|
#define MMC_SDR_MODE 0
|
||||||
#define MMC_1_2V_DDR_MODE 1
|
#define MMC_1_2V_DDR_MODE 1
|
||||||
#define MMC_1_8V_DDR_MODE 2
|
#define MMC_1_8V_DDR_MODE 2
|
||||||
|
|
Reference in a new issue