Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+87
+1
drivers/mmc/host/Kconfig
··· 97 97 config MMC_SDHCI_ACPI 98 98 tristate "SDHCI support for ACPI enumerated SDHCI controllers" 99 99 depends on MMC_SDHCI && ACPI 100 + select IOSF_MBI if X86 100 101 help 101 102 This selects support for ACPI enumerated SDHCI controllers, 102 103 identified by ACPI Compatibility ID PNP0D40 or specific
+81
drivers/mmc/host/sdhci-acpi.c
··· 41 41 #include <linux/mmc/pm.h> 42 42 #include <linux/mmc/slot-gpio.h> 43 43 44 + #ifdef CONFIG_X86 45 + #include <asm/cpu_device_id.h> 46 + #include <asm/iosf_mbi.h> 47 + #endif 48 + 44 49 #include "sdhci.h" 45 50 46 51 enum { ··· 120 115 static const struct sdhci_acpi_chip sdhci_acpi_chip_int = { 121 116 .ops = &sdhci_acpi_ops_int, 122 117 }; 118 + 119 + #ifdef CONFIG_X86 120 + 121 + static bool sdhci_acpi_byt(void) 122 + { 123 + static const struct x86_cpu_id byt[] = { 124 + { X86_VENDOR_INTEL, 6, 0x37 }, 125 + {} 126 + }; 127 + 128 + return x86_match_cpu(byt); 129 + } 130 + 131 + #define BYT_IOSF_SCCEP 0x63 132 + #define BYT_IOSF_OCP_NETCTRL0 0x1078 133 + #define BYT_IOSF_OCP_TIMEOUT_BASE GENMASK(10, 8) 134 + 135 + static void sdhci_acpi_byt_setting(struct device *dev) 136 + { 137 + u32 val = 0; 138 + 139 + if (!sdhci_acpi_byt()) 140 + return; 141 + 142 + if (iosf_mbi_read(BYT_IOSF_SCCEP, MBI_CR_READ, BYT_IOSF_OCP_NETCTRL0, 143 + &val)) { 144 + dev_err(dev, "%s read error\n", __func__); 145 + return; 146 + } 147 + 148 + if (!(val & BYT_IOSF_OCP_TIMEOUT_BASE)) 149 + return; 150 + 151 + val &= ~BYT_IOSF_OCP_TIMEOUT_BASE; 152 + 153 + if (iosf_mbi_write(BYT_IOSF_SCCEP, MBI_CR_WRITE, BYT_IOSF_OCP_NETCTRL0, 154 + val)) { 155 + dev_err(dev, "%s write error\n", __func__); 156 + return; 157 + } 158 + 159 + dev_dbg(dev, "%s completed\n", __func__); 160 + } 161 + 162 + static bool sdhci_acpi_byt_defer(struct device *dev) 163 + { 164 + if (!sdhci_acpi_byt()) 165 + return false; 166 + 167 + if (!iosf_mbi_available()) 168 + return true; 169 + 170 + sdhci_acpi_byt_setting(dev); 171 + 172 + return false; 173 + } 174 + 175 + #else 176 + 177 + static inline void sdhci_acpi_byt_setting(struct device *dev) 178 + { 179 + } 180 + 181 + static inline bool sdhci_acpi_byt_defer(struct device *dev) 182 + { 183 + return false; 184 + } 185 + 186 + #endif 123 187 124 188 static int bxt_get_cd(struct mmc_host *mmc) 125 189 { ··· 396 322 if (acpi_bus_get_status(device) || !device->status.present) 397 323 return -ENODEV; 398 324 325 + if (sdhci_acpi_byt_defer(dev)) 326 + return -EPROBE_DEFER; 327 + 399 328 hid = acpi_device_hid(device); 400 329 uid = device->pnp.unique_id; 401 330 ··· 524 447 { 525 448 struct sdhci_acpi_host *c = dev_get_drvdata(dev); 526 449 450 + sdhci_acpi_byt_setting(&c->pdev->dev); 451 + 527 452 return sdhci_resume_host(c->host); 528 453 } 529 454 ··· 548 469 static int sdhci_acpi_runtime_resume(struct device *dev) 549 470 { 550 471 struct sdhci_acpi_host *c = dev_get_drvdata(dev); 472 + 473 + sdhci_acpi_byt_setting(&c->pdev->dev); 551 474 552 475 return sdhci_runtime_resume_host(c->host); 553 476 }
+5
drivers/mmc/host/sunxi-mmc.c
··· 1129 1129 MMC_CAP_1_8V_DDR | 1130 1130 MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; 1131 1131 1132 + /* TODO MMC DDR is not working on A80 */ 1133 + if (of_device_is_compatible(pdev->dev.of_node, 1134 + "allwinner,sun9i-a80-mmc")) 1135 + mmc->caps &= ~MMC_CAP_1_8V_DDR; 1136 + 1132 1137 ret = mmc_of_parse(mmc); 1133 1138 if (ret) 1134 1139 goto error_free_dma;