Commit a8feb782 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.6-rc4' of git://git.linaro.org/people/ulf.hansson/mmc

Pull MMC fixes from Ulf Hansson:
 "Here are a two MMC host fixes:

  - sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs

  - sunxi: Disable eMMC HS-DDR for Allwinner A80"

* tag 'mmc-v4.6-rc4' of git://git.linaro.org/people/ulf.hansson/mmc:
  mmc: sunxi: Disable eMMC HS-DDR (MMC_CAP_1_8V_DDR) for Allwinner A80
  mmc: sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs
parents b9cc335f 2963070a
...@@ -97,6 +97,7 @@ config MMC_RICOH_MMC ...@@ -97,6 +97,7 @@ config MMC_RICOH_MMC
config MMC_SDHCI_ACPI config MMC_SDHCI_ACPI
tristate "SDHCI support for ACPI enumerated SDHCI controllers" tristate "SDHCI support for ACPI enumerated SDHCI controllers"
depends on MMC_SDHCI && ACPI depends on MMC_SDHCI && ACPI
select IOSF_MBI if X86
help help
This selects support for ACPI enumerated SDHCI controllers, This selects support for ACPI enumerated SDHCI controllers,
identified by ACPI Compatibility ID PNP0D40 or specific identified by ACPI Compatibility ID PNP0D40 or specific
......
...@@ -41,6 +41,11 @@ ...@@ -41,6 +41,11 @@
#include <linux/mmc/pm.h> #include <linux/mmc/pm.h>
#include <linux/mmc/slot-gpio.h> #include <linux/mmc/slot-gpio.h>
#ifdef CONFIG_X86
#include <asm/cpu_device_id.h>
#include <asm/iosf_mbi.h>
#endif
#include "sdhci.h" #include "sdhci.h"
enum { enum {
...@@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { ...@@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_int = {
.ops = &sdhci_acpi_ops_int, .ops = &sdhci_acpi_ops_int,
}; };
#ifdef CONFIG_X86
static bool sdhci_acpi_byt(void)
{
static const struct x86_cpu_id byt[] = {
{ X86_VENDOR_INTEL, 6, 0x37 },
{}
};
return x86_match_cpu(byt);
}
#define BYT_IOSF_SCCEP 0x63
#define BYT_IOSF_OCP_NETCTRL0 0x1078
#define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8)
static void sdhci_acpi_byt_setting(struct device *dev)
{
u32 val = 0;
if (!sdhci_acpi_byt())
return;
if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0,
&val)) {
dev_err(dev, "%s read error\n", __func__);
return;
}
if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE))
return;
val &= ~BYT_IOSF_OCP_TIMEOUT_BASE;
if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0,
val)) {
dev_err(dev, "%s write error\n", __func__);
return;
}
dev_dbg(dev, "%s completed\n", __func__);
}
static bool sdhci_acpi_byt_defer(struct device *dev)
{
if (!sdhci_acpi_byt())
return false;
if (!iosf_mbi_available())
return true;
sdhci_acpi_byt_setting(dev);
return false;
}
#else
static inline void sdhci_acpi_byt_setting(struct device *dev)
{
}
static inline bool sdhci_acpi_byt_defer(struct device *dev)
{
return false;
}
#endif
static int bxt_get_cd(struct mmc_host *mmc) static int bxt_get_cd(struct mmc_host *mmc)
{ {
int gpio_cd = mmc_gpio_get_cd(mmc); int gpio_cd = mmc_gpio_get_cd(mmc);
...@@ -322,6 +396,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev) ...@@ -322,6 +396,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
if (acpi_bus_get_status(device) || !device->status.present) if (acpi_bus_get_status(device) || !device->status.present)
return -ENODEV; return -ENODEV;
if (sdhci_acpi_byt_defer(dev))
return -EPROBE_DEFER;
hid = acpi_device_hid(device); hid = acpi_device_hid(device);
uid = device->pnp.unique_id; uid = device->pnp.unique_id;
...@@ -447,6 +524,8 @@ static int sdhci_acpi_resume(struct device *dev) ...@@ -447,6 +524,8 @@ static int sdhci_acpi_resume(struct device *dev)
{ {
struct sdhci_acpi_host *c = dev_get_drvdata(dev); struct sdhci_acpi_host *c = dev_get_drvdata(dev);
sdhci_acpi_byt_setting(&c->pdev->dev);
return sdhci_resume_host(c->host); return sdhci_resume_host(c->host);
} }
...@@ -470,6 +549,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev) ...@@ -470,6 +549,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev)
{ {
struct sdhci_acpi_host *c = dev_get_drvdata(dev); struct sdhci_acpi_host *c = dev_get_drvdata(dev);
sdhci_acpi_byt_setting(&c->pdev->dev);
return sdhci_runtime_resume_host(c->host); return sdhci_runtime_resume_host(c->host);
} }
......
...@@ -1129,6 +1129,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev) ...@@ -1129,6 +1129,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
MMC_CAP_1_8V_DDR | MMC_CAP_1_8V_DDR |
MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
/* TODO MMC DDR is not working on A80 */
if (of_device_is_compatible(pdev->dev.of_node,
"allwinner,sun9i-a80-mmc"))
mmc->caps &= ~MMC_CAP_1_8V_DDR;
ret = mmc_of_parse(mmc); ret = mmc_of_parse(mmc);
if (ret) if (ret)
goto error_free_dma; goto error_free_dma;
......
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