21
21
#include <linux/io.h>
22
22
#include <linux/iopoll.h>
23
23
#include <linux/gpio.h>
24
+ #include <linux/gpio/machine.h>
24
25
#include <linux/pm_runtime.h>
25
26
#include <linux/pm_qos.h>
26
27
#include <linux/debugfs.h>
@@ -1236,6 +1237,29 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
1236
1237
.priv_size = sizeof (struct intel_host ),
1237
1238
};
1238
1239
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
+
1239
1263
static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
1240
1264
#ifdef CONFIG_PM_SLEEP
1241
1265
.resume = byt_resume ,
@@ -1254,6 +1278,7 @@ static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
1254
1278
.add_host = byt_add_host ,
1255
1279
.remove_slot = byt_remove_slot ,
1256
1280
.ops = & sdhci_intel_byt_ops ,
1281
+ .cd_gpio_override = sdhci_intel_byt_cd_gpio_override ,
1257
1282
.priv_size = sizeof (struct intel_host ),
1258
1283
};
1259
1284
@@ -2055,6 +2080,42 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = {
2055
2080
* *
2056
2081
\*****************************************************************************/
2057
2082
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
+
2058
2119
static struct sdhci_pci_slot * sdhci_pci_probe_slot (
2059
2120
struct pci_dev * pdev , struct sdhci_pci_chip * chip , int first_bar ,
2060
2121
int slotno )
@@ -2130,8 +2191,19 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
2130
2191
device_init_wakeup (& pdev -> dev , true);
2131
2192
2132
2193
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
+
2133
2202
ret = mmc_gpiod_request_cd (host -> mmc , "cd" , slot -> cd_idx ,
2134
2203
slot -> cd_override_level , 0 );
2204
+
2205
+ sdhci_pci_remove_gpio_lookup_table (cd_gpio_lookup_table );
2206
+
2135
2207
if (ret && ret != - EPROBE_DEFER )
2136
2208
ret = mmc_gpiod_request_cd (host -> mmc , NULL ,
2137
2209
slot -> cd_idx ,
0 commit comments