Skip to content

Commit 6e8ee86

Browse files
jwrdegoedemehmetb0
authored andcommitted
mmc: sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10 tablet
BugLink: https://bugs.launchpad.net/bugs/2095283 commit 7f0fa47 upstream. The Vexia Edu Atla 10 tablet distributed to schools in the Spanish Andalucía region has no ACPI fwnode associated with the SDHCI controller for its microsd-slot and thus has no ACPI GPIO resource info. This causes the following error to be logged and the slot to not work: [ 10.572113] sdhci-pci 0000:00:12.0: failed to setup card detect gpio Add a DMI quirk table for providing gpiod_lookup_tables with manually provided CD GPIO info and use this DMI table to provide the CD GPIO info on this tablet. This fixes the microsd-slot not working. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Cc: stable@vger.kernel.org Message-ID: <20241118210049.311079-1-hdegoede@redhat.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
1 parent d770e0f commit 6e8ee86

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

drivers/mmc/host/sdhci-pci-core.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/io.h>
2424
#include <linux/iopoll.h>
2525
#include <linux/gpio.h>
26+
#include <linux/gpio/machine.h>
2627
#include <linux/pm_runtime.h>
2728
#include <linux/pm_qos.h>
2829
#include <linux/debugfs.h>
@@ -1303,6 +1304,29 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
13031304
.priv_size = sizeof(struct intel_host),
13041305
};
13051306

1307+
/* DMI quirks for devices with missing or broken CD GPIO info */
1308+
static const struct gpiod_lookup_table vexia_edu_atla10_cd_gpios = {
1309+
.dev_id = "0000:00:12.0",
1310+
.table = {
1311+
GPIO_LOOKUP("INT33FC:00", 38, "cd", GPIO_ACTIVE_HIGH),
1312+
{ }
1313+
},
1314+
};
1315+
1316+
static const struct dmi_system_id sdhci_intel_byt_cd_gpio_override[] = {
1317+
{
1318+
/* Vexia Edu Atla 10 tablet 9V version */
1319+
.matches = {
1320+
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1321+
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1322+
/* Above strings are too generic, also match on BIOS date */
1323+
DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
1324+
},
1325+
.driver_data = (void *)&vexia_edu_atla10_cd_gpios,
1326+
},
1327+
{ }
1328+
};
1329+
13061330
static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
13071331
#ifdef CONFIG_PM_SLEEP
13081332
.resume = byt_resume,
@@ -1321,6 +1345,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
13211345
.add_host = byt_add_host,
13221346
.remove_slot = byt_remove_slot,
13231347
.ops = &sdhci_intel_byt_ops,
1348+
.cd_gpio_override = sdhci_intel_byt_cd_gpio_override,
13241349
.priv_size = sizeof(struct intel_host),
13251350
};
13261351

@@ -2120,6 +2145,42 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = {
21202145
* *
21212146
\*****************************************************************************/
21222147

2148+
static struct gpiod_lookup_table *sdhci_pci_add_gpio_lookup_table(
2149+
struct sdhci_pci_chip *chip)
2150+
{
2151+
struct gpiod_lookup_table *cd_gpio_lookup_table;
2152+
const struct dmi_system_id *dmi_id = NULL;
2153+
size_t count;
2154+
2155+
if (chip->fixes && chip->fixes->cd_gpio_override)
2156+
dmi_id = dmi_first_match(chip->fixes->cd_gpio_override);
2157+
2158+
if (!dmi_id)
2159+
return NULL;
2160+
2161+
cd_gpio_lookup_table = dmi_id->driver_data;
2162+
for (count = 0; cd_gpio_lookup_table->table[count].key; count++)
2163+
;
2164+
2165+
cd_gpio_lookup_table = kmemdup(dmi_id->driver_data,
2166+
/* count + 1 terminating entry */
2167+
struct_size(cd_gpio_lookup_table, table, count + 1),
2168+
GFP_KERNEL);
2169+
if (!cd_gpio_lookup_table)
2170+
return ERR_PTR(-ENOMEM);
2171+
2172+
gpiod_add_lookup_table(cd_gpio_lookup_table);
2173+
return cd_gpio_lookup_table;
2174+
}
2175+
2176+
static void sdhci_pci_remove_gpio_lookup_table(struct gpiod_lookup_table *lookup_table)
2177+
{
2178+
if (lookup_table) {
2179+
gpiod_remove_lookup_table(lookup_table);
2180+
kfree(lookup_table);
2181+
}
2182+
}
2183+
21232184
static struct sdhci_pci_slot *sdhci_pci_probe_slot(
21242185
struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
21252186
int slotno)
@@ -2224,8 +2285,19 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
22242285
device_init_wakeup(&pdev->dev, true);
22252286

22262287
if (slot->cd_idx >= 0) {
2288+
struct gpiod_lookup_table *cd_gpio_lookup_table;
2289+
2290+
cd_gpio_lookup_table = sdhci_pci_add_gpio_lookup_table(chip);
2291+
if (IS_ERR(cd_gpio_lookup_table)) {
2292+
ret = PTR_ERR(cd_gpio_lookup_table);
2293+
goto remove;
2294+
}
2295+
22272296
ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx,
22282297
slot->cd_override_level, 0);
2298+
2299+
sdhci_pci_remove_gpio_lookup_table(cd_gpio_lookup_table);
2300+
22292301
if (ret && ret != -EPROBE_DEFER)
22302302
ret = mmc_gpiod_request_cd(host->mmc, NULL,
22312303
slot->cd_idx,

drivers/mmc/host/sdhci-pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ struct sdhci_pci_fixes {
151151
#endif
152152

153153
const struct sdhci_ops *ops;
154+
const struct dmi_system_id *cd_gpio_override;
154155
size_t priv_size;
155156
};
156157

0 commit comments

Comments
 (0)