History

Merge tag 'mmc-v6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC fixes from Ulf Hansson: "Core: - Further prevent card detect during shutdown Host drivers: - sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10 tablet" * tag 'mmc-v6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: core: Further prevent card detect during shutdown mmc: sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10 tablet

Linus Torvalds committed 1 year ago

Commit 35b7b332 parents fa4c221 87a0d904 files · +78 −0Browse files

Unified · Split

4 files
  1. drivers/mmc/core/bus.c +2 −0
  2. drivers/mmc/core/core.c +3 −0
  3. drivers/mmc/host/sdhci-pci-core.c +72 −0
  4. drivers/mmc/host/sdhci-pci.h +1 −0
drivers/mmc/core/bus.c+2−0
@@ -149,6 +149,8 @@ static void mmc_bus_shutdown(struct device *dev) · 148 unmodified lines
149149 if (dev->driver && drv->shutdown)
150150 drv->shutdown(card);
151151
152+ __mmc_stop_host(host);
153+
152154 if (host->bus_ops->shutdown) {
153155 ret = host->bus_ops->shutdown(host);
154156 if (ret)
drivers/mmc/core/core.c+3−0
@@ -2335,6 +2335,9 @@ void mmc_start_host(struct mmc_host *host) · 2334 unmodified lines
23352335
23362336 void __mmc_stop_host(struct mmc_host *host)
23372337 {
2338+ if (host->rescan_disable)
2339+ return;
2340+
23382341 if (host->slot.cd_irq >= 0) {
23392342 mmc_gpio_set_cd_wake(host, false);
23402343 disable_irq(host->slot.cd_irq);
drivers/mmc/host/sdhci-pci-core.c+72−0
@@ -21,6 +21,7 @@ · 20 unmodified lines
2121 #include <linux/io.h>
2222 #include <linux/iopoll.h>
2323 #include <linux/gpio.h>
24+#include <linux/gpio/machine.h>
2425 #include <linux/pm_runtime.h>
2526 #include <linux/pm_qos.h>
2627 #include <linux/debugfs.h>
@@ -1236,6 +1237,29 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = { · 1209 unmodified lines
12361237 .priv_size = sizeof(struct intel_host),
12371238 };
12381239
1240+/* DMI quirks for devices with missing or broken CD GPIO info */
1241+static const struct gpiod_lookup_table vexia_edu_atla10_cd_gpios = {
1242+ .dev_id = "0000:00:12.0",
1243+ .table = {
1244+ GPIO_LOOKUP("INT33FC:00", 38, "cd", GPIO_ACTIVE_HIGH),
1245+ { }
1246+ },
1247+};
1248+
1249+static const struct dmi_system_id sdhci_intel_byt_cd_gpio_override[] = {
1250+ {
1251+ /* Vexia Edu Atla 10 tablet 9V version */
1252+ .matches = {
1253+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1254+ DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1255+ /* Above strings are too generic, also match on BIOS date */
1256+ DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
1257+ },
1258+ .driver_data = (void *)&vexia_edu_atla10_cd_gpios,
1259+ },
1260+ { }
1261+};
1262+
12391263 static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
12401264 #ifdef CONFIG_PM_SLEEP
12411265 .resume = byt_resume,
@@ -1254,6 +1278,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sd = { · 12 unmodified lines
12541278 .add_host = byt_add_host,
12551279 .remove_slot = byt_remove_slot,
12561280 .ops = &sdhci_intel_byt_ops,
1281+ .cd_gpio_override = sdhci_intel_byt_cd_gpio_override,
12571282 .priv_size = sizeof(struct intel_host),
12581283 };
12591284
@@ -2055,6 +2080,42 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = { · 795 unmodified lines
20552080 * *
20562081 \*****************************************************************************/
20572082
2083+static struct gpiod_lookup_table *sdhci_pci_add_gpio_lookup_table(
2084+ struct sdhci_pci_chip *chip)
2085+{
2086+ struct gpiod_lookup_table *cd_gpio_lookup_table;
2087+ const struct dmi_system_id *dmi_id = NULL;
2088+ size_t count;
2089+
2090+ if (chip->fixes && chip->fixes->cd_gpio_override)
2091+ dmi_id = dmi_first_match(chip->fixes->cd_gpio_override);
2092+
2093+ if (!dmi_id)
2094+ return NULL;
2095+
2096+ cd_gpio_lookup_table = dmi_id->driver_data;
2097+ for (count = 0; cd_gpio_lookup_table->table[count].key; count++)
2098+ ;
2099+
2100+ cd_gpio_lookup_table = kmemdup(dmi_id->driver_data,
2101+ /* count + 1 terminating entry */
2102+ struct_size(cd_gpio_lookup_table, table, count + 1),
2103+ GFP_KERNEL);
2104+ if (!cd_gpio_lookup_table)
2105+ return ERR_PTR(-ENOMEM);
2106+
2107+ gpiod_add_lookup_table(cd_gpio_lookup_table);
2108+ return cd_gpio_lookup_table;
2109+}
2110+
2111+static void sdhci_pci_remove_gpio_lookup_table(struct gpiod_lookup_table *lookup_table)
2112+{
2113+ if (lookup_table) {
2114+ gpiod_remove_lookup_table(lookup_table);
2115+ kfree(lookup_table);
2116+ }
2117+}
2118+
20582119 static struct sdhci_pci_slot *sdhci_pci_probe_slot(
20592120 struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
20602121 int slotno)
@@ -2130,8 +2191,19 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( · 69 unmodified lines
21302191 device_init_wakeup(&pdev->dev, true);
21312192
21322193 if (slot->cd_idx >= 0) {
2194+ struct gpiod_lookup_table *cd_gpio_lookup_table;
2195+
2196+ cd_gpio_lookup_table = sdhci_pci_add_gpio_lookup_table(chip);
2197+ if (IS_ERR(cd_gpio_lookup_table)) {
2198+ ret = PTR_ERR(cd_gpio_lookup_table);
2199+ goto remove;
2200+ }
2201+
21332202 ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx,
21342203 slot->cd_override_level, 0);
2204+
2205+ sdhci_pci_remove_gpio_lookup_table(cd_gpio_lookup_table);
2206+
21352207 if (ret && ret != -EPROBE_DEFER)
21362208 ret = mmc_gpiod_request_cd(host->mmc, NULL,
21372209 slot->cd_idx,
drivers/mmc/host/sdhci-pci.h+1−0
@@ -157,6 +157,7 @@ struct sdhci_pci_fixes { · 156 unmodified lines
157157 #endif
158158
159159 const struct sdhci_ops *ops;
160+ const struct dmi_system_id *cd_gpio_override;
160161 size_t priv_size;
161162 };
162163