blob: af446592d974b160eac32b5f7cad81abec4b15dc [file] [log] [blame]
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001/* linux/drivers/mmc/host/sdhci-pci.c - SDHCI on PCI bus interface
2 *
3 * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * Thanks to the following companies for their support:
11 *
12 * - JMicron (hardware and technical support)
13 */
14
15#include <linux/delay.h>
16#include <linux/highmem.h>
Paul Gortmaker88b47672011-07-03 15:15:51 -040017#include <linux/module.h>
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010018#include <linux/pci.h>
19#include <linux/dma-mapping.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090020#include <linux/slab.h>
Maxim Levitskyccc92c22010-08-10 18:01:42 -070021#include <linux/device.h>
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010022#include <linux/mmc/host.h>
Ameya Palandeb177bc92011-04-05 21:13:13 +030023#include <linux/scatterlist.h>
24#include <linux/io.h>
Adrian Hunter0f201652011-08-29 16:42:13 +030025#include <linux/gpio.h>
Adrian Hunter66fd8ad2011-10-03 15:33:34 +030026#include <linux/pm_runtime.h>
Adrian Hunter52c506f2011-12-27 15:48:43 +020027#include <linux/mmc/sdhci-pci-data.h>
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010028
29#include "sdhci.h"
Adam Lee522624f2013-12-18 22:23:38 +080030#include "sdhci-pci.h"
Pierre Ossman22606402008-03-23 19:33:23 +010031
32/*****************************************************************************\
33 * *
34 * Hardware specific quirk handling *
35 * *
36\*****************************************************************************/
37
38static int ricoh_probe(struct sdhci_pci_chip *chip)
39{
Chris Ballc99436f2009-09-22 16:45:22 -070040 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
41 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
Pierre Ossman22606402008-03-23 19:33:23 +010042 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
Maxim Levitskyccc92c22010-08-10 18:01:42 -070043 return 0;
44}
Pierre Ossman22606402008-03-23 19:33:23 +010045
Maxim Levitskyccc92c22010-08-10 18:01:42 -070046static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
47{
48 slot->host->caps =
49 ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT)
50 & SDHCI_TIMEOUT_CLK_MASK) |
51
52 ((0x21 << SDHCI_CLOCK_BASE_SHIFT)
53 & SDHCI_CLOCK_BASE_MASK) |
54
55 SDHCI_TIMEOUT_CLK_UNIT |
56 SDHCI_CAN_VDD_330 |
Madhvapathi Sriram1a1f1f02012-10-15 04:47:30 +000057 SDHCI_CAN_DO_HISPD |
Maxim Levitskyccc92c22010-08-10 18:01:42 -070058 SDHCI_CAN_DO_SDMA;
59 return 0;
60}
61
62static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
63{
64 /* Apply a delay to allow controller to settle */
65 /* Otherwise it becomes confused if card state changed
66 during suspend */
67 msleep(500);
Pierre Ossman22606402008-03-23 19:33:23 +010068 return 0;
69}
70
71static const struct sdhci_pci_fixes sdhci_ricoh = {
72 .probe = ricoh_probe,
Vasily Khoruzhick84938292010-03-05 13:43:46 -080073 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
74 SDHCI_QUIRK_FORCE_DMA |
75 SDHCI_QUIRK_CLOCK_BEFORE_RESET,
Pierre Ossman22606402008-03-23 19:33:23 +010076};
77
Maxim Levitskyccc92c22010-08-10 18:01:42 -070078static const struct sdhci_pci_fixes sdhci_ricoh_mmc = {
79 .probe_slot = ricoh_mmc_probe_slot,
80 .resume = ricoh_mmc_resume,
81 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
82 SDHCI_QUIRK_CLOCK_BEFORE_RESET |
83 SDHCI_QUIRK_NO_CARD_NO_RESET |
84 SDHCI_QUIRK_MISSING_CAPS
85};
86
Pierre Ossman22606402008-03-23 19:33:23 +010087static const struct sdhci_pci_fixes sdhci_ene_712 = {
88 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
89 SDHCI_QUIRK_BROKEN_DMA,
90};
91
92static const struct sdhci_pci_fixes sdhci_ene_714 = {
93 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
94 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS |
95 SDHCI_QUIRK_BROKEN_DMA,
96};
97
98static const struct sdhci_pci_fixes sdhci_cafe = {
99 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
Andres Salomona0874892009-03-02 21:48:20 +0100100 SDHCI_QUIRK_NO_BUSY_IRQ |
Daniel Drake55fc05b2012-07-03 23:13:39 +0100101 SDHCI_QUIRK_BROKEN_CARD_DETECTION |
Pierre Ossmanee53ab52008-07-05 00:25:15 +0200102 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
Pierre Ossman22606402008-03-23 19:33:23 +0100103};
104
Major Lee68077b02011-06-29 14:23:46 +0300105static int mrst_hc_probe_slot(struct sdhci_pci_slot *slot)
106{
107 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA;
108 return 0;
109}
110
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100111/*
112 * ADMA operation is disabled for Moorestown platform due to
113 * hardware bugs.
114 */
Jacob Pan35ac6f02010-11-09 13:57:29 +0000115static int mrst_hc_probe(struct sdhci_pci_chip *chip)
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100116{
117 /*
Jacob Pan35ac6f02010-11-09 13:57:29 +0000118 * slots number is fixed here for MRST as SDIO3/5 are never used and
119 * have hardware bugs.
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100120 */
121 chip->num_slots = 1;
122 return 0;
123}
124
Alexander Stein296e0b02012-03-14 08:38:58 +0100125static int pch_hc_probe_slot(struct sdhci_pci_slot *slot)
126{
127 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA;
128 return 0;
129}
130
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300131#ifdef CONFIG_PM_RUNTIME
132
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200133static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300134{
135 struct sdhci_pci_slot *slot = dev_id;
136 struct sdhci_host *host = slot->host;
137
138 mmc_detect_change(host->mmc, msecs_to_jiffies(200));
139 return IRQ_HANDLED;
140}
141
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200142static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300143{
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200144 int err, irq, gpio = slot->cd_gpio;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300145
146 slot->cd_gpio = -EINVAL;
147 slot->cd_irq = -EINVAL;
148
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200149 if (!gpio_is_valid(gpio))
150 return;
151
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300152 err = gpio_request(gpio, "sd_cd");
153 if (err < 0)
154 goto out;
155
156 err = gpio_direction_input(gpio);
157 if (err < 0)
158 goto out_free;
159
160 irq = gpio_to_irq(gpio);
161 if (irq < 0)
162 goto out_free;
163
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200164 err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING |
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300165 IRQF_TRIGGER_FALLING, "sd_cd", slot);
166 if (err)
167 goto out_free;
168
169 slot->cd_gpio = gpio;
170 slot->cd_irq = irq;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300171
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200172 return;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300173
174out_free:
175 gpio_free(gpio);
176out:
177 dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300178}
179
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200180static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300181{
182 if (slot->cd_irq >= 0)
183 free_irq(slot->cd_irq, slot);
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200184 if (gpio_is_valid(slot->cd_gpio))
185 gpio_free(slot->cd_gpio);
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300186}
187
188#else
189
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200190static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
191{
192}
193
194static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
195{
196}
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300197
198#endif
199
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300200static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
201{
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300202 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
Adrian Hunterda721cf2012-02-07 14:48:53 +0200203 slot->host->mmc->caps2 |= MMC_CAP2_BOOTPART_NOACC |
204 MMC_CAP2_HC_ERASE_SZ;
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300205 return 0;
206}
207
Adrian Hunter93933502011-12-27 15:48:47 +0200208static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
209{
Adrian Hunter012e4672012-01-30 14:27:18 +0200210 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
Adrian Hunter93933502011-12-27 15:48:47 +0200211 return 0;
212}
213
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100214static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
215 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
Major Lee68077b02011-06-29 14:23:46 +0300216 .probe_slot = mrst_hc_probe_slot,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100217};
218
Jacob Pan35ac6f02010-11-09 13:57:29 +0000219static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100220 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
Jacob Pan35ac6f02010-11-09 13:57:29 +0000221 .probe = mrst_hc_probe,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100222};
223
Xiaochen Shen29229052010-10-04 15:24:52 +0100224static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
225 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300226 .allow_runtime_pm = true,
Xiaochen Shen29229052010-10-04 15:24:52 +0100227};
228
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300229static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
Xiaochen Shen29229052010-10-04 15:24:52 +0100230 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterf3c55a72012-02-07 14:48:55 +0200231 .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300232 .allow_runtime_pm = true,
Adrian Hunter93933502011-12-27 15:48:47 +0200233 .probe_slot = mfd_sdio_probe_slot,
Xiaochen Shen29229052010-10-04 15:24:52 +0100234};
235
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300236static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
237 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300238 .allow_runtime_pm = true,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300239 .probe_slot = mfd_emmc_probe_slot,
240};
241
Alexander Stein296e0b02012-03-14 08:38:58 +0100242static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = {
243 .quirks = SDHCI_QUIRK_BROKEN_ADMA,
244 .probe_slot = pch_hc_probe_slot,
245};
246
Adrian Hunterc9faff62013-06-13 11:50:26 +0300247static void sdhci_pci_int_hw_reset(struct sdhci_host *host)
248{
249 u8 reg;
250
251 reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
252 reg |= 0x10;
253 sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
254 /* For eMMC, minimum is 1us but give it 9us for good measure */
255 udelay(9);
256 reg &= ~0x10;
257 sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
258 /* For eMMC, minimum is 200us but give it 300us for good measure */
259 usleep_range(300, 1000);
260}
261
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300262static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
263{
Adrian Hunterc9faff62013-06-13 11:50:26 +0300264 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
265 MMC_CAP_HW_RESET;
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300266 slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
Adrian Hunterc9faff62013-06-13 11:50:26 +0300267 slot->hw_reset = sdhci_pci_int_hw_reset;
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300268 return 0;
269}
270
271static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
272{
273 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
274 return 0;
275}
276
277static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
278 .allow_runtime_pm = true,
279 .probe_slot = byt_emmc_probe_slot,
280};
281
282static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
283 .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
284 .allow_runtime_pm = true,
285 .probe_slot = byt_sdio_probe_slot,
286};
287
288static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
Adrian Hunter7396e312013-05-06 12:17:34 +0300289 .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON,
290 .allow_runtime_pm = true,
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300291};
292
David Cohen8776a162013-10-01 13:18:15 -0700293/* Define Host controllers for Intel Merrifield platform */
294#define INTEL_MRFL_EMMC_0 0
295#define INTEL_MRFL_EMMC_1 1
296
297static int intel_mrfl_mmc_probe_slot(struct sdhci_pci_slot *slot)
298{
299 if ((PCI_FUNC(slot->chip->pdev->devfn) != INTEL_MRFL_EMMC_0) &&
300 (PCI_FUNC(slot->chip->pdev->devfn) != INTEL_MRFL_EMMC_1))
301 /* SD support is not ready yet */
302 return -ENODEV;
303
304 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
305 MMC_CAP_1_8V_DDR;
306
307 return 0;
308}
309
310static const struct sdhci_pci_fixes sdhci_intel_mrfl_mmc = {
311 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
312 .probe_slot = intel_mrfl_mmc_probe_slot,
313};
314
Jennifer Li26daa1e2010-11-17 23:01:59 -0500315/* O2Micro extra registers */
316#define O2_SD_LOCK_WP 0xD3
317#define O2_SD_MULTI_VCC3V 0xEE
318#define O2_SD_CLKREQ 0xEC
319#define O2_SD_CAPS 0xE0
320#define O2_SD_ADMA1 0xE2
321#define O2_SD_ADMA2 0xE7
322#define O2_SD_INF_MOD 0xF1
323
324static int o2_probe(struct sdhci_pci_chip *chip)
325{
326 int ret;
327 u8 scratch;
328
329 switch (chip->pdev->device) {
330 case PCI_DEVICE_ID_O2_8220:
331 case PCI_DEVICE_ID_O2_8221:
332 case PCI_DEVICE_ID_O2_8320:
333 case PCI_DEVICE_ID_O2_8321:
334 /* This extra setup is required due to broken ADMA. */
335 ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
336 if (ret)
337 return ret;
338 scratch &= 0x7f;
339 pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
340
341 /* Set Multi 3 to VCC3V# */
342 pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
343
344 /* Disable CLK_REQ# support after media DET */
345 ret = pci_read_config_byte(chip->pdev, O2_SD_CLKREQ, &scratch);
346 if (ret)
347 return ret;
348 scratch |= 0x20;
349 pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
350
351 /* Choose capabilities, enable SDMA. We have to write 0x01
352 * to the capabilities register first to unlock it.
353 */
354 ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
355 if (ret)
356 return ret;
357 scratch |= 0x01;
358 pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
359 pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
360
361 /* Disable ADMA1/2 */
362 pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
363 pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
364
365 /* Disable the infinite transfer mode */
366 ret = pci_read_config_byte(chip->pdev, O2_SD_INF_MOD, &scratch);
367 if (ret)
368 return ret;
369 scratch |= 0x08;
370 pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
371
372 /* Lock WP */
373 ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
374 if (ret)
375 return ret;
376 scratch |= 0x80;
377 pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
378 }
379
380 return 0;
381}
382
Pierre Ossman45211e22008-03-24 13:09:09 +0100383static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
384{
385 u8 scratch;
386 int ret;
387
388 ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch);
389 if (ret)
390 return ret;
391
392 /*
393 * Turn PMOS on [bit 0], set over current detection to 2.4 V
394 * [bit 1:2] and enable over current debouncing [bit 6].
395 */
396 if (on)
397 scratch |= 0x47;
398 else
399 scratch &= ~0x47;
400
401 ret = pci_write_config_byte(chip->pdev, 0xAE, scratch);
402 if (ret)
403 return ret;
404
405 return 0;
406}
407
408static int jmicron_probe(struct sdhci_pci_chip *chip)
409{
410 int ret;
Takashi Iwai8f230f42010-12-08 10:04:30 +0100411 u16 mmcdev = 0;
Pierre Ossman45211e22008-03-24 13:09:09 +0100412
Pierre Ossman93fc48c2008-06-28 18:21:41 +0200413 if (chip->pdev->revision == 0) {
414 chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR |
415 SDHCI_QUIRK_32BIT_DMA_SIZE |
Pierre Ossman2134a922008-06-28 18:28:51 +0200416 SDHCI_QUIRK_32BIT_ADMA_SIZE |
Pierre Ossman4a3cba32008-07-29 00:11:16 +0200417 SDHCI_QUIRK_RESET_AFTER_REQUEST |
Pierre Ossman86a6a872009-02-02 21:13:49 +0100418 SDHCI_QUIRK_BROKEN_SMALL_PIO;
Pierre Ossman93fc48c2008-06-28 18:21:41 +0200419 }
420
Pierre Ossman45211e22008-03-24 13:09:09 +0100421 /*
Pierre Ossman44894282008-04-04 19:36:59 +0200422 * JMicron chips can have two interfaces to the same hardware
423 * in order to work around limitations in Microsoft's driver.
424 * We need to make sure we only bind to one of them.
425 *
426 * This code assumes two things:
427 *
428 * 1. The PCI code adds subfunctions in order.
429 *
430 * 2. The MMC interface has a lower subfunction number
431 * than the SD interface.
432 */
Takashi Iwai8f230f42010-12-08 10:04:30 +0100433 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD)
434 mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC;
435 else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD)
436 mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD;
437
438 if (mmcdev) {
Pierre Ossman44894282008-04-04 19:36:59 +0200439 struct pci_dev *sd_dev;
440
441 sd_dev = NULL;
442 while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON,
Takashi Iwai8f230f42010-12-08 10:04:30 +0100443 mmcdev, sd_dev)) != NULL) {
Pierre Ossman44894282008-04-04 19:36:59 +0200444 if ((PCI_SLOT(chip->pdev->devfn) ==
445 PCI_SLOT(sd_dev->devfn)) &&
446 (chip->pdev->bus == sd_dev->bus))
447 break;
448 }
449
450 if (sd_dev) {
451 pci_dev_put(sd_dev);
452 dev_info(&chip->pdev->dev, "Refusing to bind to "
453 "secondary interface.\n");
454 return -ENODEV;
455 }
456 }
457
458 /*
Pierre Ossman45211e22008-03-24 13:09:09 +0100459 * JMicron chips need a bit of a nudge to enable the power
460 * output pins.
461 */
462 ret = jmicron_pmos(chip, 1);
463 if (ret) {
464 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
465 return ret;
466 }
467
Takashi Iwai82b0e232011-04-21 20:26:38 +0200468 /* quirk for unsable RO-detection on JM388 chips */
469 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
470 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
471 chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT;
472
Pierre Ossman45211e22008-03-24 13:09:09 +0100473 return 0;
474}
475
Pierre Ossman44894282008-04-04 19:36:59 +0200476static void jmicron_enable_mmc(struct sdhci_host *host, int on)
477{
478 u8 scratch;
479
480 scratch = readb(host->ioaddr + 0xC0);
481
482 if (on)
483 scratch |= 0x01;
484 else
485 scratch &= ~0x01;
486
487 writeb(scratch, host->ioaddr + 0xC0);
488}
489
490static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
491{
Pierre Ossman2134a922008-06-28 18:28:51 +0200492 if (slot->chip->pdev->revision == 0) {
493 u16 version;
494
495 version = readl(slot->host->ioaddr + SDHCI_HOST_VERSION);
496 version = (version & SDHCI_VENDOR_VER_MASK) >>
497 SDHCI_VENDOR_VER_SHIFT;
498
499 /*
500 * Older versions of the chip have lots of nasty glitches
501 * in the ADMA engine. It's best just to avoid it
502 * completely.
503 */
504 if (version < 0xAC)
505 slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
506 }
507
Takashi Iwai8f230f42010-12-08 10:04:30 +0100508 /* JM388 MMC doesn't support 1.8V while SD supports it */
509 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
510 slot->host->ocr_avail_sd = MMC_VDD_32_33 | MMC_VDD_33_34 |
511 MMC_VDD_29_30 | MMC_VDD_30_31 |
512 MMC_VDD_165_195; /* allow 1.8V */
513 slot->host->ocr_avail_mmc = MMC_VDD_32_33 | MMC_VDD_33_34 |
514 MMC_VDD_29_30 | MMC_VDD_30_31; /* no 1.8V for MMC */
515 }
516
Pierre Ossman44894282008-04-04 19:36:59 +0200517 /*
518 * The secondary interface requires a bit set to get the
519 * interrupts.
520 */
Takashi Iwai8f230f42010-12-08 10:04:30 +0100521 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
522 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
Pierre Ossman44894282008-04-04 19:36:59 +0200523 jmicron_enable_mmc(slot->host, 1);
524
Takashi Iwaid75c1082010-12-16 17:54:14 +0100525 slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST;
526
Pierre Ossman44894282008-04-04 19:36:59 +0200527 return 0;
528}
529
Pierre Ossman1e728592008-04-16 19:13:13 +0200530static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead)
Pierre Ossman44894282008-04-04 19:36:59 +0200531{
Pierre Ossman1e728592008-04-16 19:13:13 +0200532 if (dead)
533 return;
534
Takashi Iwai8f230f42010-12-08 10:04:30 +0100535 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
536 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
Pierre Ossman44894282008-04-04 19:36:59 +0200537 jmicron_enable_mmc(slot->host, 0);
538}
539
Manuel Lauss29495aa2011-11-03 11:09:45 +0100540static int jmicron_suspend(struct sdhci_pci_chip *chip)
Pierre Ossman44894282008-04-04 19:36:59 +0200541{
542 int i;
543
Takashi Iwai8f230f42010-12-08 10:04:30 +0100544 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
545 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
Ameya Palandeb177bc92011-04-05 21:13:13 +0300546 for (i = 0; i < chip->num_slots; i++)
Pierre Ossman44894282008-04-04 19:36:59 +0200547 jmicron_enable_mmc(chip->slots[i]->host, 0);
548 }
549
550 return 0;
551}
552
Pierre Ossman45211e22008-03-24 13:09:09 +0100553static int jmicron_resume(struct sdhci_pci_chip *chip)
554{
Pierre Ossman44894282008-04-04 19:36:59 +0200555 int ret, i;
556
Takashi Iwai8f230f42010-12-08 10:04:30 +0100557 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
558 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
Ameya Palandeb177bc92011-04-05 21:13:13 +0300559 for (i = 0; i < chip->num_slots; i++)
Pierre Ossman44894282008-04-04 19:36:59 +0200560 jmicron_enable_mmc(chip->slots[i]->host, 1);
561 }
Pierre Ossman45211e22008-03-24 13:09:09 +0100562
563 ret = jmicron_pmos(chip, 1);
564 if (ret) {
565 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
566 return ret;
567 }
568
569 return 0;
570}
571
Jennifer Li26daa1e2010-11-17 23:01:59 -0500572static const struct sdhci_pci_fixes sdhci_o2 = {
573 .probe = o2_probe,
574};
575
Pierre Ossman22606402008-03-23 19:33:23 +0100576static const struct sdhci_pci_fixes sdhci_jmicron = {
Pierre Ossman45211e22008-03-24 13:09:09 +0100577 .probe = jmicron_probe,
578
Pierre Ossman44894282008-04-04 19:36:59 +0200579 .probe_slot = jmicron_probe_slot,
580 .remove_slot = jmicron_remove_slot,
581
582 .suspend = jmicron_suspend,
Pierre Ossman45211e22008-03-24 13:09:09 +0100583 .resume = jmicron_resume,
Pierre Ossman22606402008-03-23 19:33:23 +0100584};
585
Nicolas Pitrea7a61862009-12-14 18:01:26 -0800586/* SysKonnect CardBus2SDIO extra registers */
587#define SYSKT_CTRL 0x200
588#define SYSKT_RDFIFO_STAT 0x204
589#define SYSKT_WRFIFO_STAT 0x208
590#define SYSKT_POWER_DATA 0x20c
591#define SYSKT_POWER_330 0xef
592#define SYSKT_POWER_300 0xf8
593#define SYSKT_POWER_184 0xcc
594#define SYSKT_POWER_CMD 0x20d
595#define SYSKT_POWER_START (1 << 7)
596#define SYSKT_POWER_STATUS 0x20e
597#define SYSKT_POWER_STATUS_OK (1 << 0)
598#define SYSKT_BOARD_REV 0x210
599#define SYSKT_CHIP_REV 0x211
600#define SYSKT_CONF_DATA 0x212
601#define SYSKT_CONF_DATA_1V8 (1 << 2)
602#define SYSKT_CONF_DATA_2V5 (1 << 1)
603#define SYSKT_CONF_DATA_3V3 (1 << 0)
604
605static int syskt_probe(struct sdhci_pci_chip *chip)
606{
607 if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
608 chip->pdev->class &= ~0x0000FF;
609 chip->pdev->class |= PCI_SDHCI_IFDMA;
610 }
611 return 0;
612}
613
614static int syskt_probe_slot(struct sdhci_pci_slot *slot)
615{
616 int tm, ps;
617
618 u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV);
619 u8 chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV);
620 dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, "
621 "board rev %d.%d, chip rev %d.%d\n",
622 board_rev >> 4, board_rev & 0xf,
623 chip_rev >> 4, chip_rev & 0xf);
624 if (chip_rev >= 0x20)
625 slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA;
626
627 writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA);
628 writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD);
629 udelay(50);
630 tm = 10; /* Wait max 1 ms */
631 do {
632 ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS);
633 if (ps & SYSKT_POWER_STATUS_OK)
634 break;
635 udelay(100);
636 } while (--tm);
637 if (!tm) {
638 dev_err(&slot->chip->pdev->dev,
639 "power regulator never stabilized");
640 writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD);
641 return -ENODEV;
642 }
643
644 return 0;
645}
646
647static const struct sdhci_pci_fixes sdhci_syskt = {
648 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER,
649 .probe = syskt_probe,
650 .probe_slot = syskt_probe_slot,
651};
652
Harald Welte557b0692009-06-18 16:53:38 +0200653static int via_probe(struct sdhci_pci_chip *chip)
654{
655 if (chip->pdev->revision == 0x10)
656 chip->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER;
657
658 return 0;
659}
660
661static const struct sdhci_pci_fixes sdhci_via = {
662 .probe = via_probe,
663};
664
Bill Pemberton9647f842012-11-19 13:25:11 -0500665static const struct pci_device_id pci_ids[] = {
Pierre Ossman22606402008-03-23 19:33:23 +0100666 {
667 .vendor = PCI_VENDOR_ID_RICOH,
668 .device = PCI_DEVICE_ID_RICOH_R5C822,
669 .subvendor = PCI_ANY_ID,
670 .subdevice = PCI_ANY_ID,
671 .driver_data = (kernel_ulong_t)&sdhci_ricoh,
672 },
673
674 {
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700675 .vendor = PCI_VENDOR_ID_RICOH,
676 .device = 0x843,
677 .subvendor = PCI_ANY_ID,
678 .subdevice = PCI_ANY_ID,
679 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
680 },
681
682 {
Pablo Castillo568133e2010-08-10 18:02:01 -0700683 .vendor = PCI_VENDOR_ID_RICOH,
684 .device = 0xe822,
685 .subvendor = PCI_ANY_ID,
686 .subdevice = PCI_ANY_ID,
687 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
688 },
689
690 {
Manoj Iyer5fd11c02011-02-11 16:25:31 -0600691 .vendor = PCI_VENDOR_ID_RICOH,
692 .device = 0xe823,
693 .subvendor = PCI_ANY_ID,
694 .subdevice = PCI_ANY_ID,
695 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
696 },
697
698 {
Pierre Ossman22606402008-03-23 19:33:23 +0100699 .vendor = PCI_VENDOR_ID_ENE,
700 .device = PCI_DEVICE_ID_ENE_CB712_SD,
701 .subvendor = PCI_ANY_ID,
702 .subdevice = PCI_ANY_ID,
703 .driver_data = (kernel_ulong_t)&sdhci_ene_712,
704 },
705
706 {
707 .vendor = PCI_VENDOR_ID_ENE,
708 .device = PCI_DEVICE_ID_ENE_CB712_SD_2,
709 .subvendor = PCI_ANY_ID,
710 .subdevice = PCI_ANY_ID,
711 .driver_data = (kernel_ulong_t)&sdhci_ene_712,
712 },
713
714 {
715 .vendor = PCI_VENDOR_ID_ENE,
716 .device = PCI_DEVICE_ID_ENE_CB714_SD,
717 .subvendor = PCI_ANY_ID,
718 .subdevice = PCI_ANY_ID,
719 .driver_data = (kernel_ulong_t)&sdhci_ene_714,
720 },
721
722 {
723 .vendor = PCI_VENDOR_ID_ENE,
724 .device = PCI_DEVICE_ID_ENE_CB714_SD_2,
725 .subvendor = PCI_ANY_ID,
726 .subdevice = PCI_ANY_ID,
727 .driver_data = (kernel_ulong_t)&sdhci_ene_714,
728 },
729
730 {
731 .vendor = PCI_VENDOR_ID_MARVELL,
David Woodhouse8c5eb882008-09-03 09:45:57 +0100732 .device = PCI_DEVICE_ID_MARVELL_88ALP01_SD,
Pierre Ossman22606402008-03-23 19:33:23 +0100733 .subvendor = PCI_ANY_ID,
734 .subdevice = PCI_ANY_ID,
735 .driver_data = (kernel_ulong_t)&sdhci_cafe,
736 },
737
738 {
739 .vendor = PCI_VENDOR_ID_JMICRON,
740 .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
741 .subvendor = PCI_ANY_ID,
742 .subdevice = PCI_ANY_ID,
743 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
744 },
745
Pierre Ossman44894282008-04-04 19:36:59 +0200746 {
747 .vendor = PCI_VENDOR_ID_JMICRON,
748 .device = PCI_DEVICE_ID_JMICRON_JMB38X_MMC,
749 .subvendor = PCI_ANY_ID,
750 .subdevice = PCI_ANY_ID,
751 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
752 },
753
Harald Welte557b0692009-06-18 16:53:38 +0200754 {
Takashi Iwai8f230f42010-12-08 10:04:30 +0100755 .vendor = PCI_VENDOR_ID_JMICRON,
756 .device = PCI_DEVICE_ID_JMICRON_JMB388_SD,
757 .subvendor = PCI_ANY_ID,
758 .subdevice = PCI_ANY_ID,
759 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
760 },
761
762 {
763 .vendor = PCI_VENDOR_ID_JMICRON,
764 .device = PCI_DEVICE_ID_JMICRON_JMB388_ESD,
765 .subvendor = PCI_ANY_ID,
766 .subdevice = PCI_ANY_ID,
767 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
768 },
769
770 {
Nicolas Pitrea7a61862009-12-14 18:01:26 -0800771 .vendor = PCI_VENDOR_ID_SYSKONNECT,
772 .device = 0x8000,
773 .subvendor = PCI_ANY_ID,
774 .subdevice = PCI_ANY_ID,
775 .driver_data = (kernel_ulong_t)&sdhci_syskt,
776 },
777
778 {
Harald Welte557b0692009-06-18 16:53:38 +0200779 .vendor = PCI_VENDOR_ID_VIA,
780 .device = 0x95d0,
781 .subvendor = PCI_ANY_ID,
782 .subdevice = PCI_ANY_ID,
783 .driver_data = (kernel_ulong_t)&sdhci_via,
784 },
785
Xiaochen Shen29229052010-10-04 15:24:52 +0100786 {
787 .vendor = PCI_VENDOR_ID_INTEL,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100788 .device = PCI_DEVICE_ID_INTEL_MRST_SD0,
789 .subvendor = PCI_ANY_ID,
790 .subdevice = PCI_ANY_ID,
791 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc0,
792 },
793
794 {
795 .vendor = PCI_VENDOR_ID_INTEL,
796 .device = PCI_DEVICE_ID_INTEL_MRST_SD1,
797 .subvendor = PCI_ANY_ID,
798 .subdevice = PCI_ANY_ID,
Jacob Pan35ac6f02010-11-09 13:57:29 +0000799 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
800 },
801
802 {
803 .vendor = PCI_VENDOR_ID_INTEL,
804 .device = PCI_DEVICE_ID_INTEL_MRST_SD2,
805 .subvendor = PCI_ANY_ID,
806 .subdevice = PCI_ANY_ID,
807 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100808 },
809
810 {
811 .vendor = PCI_VENDOR_ID_INTEL,
Xiaochen Shen29229052010-10-04 15:24:52 +0100812 .device = PCI_DEVICE_ID_INTEL_MFD_SD,
813 .subvendor = PCI_ANY_ID,
814 .subdevice = PCI_ANY_ID,
815 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sd,
816 },
817
818 {
819 .vendor = PCI_VENDOR_ID_INTEL,
820 .device = PCI_DEVICE_ID_INTEL_MFD_SDIO1,
821 .subvendor = PCI_ANY_ID,
822 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300823 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
Xiaochen Shen29229052010-10-04 15:24:52 +0100824 },
825
826 {
827 .vendor = PCI_VENDOR_ID_INTEL,
828 .device = PCI_DEVICE_ID_INTEL_MFD_SDIO2,
829 .subvendor = PCI_ANY_ID,
830 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300831 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
Xiaochen Shen29229052010-10-04 15:24:52 +0100832 },
833
834 {
835 .vendor = PCI_VENDOR_ID_INTEL,
836 .device = PCI_DEVICE_ID_INTEL_MFD_EMMC0,
837 .subvendor = PCI_ANY_ID,
838 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300839 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
Xiaochen Shen29229052010-10-04 15:24:52 +0100840 },
841
842 {
843 .vendor = PCI_VENDOR_ID_INTEL,
844 .device = PCI_DEVICE_ID_INTEL_MFD_EMMC1,
845 .subvendor = PCI_ANY_ID,
846 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300847 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
Xiaochen Shen29229052010-10-04 15:24:52 +0100848 },
849
Jennifer Li26daa1e2010-11-17 23:01:59 -0500850 {
Alexander Stein296e0b02012-03-14 08:38:58 +0100851 .vendor = PCI_VENDOR_ID_INTEL,
852 .device = PCI_DEVICE_ID_INTEL_PCH_SDIO0,
853 .subvendor = PCI_ANY_ID,
854 .subdevice = PCI_ANY_ID,
855 .driver_data = (kernel_ulong_t)&sdhci_intel_pch_sdio,
856 },
857
858 {
859 .vendor = PCI_VENDOR_ID_INTEL,
860 .device = PCI_DEVICE_ID_INTEL_PCH_SDIO1,
861 .subvendor = PCI_ANY_ID,
862 .subdevice = PCI_ANY_ID,
863 .driver_data = (kernel_ulong_t)&sdhci_intel_pch_sdio,
864 },
865
866 {
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300867 .vendor = PCI_VENDOR_ID_INTEL,
868 .device = PCI_DEVICE_ID_INTEL_BYT_EMMC,
869 .subvendor = PCI_ANY_ID,
870 .subdevice = PCI_ANY_ID,
871 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
872 },
873
874 {
875 .vendor = PCI_VENDOR_ID_INTEL,
876 .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
877 .subvendor = PCI_ANY_ID,
878 .subdevice = PCI_ANY_ID,
879 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio,
880 },
881
882 {
883 .vendor = PCI_VENDOR_ID_INTEL,
884 .device = PCI_DEVICE_ID_INTEL_BYT_SD,
885 .subvendor = PCI_ANY_ID,
886 .subdevice = PCI_ANY_ID,
887 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd,
888 },
889
890 {
Adrian Hunter30d025c2013-06-20 12:57:59 +0300891 .vendor = PCI_VENDOR_ID_INTEL,
892 .device = PCI_DEVICE_ID_INTEL_BYT_EMMC2,
893 .subvendor = PCI_ANY_ID,
894 .subdevice = PCI_ANY_ID,
895 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
896 },
897
Eric Ernstd0520682013-10-21 09:54:41 -0700898
899 {
900 .vendor = PCI_VENDOR_ID_INTEL,
901 .device = PCI_DEVICE_ID_INTEL_CLV_SDIO0,
902 .subvendor = PCI_ANY_ID,
903 .subdevice = PCI_ANY_ID,
904 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sd,
905 },
906
907 {
908 .vendor = PCI_VENDOR_ID_INTEL,
909 .device = PCI_DEVICE_ID_INTEL_CLV_SDIO1,
910 .subvendor = PCI_ANY_ID,
911 .subdevice = PCI_ANY_ID,
912 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
913 },
914
915 {
916 .vendor = PCI_VENDOR_ID_INTEL,
917 .device = PCI_DEVICE_ID_INTEL_CLV_SDIO2,
918 .subvendor = PCI_ANY_ID,
919 .subdevice = PCI_ANY_ID,
920 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
921 },
922
923 {
924 .vendor = PCI_VENDOR_ID_INTEL,
925 .device = PCI_DEVICE_ID_INTEL_CLV_EMMC0,
926 .subvendor = PCI_ANY_ID,
927 .subdevice = PCI_ANY_ID,
928 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
929 },
930
931 {
932 .vendor = PCI_VENDOR_ID_INTEL,
933 .device = PCI_DEVICE_ID_INTEL_CLV_EMMC1,
934 .subvendor = PCI_ANY_ID,
935 .subdevice = PCI_ANY_ID,
936 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
937 },
938
Adrian Hunter30d025c2013-06-20 12:57:59 +0300939 {
David Cohen8776a162013-10-01 13:18:15 -0700940 .vendor = PCI_VENDOR_ID_INTEL,
941 .device = PCI_DEVICE_ID_INTEL_MRFL_MMC,
942 .subvendor = PCI_ANY_ID,
943 .subdevice = PCI_ANY_ID,
944 .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
945 },
946 {
Jennifer Li26daa1e2010-11-17 23:01:59 -0500947 .vendor = PCI_VENDOR_ID_O2,
948 .device = PCI_DEVICE_ID_O2_8120,
949 .subvendor = PCI_ANY_ID,
950 .subdevice = PCI_ANY_ID,
951 .driver_data = (kernel_ulong_t)&sdhci_o2,
952 },
953
954 {
955 .vendor = PCI_VENDOR_ID_O2,
956 .device = PCI_DEVICE_ID_O2_8220,
957 .subvendor = PCI_ANY_ID,
958 .subdevice = PCI_ANY_ID,
959 .driver_data = (kernel_ulong_t)&sdhci_o2,
960 },
961
962 {
963 .vendor = PCI_VENDOR_ID_O2,
964 .device = PCI_DEVICE_ID_O2_8221,
965 .subvendor = PCI_ANY_ID,
966 .subdevice = PCI_ANY_ID,
967 .driver_data = (kernel_ulong_t)&sdhci_o2,
968 },
969
970 {
971 .vendor = PCI_VENDOR_ID_O2,
972 .device = PCI_DEVICE_ID_O2_8320,
973 .subvendor = PCI_ANY_ID,
974 .subdevice = PCI_ANY_ID,
975 .driver_data = (kernel_ulong_t)&sdhci_o2,
976 },
977
978 {
979 .vendor = PCI_VENDOR_ID_O2,
980 .device = PCI_DEVICE_ID_O2_8321,
981 .subvendor = PCI_ANY_ID,
982 .subdevice = PCI_ANY_ID,
983 .driver_data = (kernel_ulong_t)&sdhci_o2,
984 },
985
Pierre Ossman22606402008-03-23 19:33:23 +0100986 { /* Generic SD host controller */
987 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
988 },
989
990 { /* end: all zeroes */ },
991};
992
993MODULE_DEVICE_TABLE(pci, pci_ids);
994
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +0100995/*****************************************************************************\
996 * *
997 * SDHCI core callbacks *
998 * *
999\*****************************************************************************/
1000
1001static int sdhci_pci_enable_dma(struct sdhci_host *host)
1002{
1003 struct sdhci_pci_slot *slot;
1004 struct pci_dev *pdev;
1005 int ret;
1006
1007 slot = sdhci_priv(host);
1008 pdev = slot->chip->pdev;
1009
1010 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
1011 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
Richard Röjforsa13abc72009-09-22 16:45:30 -07001012 (host->flags & SDHCI_USE_SDMA)) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001013 dev_warn(&pdev->dev, "Will use DMA mode even though HW "
1014 "doesn't fully claim to support it.\n");
1015 }
1016
Yang Hongyang284901a2009-04-06 19:01:15 -07001017 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001018 if (ret)
1019 return ret;
1020
1021 pci_set_master(pdev);
1022
1023 return 0;
1024}
1025
Sascha Hauer7bc088d2013-01-21 19:02:27 +08001026static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
Major Lee68077b02011-06-29 14:23:46 +03001027{
1028 u8 ctrl;
1029
1030 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
1031
1032 switch (width) {
1033 case MMC_BUS_WIDTH_8:
1034 ctrl |= SDHCI_CTRL_8BITBUS;
1035 ctrl &= ~SDHCI_CTRL_4BITBUS;
1036 break;
1037 case MMC_BUS_WIDTH_4:
1038 ctrl |= SDHCI_CTRL_4BITBUS;
1039 ctrl &= ~SDHCI_CTRL_8BITBUS;
1040 break;
1041 default:
1042 ctrl &= ~(SDHCI_CTRL_8BITBUS | SDHCI_CTRL_4BITBUS);
1043 break;
1044 }
1045
1046 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1047
1048 return 0;
1049}
1050
Adrian Hunterc9faff62013-06-13 11:50:26 +03001051static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
Adrian Hunter0f201652011-08-29 16:42:13 +03001052{
1053 struct sdhci_pci_slot *slot = sdhci_priv(host);
1054 int rst_n_gpio = slot->rst_n_gpio;
1055
1056 if (!gpio_is_valid(rst_n_gpio))
1057 return;
1058 gpio_set_value_cansleep(rst_n_gpio, 0);
1059 /* For eMMC, minimum is 1us but give it 10us for good measure */
1060 udelay(10);
1061 gpio_set_value_cansleep(rst_n_gpio, 1);
1062 /* For eMMC, minimum is 200us but give it 300us for good measure */
1063 usleep_range(300, 1000);
1064}
1065
Adrian Hunterc9faff62013-06-13 11:50:26 +03001066static void sdhci_pci_hw_reset(struct sdhci_host *host)
1067{
1068 struct sdhci_pci_slot *slot = sdhci_priv(host);
1069
1070 if (slot->hw_reset)
1071 slot->hw_reset(host);
1072}
1073
Lars-Peter Clausenc9155682013-03-13 19:26:05 +01001074static const struct sdhci_ops sdhci_pci_ops = {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001075 .enable_dma = sdhci_pci_enable_dma,
Sascha Hauer7bc088d2013-01-21 19:02:27 +08001076 .platform_bus_width = sdhci_pci_bus_width,
Adrian Hunter0f201652011-08-29 16:42:13 +03001077 .hw_reset = sdhci_pci_hw_reset,
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001078};
1079
1080/*****************************************************************************\
1081 * *
1082 * Suspend/resume *
1083 * *
1084\*****************************************************************************/
1085
1086#ifdef CONFIG_PM
1087
Manuel Lauss29495aa2011-11-03 11:09:45 +01001088static int sdhci_pci_suspend(struct device *dev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001089{
Manuel Lauss29495aa2011-11-03 11:09:45 +01001090 struct pci_dev *pdev = to_pci_dev(dev);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001091 struct sdhci_pci_chip *chip;
1092 struct sdhci_pci_slot *slot;
Daniel Drake5f619702010-11-04 22:20:39 +00001093 mmc_pm_flag_t slot_pm_flags;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001094 mmc_pm_flag_t pm_flags = 0;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001095 int i, ret;
1096
1097 chip = pci_get_drvdata(pdev);
1098 if (!chip)
1099 return 0;
1100
Ameya Palandeb177bc92011-04-05 21:13:13 +03001101 for (i = 0; i < chip->num_slots; i++) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001102 slot = chip->slots[i];
1103 if (!slot)
1104 continue;
1105
Manuel Lauss29495aa2011-11-03 11:09:45 +01001106 ret = sdhci_suspend_host(slot->host);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001107
Axel Linb678b912011-12-03 15:28:05 +08001108 if (ret)
1109 goto err_pci_suspend;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001110
Daniel Drake5f619702010-11-04 22:20:39 +00001111 slot_pm_flags = slot->host->mmc->pm_flags;
1112 if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
1113 sdhci_enable_irq_wakeups(slot->host);
1114
1115 pm_flags |= slot_pm_flags;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001116 }
1117
Pierre Ossman44894282008-04-04 19:36:59 +02001118 if (chip->fixes && chip->fixes->suspend) {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001119 ret = chip->fixes->suspend(chip);
Axel Linb678b912011-12-03 15:28:05 +08001120 if (ret)
1121 goto err_pci_suspend;
Pierre Ossman44894282008-04-04 19:36:59 +02001122 }
1123
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001124 pci_save_state(pdev);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001125 if (pm_flags & MMC_PM_KEEP_POWER) {
Daniel Drake5f619702010-11-04 22:20:39 +00001126 if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
1127 pci_pme_active(pdev, true);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001128 pci_enable_wake(pdev, PCI_D3hot, 1);
Daniel Drake5f619702010-11-04 22:20:39 +00001129 }
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001130 pci_set_power_state(pdev, PCI_D3hot);
1131 } else {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001132 pci_enable_wake(pdev, PCI_D3hot, 0);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001133 pci_disable_device(pdev);
Manuel Lauss29495aa2011-11-03 11:09:45 +01001134 pci_set_power_state(pdev, PCI_D3hot);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001135 }
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001136
1137 return 0;
Axel Linb678b912011-12-03 15:28:05 +08001138
1139err_pci_suspend:
1140 while (--i >= 0)
1141 sdhci_resume_host(chip->slots[i]->host);
1142 return ret;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001143}
1144
Manuel Lauss29495aa2011-11-03 11:09:45 +01001145static int sdhci_pci_resume(struct device *dev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001146{
Manuel Lauss29495aa2011-11-03 11:09:45 +01001147 struct pci_dev *pdev = to_pci_dev(dev);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001148 struct sdhci_pci_chip *chip;
1149 struct sdhci_pci_slot *slot;
1150 int i, ret;
1151
1152 chip = pci_get_drvdata(pdev);
1153 if (!chip)
1154 return 0;
1155
1156 pci_set_power_state(pdev, PCI_D0);
1157 pci_restore_state(pdev);
1158 ret = pci_enable_device(pdev);
1159 if (ret)
1160 return ret;
1161
Pierre Ossman45211e22008-03-24 13:09:09 +01001162 if (chip->fixes && chip->fixes->resume) {
1163 ret = chip->fixes->resume(chip);
1164 if (ret)
1165 return ret;
1166 }
1167
Ameya Palandeb177bc92011-04-05 21:13:13 +03001168 for (i = 0; i < chip->num_slots; i++) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001169 slot = chip->slots[i];
1170 if (!slot)
1171 continue;
1172
1173 ret = sdhci_resume_host(slot->host);
1174 if (ret)
1175 return ret;
1176 }
1177
1178 return 0;
1179}
1180
1181#else /* CONFIG_PM */
1182
1183#define sdhci_pci_suspend NULL
1184#define sdhci_pci_resume NULL
1185
1186#endif /* CONFIG_PM */
1187
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001188#ifdef CONFIG_PM_RUNTIME
1189
1190static int sdhci_pci_runtime_suspend(struct device *dev)
1191{
1192 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
1193 struct sdhci_pci_chip *chip;
1194 struct sdhci_pci_slot *slot;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001195 int i, ret;
1196
1197 chip = pci_get_drvdata(pdev);
1198 if (!chip)
1199 return 0;
1200
1201 for (i = 0; i < chip->num_slots; i++) {
1202 slot = chip->slots[i];
1203 if (!slot)
1204 continue;
1205
1206 ret = sdhci_runtime_suspend_host(slot->host);
1207
Axel Linb678b912011-12-03 15:28:05 +08001208 if (ret)
1209 goto err_pci_runtime_suspend;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001210 }
1211
1212 if (chip->fixes && chip->fixes->suspend) {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001213 ret = chip->fixes->suspend(chip);
Axel Linb678b912011-12-03 15:28:05 +08001214 if (ret)
1215 goto err_pci_runtime_suspend;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001216 }
1217
1218 return 0;
Axel Linb678b912011-12-03 15:28:05 +08001219
1220err_pci_runtime_suspend:
1221 while (--i >= 0)
1222 sdhci_runtime_resume_host(chip->slots[i]->host);
1223 return ret;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001224}
1225
1226static int sdhci_pci_runtime_resume(struct device *dev)
1227{
1228 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
1229 struct sdhci_pci_chip *chip;
1230 struct sdhci_pci_slot *slot;
1231 int i, ret;
1232
1233 chip = pci_get_drvdata(pdev);
1234 if (!chip)
1235 return 0;
1236
1237 if (chip->fixes && chip->fixes->resume) {
1238 ret = chip->fixes->resume(chip);
1239 if (ret)
1240 return ret;
1241 }
1242
1243 for (i = 0; i < chip->num_slots; i++) {
1244 slot = chip->slots[i];
1245 if (!slot)
1246 continue;
1247
1248 ret = sdhci_runtime_resume_host(slot->host);
1249 if (ret)
1250 return ret;
1251 }
1252
1253 return 0;
1254}
1255
1256static int sdhci_pci_runtime_idle(struct device *dev)
1257{
1258 return 0;
1259}
1260
1261#else
1262
1263#define sdhci_pci_runtime_suspend NULL
1264#define sdhci_pci_runtime_resume NULL
1265#define sdhci_pci_runtime_idle NULL
1266
1267#endif
1268
1269static const struct dev_pm_ops sdhci_pci_pm_ops = {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001270 .suspend = sdhci_pci_suspend,
1271 .resume = sdhci_pci_resume,
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001272 .runtime_suspend = sdhci_pci_runtime_suspend,
1273 .runtime_resume = sdhci_pci_runtime_resume,
1274 .runtime_idle = sdhci_pci_runtime_idle,
1275};
1276
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001277/*****************************************************************************\
1278 * *
1279 * Device probing/removal *
1280 * *
1281\*****************************************************************************/
1282
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001283static struct sdhci_pci_slot *sdhci_pci_probe_slot(
Adrian Hunter52c506f2011-12-27 15:48:43 +02001284 struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
1285 int slotno)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001286{
1287 struct sdhci_pci_slot *slot;
1288 struct sdhci_host *host;
Adrian Hunter52c506f2011-12-27 15:48:43 +02001289 int ret, bar = first_bar + slotno;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001290
1291 if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
1292 dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
1293 return ERR_PTR(-ENODEV);
1294 }
1295
Adrian Hunter90b3e6c2012-10-18 09:54:31 +03001296 if (pci_resource_len(pdev, bar) < 0x100) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001297 dev_err(&pdev->dev, "Invalid iomem size. You may "
1298 "experience problems.\n");
1299 }
1300
1301 if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
1302 dev_err(&pdev->dev, "Vendor specific interface. Aborting.\n");
1303 return ERR_PTR(-ENODEV);
1304 }
1305
1306 if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) {
1307 dev_err(&pdev->dev, "Unknown interface. Aborting.\n");
1308 return ERR_PTR(-ENODEV);
1309 }
1310
1311 host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot));
1312 if (IS_ERR(host)) {
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001313 dev_err(&pdev->dev, "cannot allocate host\n");
Julia Lawalldc0fd7b2010-05-26 14:42:11 -07001314 return ERR_CAST(host);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001315 }
1316
1317 slot = sdhci_priv(host);
1318
1319 slot->chip = chip;
1320 slot->host = host;
1321 slot->pci_bar = bar;
Adrian Hunter0f201652011-08-29 16:42:13 +03001322 slot->rst_n_gpio = -EINVAL;
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001323 slot->cd_gpio = -EINVAL;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001324
Adrian Hunter52c506f2011-12-27 15:48:43 +02001325 /* Retrieve platform data if there is any */
1326 if (*sdhci_pci_get_data)
1327 slot->data = sdhci_pci_get_data(pdev, slotno);
1328
1329 if (slot->data) {
1330 if (slot->data->setup) {
1331 ret = slot->data->setup(slot->data);
1332 if (ret) {
1333 dev_err(&pdev->dev, "platform setup failed\n");
1334 goto free;
1335 }
1336 }
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001337 slot->rst_n_gpio = slot->data->rst_n_gpio;
1338 slot->cd_gpio = slot->data->cd_gpio;
Adrian Hunter52c506f2011-12-27 15:48:43 +02001339 }
1340
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001341 host->hw_name = "PCI";
1342 host->ops = &sdhci_pci_ops;
1343 host->quirks = chip->quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +02001344 host->quirks2 = chip->quirks2;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001345
1346 host->irq = pdev->irq;
1347
1348 ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
1349 if (ret) {
1350 dev_err(&pdev->dev, "cannot request region\n");
Adrian Hunter52c506f2011-12-27 15:48:43 +02001351 goto cleanup;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001352 }
1353
Arjan van de Ven092f82e2008-09-28 16:15:56 -07001354 host->ioaddr = pci_ioremap_bar(pdev, bar);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001355 if (!host->ioaddr) {
1356 dev_err(&pdev->dev, "failed to remap registers\n");
Chris Ball9fdcdbb2011-03-29 00:46:12 -04001357 ret = -ENOMEM;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001358 goto release;
1359 }
1360
Pierre Ossman44894282008-04-04 19:36:59 +02001361 if (chip->fixes && chip->fixes->probe_slot) {
1362 ret = chip->fixes->probe_slot(slot);
1363 if (ret)
1364 goto unmap;
1365 }
1366
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001367 if (gpio_is_valid(slot->rst_n_gpio)) {
1368 if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
1369 gpio_direction_output(slot->rst_n_gpio, 1);
1370 slot->host->mmc->caps |= MMC_CAP_HW_RESET;
Adrian Hunterc9faff62013-06-13 11:50:26 +03001371 slot->hw_reset = sdhci_pci_gpio_hw_reset;
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001372 } else {
1373 dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
1374 slot->rst_n_gpio = -EINVAL;
1375 }
1376 }
1377
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001378 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
Aaron Lueed222a2013-03-05 11:24:52 +08001379 host->mmc->slotno = slotno;
Adrian Huntera08b17b2013-04-15 11:27:25 -04001380 host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001381
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001382 ret = sdhci_add_host(host);
1383 if (ret)
Pierre Ossman44894282008-04-04 19:36:59 +02001384 goto remove;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001385
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001386 sdhci_pci_add_own_cd(slot);
1387
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001388 return slot;
1389
Pierre Ossman44894282008-04-04 19:36:59 +02001390remove:
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001391 if (gpio_is_valid(slot->rst_n_gpio))
1392 gpio_free(slot->rst_n_gpio);
1393
Pierre Ossman44894282008-04-04 19:36:59 +02001394 if (chip->fixes && chip->fixes->remove_slot)
Pierre Ossman1e728592008-04-16 19:13:13 +02001395 chip->fixes->remove_slot(slot, 0);
Pierre Ossman44894282008-04-04 19:36:59 +02001396
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001397unmap:
1398 iounmap(host->ioaddr);
1399
1400release:
1401 pci_release_region(pdev, bar);
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001402
Adrian Hunter52c506f2011-12-27 15:48:43 +02001403cleanup:
1404 if (slot->data && slot->data->cleanup)
1405 slot->data->cleanup(slot->data);
1406
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001407free:
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001408 sdhci_free_host(host);
1409
1410 return ERR_PTR(ret);
1411}
1412
1413static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
1414{
Pierre Ossman1e728592008-04-16 19:13:13 +02001415 int dead;
1416 u32 scratch;
1417
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001418 sdhci_pci_remove_own_cd(slot);
1419
Pierre Ossman1e728592008-04-16 19:13:13 +02001420 dead = 0;
1421 scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
1422 if (scratch == (u32)-1)
1423 dead = 1;
1424
1425 sdhci_remove_host(slot->host, dead);
Pierre Ossman44894282008-04-04 19:36:59 +02001426
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001427 if (gpio_is_valid(slot->rst_n_gpio))
1428 gpio_free(slot->rst_n_gpio);
1429
Pierre Ossman44894282008-04-04 19:36:59 +02001430 if (slot->chip->fixes && slot->chip->fixes->remove_slot)
Pierre Ossman1e728592008-04-16 19:13:13 +02001431 slot->chip->fixes->remove_slot(slot, dead);
Pierre Ossman44894282008-04-04 19:36:59 +02001432
Adrian Hunter52c506f2011-12-27 15:48:43 +02001433 if (slot->data && slot->data->cleanup)
1434 slot->data->cleanup(slot->data);
1435
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001436 pci_release_region(slot->chip->pdev, slot->pci_bar);
Pierre Ossman44894282008-04-04 19:36:59 +02001437
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001438 sdhci_free_host(slot->host);
1439}
1440
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001441static void sdhci_pci_runtime_pm_allow(struct device *dev)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001442{
1443 pm_runtime_put_noidle(dev);
1444 pm_runtime_allow(dev);
1445 pm_runtime_set_autosuspend_delay(dev, 50);
1446 pm_runtime_use_autosuspend(dev);
1447 pm_suspend_ignore_children(dev, 1);
1448}
1449
Bill Pemberton6e0ee712012-11-19 13:26:03 -05001450static void sdhci_pci_runtime_pm_forbid(struct device *dev)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001451{
1452 pm_runtime_forbid(dev);
1453 pm_runtime_get_noresume(dev);
1454}
1455
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001456static int sdhci_pci_probe(struct pci_dev *pdev,
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001457 const struct pci_device_id *ent)
1458{
1459 struct sdhci_pci_chip *chip;
1460 struct sdhci_pci_slot *slot;
1461
Sergei Shtylyovcf5e23e2011-03-17 16:46:17 -04001462 u8 slots, first_bar;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001463 int ret, i;
1464
1465 BUG_ON(pdev == NULL);
1466 BUG_ON(ent == NULL);
1467
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001468 dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n",
Sergei Shtylyovcf5e23e2011-03-17 16:46:17 -04001469 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001470
1471 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
1472 if (ret)
1473 return ret;
1474
1475 slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
1476 dev_dbg(&pdev->dev, "found %d slot(s)\n", slots);
1477 if (slots == 0)
1478 return -ENODEV;
1479
1480 BUG_ON(slots > MAX_SLOTS);
1481
1482 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar);
1483 if (ret)
1484 return ret;
1485
1486 first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK;
1487
1488 if (first_bar > 5) {
1489 dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n");
1490 return -ENODEV;
1491 }
1492
1493 ret = pci_enable_device(pdev);
1494 if (ret)
1495 return ret;
1496
1497 chip = kzalloc(sizeof(struct sdhci_pci_chip), GFP_KERNEL);
1498 if (!chip) {
1499 ret = -ENOMEM;
1500 goto err;
1501 }
1502
1503 chip->pdev = pdev;
Ameya Palandeb177bc92011-04-05 21:13:13 +03001504 chip->fixes = (const struct sdhci_pci_fixes *)ent->driver_data;
Adrian Hunterc43fd772011-10-17 10:52:44 +03001505 if (chip->fixes) {
Pierre Ossman22606402008-03-23 19:33:23 +01001506 chip->quirks = chip->fixes->quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +02001507 chip->quirks2 = chip->fixes->quirks2;
Adrian Hunterc43fd772011-10-17 10:52:44 +03001508 chip->allow_runtime_pm = chip->fixes->allow_runtime_pm;
1509 }
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001510 chip->num_slots = slots;
1511
1512 pci_set_drvdata(pdev, chip);
1513
Pierre Ossman22606402008-03-23 19:33:23 +01001514 if (chip->fixes && chip->fixes->probe) {
1515 ret = chip->fixes->probe(chip);
1516 if (ret)
1517 goto free;
1518 }
1519
Alan Cox225d85f2010-10-04 15:24:21 +01001520 slots = chip->num_slots; /* Quirk may have changed this */
1521
Ameya Palandeb177bc92011-04-05 21:13:13 +03001522 for (i = 0; i < slots; i++) {
Adrian Hunter52c506f2011-12-27 15:48:43 +02001523 slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001524 if (IS_ERR(slot)) {
Ameya Palandeb177bc92011-04-05 21:13:13 +03001525 for (i--; i >= 0; i--)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001526 sdhci_pci_remove_slot(chip->slots[i]);
1527 ret = PTR_ERR(slot);
1528 goto free;
1529 }
1530
1531 chip->slots[i] = slot;
1532 }
1533
Adrian Hunterc43fd772011-10-17 10:52:44 +03001534 if (chip->allow_runtime_pm)
1535 sdhci_pci_runtime_pm_allow(&pdev->dev);
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001536
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001537 return 0;
1538
1539free:
1540 pci_set_drvdata(pdev, NULL);
1541 kfree(chip);
1542
1543err:
1544 pci_disable_device(pdev);
1545 return ret;
1546}
1547
Bill Pemberton6e0ee712012-11-19 13:26:03 -05001548static void sdhci_pci_remove(struct pci_dev *pdev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001549{
1550 int i;
1551 struct sdhci_pci_chip *chip;
1552
1553 chip = pci_get_drvdata(pdev);
1554
1555 if (chip) {
Adrian Hunterc43fd772011-10-17 10:52:44 +03001556 if (chip->allow_runtime_pm)
1557 sdhci_pci_runtime_pm_forbid(&pdev->dev);
1558
Ameya Palandeb177bc92011-04-05 21:13:13 +03001559 for (i = 0; i < chip->num_slots; i++)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001560 sdhci_pci_remove_slot(chip->slots[i]);
1561
1562 pci_set_drvdata(pdev, NULL);
1563 kfree(chip);
1564 }
1565
1566 pci_disable_device(pdev);
1567}
1568
1569static struct pci_driver sdhci_driver = {
Ameya Palandeb177bc92011-04-05 21:13:13 +03001570 .name = "sdhci-pci",
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001571 .id_table = pci_ids,
Ameya Palandeb177bc92011-04-05 21:13:13 +03001572 .probe = sdhci_pci_probe,
Bill Pemberton0433c142012-11-19 13:20:26 -05001573 .remove = sdhci_pci_remove,
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001574 .driver = {
1575 .pm = &sdhci_pci_pm_ops
1576 },
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001577};
1578
Sachin Kamatacc69642012-08-27 11:57:02 +05301579module_pci_driver(sdhci_driver);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001580
Pierre Ossman32710e82009-04-08 20:14:54 +02001581MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001582MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
1583MODULE_LICENSE("GPL");