blob: f46b84ce4ec8dc13ab8d5412117373478591e0bf [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"
Adam Lee01acf692013-12-19 00:01:26 +080031#include "sdhci-pci-o2micro.h"
Pierre Ossman22606402008-03-23 19:33:23 +010032
33/*****************************************************************************\
34 * *
35 * Hardware specific quirk handling *
36 * *
37\*****************************************************************************/
38
39static int ricoh_probe(struct sdhci_pci_chip *chip)
40{
Chris Ballc99436f2009-09-22 16:45:22 -070041 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
42 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
Pierre Ossman22606402008-03-23 19:33:23 +010043 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
Maxim Levitskyccc92c22010-08-10 18:01:42 -070044 return 0;
45}
Pierre Ossman22606402008-03-23 19:33:23 +010046
Maxim Levitskyccc92c22010-08-10 18:01:42 -070047static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
48{
49 slot->host->caps =
50 ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT)
51 & SDHCI_TIMEOUT_CLK_MASK) |
52
53 ((0x21 << SDHCI_CLOCK_BASE_SHIFT)
54 & SDHCI_CLOCK_BASE_MASK) |
55
56 SDHCI_TIMEOUT_CLK_UNIT |
57 SDHCI_CAN_VDD_330 |
Madhvapathi Sriram1a1f1f02012-10-15 04:47:30 +000058 SDHCI_CAN_DO_HISPD |
Maxim Levitskyccc92c22010-08-10 18:01:42 -070059 SDHCI_CAN_DO_SDMA;
60 return 0;
61}
62
63static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
64{
65 /* Apply a delay to allow controller to settle */
66 /* Otherwise it becomes confused if card state changed
67 during suspend */
68 msleep(500);
Pierre Ossman22606402008-03-23 19:33:23 +010069 return 0;
70}
71
72static const struct sdhci_pci_fixes sdhci_ricoh = {
73 .probe = ricoh_probe,
Vasily Khoruzhick84938292010-03-05 13:43:46 -080074 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
75 SDHCI_QUIRK_FORCE_DMA |
76 SDHCI_QUIRK_CLOCK_BEFORE_RESET,
Pierre Ossman22606402008-03-23 19:33:23 +010077};
78
Maxim Levitskyccc92c22010-08-10 18:01:42 -070079static const struct sdhci_pci_fixes sdhci_ricoh_mmc = {
80 .probe_slot = ricoh_mmc_probe_slot,
81 .resume = ricoh_mmc_resume,
82 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
83 SDHCI_QUIRK_CLOCK_BEFORE_RESET |
84 SDHCI_QUIRK_NO_CARD_NO_RESET |
85 SDHCI_QUIRK_MISSING_CAPS
86};
87
Pierre Ossman22606402008-03-23 19:33:23 +010088static const struct sdhci_pci_fixes sdhci_ene_712 = {
89 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
90 SDHCI_QUIRK_BROKEN_DMA,
91};
92
93static const struct sdhci_pci_fixes sdhci_ene_714 = {
94 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
95 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS |
96 SDHCI_QUIRK_BROKEN_DMA,
97};
98
99static const struct sdhci_pci_fixes sdhci_cafe = {
100 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
Andres Salomona0874892009-03-02 21:48:20 +0100101 SDHCI_QUIRK_NO_BUSY_IRQ |
Daniel Drake55fc05b2012-07-03 23:13:39 +0100102 SDHCI_QUIRK_BROKEN_CARD_DETECTION |
Pierre Ossmanee53ab52008-07-05 00:25:15 +0200103 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
Pierre Ossman22606402008-03-23 19:33:23 +0100104};
105
Major Lee68077b02011-06-29 14:23:46 +0300106static int mrst_hc_probe_slot(struct sdhci_pci_slot *slot)
107{
108 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA;
109 return 0;
110}
111
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100112/*
113 * ADMA operation is disabled for Moorestown platform due to
114 * hardware bugs.
115 */
Jacob Pan35ac6f02010-11-09 13:57:29 +0000116static int mrst_hc_probe(struct sdhci_pci_chip *chip)
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100117{
118 /*
Jacob Pan35ac6f02010-11-09 13:57:29 +0000119 * slots number is fixed here for MRST as SDIO3/5 are never used and
120 * have hardware bugs.
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100121 */
122 chip->num_slots = 1;
123 return 0;
124}
125
Alexander Stein296e0b02012-03-14 08:38:58 +0100126static int pch_hc_probe_slot(struct sdhci_pci_slot *slot)
127{
128 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA;
129 return 0;
130}
131
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300132#ifdef CONFIG_PM_RUNTIME
133
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200134static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300135{
136 struct sdhci_pci_slot *slot = dev_id;
137 struct sdhci_host *host = slot->host;
138
139 mmc_detect_change(host->mmc, msecs_to_jiffies(200));
140 return IRQ_HANDLED;
141}
142
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200143static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300144{
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200145 int err, irq, gpio = slot->cd_gpio;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300146
147 slot->cd_gpio = -EINVAL;
148 slot->cd_irq = -EINVAL;
149
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200150 if (!gpio_is_valid(gpio))
151 return;
152
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300153 err = gpio_request(gpio, "sd_cd");
154 if (err < 0)
155 goto out;
156
157 err = gpio_direction_input(gpio);
158 if (err < 0)
159 goto out_free;
160
161 irq = gpio_to_irq(gpio);
162 if (irq < 0)
163 goto out_free;
164
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200165 err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING |
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300166 IRQF_TRIGGER_FALLING, "sd_cd", slot);
167 if (err)
168 goto out_free;
169
170 slot->cd_gpio = gpio;
171 slot->cd_irq = irq;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300172
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200173 return;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300174
175out_free:
176 gpio_free(gpio);
177out:
178 dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300179}
180
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200181static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300182{
183 if (slot->cd_irq >= 0)
184 free_irq(slot->cd_irq, slot);
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200185 if (gpio_is_valid(slot->cd_gpio))
186 gpio_free(slot->cd_gpio);
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300187}
188
189#else
190
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200191static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
192{
193}
194
195static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
196{
197}
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300198
199#endif
200
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300201static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
202{
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300203 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
Adrian Hunterda721cf2012-02-07 14:48:53 +0200204 slot->host->mmc->caps2 |= MMC_CAP2_BOOTPART_NOACC |
205 MMC_CAP2_HC_ERASE_SZ;
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300206 return 0;
207}
208
Adrian Hunter93933502011-12-27 15:48:47 +0200209static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
210{
Adrian Hunter012e4672012-01-30 14:27:18 +0200211 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
Adrian Hunter93933502011-12-27 15:48:47 +0200212 return 0;
213}
214
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100215static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
216 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
Major Lee68077b02011-06-29 14:23:46 +0300217 .probe_slot = mrst_hc_probe_slot,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100218};
219
Jacob Pan35ac6f02010-11-09 13:57:29 +0000220static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100221 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
Jacob Pan35ac6f02010-11-09 13:57:29 +0000222 .probe = mrst_hc_probe,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100223};
224
Xiaochen Shen29229052010-10-04 15:24:52 +0100225static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
226 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300227 .allow_runtime_pm = true,
Xiaochen Shen29229052010-10-04 15:24:52 +0100228};
229
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300230static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
Xiaochen Shen29229052010-10-04 15:24:52 +0100231 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterf3c55a72012-02-07 14:48:55 +0200232 .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300233 .allow_runtime_pm = true,
Adrian Hunter93933502011-12-27 15:48:47 +0200234 .probe_slot = mfd_sdio_probe_slot,
Xiaochen Shen29229052010-10-04 15:24:52 +0100235};
236
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300237static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
238 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300239 .allow_runtime_pm = true,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300240 .probe_slot = mfd_emmc_probe_slot,
241};
242
Alexander Stein296e0b02012-03-14 08:38:58 +0100243static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = {
244 .quirks = SDHCI_QUIRK_BROKEN_ADMA,
245 .probe_slot = pch_hc_probe_slot,
246};
247
Adrian Hunterc9faff62013-06-13 11:50:26 +0300248static void sdhci_pci_int_hw_reset(struct sdhci_host *host)
249{
250 u8 reg;
251
252 reg = sdhci_readb(host, SDHCI_POWER_CONTROL);
253 reg |= 0x10;
254 sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
255 /* For eMMC, minimum is 1us but give it 9us for good measure */
256 udelay(9);
257 reg &= ~0x10;
258 sdhci_writeb(host, reg, SDHCI_POWER_CONTROL);
259 /* For eMMC, minimum is 200us but give it 300us for good measure */
260 usleep_range(300, 1000);
261}
262
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300263static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
264{
Adrian Hunterc9faff62013-06-13 11:50:26 +0300265 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
266 MMC_CAP_HW_RESET;
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300267 slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
Adrian Hunterc9faff62013-06-13 11:50:26 +0300268 slot->hw_reset = sdhci_pci_int_hw_reset;
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300269 return 0;
270}
271
272static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
273{
274 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
275 return 0;
276}
277
278static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
279 .allow_runtime_pm = true,
280 .probe_slot = byt_emmc_probe_slot,
281};
282
283static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
284 .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
285 .allow_runtime_pm = true,
286 .probe_slot = byt_sdio_probe_slot,
287};
288
289static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
Adrian Hunter7396e312013-05-06 12:17:34 +0300290 .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON,
291 .allow_runtime_pm = true,
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300292};
293
David Cohen8776a162013-10-01 13:18:15 -0700294/* Define Host controllers for Intel Merrifield platform */
295#define INTEL_MRFL_EMMC_0 0
296#define INTEL_MRFL_EMMC_1 1
297
298static int intel_mrfl_mmc_probe_slot(struct sdhci_pci_slot *slot)
299{
300 if ((PCI_FUNC(slot->chip->pdev->devfn) != INTEL_MRFL_EMMC_0) &&
301 (PCI_FUNC(slot->chip->pdev->devfn) != INTEL_MRFL_EMMC_1))
302 /* SD support is not ready yet */
303 return -ENODEV;
304
305 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
306 MMC_CAP_1_8V_DDR;
307
308 return 0;
309}
310
311static const struct sdhci_pci_fixes sdhci_intel_mrfl_mmc = {
312 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
David Cohen390145f2013-10-29 10:58:27 -0700313 .quirks2 = SDHCI_QUIRK2_BROKEN_HS200,
David Cohen8776a162013-10-01 13:18:15 -0700314 .probe_slot = intel_mrfl_mmc_probe_slot,
315};
316
Jennifer Li26daa1e2010-11-17 23:01:59 -0500317/* O2Micro extra registers */
318#define O2_SD_LOCK_WP 0xD3
319#define O2_SD_MULTI_VCC3V 0xEE
320#define O2_SD_CLKREQ 0xEC
321#define O2_SD_CAPS 0xE0
322#define O2_SD_ADMA1 0xE2
323#define O2_SD_ADMA2 0xE7
324#define O2_SD_INF_MOD 0xF1
325
Pierre Ossman45211e22008-03-24 13:09:09 +0100326static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
327{
328 u8 scratch;
329 int ret;
330
331 ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch);
332 if (ret)
333 return ret;
334
335 /*
336 * Turn PMOS on [bit 0], set over current detection to 2.4 V
337 * [bit 1:2] and enable over current debouncing [bit 6].
338 */
339 if (on)
340 scratch |= 0x47;
341 else
342 scratch &= ~0x47;
343
344 ret = pci_write_config_byte(chip->pdev, 0xAE, scratch);
345 if (ret)
346 return ret;
347
348 return 0;
349}
350
351static int jmicron_probe(struct sdhci_pci_chip *chip)
352{
353 int ret;
Takashi Iwai8f230f42010-12-08 10:04:30 +0100354 u16 mmcdev = 0;
Pierre Ossman45211e22008-03-24 13:09:09 +0100355
Pierre Ossman93fc48c2008-06-28 18:21:41 +0200356 if (chip->pdev->revision == 0) {
357 chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR |
358 SDHCI_QUIRK_32BIT_DMA_SIZE |
Pierre Ossman2134a922008-06-28 18:28:51 +0200359 SDHCI_QUIRK_32BIT_ADMA_SIZE |
Pierre Ossman4a3cba32008-07-29 00:11:16 +0200360 SDHCI_QUIRK_RESET_AFTER_REQUEST |
Pierre Ossman86a6a872009-02-02 21:13:49 +0100361 SDHCI_QUIRK_BROKEN_SMALL_PIO;
Pierre Ossman93fc48c2008-06-28 18:21:41 +0200362 }
363
Pierre Ossman45211e22008-03-24 13:09:09 +0100364 /*
Pierre Ossman44894282008-04-04 19:36:59 +0200365 * JMicron chips can have two interfaces to the same hardware
366 * in order to work around limitations in Microsoft's driver.
367 * We need to make sure we only bind to one of them.
368 *
369 * This code assumes two things:
370 *
371 * 1. The PCI code adds subfunctions in order.
372 *
373 * 2. The MMC interface has a lower subfunction number
374 * than the SD interface.
375 */
Takashi Iwai8f230f42010-12-08 10:04:30 +0100376 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD)
377 mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC;
378 else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD)
379 mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD;
380
381 if (mmcdev) {
Pierre Ossman44894282008-04-04 19:36:59 +0200382 struct pci_dev *sd_dev;
383
384 sd_dev = NULL;
385 while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON,
Takashi Iwai8f230f42010-12-08 10:04:30 +0100386 mmcdev, sd_dev)) != NULL) {
Pierre Ossman44894282008-04-04 19:36:59 +0200387 if ((PCI_SLOT(chip->pdev->devfn) ==
388 PCI_SLOT(sd_dev->devfn)) &&
389 (chip->pdev->bus == sd_dev->bus))
390 break;
391 }
392
393 if (sd_dev) {
394 pci_dev_put(sd_dev);
395 dev_info(&chip->pdev->dev, "Refusing to bind to "
396 "secondary interface.\n");
397 return -ENODEV;
398 }
399 }
400
401 /*
Pierre Ossman45211e22008-03-24 13:09:09 +0100402 * JMicron chips need a bit of a nudge to enable the power
403 * output pins.
404 */
405 ret = jmicron_pmos(chip, 1);
406 if (ret) {
407 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
408 return ret;
409 }
410
Takashi Iwai82b0e232011-04-21 20:26:38 +0200411 /* quirk for unsable RO-detection on JM388 chips */
412 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
413 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
414 chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT;
415
Pierre Ossman45211e22008-03-24 13:09:09 +0100416 return 0;
417}
418
Pierre Ossman44894282008-04-04 19:36:59 +0200419static void jmicron_enable_mmc(struct sdhci_host *host, int on)
420{
421 u8 scratch;
422
423 scratch = readb(host->ioaddr + 0xC0);
424
425 if (on)
426 scratch |= 0x01;
427 else
428 scratch &= ~0x01;
429
430 writeb(scratch, host->ioaddr + 0xC0);
431}
432
433static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
434{
Pierre Ossman2134a922008-06-28 18:28:51 +0200435 if (slot->chip->pdev->revision == 0) {
436 u16 version;
437
438 version = readl(slot->host->ioaddr + SDHCI_HOST_VERSION);
439 version = (version & SDHCI_VENDOR_VER_MASK) >>
440 SDHCI_VENDOR_VER_SHIFT;
441
442 /*
443 * Older versions of the chip have lots of nasty glitches
444 * in the ADMA engine. It's best just to avoid it
445 * completely.
446 */
447 if (version < 0xAC)
448 slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
449 }
450
Takashi Iwai8f230f42010-12-08 10:04:30 +0100451 /* JM388 MMC doesn't support 1.8V while SD supports it */
452 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
453 slot->host->ocr_avail_sd = MMC_VDD_32_33 | MMC_VDD_33_34 |
454 MMC_VDD_29_30 | MMC_VDD_30_31 |
455 MMC_VDD_165_195; /* allow 1.8V */
456 slot->host->ocr_avail_mmc = MMC_VDD_32_33 | MMC_VDD_33_34 |
457 MMC_VDD_29_30 | MMC_VDD_30_31; /* no 1.8V for MMC */
458 }
459
Pierre Ossman44894282008-04-04 19:36:59 +0200460 /*
461 * The secondary interface requires a bit set to get the
462 * interrupts.
463 */
Takashi Iwai8f230f42010-12-08 10:04:30 +0100464 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
465 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
Pierre Ossman44894282008-04-04 19:36:59 +0200466 jmicron_enable_mmc(slot->host, 1);
467
Takashi Iwaid75c1082010-12-16 17:54:14 +0100468 slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST;
469
Pierre Ossman44894282008-04-04 19:36:59 +0200470 return 0;
471}
472
Pierre Ossman1e728592008-04-16 19:13:13 +0200473static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead)
Pierre Ossman44894282008-04-04 19:36:59 +0200474{
Pierre Ossman1e728592008-04-16 19:13:13 +0200475 if (dead)
476 return;
477
Takashi Iwai8f230f42010-12-08 10:04:30 +0100478 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
479 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
Pierre Ossman44894282008-04-04 19:36:59 +0200480 jmicron_enable_mmc(slot->host, 0);
481}
482
Manuel Lauss29495aa2011-11-03 11:09:45 +0100483static int jmicron_suspend(struct sdhci_pci_chip *chip)
Pierre Ossman44894282008-04-04 19:36:59 +0200484{
485 int i;
486
Takashi Iwai8f230f42010-12-08 10:04:30 +0100487 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
488 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
Ameya Palandeb177bc92011-04-05 21:13:13 +0300489 for (i = 0; i < chip->num_slots; i++)
Pierre Ossman44894282008-04-04 19:36:59 +0200490 jmicron_enable_mmc(chip->slots[i]->host, 0);
491 }
492
493 return 0;
494}
495
Pierre Ossman45211e22008-03-24 13:09:09 +0100496static int jmicron_resume(struct sdhci_pci_chip *chip)
497{
Pierre Ossman44894282008-04-04 19:36:59 +0200498 int ret, i;
499
Takashi Iwai8f230f42010-12-08 10:04:30 +0100500 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
501 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
Ameya Palandeb177bc92011-04-05 21:13:13 +0300502 for (i = 0; i < chip->num_slots; i++)
Pierre Ossman44894282008-04-04 19:36:59 +0200503 jmicron_enable_mmc(chip->slots[i]->host, 1);
504 }
Pierre Ossman45211e22008-03-24 13:09:09 +0100505
506 ret = jmicron_pmos(chip, 1);
507 if (ret) {
508 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
509 return ret;
510 }
511
512 return 0;
513}
514
Jennifer Li26daa1e2010-11-17 23:01:59 -0500515static const struct sdhci_pci_fixes sdhci_o2 = {
Adam Lee01acf692013-12-19 00:01:26 +0800516 .probe = sdhci_pci_o2_probe,
517 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
518 .probe_slot = sdhci_pci_o2_probe_slot,
519 .resume = sdhci_pci_o2_resume,
Jennifer Li26daa1e2010-11-17 23:01:59 -0500520};
521
Pierre Ossman22606402008-03-23 19:33:23 +0100522static const struct sdhci_pci_fixes sdhci_jmicron = {
Pierre Ossman45211e22008-03-24 13:09:09 +0100523 .probe = jmicron_probe,
524
Pierre Ossman44894282008-04-04 19:36:59 +0200525 .probe_slot = jmicron_probe_slot,
526 .remove_slot = jmicron_remove_slot,
527
528 .suspend = jmicron_suspend,
Pierre Ossman45211e22008-03-24 13:09:09 +0100529 .resume = jmicron_resume,
Pierre Ossman22606402008-03-23 19:33:23 +0100530};
531
Nicolas Pitrea7a61862009-12-14 18:01:26 -0800532/* SysKonnect CardBus2SDIO extra registers */
533#define SYSKT_CTRL 0x200
534#define SYSKT_RDFIFO_STAT 0x204
535#define SYSKT_WRFIFO_STAT 0x208
536#define SYSKT_POWER_DATA 0x20c
537#define SYSKT_POWER_330 0xef
538#define SYSKT_POWER_300 0xf8
539#define SYSKT_POWER_184 0xcc
540#define SYSKT_POWER_CMD 0x20d
541#define SYSKT_POWER_START (1 << 7)
542#define SYSKT_POWER_STATUS 0x20e
543#define SYSKT_POWER_STATUS_OK (1 << 0)
544#define SYSKT_BOARD_REV 0x210
545#define SYSKT_CHIP_REV 0x211
546#define SYSKT_CONF_DATA 0x212
547#define SYSKT_CONF_DATA_1V8 (1 << 2)
548#define SYSKT_CONF_DATA_2V5 (1 << 1)
549#define SYSKT_CONF_DATA_3V3 (1 << 0)
550
551static int syskt_probe(struct sdhci_pci_chip *chip)
552{
553 if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
554 chip->pdev->class &= ~0x0000FF;
555 chip->pdev->class |= PCI_SDHCI_IFDMA;
556 }
557 return 0;
558}
559
560static int syskt_probe_slot(struct sdhci_pci_slot *slot)
561{
562 int tm, ps;
563
564 u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV);
565 u8 chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV);
566 dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, "
567 "board rev %d.%d, chip rev %d.%d\n",
568 board_rev >> 4, board_rev & 0xf,
569 chip_rev >> 4, chip_rev & 0xf);
570 if (chip_rev >= 0x20)
571 slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA;
572
573 writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA);
574 writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD);
575 udelay(50);
576 tm = 10; /* Wait max 1 ms */
577 do {
578 ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS);
579 if (ps & SYSKT_POWER_STATUS_OK)
580 break;
581 udelay(100);
582 } while (--tm);
583 if (!tm) {
584 dev_err(&slot->chip->pdev->dev,
585 "power regulator never stabilized");
586 writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD);
587 return -ENODEV;
588 }
589
590 return 0;
591}
592
593static const struct sdhci_pci_fixes sdhci_syskt = {
594 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER,
595 .probe = syskt_probe,
596 .probe_slot = syskt_probe_slot,
597};
598
Harald Welte557b0692009-06-18 16:53:38 +0200599static int via_probe(struct sdhci_pci_chip *chip)
600{
601 if (chip->pdev->revision == 0x10)
602 chip->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER;
603
604 return 0;
605}
606
607static const struct sdhci_pci_fixes sdhci_via = {
608 .probe = via_probe,
609};
610
Bill Pemberton9647f842012-11-19 13:25:11 -0500611static const struct pci_device_id pci_ids[] = {
Pierre Ossman22606402008-03-23 19:33:23 +0100612 {
613 .vendor = PCI_VENDOR_ID_RICOH,
614 .device = PCI_DEVICE_ID_RICOH_R5C822,
615 .subvendor = PCI_ANY_ID,
616 .subdevice = PCI_ANY_ID,
617 .driver_data = (kernel_ulong_t)&sdhci_ricoh,
618 },
619
620 {
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700621 .vendor = PCI_VENDOR_ID_RICOH,
622 .device = 0x843,
623 .subvendor = PCI_ANY_ID,
624 .subdevice = PCI_ANY_ID,
625 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
626 },
627
628 {
Pablo Castillo568133e2010-08-10 18:02:01 -0700629 .vendor = PCI_VENDOR_ID_RICOH,
630 .device = 0xe822,
631 .subvendor = PCI_ANY_ID,
632 .subdevice = PCI_ANY_ID,
633 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
634 },
635
636 {
Manoj Iyer5fd11c02011-02-11 16:25:31 -0600637 .vendor = PCI_VENDOR_ID_RICOH,
638 .device = 0xe823,
639 .subvendor = PCI_ANY_ID,
640 .subdevice = PCI_ANY_ID,
641 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
642 },
643
644 {
Pierre Ossman22606402008-03-23 19:33:23 +0100645 .vendor = PCI_VENDOR_ID_ENE,
646 .device = PCI_DEVICE_ID_ENE_CB712_SD,
647 .subvendor = PCI_ANY_ID,
648 .subdevice = PCI_ANY_ID,
649 .driver_data = (kernel_ulong_t)&sdhci_ene_712,
650 },
651
652 {
653 .vendor = PCI_VENDOR_ID_ENE,
654 .device = PCI_DEVICE_ID_ENE_CB712_SD_2,
655 .subvendor = PCI_ANY_ID,
656 .subdevice = PCI_ANY_ID,
657 .driver_data = (kernel_ulong_t)&sdhci_ene_712,
658 },
659
660 {
661 .vendor = PCI_VENDOR_ID_ENE,
662 .device = PCI_DEVICE_ID_ENE_CB714_SD,
663 .subvendor = PCI_ANY_ID,
664 .subdevice = PCI_ANY_ID,
665 .driver_data = (kernel_ulong_t)&sdhci_ene_714,
666 },
667
668 {
669 .vendor = PCI_VENDOR_ID_ENE,
670 .device = PCI_DEVICE_ID_ENE_CB714_SD_2,
671 .subvendor = PCI_ANY_ID,
672 .subdevice = PCI_ANY_ID,
673 .driver_data = (kernel_ulong_t)&sdhci_ene_714,
674 },
675
676 {
677 .vendor = PCI_VENDOR_ID_MARVELL,
David Woodhouse8c5eb882008-09-03 09:45:57 +0100678 .device = PCI_DEVICE_ID_MARVELL_88ALP01_SD,
Pierre Ossman22606402008-03-23 19:33:23 +0100679 .subvendor = PCI_ANY_ID,
680 .subdevice = PCI_ANY_ID,
681 .driver_data = (kernel_ulong_t)&sdhci_cafe,
682 },
683
684 {
685 .vendor = PCI_VENDOR_ID_JMICRON,
686 .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
687 .subvendor = PCI_ANY_ID,
688 .subdevice = PCI_ANY_ID,
689 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
690 },
691
Pierre Ossman44894282008-04-04 19:36:59 +0200692 {
693 .vendor = PCI_VENDOR_ID_JMICRON,
694 .device = PCI_DEVICE_ID_JMICRON_JMB38X_MMC,
695 .subvendor = PCI_ANY_ID,
696 .subdevice = PCI_ANY_ID,
697 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
698 },
699
Harald Welte557b0692009-06-18 16:53:38 +0200700 {
Takashi Iwai8f230f42010-12-08 10:04:30 +0100701 .vendor = PCI_VENDOR_ID_JMICRON,
702 .device = PCI_DEVICE_ID_JMICRON_JMB388_SD,
703 .subvendor = PCI_ANY_ID,
704 .subdevice = PCI_ANY_ID,
705 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
706 },
707
708 {
709 .vendor = PCI_VENDOR_ID_JMICRON,
710 .device = PCI_DEVICE_ID_JMICRON_JMB388_ESD,
711 .subvendor = PCI_ANY_ID,
712 .subdevice = PCI_ANY_ID,
713 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
714 },
715
716 {
Nicolas Pitrea7a61862009-12-14 18:01:26 -0800717 .vendor = PCI_VENDOR_ID_SYSKONNECT,
718 .device = 0x8000,
719 .subvendor = PCI_ANY_ID,
720 .subdevice = PCI_ANY_ID,
721 .driver_data = (kernel_ulong_t)&sdhci_syskt,
722 },
723
724 {
Harald Welte557b0692009-06-18 16:53:38 +0200725 .vendor = PCI_VENDOR_ID_VIA,
726 .device = 0x95d0,
727 .subvendor = PCI_ANY_ID,
728 .subdevice = PCI_ANY_ID,
729 .driver_data = (kernel_ulong_t)&sdhci_via,
730 },
731
Xiaochen Shen29229052010-10-04 15:24:52 +0100732 {
733 .vendor = PCI_VENDOR_ID_INTEL,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100734 .device = PCI_DEVICE_ID_INTEL_MRST_SD0,
735 .subvendor = PCI_ANY_ID,
736 .subdevice = PCI_ANY_ID,
737 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc0,
738 },
739
740 {
741 .vendor = PCI_VENDOR_ID_INTEL,
742 .device = PCI_DEVICE_ID_INTEL_MRST_SD1,
743 .subvendor = PCI_ANY_ID,
744 .subdevice = PCI_ANY_ID,
Jacob Pan35ac6f02010-11-09 13:57:29 +0000745 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
746 },
747
748 {
749 .vendor = PCI_VENDOR_ID_INTEL,
750 .device = PCI_DEVICE_ID_INTEL_MRST_SD2,
751 .subvendor = PCI_ANY_ID,
752 .subdevice = PCI_ANY_ID,
753 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100754 },
755
756 {
757 .vendor = PCI_VENDOR_ID_INTEL,
Xiaochen Shen29229052010-10-04 15:24:52 +0100758 .device = PCI_DEVICE_ID_INTEL_MFD_SD,
759 .subvendor = PCI_ANY_ID,
760 .subdevice = PCI_ANY_ID,
761 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sd,
762 },
763
764 {
765 .vendor = PCI_VENDOR_ID_INTEL,
766 .device = PCI_DEVICE_ID_INTEL_MFD_SDIO1,
767 .subvendor = PCI_ANY_ID,
768 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300769 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
Xiaochen Shen29229052010-10-04 15:24:52 +0100770 },
771
772 {
773 .vendor = PCI_VENDOR_ID_INTEL,
774 .device = PCI_DEVICE_ID_INTEL_MFD_SDIO2,
775 .subvendor = PCI_ANY_ID,
776 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300777 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
Xiaochen Shen29229052010-10-04 15:24:52 +0100778 },
779
780 {
781 .vendor = PCI_VENDOR_ID_INTEL,
782 .device = PCI_DEVICE_ID_INTEL_MFD_EMMC0,
783 .subvendor = PCI_ANY_ID,
784 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300785 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
Xiaochen Shen29229052010-10-04 15:24:52 +0100786 },
787
788 {
789 .vendor = PCI_VENDOR_ID_INTEL,
790 .device = PCI_DEVICE_ID_INTEL_MFD_EMMC1,
791 .subvendor = PCI_ANY_ID,
792 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300793 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
Xiaochen Shen29229052010-10-04 15:24:52 +0100794 },
795
Jennifer Li26daa1e2010-11-17 23:01:59 -0500796 {
Alexander Stein296e0b02012-03-14 08:38:58 +0100797 .vendor = PCI_VENDOR_ID_INTEL,
798 .device = PCI_DEVICE_ID_INTEL_PCH_SDIO0,
799 .subvendor = PCI_ANY_ID,
800 .subdevice = PCI_ANY_ID,
801 .driver_data = (kernel_ulong_t)&sdhci_intel_pch_sdio,
802 },
803
804 {
805 .vendor = PCI_VENDOR_ID_INTEL,
806 .device = PCI_DEVICE_ID_INTEL_PCH_SDIO1,
807 .subvendor = PCI_ANY_ID,
808 .subdevice = PCI_ANY_ID,
809 .driver_data = (kernel_ulong_t)&sdhci_intel_pch_sdio,
810 },
811
812 {
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300813 .vendor = PCI_VENDOR_ID_INTEL,
814 .device = PCI_DEVICE_ID_INTEL_BYT_EMMC,
815 .subvendor = PCI_ANY_ID,
816 .subdevice = PCI_ANY_ID,
817 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
818 },
819
820 {
821 .vendor = PCI_VENDOR_ID_INTEL,
822 .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
823 .subvendor = PCI_ANY_ID,
824 .subdevice = PCI_ANY_ID,
825 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio,
826 },
827
828 {
829 .vendor = PCI_VENDOR_ID_INTEL,
830 .device = PCI_DEVICE_ID_INTEL_BYT_SD,
831 .subvendor = PCI_ANY_ID,
832 .subdevice = PCI_ANY_ID,
833 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd,
834 },
835
836 {
Adrian Hunter30d025c2013-06-20 12:57:59 +0300837 .vendor = PCI_VENDOR_ID_INTEL,
838 .device = PCI_DEVICE_ID_INTEL_BYT_EMMC2,
839 .subvendor = PCI_ANY_ID,
840 .subdevice = PCI_ANY_ID,
841 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
842 },
843
Eric Ernstd0520682013-10-21 09:54:41 -0700844
845 {
846 .vendor = PCI_VENDOR_ID_INTEL,
847 .device = PCI_DEVICE_ID_INTEL_CLV_SDIO0,
848 .subvendor = PCI_ANY_ID,
849 .subdevice = PCI_ANY_ID,
850 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sd,
851 },
852
853 {
854 .vendor = PCI_VENDOR_ID_INTEL,
855 .device = PCI_DEVICE_ID_INTEL_CLV_SDIO1,
856 .subvendor = PCI_ANY_ID,
857 .subdevice = PCI_ANY_ID,
858 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
859 },
860
861 {
862 .vendor = PCI_VENDOR_ID_INTEL,
863 .device = PCI_DEVICE_ID_INTEL_CLV_SDIO2,
864 .subvendor = PCI_ANY_ID,
865 .subdevice = PCI_ANY_ID,
866 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
867 },
868
869 {
870 .vendor = PCI_VENDOR_ID_INTEL,
871 .device = PCI_DEVICE_ID_INTEL_CLV_EMMC0,
872 .subvendor = PCI_ANY_ID,
873 .subdevice = PCI_ANY_ID,
874 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
875 },
876
877 {
878 .vendor = PCI_VENDOR_ID_INTEL,
879 .device = PCI_DEVICE_ID_INTEL_CLV_EMMC1,
880 .subvendor = PCI_ANY_ID,
881 .subdevice = PCI_ANY_ID,
882 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
883 },
884
Adrian Hunter30d025c2013-06-20 12:57:59 +0300885 {
David Cohen8776a162013-10-01 13:18:15 -0700886 .vendor = PCI_VENDOR_ID_INTEL,
887 .device = PCI_DEVICE_ID_INTEL_MRFL_MMC,
888 .subvendor = PCI_ANY_ID,
889 .subdevice = PCI_ANY_ID,
890 .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc,
891 },
892 {
Jennifer Li26daa1e2010-11-17 23:01:59 -0500893 .vendor = PCI_VENDOR_ID_O2,
894 .device = PCI_DEVICE_ID_O2_8120,
895 .subvendor = PCI_ANY_ID,
896 .subdevice = PCI_ANY_ID,
897 .driver_data = (kernel_ulong_t)&sdhci_o2,
898 },
899
900 {
901 .vendor = PCI_VENDOR_ID_O2,
902 .device = PCI_DEVICE_ID_O2_8220,
903 .subvendor = PCI_ANY_ID,
904 .subdevice = PCI_ANY_ID,
905 .driver_data = (kernel_ulong_t)&sdhci_o2,
906 },
907
908 {
909 .vendor = PCI_VENDOR_ID_O2,
910 .device = PCI_DEVICE_ID_O2_8221,
911 .subvendor = PCI_ANY_ID,
912 .subdevice = PCI_ANY_ID,
913 .driver_data = (kernel_ulong_t)&sdhci_o2,
914 },
915
916 {
917 .vendor = PCI_VENDOR_ID_O2,
918 .device = PCI_DEVICE_ID_O2_8320,
919 .subvendor = PCI_ANY_ID,
920 .subdevice = PCI_ANY_ID,
921 .driver_data = (kernel_ulong_t)&sdhci_o2,
922 },
923
924 {
925 .vendor = PCI_VENDOR_ID_O2,
926 .device = PCI_DEVICE_ID_O2_8321,
927 .subvendor = PCI_ANY_ID,
928 .subdevice = PCI_ANY_ID,
929 .driver_data = (kernel_ulong_t)&sdhci_o2,
930 },
931
Adam Lee01acf692013-12-19 00:01:26 +0800932 {
933 .vendor = PCI_VENDOR_ID_O2,
934 .device = PCI_DEVICE_ID_O2_FUJIN2,
935 .subvendor = PCI_ANY_ID,
936 .subdevice = PCI_ANY_ID,
937 .driver_data = (kernel_ulong_t)&sdhci_o2,
938 },
939
940 {
941 .vendor = PCI_VENDOR_ID_O2,
942 .device = PCI_DEVICE_ID_O2_SDS0,
943 .subvendor = PCI_ANY_ID,
944 .subdevice = PCI_ANY_ID,
945 .driver_data = (kernel_ulong_t)&sdhci_o2,
946 },
947
948 {
949 .vendor = PCI_VENDOR_ID_O2,
950 .device = PCI_DEVICE_ID_O2_SDS1,
951 .subvendor = PCI_ANY_ID,
952 .subdevice = PCI_ANY_ID,
953 .driver_data = (kernel_ulong_t)&sdhci_o2,
954 },
955
956 {
957 .vendor = PCI_VENDOR_ID_O2,
958 .device = PCI_DEVICE_ID_O2_SEABIRD0,
959 .subvendor = PCI_ANY_ID,
960 .subdevice = PCI_ANY_ID,
961 .driver_data = (kernel_ulong_t)&sdhci_o2,
962 },
963
964 {
965 .vendor = PCI_VENDOR_ID_O2,
966 .device = PCI_DEVICE_ID_O2_SEABIRD1,
967 .subvendor = PCI_ANY_ID,
968 .subdevice = PCI_ANY_ID,
969 .driver_data = (kernel_ulong_t)&sdhci_o2,
970 },
971
Pierre Ossman22606402008-03-23 19:33:23 +0100972 { /* Generic SD host controller */
973 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
974 },
975
976 { /* end: all zeroes */ },
977};
978
979MODULE_DEVICE_TABLE(pci, pci_ids);
980
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +0100981/*****************************************************************************\
982 * *
983 * SDHCI core callbacks *
984 * *
985\*****************************************************************************/
986
987static int sdhci_pci_enable_dma(struct sdhci_host *host)
988{
989 struct sdhci_pci_slot *slot;
990 struct pci_dev *pdev;
991 int ret;
992
993 slot = sdhci_priv(host);
994 pdev = slot->chip->pdev;
995
996 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
997 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
Richard Röjforsa13abc72009-09-22 16:45:30 -0700998 (host->flags & SDHCI_USE_SDMA)) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +0100999 dev_warn(&pdev->dev, "Will use DMA mode even though HW "
1000 "doesn't fully claim to support it.\n");
1001 }
1002
Yang Hongyang284901a2009-04-06 19:01:15 -07001003 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001004 if (ret)
1005 return ret;
1006
1007 pci_set_master(pdev);
1008
1009 return 0;
1010}
1011
Sascha Hauer7bc088d2013-01-21 19:02:27 +08001012static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
Major Lee68077b02011-06-29 14:23:46 +03001013{
1014 u8 ctrl;
1015
1016 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
1017
1018 switch (width) {
1019 case MMC_BUS_WIDTH_8:
1020 ctrl |= SDHCI_CTRL_8BITBUS;
1021 ctrl &= ~SDHCI_CTRL_4BITBUS;
1022 break;
1023 case MMC_BUS_WIDTH_4:
1024 ctrl |= SDHCI_CTRL_4BITBUS;
1025 ctrl &= ~SDHCI_CTRL_8BITBUS;
1026 break;
1027 default:
1028 ctrl &= ~(SDHCI_CTRL_8BITBUS | SDHCI_CTRL_4BITBUS);
1029 break;
1030 }
1031
1032 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1033
1034 return 0;
1035}
1036
Adrian Hunterc9faff62013-06-13 11:50:26 +03001037static void sdhci_pci_gpio_hw_reset(struct sdhci_host *host)
Adrian Hunter0f201652011-08-29 16:42:13 +03001038{
1039 struct sdhci_pci_slot *slot = sdhci_priv(host);
1040 int rst_n_gpio = slot->rst_n_gpio;
1041
1042 if (!gpio_is_valid(rst_n_gpio))
1043 return;
1044 gpio_set_value_cansleep(rst_n_gpio, 0);
1045 /* For eMMC, minimum is 1us but give it 10us for good measure */
1046 udelay(10);
1047 gpio_set_value_cansleep(rst_n_gpio, 1);
1048 /* For eMMC, minimum is 200us but give it 300us for good measure */
1049 usleep_range(300, 1000);
1050}
1051
Adrian Hunterc9faff62013-06-13 11:50:26 +03001052static void sdhci_pci_hw_reset(struct sdhci_host *host)
1053{
1054 struct sdhci_pci_slot *slot = sdhci_priv(host);
1055
1056 if (slot->hw_reset)
1057 slot->hw_reset(host);
1058}
1059
Lars-Peter Clausenc9155682013-03-13 19:26:05 +01001060static const struct sdhci_ops sdhci_pci_ops = {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001061 .enable_dma = sdhci_pci_enable_dma,
Sascha Hauer7bc088d2013-01-21 19:02:27 +08001062 .platform_bus_width = sdhci_pci_bus_width,
Adrian Hunter0f201652011-08-29 16:42:13 +03001063 .hw_reset = sdhci_pci_hw_reset,
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001064};
1065
1066/*****************************************************************************\
1067 * *
1068 * Suspend/resume *
1069 * *
1070\*****************************************************************************/
1071
1072#ifdef CONFIG_PM
1073
Manuel Lauss29495aa2011-11-03 11:09:45 +01001074static int sdhci_pci_suspend(struct device *dev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001075{
Manuel Lauss29495aa2011-11-03 11:09:45 +01001076 struct pci_dev *pdev = to_pci_dev(dev);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001077 struct sdhci_pci_chip *chip;
1078 struct sdhci_pci_slot *slot;
Daniel Drake5f619702010-11-04 22:20:39 +00001079 mmc_pm_flag_t slot_pm_flags;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001080 mmc_pm_flag_t pm_flags = 0;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001081 int i, ret;
1082
1083 chip = pci_get_drvdata(pdev);
1084 if (!chip)
1085 return 0;
1086
Ameya Palandeb177bc92011-04-05 21:13:13 +03001087 for (i = 0; i < chip->num_slots; i++) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001088 slot = chip->slots[i];
1089 if (!slot)
1090 continue;
1091
Manuel Lauss29495aa2011-11-03 11:09:45 +01001092 ret = sdhci_suspend_host(slot->host);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001093
Axel Linb678b912011-12-03 15:28:05 +08001094 if (ret)
1095 goto err_pci_suspend;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001096
Daniel Drake5f619702010-11-04 22:20:39 +00001097 slot_pm_flags = slot->host->mmc->pm_flags;
1098 if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
1099 sdhci_enable_irq_wakeups(slot->host);
1100
1101 pm_flags |= slot_pm_flags;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001102 }
1103
Pierre Ossman44894282008-04-04 19:36:59 +02001104 if (chip->fixes && chip->fixes->suspend) {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001105 ret = chip->fixes->suspend(chip);
Axel Linb678b912011-12-03 15:28:05 +08001106 if (ret)
1107 goto err_pci_suspend;
Pierre Ossman44894282008-04-04 19:36:59 +02001108 }
1109
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001110 pci_save_state(pdev);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001111 if (pm_flags & MMC_PM_KEEP_POWER) {
Daniel Drake5f619702010-11-04 22:20:39 +00001112 if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
1113 pci_pme_active(pdev, true);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001114 pci_enable_wake(pdev, PCI_D3hot, 1);
Daniel Drake5f619702010-11-04 22:20:39 +00001115 }
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001116 pci_set_power_state(pdev, PCI_D3hot);
1117 } else {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001118 pci_enable_wake(pdev, PCI_D3hot, 0);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001119 pci_disable_device(pdev);
Manuel Lauss29495aa2011-11-03 11:09:45 +01001120 pci_set_power_state(pdev, PCI_D3hot);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001121 }
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001122
1123 return 0;
Axel Linb678b912011-12-03 15:28:05 +08001124
1125err_pci_suspend:
1126 while (--i >= 0)
1127 sdhci_resume_host(chip->slots[i]->host);
1128 return ret;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001129}
1130
Manuel Lauss29495aa2011-11-03 11:09:45 +01001131static int sdhci_pci_resume(struct device *dev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001132{
Manuel Lauss29495aa2011-11-03 11:09:45 +01001133 struct pci_dev *pdev = to_pci_dev(dev);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001134 struct sdhci_pci_chip *chip;
1135 struct sdhci_pci_slot *slot;
1136 int i, ret;
1137
1138 chip = pci_get_drvdata(pdev);
1139 if (!chip)
1140 return 0;
1141
1142 pci_set_power_state(pdev, PCI_D0);
1143 pci_restore_state(pdev);
1144 ret = pci_enable_device(pdev);
1145 if (ret)
1146 return ret;
1147
Pierre Ossman45211e22008-03-24 13:09:09 +01001148 if (chip->fixes && chip->fixes->resume) {
1149 ret = chip->fixes->resume(chip);
1150 if (ret)
1151 return ret;
1152 }
1153
Ameya Palandeb177bc92011-04-05 21:13:13 +03001154 for (i = 0; i < chip->num_slots; i++) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001155 slot = chip->slots[i];
1156 if (!slot)
1157 continue;
1158
1159 ret = sdhci_resume_host(slot->host);
1160 if (ret)
1161 return ret;
1162 }
1163
1164 return 0;
1165}
1166
1167#else /* CONFIG_PM */
1168
1169#define sdhci_pci_suspend NULL
1170#define sdhci_pci_resume NULL
1171
1172#endif /* CONFIG_PM */
1173
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001174#ifdef CONFIG_PM_RUNTIME
1175
1176static int sdhci_pci_runtime_suspend(struct device *dev)
1177{
1178 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
1179 struct sdhci_pci_chip *chip;
1180 struct sdhci_pci_slot *slot;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001181 int i, ret;
1182
1183 chip = pci_get_drvdata(pdev);
1184 if (!chip)
1185 return 0;
1186
1187 for (i = 0; i < chip->num_slots; i++) {
1188 slot = chip->slots[i];
1189 if (!slot)
1190 continue;
1191
1192 ret = sdhci_runtime_suspend_host(slot->host);
1193
Axel Linb678b912011-12-03 15:28:05 +08001194 if (ret)
1195 goto err_pci_runtime_suspend;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001196 }
1197
1198 if (chip->fixes && chip->fixes->suspend) {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001199 ret = chip->fixes->suspend(chip);
Axel Linb678b912011-12-03 15:28:05 +08001200 if (ret)
1201 goto err_pci_runtime_suspend;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001202 }
1203
1204 return 0;
Axel Linb678b912011-12-03 15:28:05 +08001205
1206err_pci_runtime_suspend:
1207 while (--i >= 0)
1208 sdhci_runtime_resume_host(chip->slots[i]->host);
1209 return ret;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001210}
1211
1212static int sdhci_pci_runtime_resume(struct device *dev)
1213{
1214 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
1215 struct sdhci_pci_chip *chip;
1216 struct sdhci_pci_slot *slot;
1217 int i, ret;
1218
1219 chip = pci_get_drvdata(pdev);
1220 if (!chip)
1221 return 0;
1222
1223 if (chip->fixes && chip->fixes->resume) {
1224 ret = chip->fixes->resume(chip);
1225 if (ret)
1226 return ret;
1227 }
1228
1229 for (i = 0; i < chip->num_slots; i++) {
1230 slot = chip->slots[i];
1231 if (!slot)
1232 continue;
1233
1234 ret = sdhci_runtime_resume_host(slot->host);
1235 if (ret)
1236 return ret;
1237 }
1238
1239 return 0;
1240}
1241
1242static int sdhci_pci_runtime_idle(struct device *dev)
1243{
1244 return 0;
1245}
1246
1247#else
1248
1249#define sdhci_pci_runtime_suspend NULL
1250#define sdhci_pci_runtime_resume NULL
1251#define sdhci_pci_runtime_idle NULL
1252
1253#endif
1254
1255static const struct dev_pm_ops sdhci_pci_pm_ops = {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001256 .suspend = sdhci_pci_suspend,
1257 .resume = sdhci_pci_resume,
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001258 .runtime_suspend = sdhci_pci_runtime_suspend,
1259 .runtime_resume = sdhci_pci_runtime_resume,
1260 .runtime_idle = sdhci_pci_runtime_idle,
1261};
1262
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001263/*****************************************************************************\
1264 * *
1265 * Device probing/removal *
1266 * *
1267\*****************************************************************************/
1268
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001269static struct sdhci_pci_slot *sdhci_pci_probe_slot(
Adrian Hunter52c506f2011-12-27 15:48:43 +02001270 struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
1271 int slotno)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001272{
1273 struct sdhci_pci_slot *slot;
1274 struct sdhci_host *host;
Adrian Hunter52c506f2011-12-27 15:48:43 +02001275 int ret, bar = first_bar + slotno;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001276
1277 if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
1278 dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
1279 return ERR_PTR(-ENODEV);
1280 }
1281
Adrian Hunter90b3e6c2012-10-18 09:54:31 +03001282 if (pci_resource_len(pdev, bar) < 0x100) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001283 dev_err(&pdev->dev, "Invalid iomem size. You may "
1284 "experience problems.\n");
1285 }
1286
1287 if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
1288 dev_err(&pdev->dev, "Vendor specific interface. Aborting.\n");
1289 return ERR_PTR(-ENODEV);
1290 }
1291
1292 if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) {
1293 dev_err(&pdev->dev, "Unknown interface. Aborting.\n");
1294 return ERR_PTR(-ENODEV);
1295 }
1296
1297 host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot));
1298 if (IS_ERR(host)) {
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001299 dev_err(&pdev->dev, "cannot allocate host\n");
Julia Lawalldc0fd7b2010-05-26 14:42:11 -07001300 return ERR_CAST(host);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001301 }
1302
1303 slot = sdhci_priv(host);
1304
1305 slot->chip = chip;
1306 slot->host = host;
1307 slot->pci_bar = bar;
Adrian Hunter0f201652011-08-29 16:42:13 +03001308 slot->rst_n_gpio = -EINVAL;
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001309 slot->cd_gpio = -EINVAL;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001310
Adrian Hunter52c506f2011-12-27 15:48:43 +02001311 /* Retrieve platform data if there is any */
1312 if (*sdhci_pci_get_data)
1313 slot->data = sdhci_pci_get_data(pdev, slotno);
1314
1315 if (slot->data) {
1316 if (slot->data->setup) {
1317 ret = slot->data->setup(slot->data);
1318 if (ret) {
1319 dev_err(&pdev->dev, "platform setup failed\n");
1320 goto free;
1321 }
1322 }
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001323 slot->rst_n_gpio = slot->data->rst_n_gpio;
1324 slot->cd_gpio = slot->data->cd_gpio;
Adrian Hunter52c506f2011-12-27 15:48:43 +02001325 }
1326
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001327 host->hw_name = "PCI";
1328 host->ops = &sdhci_pci_ops;
1329 host->quirks = chip->quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +02001330 host->quirks2 = chip->quirks2;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001331
1332 host->irq = pdev->irq;
1333
1334 ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
1335 if (ret) {
1336 dev_err(&pdev->dev, "cannot request region\n");
Adrian Hunter52c506f2011-12-27 15:48:43 +02001337 goto cleanup;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001338 }
1339
Arjan van de Ven092f82e2008-09-28 16:15:56 -07001340 host->ioaddr = pci_ioremap_bar(pdev, bar);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001341 if (!host->ioaddr) {
1342 dev_err(&pdev->dev, "failed to remap registers\n");
Chris Ball9fdcdbb2011-03-29 00:46:12 -04001343 ret = -ENOMEM;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001344 goto release;
1345 }
1346
Pierre Ossman44894282008-04-04 19:36:59 +02001347 if (chip->fixes && chip->fixes->probe_slot) {
1348 ret = chip->fixes->probe_slot(slot);
1349 if (ret)
1350 goto unmap;
1351 }
1352
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001353 if (gpio_is_valid(slot->rst_n_gpio)) {
1354 if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
1355 gpio_direction_output(slot->rst_n_gpio, 1);
1356 slot->host->mmc->caps |= MMC_CAP_HW_RESET;
Adrian Hunterc9faff62013-06-13 11:50:26 +03001357 slot->hw_reset = sdhci_pci_gpio_hw_reset;
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001358 } else {
1359 dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
1360 slot->rst_n_gpio = -EINVAL;
1361 }
1362 }
1363
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001364 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
Aaron Lueed222a2013-03-05 11:24:52 +08001365 host->mmc->slotno = slotno;
Adrian Huntera08b17b2013-04-15 11:27:25 -04001366 host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001367
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001368 ret = sdhci_add_host(host);
1369 if (ret)
Pierre Ossman44894282008-04-04 19:36:59 +02001370 goto remove;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001371
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001372 sdhci_pci_add_own_cd(slot);
1373
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001374 return slot;
1375
Pierre Ossman44894282008-04-04 19:36:59 +02001376remove:
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001377 if (gpio_is_valid(slot->rst_n_gpio))
1378 gpio_free(slot->rst_n_gpio);
1379
Pierre Ossman44894282008-04-04 19:36:59 +02001380 if (chip->fixes && chip->fixes->remove_slot)
Pierre Ossman1e728592008-04-16 19:13:13 +02001381 chip->fixes->remove_slot(slot, 0);
Pierre Ossman44894282008-04-04 19:36:59 +02001382
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001383unmap:
1384 iounmap(host->ioaddr);
1385
1386release:
1387 pci_release_region(pdev, bar);
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001388
Adrian Hunter52c506f2011-12-27 15:48:43 +02001389cleanup:
1390 if (slot->data && slot->data->cleanup)
1391 slot->data->cleanup(slot->data);
1392
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001393free:
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001394 sdhci_free_host(host);
1395
1396 return ERR_PTR(ret);
1397}
1398
1399static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
1400{
Pierre Ossman1e728592008-04-16 19:13:13 +02001401 int dead;
1402 u32 scratch;
1403
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001404 sdhci_pci_remove_own_cd(slot);
1405
Pierre Ossman1e728592008-04-16 19:13:13 +02001406 dead = 0;
1407 scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
1408 if (scratch == (u32)-1)
1409 dead = 1;
1410
1411 sdhci_remove_host(slot->host, dead);
Pierre Ossman44894282008-04-04 19:36:59 +02001412
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001413 if (gpio_is_valid(slot->rst_n_gpio))
1414 gpio_free(slot->rst_n_gpio);
1415
Pierre Ossman44894282008-04-04 19:36:59 +02001416 if (slot->chip->fixes && slot->chip->fixes->remove_slot)
Pierre Ossman1e728592008-04-16 19:13:13 +02001417 slot->chip->fixes->remove_slot(slot, dead);
Pierre Ossman44894282008-04-04 19:36:59 +02001418
Adrian Hunter52c506f2011-12-27 15:48:43 +02001419 if (slot->data && slot->data->cleanup)
1420 slot->data->cleanup(slot->data);
1421
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001422 pci_release_region(slot->chip->pdev, slot->pci_bar);
Pierre Ossman44894282008-04-04 19:36:59 +02001423
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001424 sdhci_free_host(slot->host);
1425}
1426
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001427static void sdhci_pci_runtime_pm_allow(struct device *dev)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001428{
1429 pm_runtime_put_noidle(dev);
1430 pm_runtime_allow(dev);
1431 pm_runtime_set_autosuspend_delay(dev, 50);
1432 pm_runtime_use_autosuspend(dev);
1433 pm_suspend_ignore_children(dev, 1);
1434}
1435
Bill Pemberton6e0ee712012-11-19 13:26:03 -05001436static void sdhci_pci_runtime_pm_forbid(struct device *dev)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001437{
1438 pm_runtime_forbid(dev);
1439 pm_runtime_get_noresume(dev);
1440}
1441
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001442static int sdhci_pci_probe(struct pci_dev *pdev,
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001443 const struct pci_device_id *ent)
1444{
1445 struct sdhci_pci_chip *chip;
1446 struct sdhci_pci_slot *slot;
1447
Sergei Shtylyovcf5e23e2011-03-17 16:46:17 -04001448 u8 slots, first_bar;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001449 int ret, i;
1450
1451 BUG_ON(pdev == NULL);
1452 BUG_ON(ent == NULL);
1453
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001454 dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n",
Sergei Shtylyovcf5e23e2011-03-17 16:46:17 -04001455 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001456
1457 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
1458 if (ret)
1459 return ret;
1460
1461 slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
1462 dev_dbg(&pdev->dev, "found %d slot(s)\n", slots);
1463 if (slots == 0)
1464 return -ENODEV;
1465
1466 BUG_ON(slots > MAX_SLOTS);
1467
1468 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar);
1469 if (ret)
1470 return ret;
1471
1472 first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK;
1473
1474 if (first_bar > 5) {
1475 dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n");
1476 return -ENODEV;
1477 }
1478
1479 ret = pci_enable_device(pdev);
1480 if (ret)
1481 return ret;
1482
1483 chip = kzalloc(sizeof(struct sdhci_pci_chip), GFP_KERNEL);
1484 if (!chip) {
1485 ret = -ENOMEM;
1486 goto err;
1487 }
1488
1489 chip->pdev = pdev;
Ameya Palandeb177bc92011-04-05 21:13:13 +03001490 chip->fixes = (const struct sdhci_pci_fixes *)ent->driver_data;
Adrian Hunterc43fd772011-10-17 10:52:44 +03001491 if (chip->fixes) {
Pierre Ossman22606402008-03-23 19:33:23 +01001492 chip->quirks = chip->fixes->quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +02001493 chip->quirks2 = chip->fixes->quirks2;
Adrian Hunterc43fd772011-10-17 10:52:44 +03001494 chip->allow_runtime_pm = chip->fixes->allow_runtime_pm;
1495 }
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001496 chip->num_slots = slots;
1497
1498 pci_set_drvdata(pdev, chip);
1499
Pierre Ossman22606402008-03-23 19:33:23 +01001500 if (chip->fixes && chip->fixes->probe) {
1501 ret = chip->fixes->probe(chip);
1502 if (ret)
1503 goto free;
1504 }
1505
Alan Cox225d85f2010-10-04 15:24:21 +01001506 slots = chip->num_slots; /* Quirk may have changed this */
1507
Ameya Palandeb177bc92011-04-05 21:13:13 +03001508 for (i = 0; i < slots; i++) {
Adrian Hunter52c506f2011-12-27 15:48:43 +02001509 slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001510 if (IS_ERR(slot)) {
Ameya Palandeb177bc92011-04-05 21:13:13 +03001511 for (i--; i >= 0; i--)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001512 sdhci_pci_remove_slot(chip->slots[i]);
1513 ret = PTR_ERR(slot);
1514 goto free;
1515 }
1516
1517 chip->slots[i] = slot;
1518 }
1519
Adrian Hunterc43fd772011-10-17 10:52:44 +03001520 if (chip->allow_runtime_pm)
1521 sdhci_pci_runtime_pm_allow(&pdev->dev);
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001522
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001523 return 0;
1524
1525free:
1526 pci_set_drvdata(pdev, NULL);
1527 kfree(chip);
1528
1529err:
1530 pci_disable_device(pdev);
1531 return ret;
1532}
1533
Bill Pemberton6e0ee712012-11-19 13:26:03 -05001534static void sdhci_pci_remove(struct pci_dev *pdev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001535{
1536 int i;
1537 struct sdhci_pci_chip *chip;
1538
1539 chip = pci_get_drvdata(pdev);
1540
1541 if (chip) {
Adrian Hunterc43fd772011-10-17 10:52:44 +03001542 if (chip->allow_runtime_pm)
1543 sdhci_pci_runtime_pm_forbid(&pdev->dev);
1544
Ameya Palandeb177bc92011-04-05 21:13:13 +03001545 for (i = 0; i < chip->num_slots; i++)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001546 sdhci_pci_remove_slot(chip->slots[i]);
1547
1548 pci_set_drvdata(pdev, NULL);
1549 kfree(chip);
1550 }
1551
1552 pci_disable_device(pdev);
1553}
1554
1555static struct pci_driver sdhci_driver = {
Ameya Palandeb177bc92011-04-05 21:13:13 +03001556 .name = "sdhci-pci",
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001557 .id_table = pci_ids,
Ameya Palandeb177bc92011-04-05 21:13:13 +03001558 .probe = sdhci_pci_probe,
Bill Pemberton0433c142012-11-19 13:20:26 -05001559 .remove = sdhci_pci_remove,
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001560 .driver = {
1561 .pm = &sdhci_pci_pm_ops
1562 },
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001563};
1564
Sachin Kamatacc69642012-08-27 11:57:02 +05301565module_pci_driver(sdhci_driver);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001566
Pierre Ossman32710e82009-04-08 20:14:54 +02001567MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001568MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
1569MODULE_LICENSE("GPL");