aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2011-12-27 08:48:44 -0500
committerChris Ball <cjb@laptop.org>2012-01-11 23:58:47 -0500
commitc5e027a4a19d6267e36107fc32b5a4f3cd27976a (patch)
tree73f3d6c4e2e7efe957858e857a07ace69f558764 /drivers/mmc
parent52c506f0bc72530fb786838e7ffd4f158a2e5c3a (diff)
mmc: sdhci-pci: get gpio numbers from platform data
Retrieve the GPIO numbers for hardware reset and card detect from platform data. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/sdhci-pci.c109
1 files changed, 41 insertions, 68 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 4e8f324e2c84..646680a5993a 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -23,7 +23,6 @@
23#include <linux/scatterlist.h> 23#include <linux/scatterlist.h>
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/gpio.h> 25#include <linux/gpio.h>
26#include <linux/sfi.h>
27#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
28#include <linux/mmc/sdhci-pci-data.h> 27#include <linux/mmc/sdhci-pci-data.h>
29 28
@@ -173,32 +172,9 @@ static int mrst_hc_probe(struct sdhci_pci_chip *chip)
173 return 0; 172 return 0;
174} 173}
175 174
176/* Medfield eMMC hardware reset GPIOs */
177static int mfd_emmc0_rst_gpio = -EINVAL;
178static int mfd_emmc1_rst_gpio = -EINVAL;
179
180static int mfd_emmc_gpio_parse(struct sfi_table_header *table)
181{
182 struct sfi_table_simple *sb = (struct sfi_table_simple *)table;
183 struct sfi_gpio_table_entry *entry;
184 int i, num;
185
186 num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
187 entry = (struct sfi_gpio_table_entry *)sb->pentry;
188
189 for (i = 0; i < num; i++, entry++) {
190 if (!strncmp(entry->pin_name, "emmc0_rst", SFI_NAME_LEN))
191 mfd_emmc0_rst_gpio = entry->pin_no;
192 else if (!strncmp(entry->pin_name, "emmc1_rst", SFI_NAME_LEN))
193 mfd_emmc1_rst_gpio = entry->pin_no;
194 }
195
196 return 0;
197}
198
199#ifdef CONFIG_PM_RUNTIME 175#ifdef CONFIG_PM_RUNTIME
200 176
201static irqreturn_t mfd_sd_cd(int irq, void *dev_id) 177static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id)
202{ 178{
203 struct sdhci_pci_slot *slot = dev_id; 179 struct sdhci_pci_slot *slot = dev_id;
204 struct sdhci_host *host = slot->host; 180 struct sdhci_host *host = slot->host;
@@ -207,15 +183,16 @@ static irqreturn_t mfd_sd_cd(int irq, void *dev_id)
207 return IRQ_HANDLED; 183 return IRQ_HANDLED;
208} 184}
209 185
210#define MFLD_SD_CD_PIN 69 186static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
211
212static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
213{ 187{
214 int err, irq, gpio = MFLD_SD_CD_PIN; 188 int err, irq, gpio = slot->cd_gpio;
215 189
216 slot->cd_gpio = -EINVAL; 190 slot->cd_gpio = -EINVAL;
217 slot->cd_irq = -EINVAL; 191 slot->cd_irq = -EINVAL;
218 192
193 if (!gpio_is_valid(gpio))
194 return;
195
219 err = gpio_request(gpio, "sd_cd"); 196 err = gpio_request(gpio, "sd_cd");
220 if (err < 0) 197 if (err < 0)
221 goto out; 198 goto out;
@@ -228,7 +205,7 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
228 if (irq < 0) 205 if (irq < 0)
229 goto out_free; 206 goto out_free;
230 207
231 err = request_irq(irq, mfd_sd_cd, IRQF_TRIGGER_RISING | 208 err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING |
232 IRQF_TRIGGER_FALLING, "sd_cd", slot); 209 IRQF_TRIGGER_FALLING, "sd_cd", slot);
233 if (err) 210 if (err)
234 goto out_free; 211 goto out_free;
@@ -237,65 +214,41 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
237 slot->cd_irq = irq; 214 slot->cd_irq = irq;
238 slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION; 215 slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION;
239 216
240 return 0; 217 return;
241 218
242out_free: 219out_free:
243 gpio_free(gpio); 220 gpio_free(gpio);
244out: 221out:
245 dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n"); 222 dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
246 return 0;
247} 223}
248 224
249static void mfd_sd_remove_slot(struct sdhci_pci_slot *slot, int dead) 225static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
250{ 226{
251 if (slot->cd_irq >= 0) 227 if (slot->cd_irq >= 0)
252 free_irq(slot->cd_irq, slot); 228 free_irq(slot->cd_irq, slot);
253 gpio_free(slot->cd_gpio); 229 if (gpio_is_valid(slot->cd_gpio))
230 gpio_free(slot->cd_gpio);
254} 231}
255 232
256#else 233#else
257 234
258#define mfd_sd_probe_slot NULL 235static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
259#define mfd_sd_remove_slot NULL 236{
237}
238
239static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
240{
241}
260 242
261#endif 243#endif
262 244
263static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) 245static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
264{ 246{
265 const char *name = NULL;
266 int gpio = -EINVAL;
267
268 sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, mfd_emmc_gpio_parse);
269
270 switch (slot->chip->pdev->device) {
271 case PCI_DEVICE_ID_INTEL_MFD_EMMC0:
272 gpio = mfd_emmc0_rst_gpio;
273 name = "eMMC0_reset";
274 break;
275 case PCI_DEVICE_ID_INTEL_MFD_EMMC1:
276 gpio = mfd_emmc1_rst_gpio;
277 name = "eMMC1_reset";
278 break;
279 }
280
281 if (!gpio_request(gpio, name)) {
282 gpio_direction_output(gpio, 1);
283 slot->rst_n_gpio = gpio;
284 slot->host->mmc->caps |= MMC_CAP_HW_RESET;
285 }
286
287 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; 247 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
288
289 slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC; 248 slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC;
290
291 return 0; 249 return 0;
292} 250}
293 251
294static void mfd_emmc_remove_slot(struct sdhci_pci_slot *slot, int dead)
295{
296 gpio_free(slot->rst_n_gpio);
297}
298
299static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { 252static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
300 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT, 253 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
301 .probe_slot = mrst_hc_probe_slot, 254 .probe_slot = mrst_hc_probe_slot,
@@ -309,8 +262,6 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
309static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { 262static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
310 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 263 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
311 .allow_runtime_pm = true, 264 .allow_runtime_pm = true,
312 .probe_slot = mfd_sd_probe_slot,
313 .remove_slot = mfd_sd_remove_slot,
314}; 265};
315 266
316static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = { 267static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
@@ -322,7 +273,6 @@ static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
322 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, 273 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
323 .allow_runtime_pm = true, 274 .allow_runtime_pm = true,
324 .probe_slot = mfd_emmc_probe_slot, 275 .probe_slot = mfd_emmc_probe_slot,
325 .remove_slot = mfd_emmc_remove_slot,
326}; 276};
327 277
328/* O2Micro extra registers */ 278/* O2Micro extra registers */
@@ -1229,6 +1179,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
1229 slot->host = host; 1179 slot->host = host;
1230 slot->pci_bar = bar; 1180 slot->pci_bar = bar;
1231 slot->rst_n_gpio = -EINVAL; 1181 slot->rst_n_gpio = -EINVAL;
1182 slot->cd_gpio = -EINVAL;
1232 1183
1233 /* Retrieve platform data if there is any */ 1184 /* Retrieve platform data if there is any */
1234 if (*sdhci_pci_get_data) 1185 if (*sdhci_pci_get_data)
@@ -1242,6 +1193,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
1242 goto free; 1193 goto free;
1243 } 1194 }
1244 } 1195 }
1196 slot->rst_n_gpio = slot->data->rst_n_gpio;
1197 slot->cd_gpio = slot->data->cd_gpio;
1245 } 1198 }
1246 1199
1247 host->hw_name = "PCI"; 1200 host->hw_name = "PCI";
@@ -1269,15 +1222,30 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
1269 goto unmap; 1222 goto unmap;
1270 } 1223 }
1271 1224
1225 if (gpio_is_valid(slot->rst_n_gpio)) {
1226 if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
1227 gpio_direction_output(slot->rst_n_gpio, 1);
1228 slot->host->mmc->caps |= MMC_CAP_HW_RESET;
1229 } else {
1230 dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
1231 slot->rst_n_gpio = -EINVAL;
1232 }
1233 }
1234
1272 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; 1235 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
1273 1236
1274 ret = sdhci_add_host(host); 1237 ret = sdhci_add_host(host);
1275 if (ret) 1238 if (ret)
1276 goto remove; 1239 goto remove;
1277 1240
1241 sdhci_pci_add_own_cd(slot);
1242
1278 return slot; 1243 return slot;
1279 1244
1280remove: 1245remove:
1246 if (gpio_is_valid(slot->rst_n_gpio))
1247 gpio_free(slot->rst_n_gpio);
1248
1281 if (chip->fixes && chip->fixes->remove_slot) 1249 if (chip->fixes && chip->fixes->remove_slot)
1282 chip->fixes->remove_slot(slot, 0); 1250 chip->fixes->remove_slot(slot, 0);
1283 1251
@@ -1302,6 +1270,8 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
1302 int dead; 1270 int dead;
1303 u32 scratch; 1271 u32 scratch;
1304 1272
1273 sdhci_pci_remove_own_cd(slot);
1274
1305 dead = 0; 1275 dead = 0;
1306 scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); 1276 scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
1307 if (scratch == (u32)-1) 1277 if (scratch == (u32)-1)
@@ -1309,6 +1279,9 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
1309 1279
1310 sdhci_remove_host(slot->host, dead); 1280 sdhci_remove_host(slot->host, dead);
1311 1281
1282 if (gpio_is_valid(slot->rst_n_gpio))
1283 gpio_free(slot->rst_n_gpio);
1284
1312 if (slot->chip->fixes && slot->chip->fixes->remove_slot) 1285 if (slot->chip->fixes && slot->chip->fixes->remove_slot)
1313 slot->chip->fixes->remove_slot(slot, dead); 1286 slot->chip->fixes->remove_slot(slot, dead);
1314 1287