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+
12391263static 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+
20582119static 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 ,
0 commit comments