mirror of https://gitee.com/openkylin/linux.git
MMC host:
- sdhci-acpi: Reduce Baytrail eMMC/SD/SDIO hangs - sunxi: Disable eMMC HS-DDR for Allwinner A80 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXInEdAAoJEP4mhCVzWIwpMIUP/0WLTuK68GJ7/hbx7cFfJUsQ R05hc31VQkN8Q8ebunz/BuNo5a80QZqLX8zIpnFpoPWkE56ERwAsFr2Qv7qGhQvA Qnh03EiKsdrt9du4ZfPT6rBU+4xcUoyGZauGKBOt/cqvG6m7VQxJ4XTbb3u9m4BV QM2K1t4po195b4FsTWetfZ/Uqib4vW+F/ekqmQh4SdQ++RRxuDw/aYtdFd3gp3DS 5ZQToN3lsS5ibFPbzSOBTY0Emu6b/0DQE3PxtQhmJsp1fHCf9aEMhO9ETL5QuntZ xkqBtTbhmR2NcITpgha/m9caLBFtMJNfK1xtAnJOoEenK9u4Dd/p9V/eQ9RUBq+k VRfiOKdxjKtYIPogdF9E4XUYBKUT7sIGF0lfNT/Rru5WA+zmlf6moNHlrChvdN8S TSq/Tj6+8dU1Vm2+IPKrlsR5EjqGaOq5RYptRDNTnnvT8ni/m3UQETtI+V4VaC/k 5LxnjyvnyMRYL9hz7cekmuW2xRCVSEcD6cCwRKRa9wQaoazV6Su5ZzrkzBtgExqb gR+QAPoWxf8DbiBCWsTT+/X+DVypeHZCrZX0v+sDQrbBHMR0n7ApVD3FzvZNGyZl vPvW4GCH0fsRMkfJkjZsfqrO8qFXcnF0NqQ7NM4msYEPJFm+SCg+lcaGa96p7mwM v04TgEXKeHIDFoVaHhzW =t5At -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a8feb78209
|
@ -97,6 +97,7 @@ config MMC_RICOH_MMC
|
|||
config MMC_SDHCI_ACPI
|
||||
tristate "SDHCI support for ACPI enumerated SDHCI controllers"
|
||||
depends on MMC_SDHCI && ACPI
|
||||
select IOSF_MBI if X86
|
||||
help
|
||||
This selects support for ACPI enumerated SDHCI controllers,
|
||||
identified by ACPI Compatibility ID PNP0D40 or specific
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
#include <linux/mmc/pm.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"
|
||||
|
||||
enum {
|
||||
|
@ -116,6 +121,75 @@ static const struct sdhci_acpi_chip sdhci_acpi_chip_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)
|
||||
{
|
||||
int gpio_cd = mmc_gpio_get_cd(mmc);
|
||||
|
@ -322,6 +396,9 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
|||
if (acpi_bus_get_status(device) || !device->status.present)
|
||||
return -ENODEV;
|
||||
|
||||
if (sdhci_acpi_byt_defer(dev))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
hid = acpi_device_hid(device);
|
||||
uid = device->pnp.unique_id;
|
||||
|
||||
|
@ -447,6 +524,8 @@ static int sdhci_acpi_resume(struct device *dev)
|
|||
{
|
||||
struct sdhci_acpi_host *c = dev_get_drvdata(dev);
|
||||
|
||||
sdhci_acpi_byt_setting(&c->pdev->dev);
|
||||
|
||||
return sdhci_resume_host(c->host);
|
||||
}
|
||||
|
||||
|
@ -470,6 +549,8 @@ static int sdhci_acpi_runtime_resume(struct device *dev)
|
|||
{
|
||||
struct sdhci_acpi_host *c = dev_get_drvdata(dev);
|
||||
|
||||
sdhci_acpi_byt_setting(&c->pdev->dev);
|
||||
|
||||
return sdhci_runtime_resume_host(c->host);
|
||||
}
|
||||
|
||||
|
|
|
@ -1129,6 +1129,11 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
|
|||
MMC_CAP_1_8V_DDR |
|
||||
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);
|
||||
if (ret)
|
||||
goto error_free_dma;
|
||||
|
|
Loading…
Reference in New Issue