Skip to content

Commit 35b7b33

Browse files
committed
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
2 parents fa4c221 + 87a0d90 commit 35b7b33

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

drivers/mmc/core/bus.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ static void mmc_bus_shutdown(struct device *dev)
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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,9 @@ void mmc_start_host(struct mmc_host *host)
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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
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 = {
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 = {
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 = {
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(
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ struct sdhci_pci_fixes {
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

0 commit comments

Comments
 (0)