diff options
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-mmc-driver-1.0.patch')
-rw-r--r-- | meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-mmc-driver-1.0.patch | 1367 |
1 files changed, 0 insertions, 1367 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-mmc-driver-1.0.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-mmc-driver-1.0.patch deleted file mode 100644 index b93f76a8e..000000000 --- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-mmc-driver-1.0.patch +++ /dev/null @@ -1,1367 +0,0 @@ -From bac1959b76f55a7845b0bb20eafd32e40c49dd74 Mon Sep 17 00:00:00 2001 -From: JiebingLi <jiebing.li@intel.com> -Date: Wed, 25 Nov 2009 19:43:03 +0800 -Subject: [PATCH 077/104] MMC driver Beta 1.0 It is a consolidated patch against upstream Linux 2.6.31.6 - -Beta features: -1. removed CEATA function from MMC bus driver -2. Added 25MHz support at High-Speed mode for SDIO Comms devices -3. Added eMMC support for Moorestown platform -4. Fixed sighting 3469229 and 3452438 - -Kernel configuration: -CONFIG_MMC=y -CONFIG_MRST_LNW_A2_WR=y -CONFIG_SDIO_SUSPEND=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_BOUNCE=y -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PCI=y - -Note: Please DO NOT enable CONFIG_MMC_SDHCI_MRST_EMMC unless you - are sure that you want to enable eMMC device for Moorestown. - -Signed-off-by: JiebingLi <jiebing.li@intel.com> ---- - drivers/mmc/Kconfig | 14 ++ - drivers/mmc/card/block.c | 3 +- - drivers/mmc/core/Kconfig | 11 + - drivers/mmc/core/core.c | 6 + - drivers/mmc/core/mmc.c | 41 ++++- - drivers/mmc/core/sd.c | 8 + - drivers/mmc/core/sdio.c | 464 +++++++++++++++++++++++++++++++++++++++++ - drivers/mmc/core/sdio_bus.c | 38 ++++ - drivers/mmc/core/sdio_bus.h | 4 + - drivers/mmc/host/Kconfig | 10 + - drivers/mmc/host/sdhci-pci.c | 81 ++++++-- - drivers/mmc/host/sdhci.c | 125 ++++++++++- - drivers/mmc/host/sdhci.h | 3 + - include/linux/mmc/card.h | 12 + - include/linux/mmc/host.h | 2 + - include/linux/mmc/sdio_func.h | 14 ++ - include/linux/pci_ids.h | 2 + - 17 files changed, 810 insertions(+), 28 deletions(-) - -diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig -index f2eeb38..2c19682 100644 ---- a/drivers/mmc/Kconfig -+++ b/drivers/mmc/Kconfig -@@ -19,6 +19,20 @@ config MMC_DEBUG - This is an option for use by developers; most people should - say N here. This enables MMC core and driver debugging. - -+config MRST_LNW_A1_WR -+ bool "software workaround for Moorestown LNW A-1" -+ depends on MMC -+ help -+ This is an option for Moorestown developers to add workaround -+ in the code due to LNW A-1 Silicon restrictions. -+ -+config MRST_LNW_A2_WR -+ bool "software workaround for Moorestown LNW A-2" -+ depends on MMC -+ help -+ This is an option for Moorestown developers to add workaround -+ in the code due to LNW A-2 Silicon restrictions. -+ - if MMC - - source "drivers/mmc/core/Kconfig" -diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index 1f552c6..f4ebc68 100644 ---- a/drivers/mmc/card/block.c -+++ b/drivers/mmc/card/block.c -@@ -534,7 +534,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) - * messages to tell when the card is present. - */ - -- sprintf(md->disk->disk_name, "mmcblk%d", devidx); -+ snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), -+ "mmcblk%d", devidx); - - blk_queue_logical_block_size(md->queue.queue, 512); - -diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig -index bb22ffd..205186c 100644 ---- a/drivers/mmc/core/Kconfig -+++ b/drivers/mmc/core/Kconfig -@@ -16,3 +16,14 @@ config MMC_UNSAFE_RESUME - - This option sets a default which can be overridden by the - module parameter "removable=0" or "removable=1". -+ -+config SDIO_SUSPEND -+ bool "SDIO selective suspend/resume" -+ depends on MMC && PM -+ help -+ If you say Y here, you can use driver calls or the sysfs -+ "power/level" file to suspend or resume the SDIO -+ peripherals. -+ -+ If you are unsure about this, say N here. -+ -diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c -index 30acd52..951561d 100644 ---- a/drivers/mmc/core/core.c -+++ b/drivers/mmc/core/core.c -@@ -213,9 +213,15 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) - mrq->done_data = &complete; - mrq->done = mmc_wait_done; - -+ if (host->port_mutex) -+ mutex_lock(host->port_mutex); -+ - mmc_start_request(host, mrq); - - wait_for_completion(&complete); -+ -+ if (host->port_mutex) -+ mutex_unlock(host->port_mutex); - } - - EXPORT_SYMBOL(mmc_wait_for_req); -diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c -index 0eac6c8..15aaa66 100644 ---- a/drivers/mmc/core/mmc.c -+++ b/drivers/mmc/core/mmc.c -@@ -179,8 +179,10 @@ static int mmc_read_ext_csd(struct mmc_card *card) - - err = mmc_send_ext_csd(card, ext_csd); - if (err) { -- /* If the host or the card can't do the switch, -- * fail more gracefully. */ -+ /* -+ * If the host or the card can't do the switch, -+ * fail more gracefully. -+ */ - if ((err != -EINVAL) - && (err != -ENOSYS) - && (err != -EFAULT)) -@@ -294,6 +296,28 @@ static struct device_type mmc_type = { - }; - - /* -+ * Distinguish the fake MMCA4 MMC card. -+ * -+ * Transcend 2GB MMC card is a kind of MMCA3.31 MMC card. -+ * However, it makes up itself as a MMCA4 one via SPEC_VERS -+ * field of its CSD register. Once it's treated as MMCA4 by -+ * driver, 4 bit bus is activated which leads to data error. -+ */ -+static bool fake_mmca4_card(struct mmc_card *card) -+{ -+ if (card->cid.manfid == 0x1e && -+ card->cid.oemid == 0xffff && -+ card->cid.prod_name[0] == 'M' && -+ card->cid.prod_name[1] == 'M' && -+ card->cid.prod_name[2] == 'C' && -+ card->cid.month == 9 && -+ card->cid.year == 2008) -+ return true; -+ else -+ return false; -+} -+ -+/* - * Handle the detection and initialisation of a card. - * - * In the case of a resume, "oldcard" will contain the card -@@ -389,6 +413,12 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, - err = mmc_decode_cid(card); - if (err) - goto free_card; -+ -+ /* -+ * Get card's true specification version -+ */ -+ if (fake_mmca4_card(card)) -+ card->csd.mmca_vsn = CSD_SPEC_VER_3; - } - - /* -@@ -409,6 +439,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, - goto free_card; - } - -+/* -+ * avoid MMC cards to switch to HS timing -+ * which doesn't work yet due to LNW A-1 Silicon bug -+ */ -+#if !defined CONFIG_MRST_LNW_A1_WR && !defined CONFIG_MRST_LNW_A2_WR - /* - * Activate high speed (if supported) - */ -@@ -428,7 +463,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, - mmc_set_timing(card->host, MMC_TIMING_MMC_HS); - } - } -- -+#endif - /* - * Compute bus speed. - */ -diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c -index fdd414e..5aae661 100644 ---- a/drivers/mmc/core/sd.c -+++ b/drivers/mmc/core/sd.c -@@ -234,6 +234,7 @@ out: - return err; - } - -+#if !defined CONFIG_MRST_LNW_A1_WR && !defined CONFIG_MRST_LNW_A2_WR - /* - * Test if the card supports high-speed mode and, if so, switch to it. - */ -@@ -281,6 +282,7 @@ out: - - return err; - } -+#endif - - MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], - card->raw_cid[2], card->raw_cid[3]); -@@ -460,12 +462,18 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, - goto free_card; - } - -+/* -+ * avoid SD cards to switch to HS timing -+ * which doesn't work yet due to LNW A-1 Silicon bug -+ */ -+#if !defined CONFIG_MRST_LNW_A1_WR && !defined CONFIG_MRST_LNW_A2_WR - /* - * Attempt to change to high-speed (if supported) - */ - err = mmc_switch_hs(card); - if (err) - goto free_card; -+#endif - - /* - * Compute bus speed. -diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c -index 06b6408..42977e1 100644 ---- a/drivers/mmc/core/sdio.c -+++ b/drivers/mmc/core/sdio.c -@@ -24,6 +24,262 @@ - #include "sdio_ops.h" - #include "sdio_cis.h" - -+#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) -+ -+#ifdef CONFIG_SDIO_SUSPEND -+ -+static int sdio_suspend_func(struct mmc_card *card, -+ struct sdio_func *func, pm_message_t msg) -+{ -+ struct device *dev; -+ int error = 0; -+ -+ dev = &func->dev; -+ BUG_ON(!dev); -+ -+ if (dev->bus) -+ if (dev->bus->suspend) -+ error = dev->bus->suspend(dev, msg); -+ -+ return error; -+} -+ -+static int sdio_resume_func(struct mmc_card *card, struct sdio_func *func) -+{ -+ struct device *dev; -+ int error = 0; -+ -+ dev = &func->dev; -+ BUG_ON(!dev); -+ -+ if (dev->bus) -+ if (dev->bus->resume) -+ error = dev->bus->resume(dev); -+ -+ return error; -+} -+ -+int sdio_suspend_host(struct mmc_card *card, pm_message_t msg) -+{ -+ int ret = 0; -+ int i = 0; -+ struct device *dev; -+ struct sdio_driver *drv; -+ -+ mutex_lock(&card->pm_mutex); -+ -+ if (!mmc_card_present(card) || -+ mmc_card_suspended(card)) -+ goto done; -+ -+ for (i = 0; i < card->sdio_funcs; i++) -+ if (!sdio_func_suspended(card->sdio_func[i])) { -+ dev = &(card->sdio_func[i])->dev; -+ BUG_ON(!dev); -+ -+ drv = to_sdio_driver(dev->driver); -+ -+ if (dev->driver && drv->suspend) -+ goto done; -+ } -+ -+ ret = mmc_suspend_host(card->host, msg); -+ -+ if (ret == 0) -+ mmc_card_set_suspended(card); -+ -+done: -+ mutex_unlock(&card->pm_mutex); -+ -+ return ret; -+} -+ -+int sdio_resume_host(struct mmc_card *card) -+{ -+ int ret = 0; -+ -+ mutex_lock(&card->pm_mutex); -+ -+ if (!mmc_card_present(card)) { -+ ret = -ENODEV; -+ goto done; -+ } -+ -+ if (mmc_card_suspended(card)) { -+ ret = mmc_resume_host(card->host); -+ -+ if (ret == 0) -+ mmc_card_clear_suspended(card); -+ else -+ goto done; -+ } -+ -+done: -+ mutex_unlock(&card->pm_mutex); -+ -+ return ret; -+} -+ -+/* -+ * This routine handles external suspend request coming from sysfs -+ */ -+int sdio_external_suspend_device(struct sdio_func *func, pm_message_t msg) -+{ -+ int ret = 0; -+ struct mmc_card *card = func->card; -+ -+ BUG_ON(!card); -+ BUG_ON(!card->host); -+ -+ mutex_lock(&card->pm_mutex); -+ -+ if (!sdio_func_present(func) || -+ sdio_func_suspended(func)) { -+ mutex_unlock(&card->pm_mutex); -+ goto done; -+ } -+ -+ /* suspend the function of the SDIO device */ -+ ret = sdio_suspend_func(card, func, msg); -+ -+ if (ret != 0) { -+ mutex_unlock(&card->pm_mutex); -+ goto done; -+ } -+ -+ sdio_func_set_suspended(func); -+ -+ mutex_unlock(&card->pm_mutex); -+ -+ ret = sdio_suspend_host(card, msg); -+ -+done: -+ return ret; -+} -+ -+/* -+ * This routine handles external resume request coming from sysfs -+ */ -+int sdio_external_resume_device(struct sdio_func *func) -+{ -+ int ret = 0; -+ struct mmc_card *card = func->card; -+ -+ BUG_ON(!card); -+ BUG_ON(!card->host); -+ -+ ret = sdio_resume_host(card); -+ if (ret) -+ goto done; -+ -+ mutex_lock(&card->pm_mutex); -+ -+ if (sdio_func_suspended(func)) { -+ ret = sdio_resume_func(card, func); -+ -+ if (ret != 0) { -+ mutex_unlock(&card->pm_mutex); -+ goto done; -+ } else -+ sdio_func_clear_suspended(func); -+ } -+ -+ mutex_unlock(&card->pm_mutex); -+done: -+ -+ return ret; -+} -+ -+static const char power_group[] = "power"; -+ -+static const char resume_string[] = "resume"; -+static const char suspend_string[] = "suspend"; -+ -+static ssize_t -+show_level(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct sdio_func *func = container_of(dev, struct sdio_func, dev); -+ const char *p = suspend_string; -+ -+ BUG_ON(!func); -+ -+ if (sdio_func_suspended(func)) -+ p = suspend_string; -+ else -+ p = resume_string; -+ -+ return sprintf(buf, "%s\n", p); -+} -+ -+static ssize_t -+set_level(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct sdio_func *func = container_of(dev, struct sdio_func, dev); -+ int len = count; -+ char *cp; -+ int ret = 0; -+ -+ BUG_ON(!func); -+ -+ cp = memchr(buf, '\n', count); -+ if (cp) -+ len = cp - buf; -+ -+ down(&dev->sem); -+ -+ if (len == sizeof resume_string - 1 && -+ strncmp(buf, resume_string, len) == 0) { -+ ret = sdio_external_resume_device(func); -+ } else if (len == sizeof suspend_string - 1 && -+ strncmp(buf, suspend_string, len) == 0) { -+ ret = sdio_external_suspend_device(func, PMSG_SUSPEND); -+ } else { -+ ret = -EINVAL; -+ } -+ -+ up(&dev->sem); -+ -+ return (ret < 0 ? ret : count); -+} -+ -+static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); -+ -+void sdio_remove_sysfs_file(struct sdio_func *func) -+{ -+ struct device *dev = &func->dev; -+ struct sdio_driver *drv = to_sdio_driver(dev->driver); -+ -+ if (dev->driver && drv->suspend) -+ sysfs_remove_file_from_group(&dev->kobj, -+ &dev_attr_level.attr, -+ power_group); -+} -+ -+int sdio_create_sysfs_file(struct sdio_func *func) -+{ -+ int ret; -+ struct device *dev = &func->dev; -+ struct sdio_driver *drv = to_sdio_driver(dev->driver); -+ -+ if (dev->driver && drv->suspend) { -+ ret = sysfs_add_file_to_group(&dev->kobj, -+ &dev_attr_level.attr, -+ power_group); -+ -+ if (ret) -+ goto error; -+ } -+ -+ return 0; -+ -+error: -+ sdio_remove_sysfs_file(func); -+ return ret; -+} -+ -+#endif /* CONFIG_SDIO_SUSPEND */ -+ - static int sdio_read_fbr(struct sdio_func *func) - { - int ret; -@@ -187,6 +443,7 @@ static int sdio_disable_cd(struct mmc_card *card) - return mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); - } - -+#if !defined(CONFIG_MRST_LNW_A1_WR) && !defined(CONFIG_MRST_LNW_A2_WR) - /* - * Test if the card supports high-speed mode and, if so, switch to it. - */ -@@ -216,6 +473,128 @@ static int sdio_enable_hs(struct mmc_card *card) - - return 0; - } -+#else -+static int sdio_enable_hs(struct mmc_card *card) -+{ -+ return 0; -+} -+#endif -+ -+/* -+ * Handle the re-initialization of a SDIO card. -+ */ -+static int mmc_sdio_reinit_card(struct mmc_host *host, -+ struct mmc_card *oldcard) -+{ -+ int err = 0; -+ u16 funcs; -+ u32 ocr; -+ struct mmc_card *card; -+ -+#if !defined(CONFIG_MRST_LNW_A1_WR) && !defined(CONFIG_MRST_LNW_A2_WR) -+ unsigned int max_dtr; -+#endif -+ -+ BUG_ON(!host); -+ WARN_ON(!host->claimed); -+ -+ if (!oldcard) -+ goto err; -+ -+ card = oldcard; -+ -+ err = mmc_send_io_op_cond(host, 0, &ocr); -+ if (err) -+ goto remove; -+ -+ /* -+ * Inform the card of the voltage -+ */ -+ err = mmc_send_io_op_cond(host, host->ocr, &ocr); -+ if (err) -+ goto remove; -+ -+ /* -+ * For SPI, enable CRC as appropriate. -+ */ -+ if (mmc_host_is_spi(host)) { -+ err = mmc_spi_set_crc(host, use_spi_crc); -+ if (err) -+ goto remove; -+ } -+ -+ funcs = (ocr & 0x70000000) >> 28; -+ -+ if (funcs != card->sdio_funcs) -+ printk(KERN_INFO "funcs number is changed from OCR register after suspend!\n"); -+ -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_send_relative_addr(host, &card->rca); -+ if (err) -+ goto remove; -+ -+ mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); -+ } -+ -+ /* -+ * Select card, as all following commands rely on that. -+ */ -+ if (!mmc_host_is_spi(host)) { -+ err = mmc_select_card(card); -+ if (err) -+ goto remove; -+ } -+ -+ /* -+ * Read the common CIS tuples. -+ */ -+ err = sdio_read_cccr(card); -+ if (err) -+ goto remove; -+ -+#if defined(CONFIG_MRST_LNW_A1_WR) || defined(CONFIG_MRST_LNW_A2_WR) -+ /* restricting to 24MHz for Langwell A0 */ -+ if (card->cis.max_dtr > 24000000) -+ card->cis.max_dtr = 24000000; -+ -+ mmc_set_clock(host, card->cis.max_dtr); -+#else -+ /* -+ * Switch to high-speed (if supported). -+ */ -+ err = sdio_enable_hs(card); -+ if (err) -+ goto remove; -+ -+ max_dtr = card->cis.max_dtr; -+ -+ /* -+ * Change to the card's maximum speed. -+ */ -+ if (mmc_card_highspeed(card)) { -+ if (max_dtr > 50000000) -+ max_dtr = 50000000; -+ } else if (max_dtr > 25000000) -+ max_dtr = 25000000; -+ -+ mmc_set_clock(host, max_dtr); -+#endif -+ -+ /* -+ * Switch to wider bus (if supported). -+ */ -+ err = sdio_enable_wide(card); -+ if (err) -+ goto remove; -+ -+ host->card = card; -+ -+ return 0; -+ -+remove: -+err: -+ return err; -+} - - /* - * Handle the detection and initialisation of a card. -@@ -478,6 +857,10 @@ int mmc_attach_sdio(struct mmc_host *host, u32 ocr) - int i, funcs; - struct mmc_card *card; - -+#if !defined(CONFIG_MRST_LNW_A1_WR) && !defined(CONFIG_MRST_LNW_A2_WR) -+ unsigned int max_dtr; -+#endif -+ - BUG_ON(!host); - WARN_ON(!host->claimed); - -@@ -574,3 +957,84 @@ err: - return err; - } - -+/* -+ * warn device driver and perform a SDIO device reset. -+ * Assume that device driver knows hot to handle resets. -+ */ -+int sdio_reset_device(struct mmc_card *card) -+{ -+ int ret = 0; -+ int i = 0; -+ u8 reg = 0; -+ -+ BUG_ON(!card); -+ BUG_ON(!card->host); -+ BUG_ON(!card->sdio_func); -+ -+ if (!mmc_card_present(card) || -+ mmc_card_suspended(card)) { -+ dev_dbg(&card->dev, "device reset not allowed\n"); -+ return -EINVAL; -+ } -+ -+ for (; i < card->sdio_funcs; i++) { -+ struct sdio_func *func = card->sdio_func[i]; -+ struct sdio_driver *drv; -+ -+ if (func && func->dev.driver) { -+ drv = to_sdio_driver(func->dev.driver); -+ if (drv->pre_reset) { -+ ret = (drv->pre_reset)(func); -+ if (ret) -+ break; -+ } -+ } -+ } -+ -+ if (ret) -+ goto err; -+ -+ /* reset SDIO card via CMD52 */ -+ mmc_claim_host(card->host); -+ -+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_ABORT, 0, ®); -+ -+ if (ret) -+ reg = 0x08; -+ else -+ reg |= 0x08; -+ -+ mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_ABORT, reg, NULL); -+ -+ /* re-enumerate the device */ -+ ret = mmc_sdio_reinit_card(card->host, card); -+ -+ mmc_release_host(card->host); -+ -+ if (ret) -+ goto err; -+ -+ for (i = card->sdio_funcs - 1; i >= 0; i--) { -+ struct sdio_func *func = card->sdio_func[i]; -+ struct sdio_driver *drv; -+ -+ if (func && func->dev.driver) { -+ drv = to_sdio_driver(func->dev.driver); -+ if (drv->post_reset) { -+ ret = (drv->post_reset)(func); -+ if (ret) -+ break; -+ } -+ } -+ } -+ -+ if (ret) -+ goto err; -+ -+ return 0; -+ -+err: -+ return -EINVAL; -+ -+} -+EXPORT_SYMBOL_GPL(sdio_reset_device); -diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c -index 9e060c8..84414e8 100644 ---- a/drivers/mmc/core/sdio_bus.c -+++ b/drivers/mmc/core/sdio_bus.c -@@ -124,6 +124,14 @@ static int sdio_bus_probe(struct device *dev) - if (!id) - return -ENODEV; - -+ /* -+ * create the user interface to call suspend/resume -+ * from susfs -+ */ -+#ifdef CONFIG_SDIO_SUSPEND -+ sdio_create_sysfs_file(func); -+#endif -+ - /* Set the default block size so the driver is sure it's something - * sensible. */ - sdio_claim_host(func); -@@ -140,6 +148,10 @@ 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); - -+#ifdef CONFIG_SDIO_SUSPEND -+ sdio_remove_sysfs_file(func); -+#endif -+ - drv->remove(func); - - if (func->irq_handler) { -@@ -153,6 +165,30 @@ static int sdio_bus_remove(struct device *dev) - return 0; - } - -+static int sdio_bus_suspend(struct device *dev, pm_message_t state) -+{ -+ struct sdio_driver *drv = to_sdio_driver(dev->driver); -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ int ret = 0; -+ -+ if (dev->driver && drv->suspend) -+ ret = drv->suspend(func, state); -+ -+ return ret; -+} -+ -+static int sdio_bus_resume(struct device *dev) -+{ -+ struct sdio_driver *drv = to_sdio_driver(dev->driver); -+ struct sdio_func *func = dev_to_sdio_func(dev); -+ int ret = 0; -+ -+ if (dev->driver && drv->resume) -+ ret = drv->resume(func); -+ -+ return ret; -+} -+ - static struct bus_type sdio_bus_type = { - .name = "sdio", - .dev_attrs = sdio_dev_attrs, -@@ -160,6 +196,8 @@ static struct bus_type sdio_bus_type = { - .uevent = sdio_bus_uevent, - .probe = sdio_bus_probe, - .remove = sdio_bus_remove, -+ .suspend = sdio_bus_suspend, -+ .resume = sdio_bus_resume, - }; - - int sdio_register_bus(void) -diff --git a/drivers/mmc/core/sdio_bus.h b/drivers/mmc/core/sdio_bus.h -index 567a768..18616b2 100644 ---- a/drivers/mmc/core/sdio_bus.h -+++ b/drivers/mmc/core/sdio_bus.h -@@ -18,5 +18,9 @@ void sdio_remove_func(struct sdio_func *func); - int sdio_register_bus(void); - void sdio_unregister_bus(void); - -+#ifdef CONFIG_SDIO_SUSPEND -+int sdio_create_sysfs_file(struct sdio_func *func); -+void sdio_remove_sysfs_file(struct sdio_func *func); -+#endif - #endif - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index ce1d288..521cf2e 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -68,6 +68,16 @@ config MMC_SDHCI_PCI - - If unsure, say N. - -+config MMC_SDHCI_MRST_EMMC -+ tristate "Enable eMMC device on MRST" -+ depends on MMC_SDHCI && PCI -+ help -+ This enables eMMC device for MRST platform. -+ -+ If you're using eMMC device on Moorestown, say Y or M here. -+ -+ If unsure, say N. -+ - config MMC_RICOH_MMC - tristate "Ricoh MMC Controller Disabler (EXPERIMENTAL)" - depends on MMC_SDHCI_PCI -diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c -index 5c3a176..53f3719 100644 ---- a/drivers/mmc/host/sdhci-pci.c -+++ b/drivers/mmc/host/sdhci-pci.c -@@ -38,6 +38,8 @@ - - #define MAX_SLOTS 8 - -+static struct mutex port_mutex; -+ - struct sdhci_pci_chip; - struct sdhci_pci_slot; - -@@ -364,6 +366,17 @@ static const struct sdhci_pci_fixes sdhci_via = { - .probe = via_probe, - }; - -+/* -+ * ADMA operation is disabled for Moorestown platform. -+ */ -+static const struct sdhci_pci_fixes sdhci_intel_mrst = { -+ .quirks = SDHCI_QUIRK_BROKEN_ADMA | -+#ifdef CONFIG_MMC_SDHCI_MRST_EMMC -+ SDHCI_QUIRK_BROKEN_CARD_DETECTION | -+#endif -+ SDHCI_QUIRK_MRST_RESTRICTION, -+}; -+ - static const struct pci_device_id pci_ids[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_RICOH, -@@ -445,6 +458,22 @@ static const struct pci_device_id pci_ids[] __devinitdata = { - .driver_data = (kernel_ulong_t)&sdhci_via, - }, - -+ { -+ .vendor = PCI_VENDOR_ID_INTEL, -+ .device = PCI_DEVICE_ID_INTEL_MRST_SD0, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .driver_data = (kernel_ulong_t)&sdhci_intel_mrst, -+ }, -+ -+ { -+ .vendor = PCI_VENDOR_ID_INTEL, -+ .device = PCI_DEVICE_ID_INTEL_MRST_SD1, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .driver_data = (kernel_ulong_t)&sdhci_intel_mrst, -+ }, -+ - { /* Generic SD host controller */ - PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) - }, -@@ -469,11 +498,14 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host) - slot = sdhci_priv(host); - pdev = slot->chip->pdev; - -- if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) && -- ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && -- (host->flags & SDHCI_USE_SDMA)) { -- dev_warn(&pdev->dev, "Will use DMA mode even though HW " -- "doesn't fully claim to support it.\n"); -+ if (!(host->quirks & SDHCI_QUIRK_MRST_RESTRICTION)) { -+ if (((pdev->class & 0xFFFF00) == -+ (PCI_CLASS_SYSTEM_SDHCI << 8)) && -+ ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) && -+ (host->flags & SDHCI_USE_SDMA)) { -+ dev_warn(&pdev->dev, "Will use DMA mode even though HW " -+ "doesn't fully claim to support it.\n"); -+ } - } - - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); -@@ -622,6 +654,9 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( - return ERR_PTR(PTR_ERR(host)); - } - -+ if (pdev->device == PCI_DEVICE_ID_INTEL_MRST_SD0) -+ host->mmc->port_mutex = &port_mutex; -+ - slot = sdhci_priv(host); - - slot->chip = chip; -@@ -712,22 +747,42 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, - dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n", - (int)pdev->vendor, (int)pdev->device, (int)rev); - -- ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); -- if (ret) -- return ret; -+ /* -+ * slots number is fixed to 2 by Moorestown architecture -+ */ -+ if (pdev->device == PCI_DEVICE_ID_INTEL_MRST_SD0) { -+ slots = 2; -+ mutex_init(&port_mutex); -+ } else if (pdev->device == PCI_DEVICE_ID_INTEL_MRST_SD1) -+ slots = 1; -+ else { -+ ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); -+ -+ if (ret) -+ return ret; -+ -+ slots = PCI_SLOT_INFO_SLOTS(slots) + 1; -+ } - -- slots = PCI_SLOT_INFO_SLOTS(slots) + 1; - dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); - if (slots == 0) - return -ENODEV; - - BUG_ON(slots > MAX_SLOTS); - -- ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); -- if (ret) -- return ret; -+ /* -+ * first BAR is fixed to 0 by Moorestown architecture -+ */ -+ if (pdev->device == PCI_DEVICE_ID_INTEL_MRST_SD0 || -+ pdev->device == PCI_DEVICE_ID_INTEL_MRST_SD1) { -+ first_bar = 0; -+ } else { -+ ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); -+ if (ret) -+ return ret; - -- first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; -+ first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; -+ } - - if (first_bar > 5) { - dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n"); -diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c -index c279fbc..ff26db0 100644 ---- a/drivers/mmc/host/sdhci.c -+++ b/drivers/mmc/host/sdhci.c -@@ -161,9 +161,11 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) - /* hw clears the bit when it's done */ - while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { - if (timeout == 0) { -+#ifndef CONFIG_MRST_LNW_A2_WR - printk(KERN_ERR "%s: Reset 0x%x never completed.\n", - mmc_hostname(host->mmc), (int)mask); - sdhci_dumpregs(host); -+#endif - return; - } - timeout--; -@@ -176,13 +178,25 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) - - static void sdhci_init(struct sdhci_host *host) - { -+ u32 intmask; -+ -+ intmask = sdhci_readl(host, SDHCI_INT_STATUS); -+ sdhci_writel(host, -+ intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), -+ SDHCI_INT_STATUS); -+ -+#ifndef CONFIG_MRST_LNW_A2_WR - sdhci_reset(host, SDHCI_RESET_ALL); -+#endif - - sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, - SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | - SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | - SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | - SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); -+ -+ /* disable wakeup signal during initialization */ -+ sdhci_writeb(host, 0x0, SDHCI_WAKE_UP_CONTROL); - } - - static void sdhci_reinit(struct sdhci_host *host) -@@ -465,6 +479,54 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, - len -= offset; - } - -+#if defined(CONFIG_MRST_LNW_A1_WR) || defined(CONFIG_MRST_LNW_A2_WR) -+ if (len != 65536) { -+ desc[7] = (addr >> 24) & 0xff; -+ desc[6] = (addr >> 16) & 0xff; -+ desc[5] = (addr >> 8) & 0xff; -+ desc[4] = (addr >> 0) & 0xff; -+ -+ BUG_ON(len > 65536); -+ -+ desc[3] = (len >> 8) & 0xff; -+ desc[2] = (len >> 0) & 0xff; -+ -+ desc[1] = 0x00; -+ desc[0] = 0x21; /* tran, valid */ -+ -+ desc += 8; -+ } else { -+ desc[7] = (addr >> 24) & 0xff; -+ desc[6] = (addr >> 16) & 0xff; -+ desc[5] = (addr >> 8) & 0xff; -+ desc[4] = (addr >> 0) & 0xff; -+ -+ desc[3] = (32768 >> 8) & 0xff; -+ desc[2] = (32768 >> 0) & 0xff; -+ -+ desc[1] = 0x00; -+ desc[0] = 0x21; /* tran, valid */ -+ -+ desc += 8; -+ -+ /* 2nd */ -+ addr += 32768; -+ -+ desc[7] = (addr >> 24) & 0xff; -+ desc[6] = (addr >> 16) & 0xff; -+ desc[5] = (addr >> 8) & 0xff; -+ desc[4] = (addr >> 0) & 0xff; -+ -+ desc[3] = (32768 >> 8) & 0xff; -+ desc[2] = (32768 >> 0) & 0xff; -+ -+ desc[1] = 0x00; -+ desc[0] = 0x21; /* tran, valid */ -+ -+ desc += 8; -+ } -+#else -+ - desc[7] = (addr >> 24) & 0xff; - desc[6] = (addr >> 16) & 0xff; - desc[5] = (addr >> 8) & 0xff; -@@ -479,7 +541,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, - desc[0] = 0x21; /* tran, valid */ - - desc += 8; -- -+#endif - /* - * If this triggers then we have a calculation bug - * somewhere. :/ -@@ -487,6 +549,11 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, - WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4); - } - -+ -+#if defined(CONFIG_MRST_LNW_A1_WR) || defined(CONFIG_MRST_LNW_A2_WR) -+ desc -= 8; -+ desc[0] = 0x23; -+#else - /* - * Add a terminating entry. - */ -@@ -500,7 +567,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, - - desc[1] = 0x00; - desc[0] = 0x03; /* nop, end, valid */ -- -+#endif - /* - * Resync align buffer as we might have changed it. - */ -@@ -613,11 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data) - break; - } - -- if (count >= 0xF) { -- printk(KERN_WARNING "%s: Too large timeout requested!\n", -- mmc_hostname(host->mmc)); -+ if (count >= 0xF) - count = 0xE; -- } - - return count; - } -@@ -928,6 +992,30 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) - if (cmd->data) - flags |= SDHCI_CMD_DATA; - -+ if (host->quirks & SDHCI_QUIRK_MRST_RESTRICTION) { -+ u16 clk; -+ -+ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); -+ -+ clk |= SDHCI_CLOCK_CARD_EN; -+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); -+ -+ /* Wait max 10 ms */ -+ timeout = 10; -+ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) -+ & SDHCI_CLOCK_INT_STABLE)) { -+ if (timeout == 0) { -+ printk(KERN_ERR "%s: Internal clock never " -+ "stabilised.\n", -+ mmc_hostname(host->mmc)); -+ sdhci_dumpregs(host); -+ return; -+ } -+ timeout--; -+ mdelay(1); -+ } -+ } -+ - sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); - } - -@@ -1147,14 +1235,22 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - - ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); - -- if (ios->bus_width == MMC_BUS_WIDTH_4) -+ if (ios->bus_width == MMC_BUS_WIDTH_8) { -+ ctrl |= SDHCI_CTRL_8BITBUS; - ctrl |= SDHCI_CTRL_4BITBUS; -- else -+ } else if (ios->bus_width == MMC_BUS_WIDTH_4) { -+ ctrl &= ~SDHCI_CTRL_8BITBUS; -+ ctrl |= SDHCI_CTRL_4BITBUS; -+ } else { -+ ctrl &= ~SDHCI_CTRL_8BITBUS; - ctrl &= ~SDHCI_CTRL_4BITBUS; -+ } - -- if (ios->timing == MMC_TIMING_SD_HS) -+#ifndef CONFIG_MRST_LNW_A2_WR -+ if (ios->timing == MMC_TIMING_SD_HS || ios->timing == MMC_TIMING_MMC_HS) - ctrl |= SDHCI_CTRL_HISPD; - else -+#endif - ctrl &= ~SDHCI_CTRL_HISPD; - - sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -@@ -1354,6 +1450,10 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) - BUG_ON(intmask == 0); - - if (!host->cmd) { -+ if (host->quirks & SDHCI_QUIRK_MRST_RESTRICTION && -+ !(strncmp(mmc_hostname(host->mmc), "mmc1", 4))) -+ return; -+ - printk(KERN_ERR "%s: Got command interrupt 0x%08x even " - "though no command operation was in progress.\n", - mmc_hostname(host->mmc), (unsigned)intmask); -@@ -1667,7 +1767,9 @@ int sdhci_add_host(struct sdhci_host *host) - if (debug_quirks) - host->quirks = debug_quirks; - -+#ifndef CONFIG_MRST_LNW_A2_WR - sdhci_reset(host, SDHCI_RESET_ALL); -+#endif - - host->version = sdhci_readw(host, SDHCI_HOST_VERSION); - host->version = (host->version & SDHCI_SPEC_VER_MASK) -@@ -1787,7 +1889,7 @@ int sdhci_add_host(struct sdhci_host *host) - mmc->caps |= MMC_CAP_4_BIT_DATA; - - if (caps & SDHCI_CAN_DO_HISPD) -- mmc->caps |= MMC_CAP_SD_HIGHSPEED; -+ mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; - - if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) - mmc->caps |= MMC_CAP_NEEDS_POLL; -@@ -1845,7 +1947,8 @@ int sdhci_add_host(struct sdhci_host *host) - } else { - mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> - SDHCI_MAX_BLOCK_SHIFT; -- if (mmc->max_blk_size >= 3) { -+ if ((mmc->max_blk_size >= 3) && -+ !(host->quirks & SDHCI_QUIRK_MRST_RESTRICTION)) { - printk(KERN_WARNING "%s: Invalid maximum block size, " - "assuming 512 bytes\n", mmc_hostname(mmc)); - mmc->max_blk_size = 0; -diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h -index 842f46f..f7ba4a2 100644 ---- a/drivers/mmc/host/sdhci.h -+++ b/drivers/mmc/host/sdhci.h -@@ -67,6 +67,7 @@ - #define SDHCI_CTRL_LED 0x01 - #define SDHCI_CTRL_4BITBUS 0x02 - #define SDHCI_CTRL_HISPD 0x04 -+#define SDHCI_CTRL_8BITBUS 0x20 - #define SDHCI_CTRL_DMA_MASK 0x18 - #define SDHCI_CTRL_SDMA 0x00 - #define SDHCI_CTRL_ADMA1 0x08 -@@ -236,6 +237,8 @@ struct sdhci_host { - #define SDHCI_QUIRK_DELAY_AFTER_POWER (1<<23) - /* Controller uses SDCLK instead of TMCLK for data timeouts */ - #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) -+/* Controller of Moorestown specific restriction */ -+#define SDHCI_QUIRK_MRST_RESTRICTION (1<<25) - - int irq; /* Device IRQ */ - void __iomem * ioaddr; /* Mapped address */ -diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h -index 2ee22e8..731f984 100644 ---- a/include/linux/mmc/card.h -+++ b/include/linux/mmc/card.h -@@ -97,6 +97,7 @@ struct mmc_card { - #define MMC_STATE_READONLY (1<<1) /* card is read-only */ - #define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */ - #define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */ -+#define MMC_STATE_SUSPENDED (1<<4) /* card uses block-addressing */ - unsigned int quirks; /* card quirks */ - #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ - -@@ -109,6 +110,7 @@ struct mmc_card { - struct sd_scr scr; /* extra SD information */ - struct sd_switch_caps sw_caps; /* switch (CMD6) caps */ - -+ /* sdio related info */ - unsigned int sdio_funcs; /* number of SDIO functions */ - struct sdio_cccr cccr; /* common card info */ - struct sdio_cis cis; /* common tuple info */ -@@ -118,6 +120,10 @@ struct mmc_card { - struct sdio_func_tuple *tuples; /* unknown common tuples */ - - struct dentry *debugfs_root; -+ -+#ifdef CONFIG_SDIO_SUSPEND -+ struct mutex pm_mutex; -+#endif - }; - - #define mmc_card_mmc(c) ((c)->type == MMC_TYPE_MMC) -@@ -128,6 +134,7 @@ struct mmc_card { - #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) - #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) - #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) -+#define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) - - #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) - #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) -@@ -139,6 +146,11 @@ static inline int mmc_card_lenient_fn0(const struct mmc_card *c) - return c->quirks & MMC_QUIRK_LENIENT_FN0; - } - -+#ifdef CONFIG_SDIO_SUSPEND -+#define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) -+#define mmc_card_clear_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) -+#endif -+ - #define mmc_card_name(c) ((c)->cid.prod_name) - #define mmc_card_id(c) (dev_name(&(c)->dev)) - -diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index eaf3636..814450a 100644 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -203,6 +203,8 @@ struct mmc_host { - - struct dentry *debugfs_root; - -+ struct mutex *port_mutex; -+ - unsigned long private[0] ____cacheline_aligned; - }; - -diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h -index ac3ab68..a863a9a 100644 ---- a/include/linux/mmc/sdio_func.h -+++ b/include/linux/mmc/sdio_func.h -@@ -50,6 +50,7 @@ struct sdio_func { - - unsigned int state; /* function state */ - #define SDIO_STATE_PRESENT (1<<0) /* present in sysfs */ -+#define SDIO_STATE_SUSPENDED (1<<1) /* present in sysfs */ - - u8 tmpbuf[4]; /* DMA:able scratch buffer */ - -@@ -60,9 +61,13 @@ struct sdio_func { - }; - - #define sdio_func_present(f) ((f)->state & SDIO_STATE_PRESENT) -+#define sdio_func_suspended(f) ((f)->state & SDIO_STATE_SUSPENDED) - - #define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT) - -+#define sdio_func_set_suspended(f) ((f)->state |= SDIO_STATE_SUSPENDED) -+#define sdio_func_clear_suspended(f) ((f)->state &= ~SDIO_STATE_SUSPENDED) -+ - #define sdio_func_id(f) (dev_name(&(f)->dev)) - - #define sdio_get_drvdata(f) dev_get_drvdata(&(f)->dev) -@@ -78,6 +83,11 @@ struct sdio_driver { - - int (*probe)(struct sdio_func *, const struct sdio_device_id *); - void (*remove)(struct sdio_func *); -+ int (*suspend)(struct sdio_func *, pm_message_t); -+ int (*resume)(struct sdio_func *); -+ -+ int (*pre_reset)(struct sdio_func *); -+ int (*post_reset)(struct sdio_func *); - - struct device_driver drv; - }; -@@ -153,5 +163,9 @@ extern unsigned char sdio_f0_readb(struct sdio_func *func, - extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b, - unsigned int addr, int *err_ret); - -+extern int sdio_reset_device(struct mmc_card *card); -+ -+extern int sdio_suspend_host(struct mmc_card *card, pm_message_t msg); -+extern int sdio_resume_host(struct mmc_card *card); - #endif - -diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h -index cca8a04..2ec7f6c 100644 ---- a/include/linux/pci_ids.h -+++ b/include/linux/pci_ids.h -@@ -2396,6 +2396,8 @@ - #define PCI_DEVICE_ID_INTEL_82375 0x0482 - #define PCI_DEVICE_ID_INTEL_82424 0x0483 - #define PCI_DEVICE_ID_INTEL_82378 0x0484 -+#define PCI_DEVICE_ID_INTEL_MRST_SD0 0x0807 -+#define PCI_DEVICE_ID_INTEL_MRST_SD1 0x0808 - #define PCI_DEVICE_ID_INTEL_I960 0x0960 - #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 - #define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 --- -1.6.2.5 - |