Commit 5c3b9bac authored by Linus Torvalds's avatar Linus Torvalds

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: sdhci: 8-bit bus width changes
  mmc: sdio: fix runtime PM anomalies by introducing MMC_CAP_POWER_OFF_CARD
  mmc: sdio: fix nasty oops in mmc_sdio_detect
  mmc: omap4: hsmmc: Fix improper card detection while booting
  mmc: fix rmmod race for hosts using card-detection polling
  mmc: sdhci: Fix crash on boot with C0 stepping Moorestown platforms
  mmc: sdhci-esdhc-imx: enable QUIRK_NO_MULTIBLOCK only for i.MX25 and i.MX35
  mmc: sdhci-esdhc-imx: fix timeout on i.MX's sdhci
  mmc: sdhci: Properly enable SDIO IRQ wakeups
  mmc: ushc: Return proper error code for ushc_probe()
  mmc: Fix printing of card DDR type
parents b127c6fb 15ec4461
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
/* Require clock free running */ /* Require clock free running */
#define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0) #define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
/* Board design supports 8-bit data on SD/SDIO BUS */
#define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2)
/* /*
* struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
* @max_speed: the maximum speed supported * @max_speed: the maximum speed supported
......
...@@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host) ...@@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host)
if (host->caps & MMC_CAP_DISABLE) if (host->caps & MMC_CAP_DISABLE)
cancel_delayed_work(&host->disable); cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect); cancel_delayed_work_sync(&host->detect);
mmc_flush_scheduled_work(); mmc_flush_scheduled_work();
/* clear pm flags now and let card drivers set them as needed */ /* clear pm flags now and let card drivers set them as needed */
......
...@@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, ...@@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
struct mmc_card *oldcard) struct mmc_card *oldcard)
{ {
struct mmc_card *card; struct mmc_card *card;
int err, ddr = MMC_SDR_MODE; int err, ddr = 0;
u32 cid[4]; u32 cid[4];
unsigned int max_dtr; unsigned int max_dtr;
...@@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, ...@@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
1 << bus_width, ddr); 1 << bus_width, ddr);
err = 0; err = 0;
} else { } else {
if (ddr)
mmc_card_set_ddr_mode(card); mmc_card_set_ddr_mode(card);
else
ddr = MMC_SDR_MODE;
mmc_set_bus_width_ddr(card->host, bus_width, ddr); mmc_set_bus_width_ddr(card->host, bus_width, ddr);
} }
} }
......
...@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host) ...@@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)
BUG_ON(!host->card); BUG_ON(!host->card);
/* Make sure card is powered before detecting it */ /* Make sure card is powered before detecting it */
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
err = pm_runtime_get_sync(&host->card->dev); err = pm_runtime_get_sync(&host->card->dev);
if (err < 0) if (err < 0)
goto out; goto out;
}
mmc_claim_host(host); mmc_claim_host(host);
...@@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host) ...@@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_host *host)
mmc_release_host(host); mmc_release_host(host);
/*
* Tell PM core it's OK to power off the card now.
*
* The _sync variant is used in order to ensure that the card
* is left powered off in case an error occurred, and the card
* is going to be removed.
*
* Since there is no specific reason to believe a new user
* is about to show up at this point, the _sync variant is
* desirable anyway.
*/
if (host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_put_sync(&host->card->dev);
out: out:
if (err) { if (err) {
mmc_sdio_remove(host); mmc_sdio_remove(host);
...@@ -568,9 +584,6 @@ static void mmc_sdio_detect(struct mmc_host *host) ...@@ -568,9 +584,6 @@ static void mmc_sdio_detect(struct mmc_host *host)
mmc_detach_bus(host); mmc_detach_bus(host);
mmc_release_host(host); mmc_release_host(host);
} }
/* Tell PM core that we're done */
pm_runtime_put(&host->card->dev);
} }
/* /*
...@@ -717,6 +730,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) ...@@ -717,6 +730,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
goto err; goto err;
card = host->card; card = host->card;
/*
* Enable runtime PM only if supported by host+card+board
*/
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
/* /*
* Let runtime PM core know our card is active * Let runtime PM core know our card is active
*/ */
...@@ -728,6 +745,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) ...@@ -728,6 +745,7 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
* Enable runtime PM for this card * Enable runtime PM for this card
*/ */
pm_runtime_enable(&card->dev); pm_runtime_enable(&card->dev);
}
/* /*
* The number of functions on the card is encoded inside * The number of functions on the card is encoded inside
...@@ -745,8 +763,9 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) ...@@ -745,8 +763,9 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
goto remove; goto remove;
/* /*
* Enable Runtime PM for this func * Enable Runtime PM for this func (if supported)
*/ */
if (host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_enable(&card->sdio_func[i]->dev); pm_runtime_enable(&card->sdio_func[i]->dev);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_func.h>
#include "sdio_cis.h" #include "sdio_cis.h"
...@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev) ...@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)
* it should call pm_runtime_put_noidle() in its probe routine and * it should call pm_runtime_put_noidle() in its probe routine and
* pm_runtime_get_noresume() in its remove routine. * pm_runtime_get_noresume() in its remove routine.
*/ */
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret < 0) if (ret < 0)
goto out; goto out;
}
/* Set the default block size so the driver is sure it's something /* Set the default block size so the driver is sure it's something
* sensible. */ * sensible. */
...@@ -151,6 +154,7 @@ static int sdio_bus_probe(struct device *dev) ...@@ -151,6 +154,7 @@ static int sdio_bus_probe(struct device *dev)
return 0; return 0;
disable_runtimepm: disable_runtimepm:
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_put_noidle(dev); pm_runtime_put_noidle(dev);
out: out:
return ret; return ret;
...@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev) ...@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)
{ {
struct sdio_driver *drv = to_sdio_driver(dev->driver); struct sdio_driver *drv = to_sdio_driver(dev->driver);
struct sdio_func *func = dev_to_sdio_func(dev); struct sdio_func *func = dev_to_sdio_func(dev);
int ret; int ret = 0;
/* Make sure card is powered before invoking ->remove() */ /* Make sure card is powered before invoking ->remove() */
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret < 0) if (ret < 0)
goto out; goto out;
}
drv->remove(func); drv->remove(func);
...@@ -178,9 +184,11 @@ static int sdio_bus_remove(struct device *dev) ...@@ -178,9 +184,11 @@ static int sdio_bus_remove(struct device *dev)
} }
/* First, undo the increment made directly above */ /* First, undo the increment made directly above */
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_put_noidle(dev); pm_runtime_put_noidle(dev);
/* Then undo the runtime PM settings in sdio_bus_probe() */ /* Then undo the runtime PM settings in sdio_bus_probe() */
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_put_noidle(dev); pm_runtime_put_noidle(dev);
out: out:
...@@ -191,6 +199,8 @@ static int sdio_bus_remove(struct device *dev) ...@@ -191,6 +199,8 @@ static int sdio_bus_remove(struct device *dev)
static int sdio_bus_pm_prepare(struct device *dev) static int sdio_bus_pm_prepare(struct device *dev)
{ {
struct sdio_func *func = dev_to_sdio_func(dev);
/* /*
* Resume an SDIO device which was suspended at run time at this * Resume an SDIO device which was suspended at run time at this
* point, in order to allow standard SDIO suspend/resume paths * point, in order to allow standard SDIO suspend/resume paths
...@@ -212,6 +222,7 @@ static int sdio_bus_pm_prepare(struct device *dev) ...@@ -212,6 +222,7 @@ static int sdio_bus_pm_prepare(struct device *dev)
* since there is little point in failing system suspend if a * since there is little point in failing system suspend if a
* device can't be resumed. * device can't be resumed.
*/ */
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_resume(dev); pm_runtime_resume(dev);
return 0; return 0;
......
...@@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, ...@@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
* Monitor a 0->1 transition first * Monitor a 0->1 transition first
*/ */
if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) { if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit)) while ((!(OMAP_HSMMC_READ(host->base, SYSCTL) & bit))
&& (i++ < limit)) && (i++ < limit))
cpu_relax(); cpu_relax();
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h> #include <linux/mmc/sdhci-pltfm.h>
#include <mach/hardware.h>
#include "sdhci.h" #include "sdhci.h"
#include "sdhci-pltfm.h" #include "sdhci-pltfm.h"
#include "sdhci-esdhc.h" #include "sdhci-esdhc.h"
...@@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd ...@@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
clk_enable(clk); clk_enable(clk);
pltfm_host->clk = clk; pltfm_host->clk = clk;
if (cpu_is_mx35() || cpu_is_mx51())
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
/* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
if (cpu_is_mx25() || cpu_is_mx35())
host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
return 0; return 0;
} }
...@@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = { ...@@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = {
}; };
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
| SDHCI_QUIRK_BROKEN_ADMA,
/* ADMA has issues. Might be fixable */ /* ADMA has issues. Might be fixable */
/* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */
.ops = &sdhci_esdhc_ops, .ops = &sdhci_esdhc_ops,
.init = esdhc_pltfm_init, .init = esdhc_pltfm_init,
.exit = esdhc_pltfm_exit, .exit = esdhc_pltfm_exit,
......
...@@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = { ...@@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = {
* ADMA operation is disabled for Moorestown platform due to * ADMA operation is disabled for Moorestown platform due to
* hardware bugs. * hardware bugs.
*/ */
static int mrst_hc1_probe(struct sdhci_pci_chip *chip) static int mrst_hc_probe(struct sdhci_pci_chip *chip)
{ {
/* /*
* slots number is fixed here for MRST as SDIO3 is never used and has * slots number is fixed here for MRST as SDIO3/5 are never used and
* hardware bugs. * have hardware bugs.
*/ */
chip->num_slots = 1; chip->num_slots = 1;
return 0; return 0;
...@@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { ...@@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
.quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
}; };
static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1 = { static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
.quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
.probe = mrst_hc1_probe, .probe = mrst_hc_probe,
}; };
static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
...@@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = { ...@@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
.device = PCI_DEVICE_ID_INTEL_MRST_SD1, .device = PCI_DEVICE_ID_INTEL_MRST_SD1,
.subvendor = PCI_ANY_ID, .subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID, .subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1, .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
},
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_MRST_SD2,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
}, },
{ {
...@@ -637,6 +645,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -637,6 +645,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{ {
struct sdhci_pci_chip *chip; struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot; struct sdhci_pci_slot *slot;
mmc_pm_flag_t slot_pm_flags;
mmc_pm_flag_t pm_flags = 0; mmc_pm_flag_t pm_flags = 0;
int i, ret; int i, ret;
...@@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
return ret; return ret;
} }
pm_flags |= slot->host->mmc->pm_flags; slot_pm_flags = slot->host->mmc->pm_flags;
if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
sdhci_enable_irq_wakeups(slot->host);
pm_flags |= slot_pm_flags;
} }
if (chip->fixes && chip->fixes->suspend) { if (chip->fixes && chip->fixes->suspend) {
...@@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state) ...@@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev); pci_save_state(pdev);
if (pm_flags & MMC_PM_KEEP_POWER) { if (pm_flags & MMC_PM_KEEP_POWER) {
if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
pci_pme_active(pdev, true);
pci_enable_wake(pdev, PCI_D3hot, 1); pci_enable_wake(pdev, PCI_D3hot, 1);
}
pci_set_power_state(pdev, PCI_D3hot); pci_set_power_state(pdev, PCI_D3hot);
} else { } else {
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
......
...@@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev) ...@@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
if (pdata->quirks) if (pdata->quirks)
host->quirks |= pdata->quirks; host->quirks |= pdata->quirks;
/* If slot design supports 8 bit data, indicate this to MMC. */
if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
ret = sdhci_add_host(host); ret = sdhci_add_host(host);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to add host\n"); dev_err(&pdev->dev, "failed to add host\n");
......
...@@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -1185,17 +1185,31 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->ops->platform_send_init_74_clocks) if (host->ops->platform_send_init_74_clocks)
host->ops->platform_send_init_74_clocks(host, ios->power_mode); host->ops->platform_send_init_74_clocks(host, ios->power_mode);
/*
* If your platform has 8-bit width support but is not a v3 controller,
* or if it requires special setup code, you should implement that in
* platform_8bit_width().
*/
if (host->ops->platform_8bit_width)
host->ops->platform_8bit_width(host, ios->bus_width);
else {
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if (ios->bus_width == MMC_BUS_WIDTH_8) {
if (ios->bus_width == MMC_BUS_WIDTH_8) ctrl &= ~SDHCI_CTRL_4BITBUS;
if (host->version >= SDHCI_SPEC_300)
ctrl |= SDHCI_CTRL_8BITBUS; ctrl |= SDHCI_CTRL_8BITBUS;
else } else {
if (host->version >= SDHCI_SPEC_300)
ctrl &= ~SDHCI_CTRL_8BITBUS; ctrl &= ~SDHCI_CTRL_8BITBUS;
if (ios->bus_width == MMC_BUS_WIDTH_4) if (ios->bus_width == MMC_BUS_WIDTH_4)
ctrl |= SDHCI_CTRL_4BITBUS; ctrl |= SDHCI_CTRL_4BITBUS;
else else
ctrl &= ~SDHCI_CTRL_4BITBUS; ctrl &= ~SDHCI_CTRL_4BITBUS;
}
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if ((ios->timing == MMC_TIMING_SD_HS || if ((ios->timing == MMC_TIMING_SD_HS ||
ios->timing == MMC_TIMING_MMC_HS) ios->timing == MMC_TIMING_MMC_HS)
...@@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *host) ...@@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *host)
EXPORT_SYMBOL_GPL(sdhci_resume_host); EXPORT_SYMBOL_GPL(sdhci_resume_host);
void sdhci_enable_irq_wakeups(struct sdhci_host *host)
{
u8 val;
val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL);
val |= SDHCI_WAKE_ON_INT;
sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL);
}
EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups);
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
/*****************************************************************************\ /*****************************************************************************\
...@@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host) ...@@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
else else
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
mmc->f_max = host->max_clk; mmc->f_max = host->max_clk;
mmc->caps |= MMC_CAP_SDIO_IRQ; mmc->caps |= MMC_CAP_SDIO_IRQ;
/*
* A controller may support 8-bit width, but the board itself
* might not have the pins brought out. Boards that support
* 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in
* their platform code before calling sdhci_add_host(), and we
* won't assume 8-bit width for hosts without that CAP.
*/
if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; mmc->caps |= MMC_CAP_4_BIT_DATA;
if (caps & SDHCI_CAN_DO_HISPD) if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
......
...@@ -87,6 +87,9 @@ ...@@ -87,6 +87,9 @@
#define SDHCI_BLOCK_GAP_CONTROL 0x2A #define SDHCI_BLOCK_GAP_CONTROL 0x2A
#define SDHCI_WAKE_UP_CONTROL 0x2B #define SDHCI_WAKE_UP_CONTROL 0x2B
#define SDHCI_WAKE_ON_INT 0x01
#define SDHCI_WAKE_ON_INSERT 0x02
#define SDHCI_WAKE_ON_REMOVE 0x04
#define SDHCI_CLOCK_CONTROL 0x2C #define SDHCI_CLOCK_CONTROL 0x2C
#define SDHCI_DIVIDER_SHIFT 8 #define SDHCI_DIVIDER_SHIFT 8
...@@ -152,6 +155,7 @@ ...@@ -152,6 +155,7 @@
#define SDHCI_CLOCK_BASE_SHIFT 8 #define SDHCI_CLOCK_BASE_SHIFT 8
#define SDHCI_MAX_BLOCK_MASK 0x00030000 #define SDHCI_MAX_BLOCK_MASK 0x00030000
#define SDHCI_MAX_BLOCK_SHIFT 16 #define SDHCI_MAX_BLOCK_SHIFT 16
#define SDHCI_CAN_DO_8BIT 0x00040000
#define SDHCI_CAN_DO_ADMA2 0x00080000 #define SDHCI_CAN_DO_ADMA2 0x00080000
#define SDHCI_CAN_DO_ADMA1 0x00100000 #define SDHCI_CAN_DO_ADMA1 0x00100000
#define SDHCI_CAN_DO_HISPD 0x00200000 #define SDHCI_CAN_DO_HISPD 0x00200000
...@@ -212,6 +216,8 @@ struct sdhci_ops { ...@@ -212,6 +216,8 @@ struct sdhci_ops {
unsigned int (*get_max_clock)(struct sdhci_host *host); unsigned int (*get_max_clock)(struct sdhci_host *host);
unsigned int (*get_min_clock)(struct sdhci_host *host); unsigned int (*get_min_clock)(struct sdhci_host *host);
unsigned int (*get_timeout_clock)(struct sdhci_host *host); unsigned int (*get_timeout_clock)(struct sdhci_host *host);
int (*platform_8bit_width)(struct sdhci_host *host,
int width);
void (*platform_send_init_74_clocks)(struct sdhci_host *host, void (*platform_send_init_74_clocks)(struct sdhci_host *host,
u8 power_mode); u8 power_mode);
unsigned int (*get_ro)(struct sdhci_host *host); unsigned int (*get_ro)(struct sdhci_host *host);
...@@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead); ...@@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
#ifdef CONFIG_PM #ifdef CONFIG_PM
extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
extern int sdhci_resume_host(struct sdhci_host *host); extern int sdhci_resume_host(struct sdhci_host *host);
extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);
#endif #endif
#endif /* __SDHCI_HW_H */ #endif /* __SDHCI_HW_H */
...@@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -425,7 +425,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_device *usb_dev = interface_to_usbdev(intf); struct usb_device *usb_dev = interface_to_usbdev(intf);
struct mmc_host *mmc; struct mmc_host *mmc;
struct ushc_data *ushc; struct ushc_data *ushc;
int ret = -ENOMEM; int ret;
mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev); mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
if (mmc == NULL) if (mmc == NULL)
...@@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
mmc->max_blk_count = 511; mmc->max_blk_count = 511;
ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
if (ushc->int_urb == NULL) if (ushc->int_urb == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);
if (ushc->int_data == NULL) if (ushc->int_data == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
usb_fill_int_urb(ushc->int_urb, ushc->usb_dev, usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
usb_rcvintpipe(usb_dev, usb_rcvintpipe(usb_dev,
intf->cur_altsetting->endpoint[0].desc.bEndpointAddress), intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),
...@@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -475,11 +479,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
intf->cur_altsetting->endpoint[0].desc.bInterval); intf->cur_altsetting->endpoint[0].desc.bInterval);
ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);
if (ushc->cbw_urb == NULL) if (ushc->cbw_urb == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
if (ushc->cbw == NULL) if (ushc->cbw == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
ushc->cbw->signature = USHC_CBW_SIGNATURE; ushc->cbw->signature = USHC_CBW_SIGNATURE;
usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2),
...@@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ...@@ -487,15 +495,21 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
cbw_callback, ushc); cbw_callback, ushc);
ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
if (ushc->data_urb == NULL) if (ushc->data_urb == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);
if (ushc->csw_urb == NULL) if (ushc->csw_urb == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
if (ushc->csw == NULL) if (ushc->csw == NULL) {
ret = -ENOMEM;
goto err; goto err;
}
usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6), usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),
ushc->csw, sizeof(struct ushc_csw), ushc->csw, sizeof(struct ushc_csw),
csw_callback, ushc); csw_callback, ushc);
......
...@@ -168,6 +168,7 @@ struct mmc_host { ...@@ -168,6 +168,7 @@ struct mmc_host {
/* DDR mode at 1.8V */ /* DDR mode at 1.8V */
#define MMC_CAP_1_2V_DDR (1 << 12) /* can support */ #define MMC_CAP_1_2V_DDR (1 << 12) /* can support */
/* DDR mode at 1.2V */ /* DDR mode at 1.2V */
#define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */
mmc_pm_flag_t pm_caps; /* supported pm features */ mmc_pm_flag_t pm_caps; /* supported pm features */
......
...@@ -2441,6 +2441,7 @@ ...@@ -2441,6 +2441,7 @@
#define PCI_DEVICE_ID_INTEL_MFD_SDIO2 0x0822 #define PCI_DEVICE_ID_INTEL_MFD_SDIO2 0x0822
#define PCI_DEVICE_ID_INTEL_MFD_EMMC0 0x0823 #define PCI_DEVICE_ID_INTEL_MFD_EMMC0 0x0823
#define PCI_DEVICE_ID_INTEL_MFD_EMMC1 0x0824 #define PCI_DEVICE_ID_INTEL_MFD_EMMC1 0x0824
#define PCI_DEVICE_ID_INTEL_MRST_SD2 0x084F
#define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960 0x0960
#define PCI_DEVICE_ID_INTEL_I960RM 0x0962 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962
#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 #define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment