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
This commit is contained in:
Коммит
5c3b9bac28
|
@ -17,6 +17,9 @@
|
|||
/* Require clock free running */
|
||||
#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
|
||||
* @max_speed: the maximum speed supported
|
||||
|
|
|
@ -1559,7 +1559,7 @@ void mmc_stop_host(struct mmc_host *host)
|
|||
|
||||
if (host->caps & MMC_CAP_DISABLE)
|
||||
cancel_delayed_work(&host->disable);
|
||||
cancel_delayed_work(&host->detect);
|
||||
cancel_delayed_work_sync(&host->detect);
|
||||
mmc_flush_scheduled_work();
|
||||
|
||||
/* 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,
|
|||
struct mmc_card *oldcard)
|
||||
{
|
||||
struct mmc_card *card;
|
||||
int err, ddr = MMC_SDR_MODE;
|
||||
int err, ddr = 0;
|
||||
u32 cid[4];
|
||||
unsigned int max_dtr;
|
||||
|
||||
|
@ -562,7 +562,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
|||
1 << bus_width, ddr);
|
||||
err = 0;
|
||||
} else {
|
||||
mmc_card_set_ddr_mode(card);
|
||||
if (ddr)
|
||||
mmc_card_set_ddr_mode(card);
|
||||
else
|
||||
ddr = MMC_SDR_MODE;
|
||||
|
||||
mmc_set_bus_width_ddr(card->host, bus_width, ddr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -547,9 +547,11 @@ static void mmc_sdio_detect(struct mmc_host *host)
|
|||
BUG_ON(!host->card);
|
||||
|
||||
/* Make sure card is powered before detecting it */
|
||||
err = pm_runtime_get_sync(&host->card->dev);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
|
||||
err = pm_runtime_get_sync(&host->card->dev);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mmc_claim_host(host);
|
||||
|
||||
|
@ -560,6 +562,20 @@ static void mmc_sdio_detect(struct mmc_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:
|
||||
if (err) {
|
||||
mmc_sdio_remove(host);
|
||||
|
@ -568,9 +584,6 @@ out:
|
|||
mmc_detach_bus(host);
|
||||
mmc_release_host(host);
|
||||
}
|
||||
|
||||
/* Tell PM core that we're done */
|
||||
pm_runtime_put(&host->card->dev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -718,16 +731,21 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
|
|||
card = host->card;
|
||||
|
||||
/*
|
||||
* Let runtime PM core know our card is active
|
||||
* Enable runtime PM only if supported by host+card+board
|
||||
*/
|
||||
err = pm_runtime_set_active(&card->dev);
|
||||
if (err)
|
||||
goto remove;
|
||||
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
|
||||
/*
|
||||
* Let runtime PM core know our card is active
|
||||
*/
|
||||
err = pm_runtime_set_active(&card->dev);
|
||||
if (err)
|
||||
goto remove;
|
||||
|
||||
/*
|
||||
* Enable runtime PM for this card
|
||||
*/
|
||||
pm_runtime_enable(&card->dev);
|
||||
/*
|
||||
* Enable runtime PM for this card
|
||||
*/
|
||||
pm_runtime_enable(&card->dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* The number of functions on the card is encoded inside
|
||||
|
@ -745,9 +763,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr)
|
|||
goto remove;
|
||||
|
||||
/*
|
||||
* Enable Runtime PM for this func
|
||||
* Enable Runtime PM for this func (if supported)
|
||||
*/
|
||||
pm_runtime_enable(&card->sdio_func[i]->dev);
|
||||
if (host->caps & MMC_CAP_POWER_OFF_CARD)
|
||||
pm_runtime_enable(&card->sdio_func[i]->dev);
|
||||
}
|
||||
|
||||
mmc_release_host(host);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
|
||||
#include "sdio_cis.h"
|
||||
|
@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)
|
|||
* it should call pm_runtime_put_noidle() in its probe routine and
|
||||
* pm_runtime_get_noresume() in its remove routine.
|
||||
*/
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set the default block size so the driver is sure it's something
|
||||
* sensible. */
|
||||
|
@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev)
|
|||
return 0;
|
||||
|
||||
disable_runtimepm:
|
||||
pm_runtime_put_noidle(dev);
|
||||
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
|
||||
pm_runtime_put_noidle(dev);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)
|
|||
{
|
||||
struct sdio_driver *drv = to_sdio_driver(dev->driver);
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
/* Make sure card is powered before invoking ->remove() */
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
drv->remove(func);
|
||||
|
||||
|
@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev)
|
|||
}
|
||||
|
||||
/* First, undo the increment made directly above */
|
||||
pm_runtime_put_noidle(dev);
|
||||
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
|
||||
pm_runtime_put_noidle(dev);
|
||||
|
||||
/* Then undo the runtime PM settings in sdio_bus_probe() */
|
||||
pm_runtime_put_noidle(dev);
|
||||
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
|
||||
pm_runtime_put_noidle(dev);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
@ -191,6 +199,8 @@ out:
|
|||
|
||||
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
|
||||
* point, in order to allow standard SDIO suspend/resume paths
|
||||
|
@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev)
|
|||
* since there is little point in failing system suspend if a
|
||||
* device can't be resumed.
|
||||
*/
|
||||
pm_runtime_resume(dev);
|
||||
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
|
||||
pm_runtime_resume(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1002,7 +1002,7 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
|
|||
* Monitor a 0->1 transition first
|
||||
*/
|
||||
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))
|
||||
cpu_relax();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/sdhci-pltfm.h>
|
||||
#include <mach/hardware.h>
|
||||
#include "sdhci.h"
|
||||
#include "sdhci-pltfm.h"
|
||||
#include "sdhci-esdhc.h"
|
||||
|
@ -112,6 +113,13 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
|
|||
clk_enable(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;
|
||||
}
|
||||
|
||||
|
@ -133,10 +141,8 @@ static struct sdhci_ops sdhci_esdhc_ops = {
|
|||
};
|
||||
|
||||
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
|
||||
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_MULTIBLOCK
|
||||
| SDHCI_QUIRK_BROKEN_ADMA,
|
||||
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
|
||||
/* ADMA has issues. Might be fixable */
|
||||
/* NO_MULTIBLOCK might be MX35 only (Errata: ENGcm07207) */
|
||||
.ops = &sdhci_esdhc_ops,
|
||||
.init = esdhc_pltfm_init,
|
||||
.exit = esdhc_pltfm_exit,
|
||||
|
|
|
@ -149,11 +149,11 @@ static const struct sdhci_pci_fixes sdhci_cafe = {
|
|||
* ADMA operation is disabled for Moorestown platform due to
|
||||
* 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
|
||||
* hardware bugs.
|
||||
* slots number is fixed here for MRST as SDIO3/5 are never used and
|
||||
* have hardware bugs.
|
||||
*/
|
||||
chip->num_slots = 1;
|
||||
return 0;
|
||||
|
@ -163,9 +163,9 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
|
|||
.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,
|
||||
.probe = mrst_hc1_probe,
|
||||
.probe = mrst_hc_probe,
|
||||
};
|
||||
|
||||
static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
|
||||
|
@ -538,7 +538,15 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
|
|||
.device = PCI_DEVICE_ID_INTEL_MRST_SD1,
|
||||
.subvendor = 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)
|
|||
{
|
||||
struct sdhci_pci_chip *chip;
|
||||
struct sdhci_pci_slot *slot;
|
||||
mmc_pm_flag_t slot_pm_flags;
|
||||
mmc_pm_flag_t pm_flags = 0;
|
||||
int i, ret;
|
||||
|
||||
|
@ -657,7 +666,11 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
|
|||
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) {
|
||||
|
@ -671,8 +684,10 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
|
|||
|
||||
pci_save_state(pdev);
|
||||
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_set_power_state(pdev, PCI_D3hot);
|
||||
} else {
|
||||
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
|
||||
|
|
|
@ -141,6 +141,10 @@ static int __devinit sdhci_pxa_probe(struct platform_device *pdev)
|
|||
if (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);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to add host\n");
|
||||
|
|
|
@ -1185,18 +1185,32 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
|||
if (host->ops->platform_send_init_74_clocks)
|
||||
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);
|
||||
if (ios->bus_width == MMC_BUS_WIDTH_8) {
|
||||
ctrl &= ~SDHCI_CTRL_4BITBUS;
|
||||
if (host->version >= SDHCI_SPEC_300)
|
||||
ctrl |= SDHCI_CTRL_8BITBUS;
|
||||
} else {
|
||||
if (host->version >= SDHCI_SPEC_300)
|
||||
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||
if (ios->bus_width == MMC_BUS_WIDTH_4)
|
||||
ctrl |= SDHCI_CTRL_4BITBUS;
|
||||
else
|
||||
ctrl &= ~SDHCI_CTRL_4BITBUS;
|
||||
}
|
||||
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
|
||||
}
|
||||
|
||||
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
|
||||
|
||||
if (ios->bus_width == MMC_BUS_WIDTH_8)
|
||||
ctrl |= SDHCI_CTRL_8BITBUS;
|
||||
else
|
||||
ctrl &= ~SDHCI_CTRL_8BITBUS;
|
||||
|
||||
if (ios->bus_width == MMC_BUS_WIDTH_4)
|
||||
ctrl |= SDHCI_CTRL_4BITBUS;
|
||||
else
|
||||
ctrl &= ~SDHCI_CTRL_4BITBUS;
|
||||
|
||||
if ((ios->timing == MMC_TIMING_SD_HS ||
|
||||
ios->timing == MMC_TIMING_MMC_HS)
|
||||
&& !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
|
||||
|
@ -1681,6 +1695,16 @@ int sdhci_resume_host(struct sdhci_host *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 */
|
||||
|
||||
/*****************************************************************************\
|
||||
|
@ -1845,11 +1869,19 @@ int sdhci_add_host(struct sdhci_host *host)
|
|||
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
|
||||
else
|
||||
mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
|
||||
|
||||
mmc->f_max = host->max_clk;
|
||||
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))
|
||||
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)
|
||||
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
#define SDHCI_CTRL_ADMA1 0x08
|
||||
#define SDHCI_CTRL_ADMA32 0x10
|
||||
#define SDHCI_CTRL_ADMA64 0x18
|
||||
#define SDHCI_CTRL_8BITBUS 0x20
|
||||
#define SDHCI_CTRL_8BITBUS 0x20
|
||||
|
||||
#define SDHCI_POWER_CONTROL 0x29
|
||||
#define SDHCI_POWER_ON 0x01
|
||||
|
@ -87,6 +87,9 @@
|
|||
#define SDHCI_BLOCK_GAP_CONTROL 0x2A
|
||||
|
||||
#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_DIVIDER_SHIFT 8
|
||||
|
@ -152,6 +155,7 @@
|
|||
#define SDHCI_CLOCK_BASE_SHIFT 8
|
||||
#define SDHCI_MAX_BLOCK_MASK 0x00030000
|
||||
#define SDHCI_MAX_BLOCK_SHIFT 16
|
||||
#define SDHCI_CAN_DO_8BIT 0x00040000
|
||||
#define SDHCI_CAN_DO_ADMA2 0x00080000
|
||||
#define SDHCI_CAN_DO_ADMA1 0x00100000
|
||||
#define SDHCI_CAN_DO_HISPD 0x00200000
|
||||
|
@ -212,6 +216,8 @@ struct sdhci_ops {
|
|||
unsigned int (*get_max_clock)(struct sdhci_host *host);
|
||||
unsigned int (*get_min_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,
|
||||
u8 power_mode);
|
||||
unsigned int (*get_ro)(struct sdhci_host *host);
|
||||
|
@ -317,6 +323,7 @@ extern void sdhci_remove_host(struct sdhci_host *host, int dead);
|
|||
#ifdef CONFIG_PM
|
||||
extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state);
|
||||
extern int sdhci_resume_host(struct sdhci_host *host);
|
||||
extern void sdhci_enable_irq_wakeups(struct sdhci_host *host);
|
||||
#endif
|
||||
|
||||
#endif /* __SDHCI_HW_H */
|
||||
|
|
|
@ -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 mmc_host *mmc;
|
||||
struct ushc_data *ushc;
|
||||
int ret = -ENOMEM;
|
||||
int ret;
|
||||
|
||||
mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
|
||||
if (mmc == NULL)
|
||||
|
@ -462,11 +462,15 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|||
mmc->max_blk_count = 511;
|
||||
|
||||
ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (ushc->int_urb == NULL)
|
||||
if (ushc->int_urb == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
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;
|
||||
}
|
||||
usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
|
||||
usb_rcvintpipe(usb_dev,
|
||||
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
|
|||
intf->cur_altsetting->endpoint[0].desc.bInterval);
|
||||
|
||||
ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (ushc->cbw_urb == NULL)
|
||||
if (ushc->cbw_urb == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
|
||||
if (ushc->cbw == NULL)
|
||||
if (ushc->cbw == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
ushc->cbw->signature = USHC_CBW_SIGNATURE;
|
||||
|
||||
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
|
|||
cbw_callback, ushc);
|
||||
|
||||
ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (ushc->data_urb == NULL)
|
||||
if (ushc->data_urb == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (ushc->csw_urb == NULL)
|
||||
if (ushc->csw_urb == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
ushc->csw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
|
||||
if (ushc->csw == NULL)
|
||||
if (ushc->csw == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),
|
||||
ushc->csw, sizeof(struct ushc_csw),
|
||||
csw_callback, ushc);
|
||||
|
|
|
@ -168,6 +168,7 @@ struct mmc_host {
|
|||
/* DDR mode at 1.8V */
|
||||
#define MMC_CAP_1_2V_DDR (1 << 12) /* can support */
|
||||
/* 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 */
|
||||
|
||||
|
|
|
@ -2441,6 +2441,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_MFD_SDIO2 0x0822
|
||||
#define PCI_DEVICE_ID_INTEL_MFD_EMMC0 0x0823
|
||||
#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_I960RM 0x0962
|
||||
#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062
|
||||
|
|
Загрузка…
Ссылка в новой задаче