blob: 611331a39fe51dd799762db4cceaf108dd1bacc9 [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"
30
31/*
Alexander Stein296e0b02012-03-14 08:38:58 +010032 * PCI device IDs
33 */
34#define PCI_DEVICE_ID_INTEL_PCH_SDIO0 0x8809
35#define PCI_DEVICE_ID_INTEL_PCH_SDIO1 0x880a
Adrian Hunter728ef3d2013-04-26 11:27:23 +030036#define PCI_DEVICE_ID_INTEL_BYT_EMMC 0x0f14
37#define PCI_DEVICE_ID_INTEL_BYT_SDIO 0x0f15
38#define PCI_DEVICE_ID_INTEL_BYT_SD 0x0f16
Alexander Stein296e0b02012-03-14 08:38:58 +010039
40/*
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010041 * PCI registers
42 */
43
44#define PCI_SDHCI_IFPIO 0x00
45#define PCI_SDHCI_IFDMA 0x01
46#define PCI_SDHCI_IFVENDOR 0x02
47
48#define PCI_SLOT_INFO 0x40 /* 8 bits */
49#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7)
50#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07
51
52#define MAX_SLOTS 8
53
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010054struct sdhci_pci_chip;
Pierre Ossman44894282008-04-04 19:36:59 +020055struct sdhci_pci_slot;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010056
Pierre Ossman22606402008-03-23 19:33:23 +010057struct sdhci_pci_fixes {
58 unsigned int quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +020059 unsigned int quirks2;
Adrian Hunterc43fd772011-10-17 10:52:44 +030060 bool allow_runtime_pm;
Pierre Ossman22606402008-03-23 19:33:23 +010061
Ameya Palandeb177bc92011-04-05 21:13:13 +030062 int (*probe) (struct sdhci_pci_chip *);
Pierre Ossman45211e22008-03-24 13:09:09 +010063
Ameya Palandeb177bc92011-04-05 21:13:13 +030064 int (*probe_slot) (struct sdhci_pci_slot *);
65 void (*remove_slot) (struct sdhci_pci_slot *, int);
Pierre Ossman44894282008-04-04 19:36:59 +020066
Manuel Lauss29495aa2011-11-03 11:09:45 +010067 int (*suspend) (struct sdhci_pci_chip *);
Ameya Palandeb177bc92011-04-05 21:13:13 +030068 int (*resume) (struct sdhci_pci_chip *);
Pierre Ossman22606402008-03-23 19:33:23 +010069};
70
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010071struct sdhci_pci_slot {
72 struct sdhci_pci_chip *chip;
73 struct sdhci_host *host;
Adrian Hunter52c506f2011-12-27 15:48:43 +020074 struct sdhci_pci_data *data;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010075
76 int pci_bar;
Adrian Hunter0f201652011-08-29 16:42:13 +030077 int rst_n_gpio;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +030078 int cd_gpio;
79 int cd_irq;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010080};
81
82struct sdhci_pci_chip {
83 struct pci_dev *pdev;
Pierre Ossman22606402008-03-23 19:33:23 +010084
85 unsigned int quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +020086 unsigned int quirks2;
Adrian Hunterc43fd772011-10-17 10:52:44 +030087 bool allow_runtime_pm;
Pierre Ossman22606402008-03-23 19:33:23 +010088 const struct sdhci_pci_fixes *fixes;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +010089
90 int num_slots; /* Slots on controller */
91 struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */
92};
93
Pierre Ossman22606402008-03-23 19:33:23 +010094
95/*****************************************************************************\
96 * *
97 * Hardware specific quirk handling *
98 * *
99\*****************************************************************************/
100
101static int ricoh_probe(struct sdhci_pci_chip *chip)
102{
Chris Ballc99436f2009-09-22 16:45:22 -0700103 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
104 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
Pierre Ossman22606402008-03-23 19:33:23 +0100105 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700106 return 0;
107}
Pierre Ossman22606402008-03-23 19:33:23 +0100108
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700109static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot)
110{
111 slot->host->caps =
112 ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT)
113 & SDHCI_TIMEOUT_CLK_MASK) |
114
115 ((0x21 << SDHCI_CLOCK_BASE_SHIFT)
116 & SDHCI_CLOCK_BASE_MASK) |
117
118 SDHCI_TIMEOUT_CLK_UNIT |
119 SDHCI_CAN_VDD_330 |
Madhvapathi Sriram1a1f1f02012-10-15 04:47:30 +0000120 SDHCI_CAN_DO_HISPD |
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700121 SDHCI_CAN_DO_SDMA;
122 return 0;
123}
124
125static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
126{
127 /* Apply a delay to allow controller to settle */
128 /* Otherwise it becomes confused if card state changed
129 during suspend */
130 msleep(500);
Pierre Ossman22606402008-03-23 19:33:23 +0100131 return 0;
132}
133
134static const struct sdhci_pci_fixes sdhci_ricoh = {
135 .probe = ricoh_probe,
Vasily Khoruzhick84938292010-03-05 13:43:46 -0800136 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
137 SDHCI_QUIRK_FORCE_DMA |
138 SDHCI_QUIRK_CLOCK_BEFORE_RESET,
Pierre Ossman22606402008-03-23 19:33:23 +0100139};
140
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700141static const struct sdhci_pci_fixes sdhci_ricoh_mmc = {
142 .probe_slot = ricoh_mmc_probe_slot,
143 .resume = ricoh_mmc_resume,
144 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
145 SDHCI_QUIRK_CLOCK_BEFORE_RESET |
146 SDHCI_QUIRK_NO_CARD_NO_RESET |
147 SDHCI_QUIRK_MISSING_CAPS
148};
149
Pierre Ossman22606402008-03-23 19:33:23 +0100150static const struct sdhci_pci_fixes sdhci_ene_712 = {
151 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
152 SDHCI_QUIRK_BROKEN_DMA,
153};
154
155static const struct sdhci_pci_fixes sdhci_ene_714 = {
156 .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE |
157 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS |
158 SDHCI_QUIRK_BROKEN_DMA,
159};
160
161static const struct sdhci_pci_fixes sdhci_cafe = {
162 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
Andres Salomona0874892009-03-02 21:48:20 +0100163 SDHCI_QUIRK_NO_BUSY_IRQ |
Daniel Drake55fc05b2012-07-03 23:13:39 +0100164 SDHCI_QUIRK_BROKEN_CARD_DETECTION |
Pierre Ossmanee53ab52008-07-05 00:25:15 +0200165 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
Pierre Ossman22606402008-03-23 19:33:23 +0100166};
167
Major Lee68077b02011-06-29 14:23:46 +0300168static int mrst_hc_probe_slot(struct sdhci_pci_slot *slot)
169{
170 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA;
171 return 0;
172}
173
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100174/*
175 * ADMA operation is disabled for Moorestown platform due to
176 * hardware bugs.
177 */
Jacob Pan35ac6f02010-11-09 13:57:29 +0000178static int mrst_hc_probe(struct sdhci_pci_chip *chip)
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100179{
180 /*
Jacob Pan35ac6f02010-11-09 13:57:29 +0000181 * slots number is fixed here for MRST as SDIO3/5 are never used and
182 * have hardware bugs.
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100183 */
184 chip->num_slots = 1;
185 return 0;
186}
187
Alexander Stein296e0b02012-03-14 08:38:58 +0100188static int pch_hc_probe_slot(struct sdhci_pci_slot *slot)
189{
190 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA;
191 return 0;
192}
193
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300194#ifdef CONFIG_PM_RUNTIME
195
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200196static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300197{
198 struct sdhci_pci_slot *slot = dev_id;
199 struct sdhci_host *host = slot->host;
200
201 mmc_detect_change(host->mmc, msecs_to_jiffies(200));
202 return IRQ_HANDLED;
203}
204
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200205static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300206{
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200207 int err, irq, gpio = slot->cd_gpio;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300208
209 slot->cd_gpio = -EINVAL;
210 slot->cd_irq = -EINVAL;
211
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200212 if (!gpio_is_valid(gpio))
213 return;
214
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300215 err = gpio_request(gpio, "sd_cd");
216 if (err < 0)
217 goto out;
218
219 err = gpio_direction_input(gpio);
220 if (err < 0)
221 goto out_free;
222
223 irq = gpio_to_irq(gpio);
224 if (irq < 0)
225 goto out_free;
226
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200227 err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING |
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300228 IRQF_TRIGGER_FALLING, "sd_cd", slot);
229 if (err)
230 goto out_free;
231
232 slot->cd_gpio = gpio;
233 slot->cd_irq = irq;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300234
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200235 return;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300236
237out_free:
238 gpio_free(gpio);
239out:
240 dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300241}
242
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200243static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300244{
245 if (slot->cd_irq >= 0)
246 free_irq(slot->cd_irq, slot);
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200247 if (gpio_is_valid(slot->cd_gpio))
248 gpio_free(slot->cd_gpio);
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300249}
250
251#else
252
Adrian Hunterc5e027a2011-12-27 15:48:44 +0200253static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
254{
255}
256
257static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
258{
259}
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300260
261#endif
262
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300263static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
264{
Adrian Hunter66fd8ad2011-10-03 15:33:34 +0300265 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
Adrian Hunterda721cf2012-02-07 14:48:53 +0200266 slot->host->mmc->caps2 |= MMC_CAP2_BOOTPART_NOACC |
267 MMC_CAP2_HC_ERASE_SZ;
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300268 return 0;
269}
270
Adrian Hunter93933502011-12-27 15:48:47 +0200271static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
272{
Adrian Hunter012e4672012-01-30 14:27:18 +0200273 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
Adrian Hunter93933502011-12-27 15:48:47 +0200274 return 0;
275}
276
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100277static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
278 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
Major Lee68077b02011-06-29 14:23:46 +0300279 .probe_slot = mrst_hc_probe_slot,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100280};
281
Jacob Pan35ac6f02010-11-09 13:57:29 +0000282static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100283 .quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_NO_HISPD_BIT,
Jacob Pan35ac6f02010-11-09 13:57:29 +0000284 .probe = mrst_hc_probe,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100285};
286
Xiaochen Shen29229052010-10-04 15:24:52 +0100287static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
288 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300289 .allow_runtime_pm = true,
Xiaochen Shen29229052010-10-04 15:24:52 +0100290};
291
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300292static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
Xiaochen Shen29229052010-10-04 15:24:52 +0100293 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterf3c55a72012-02-07 14:48:55 +0200294 .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300295 .allow_runtime_pm = true,
Adrian Hunter93933502011-12-27 15:48:47 +0200296 .probe_slot = mfd_sdio_probe_slot,
Xiaochen Shen29229052010-10-04 15:24:52 +0100297};
298
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300299static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
300 .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
Adrian Hunterc43fd772011-10-17 10:52:44 +0300301 .allow_runtime_pm = true,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300302 .probe_slot = mfd_emmc_probe_slot,
303};
304
Alexander Stein296e0b02012-03-14 08:38:58 +0100305static const struct sdhci_pci_fixes sdhci_intel_pch_sdio = {
306 .quirks = SDHCI_QUIRK_BROKEN_ADMA,
307 .probe_slot = pch_hc_probe_slot,
308};
309
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300310static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
311{
312 slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
313 slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
314 return 0;
315}
316
317static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
318{
319 slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE;
320 return 0;
321}
322
323static const struct sdhci_pci_fixes sdhci_intel_byt_emmc = {
324 .allow_runtime_pm = true,
325 .probe_slot = byt_emmc_probe_slot,
326};
327
328static const struct sdhci_pci_fixes sdhci_intel_byt_sdio = {
329 .quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
330 .allow_runtime_pm = true,
331 .probe_slot = byt_sdio_probe_slot,
332};
333
334static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
Adrian Hunter7396e312013-05-06 12:17:34 +0300335 .quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON,
336 .allow_runtime_pm = true,
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300337};
338
Jennifer Li26daa1e2010-11-17 23:01:59 -0500339/* O2Micro extra registers */
340#define O2_SD_LOCK_WP 0xD3
341#define O2_SD_MULTI_VCC3V 0xEE
342#define O2_SD_CLKREQ 0xEC
343#define O2_SD_CAPS 0xE0
344#define O2_SD_ADMA1 0xE2
345#define O2_SD_ADMA2 0xE7
346#define O2_SD_INF_MOD 0xF1
347
348static int o2_probe(struct sdhci_pci_chip *chip)
349{
350 int ret;
351 u8 scratch;
352
353 switch (chip->pdev->device) {
354 case PCI_DEVICE_ID_O2_8220:
355 case PCI_DEVICE_ID_O2_8221:
356 case PCI_DEVICE_ID_O2_8320:
357 case PCI_DEVICE_ID_O2_8321:
358 /* This extra setup is required due to broken ADMA. */
359 ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
360 if (ret)
361 return ret;
362 scratch &= 0x7f;
363 pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
364
365 /* Set Multi 3 to VCC3V# */
366 pci_write_config_byte(chip->pdev, O2_SD_MULTI_VCC3V, 0x08);
367
368 /* Disable CLK_REQ# support after media DET */
369 ret = pci_read_config_byte(chip->pdev, O2_SD_CLKREQ, &scratch);
370 if (ret)
371 return ret;
372 scratch |= 0x20;
373 pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
374
375 /* Choose capabilities, enable SDMA. We have to write 0x01
376 * to the capabilities register first to unlock it.
377 */
378 ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
379 if (ret)
380 return ret;
381 scratch |= 0x01;
382 pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
383 pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
384
385 /* Disable ADMA1/2 */
386 pci_write_config_byte(chip->pdev, O2_SD_ADMA1, 0x39);
387 pci_write_config_byte(chip->pdev, O2_SD_ADMA2, 0x08);
388
389 /* Disable the infinite transfer mode */
390 ret = pci_read_config_byte(chip->pdev, O2_SD_INF_MOD, &scratch);
391 if (ret)
392 return ret;
393 scratch |= 0x08;
394 pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
395
396 /* Lock WP */
397 ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
398 if (ret)
399 return ret;
400 scratch |= 0x80;
401 pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
402 }
403
404 return 0;
405}
406
Pierre Ossman45211e22008-03-24 13:09:09 +0100407static int jmicron_pmos(struct sdhci_pci_chip *chip, int on)
408{
409 u8 scratch;
410 int ret;
411
412 ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch);
413 if (ret)
414 return ret;
415
416 /*
417 * Turn PMOS on [bit 0], set over current detection to 2.4 V
418 * [bit 1:2] and enable over current debouncing [bit 6].
419 */
420 if (on)
421 scratch |= 0x47;
422 else
423 scratch &= ~0x47;
424
425 ret = pci_write_config_byte(chip->pdev, 0xAE, scratch);
426 if (ret)
427 return ret;
428
429 return 0;
430}
431
432static int jmicron_probe(struct sdhci_pci_chip *chip)
433{
434 int ret;
Takashi Iwai8f230f42010-12-08 10:04:30 +0100435 u16 mmcdev = 0;
Pierre Ossman45211e22008-03-24 13:09:09 +0100436
Pierre Ossman93fc48c2008-06-28 18:21:41 +0200437 if (chip->pdev->revision == 0) {
438 chip->quirks |= SDHCI_QUIRK_32BIT_DMA_ADDR |
439 SDHCI_QUIRK_32BIT_DMA_SIZE |
Pierre Ossman2134a922008-06-28 18:28:51 +0200440 SDHCI_QUIRK_32BIT_ADMA_SIZE |
Pierre Ossman4a3cba32008-07-29 00:11:16 +0200441 SDHCI_QUIRK_RESET_AFTER_REQUEST |
Pierre Ossman86a6a872009-02-02 21:13:49 +0100442 SDHCI_QUIRK_BROKEN_SMALL_PIO;
Pierre Ossman93fc48c2008-06-28 18:21:41 +0200443 }
444
Pierre Ossman45211e22008-03-24 13:09:09 +0100445 /*
Pierre Ossman44894282008-04-04 19:36:59 +0200446 * JMicron chips can have two interfaces to the same hardware
447 * in order to work around limitations in Microsoft's driver.
448 * We need to make sure we only bind to one of them.
449 *
450 * This code assumes two things:
451 *
452 * 1. The PCI code adds subfunctions in order.
453 *
454 * 2. The MMC interface has a lower subfunction number
455 * than the SD interface.
456 */
Takashi Iwai8f230f42010-12-08 10:04:30 +0100457 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_SD)
458 mmcdev = PCI_DEVICE_ID_JMICRON_JMB38X_MMC;
459 else if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD)
460 mmcdev = PCI_DEVICE_ID_JMICRON_JMB388_ESD;
461
462 if (mmcdev) {
Pierre Ossman44894282008-04-04 19:36:59 +0200463 struct pci_dev *sd_dev;
464
465 sd_dev = NULL;
466 while ((sd_dev = pci_get_device(PCI_VENDOR_ID_JMICRON,
Takashi Iwai8f230f42010-12-08 10:04:30 +0100467 mmcdev, sd_dev)) != NULL) {
Pierre Ossman44894282008-04-04 19:36:59 +0200468 if ((PCI_SLOT(chip->pdev->devfn) ==
469 PCI_SLOT(sd_dev->devfn)) &&
470 (chip->pdev->bus == sd_dev->bus))
471 break;
472 }
473
474 if (sd_dev) {
475 pci_dev_put(sd_dev);
476 dev_info(&chip->pdev->dev, "Refusing to bind to "
477 "secondary interface.\n");
478 return -ENODEV;
479 }
480 }
481
482 /*
Pierre Ossman45211e22008-03-24 13:09:09 +0100483 * JMicron chips need a bit of a nudge to enable the power
484 * output pins.
485 */
486 ret = jmicron_pmos(chip, 1);
487 if (ret) {
488 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
489 return ret;
490 }
491
Takashi Iwai82b0e232011-04-21 20:26:38 +0200492 /* quirk for unsable RO-detection on JM388 chips */
493 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
494 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
495 chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT;
496
Pierre Ossman45211e22008-03-24 13:09:09 +0100497 return 0;
498}
499
Pierre Ossman44894282008-04-04 19:36:59 +0200500static void jmicron_enable_mmc(struct sdhci_host *host, int on)
501{
502 u8 scratch;
503
504 scratch = readb(host->ioaddr + 0xC0);
505
506 if (on)
507 scratch |= 0x01;
508 else
509 scratch &= ~0x01;
510
511 writeb(scratch, host->ioaddr + 0xC0);
512}
513
514static int jmicron_probe_slot(struct sdhci_pci_slot *slot)
515{
Pierre Ossman2134a922008-06-28 18:28:51 +0200516 if (slot->chip->pdev->revision == 0) {
517 u16 version;
518
519 version = readl(slot->host->ioaddr + SDHCI_HOST_VERSION);
520 version = (version & SDHCI_VENDOR_VER_MASK) >>
521 SDHCI_VENDOR_VER_SHIFT;
522
523 /*
524 * Older versions of the chip have lots of nasty glitches
525 * in the ADMA engine. It's best just to avoid it
526 * completely.
527 */
528 if (version < 0xAC)
529 slot->host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
530 }
531
Takashi Iwai8f230f42010-12-08 10:04:30 +0100532 /* JM388 MMC doesn't support 1.8V while SD supports it */
533 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
534 slot->host->ocr_avail_sd = MMC_VDD_32_33 | MMC_VDD_33_34 |
535 MMC_VDD_29_30 | MMC_VDD_30_31 |
536 MMC_VDD_165_195; /* allow 1.8V */
537 slot->host->ocr_avail_mmc = MMC_VDD_32_33 | MMC_VDD_33_34 |
538 MMC_VDD_29_30 | MMC_VDD_30_31; /* no 1.8V for MMC */
539 }
540
Pierre Ossman44894282008-04-04 19:36:59 +0200541 /*
542 * The secondary interface requires a bit set to get the
543 * interrupts.
544 */
Takashi Iwai8f230f42010-12-08 10:04:30 +0100545 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
546 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
Pierre Ossman44894282008-04-04 19:36:59 +0200547 jmicron_enable_mmc(slot->host, 1);
548
Takashi Iwaid75c1082010-12-16 17:54:14 +0100549 slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST;
550
Pierre Ossman44894282008-04-04 19:36:59 +0200551 return 0;
552}
553
Pierre Ossman1e728592008-04-16 19:13:13 +0200554static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead)
Pierre Ossman44894282008-04-04 19:36:59 +0200555{
Pierre Ossman1e728592008-04-16 19:13:13 +0200556 if (dead)
557 return;
558
Takashi Iwai8f230f42010-12-08 10:04:30 +0100559 if (slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
560 slot->chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
Pierre Ossman44894282008-04-04 19:36:59 +0200561 jmicron_enable_mmc(slot->host, 0);
562}
563
Manuel Lauss29495aa2011-11-03 11:09:45 +0100564static int jmicron_suspend(struct sdhci_pci_chip *chip)
Pierre Ossman44894282008-04-04 19:36:59 +0200565{
566 int i;
567
Takashi Iwai8f230f42010-12-08 10:04:30 +0100568 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
569 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
Ameya Palandeb177bc92011-04-05 21:13:13 +0300570 for (i = 0; i < chip->num_slots; i++)
Pierre Ossman44894282008-04-04 19:36:59 +0200571 jmicron_enable_mmc(chip->slots[i]->host, 0);
572 }
573
574 return 0;
575}
576
Pierre Ossman45211e22008-03-24 13:09:09 +0100577static int jmicron_resume(struct sdhci_pci_chip *chip)
578{
Pierre Ossman44894282008-04-04 19:36:59 +0200579 int ret, i;
580
Takashi Iwai8f230f42010-12-08 10:04:30 +0100581 if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
582 chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
Ameya Palandeb177bc92011-04-05 21:13:13 +0300583 for (i = 0; i < chip->num_slots; i++)
Pierre Ossman44894282008-04-04 19:36:59 +0200584 jmicron_enable_mmc(chip->slots[i]->host, 1);
585 }
Pierre Ossman45211e22008-03-24 13:09:09 +0100586
587 ret = jmicron_pmos(chip, 1);
588 if (ret) {
589 dev_err(&chip->pdev->dev, "Failure enabling card power\n");
590 return ret;
591 }
592
593 return 0;
594}
595
Jennifer Li26daa1e2010-11-17 23:01:59 -0500596static const struct sdhci_pci_fixes sdhci_o2 = {
597 .probe = o2_probe,
598};
599
Pierre Ossman22606402008-03-23 19:33:23 +0100600static const struct sdhci_pci_fixes sdhci_jmicron = {
Pierre Ossman45211e22008-03-24 13:09:09 +0100601 .probe = jmicron_probe,
602
Pierre Ossman44894282008-04-04 19:36:59 +0200603 .probe_slot = jmicron_probe_slot,
604 .remove_slot = jmicron_remove_slot,
605
606 .suspend = jmicron_suspend,
Pierre Ossman45211e22008-03-24 13:09:09 +0100607 .resume = jmicron_resume,
Pierre Ossman22606402008-03-23 19:33:23 +0100608};
609
Nicolas Pitrea7a61862009-12-14 18:01:26 -0800610/* SysKonnect CardBus2SDIO extra registers */
611#define SYSKT_CTRL 0x200
612#define SYSKT_RDFIFO_STAT 0x204
613#define SYSKT_WRFIFO_STAT 0x208
614#define SYSKT_POWER_DATA 0x20c
615#define SYSKT_POWER_330 0xef
616#define SYSKT_POWER_300 0xf8
617#define SYSKT_POWER_184 0xcc
618#define SYSKT_POWER_CMD 0x20d
619#define SYSKT_POWER_START (1 << 7)
620#define SYSKT_POWER_STATUS 0x20e
621#define SYSKT_POWER_STATUS_OK (1 << 0)
622#define SYSKT_BOARD_REV 0x210
623#define SYSKT_CHIP_REV 0x211
624#define SYSKT_CONF_DATA 0x212
625#define SYSKT_CONF_DATA_1V8 (1 << 2)
626#define SYSKT_CONF_DATA_2V5 (1 << 1)
627#define SYSKT_CONF_DATA_3V3 (1 << 0)
628
629static int syskt_probe(struct sdhci_pci_chip *chip)
630{
631 if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
632 chip->pdev->class &= ~0x0000FF;
633 chip->pdev->class |= PCI_SDHCI_IFDMA;
634 }
635 return 0;
636}
637
638static int syskt_probe_slot(struct sdhci_pci_slot *slot)
639{
640 int tm, ps;
641
642 u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV);
643 u8 chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV);
644 dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, "
645 "board rev %d.%d, chip rev %d.%d\n",
646 board_rev >> 4, board_rev & 0xf,
647 chip_rev >> 4, chip_rev & 0xf);
648 if (chip_rev >= 0x20)
649 slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA;
650
651 writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA);
652 writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD);
653 udelay(50);
654 tm = 10; /* Wait max 1 ms */
655 do {
656 ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS);
657 if (ps & SYSKT_POWER_STATUS_OK)
658 break;
659 udelay(100);
660 } while (--tm);
661 if (!tm) {
662 dev_err(&slot->chip->pdev->dev,
663 "power regulator never stabilized");
664 writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD);
665 return -ENODEV;
666 }
667
668 return 0;
669}
670
671static const struct sdhci_pci_fixes sdhci_syskt = {
672 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER,
673 .probe = syskt_probe,
674 .probe_slot = syskt_probe_slot,
675};
676
Harald Welte557b0692009-06-18 16:53:38 +0200677static int via_probe(struct sdhci_pci_chip *chip)
678{
679 if (chip->pdev->revision == 0x10)
680 chip->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER;
681
682 return 0;
683}
684
685static const struct sdhci_pci_fixes sdhci_via = {
686 .probe = via_probe,
687};
688
Bill Pemberton9647f842012-11-19 13:25:11 -0500689static const struct pci_device_id pci_ids[] = {
Pierre Ossman22606402008-03-23 19:33:23 +0100690 {
691 .vendor = PCI_VENDOR_ID_RICOH,
692 .device = PCI_DEVICE_ID_RICOH_R5C822,
693 .subvendor = PCI_ANY_ID,
694 .subdevice = PCI_ANY_ID,
695 .driver_data = (kernel_ulong_t)&sdhci_ricoh,
696 },
697
698 {
Maxim Levitskyccc92c22010-08-10 18:01:42 -0700699 .vendor = PCI_VENDOR_ID_RICOH,
700 .device = 0x843,
701 .subvendor = PCI_ANY_ID,
702 .subdevice = PCI_ANY_ID,
703 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
704 },
705
706 {
Pablo Castillo568133e2010-08-10 18:02:01 -0700707 .vendor = PCI_VENDOR_ID_RICOH,
708 .device = 0xe822,
709 .subvendor = PCI_ANY_ID,
710 .subdevice = PCI_ANY_ID,
711 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
712 },
713
714 {
Manoj Iyer5fd11c02011-02-11 16:25:31 -0600715 .vendor = PCI_VENDOR_ID_RICOH,
716 .device = 0xe823,
717 .subvendor = PCI_ANY_ID,
718 .subdevice = PCI_ANY_ID,
719 .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc,
720 },
721
722 {
Pierre Ossman22606402008-03-23 19:33:23 +0100723 .vendor = PCI_VENDOR_ID_ENE,
724 .device = PCI_DEVICE_ID_ENE_CB712_SD,
725 .subvendor = PCI_ANY_ID,
726 .subdevice = PCI_ANY_ID,
727 .driver_data = (kernel_ulong_t)&sdhci_ene_712,
728 },
729
730 {
731 .vendor = PCI_VENDOR_ID_ENE,
732 .device = PCI_DEVICE_ID_ENE_CB712_SD_2,
733 .subvendor = PCI_ANY_ID,
734 .subdevice = PCI_ANY_ID,
735 .driver_data = (kernel_ulong_t)&sdhci_ene_712,
736 },
737
738 {
739 .vendor = PCI_VENDOR_ID_ENE,
740 .device = PCI_DEVICE_ID_ENE_CB714_SD,
741 .subvendor = PCI_ANY_ID,
742 .subdevice = PCI_ANY_ID,
743 .driver_data = (kernel_ulong_t)&sdhci_ene_714,
744 },
745
746 {
747 .vendor = PCI_VENDOR_ID_ENE,
748 .device = PCI_DEVICE_ID_ENE_CB714_SD_2,
749 .subvendor = PCI_ANY_ID,
750 .subdevice = PCI_ANY_ID,
751 .driver_data = (kernel_ulong_t)&sdhci_ene_714,
752 },
753
754 {
755 .vendor = PCI_VENDOR_ID_MARVELL,
David Woodhouse8c5eb882008-09-03 09:45:57 +0100756 .device = PCI_DEVICE_ID_MARVELL_88ALP01_SD,
Pierre Ossman22606402008-03-23 19:33:23 +0100757 .subvendor = PCI_ANY_ID,
758 .subdevice = PCI_ANY_ID,
759 .driver_data = (kernel_ulong_t)&sdhci_cafe,
760 },
761
762 {
763 .vendor = PCI_VENDOR_ID_JMICRON,
764 .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
765 .subvendor = PCI_ANY_ID,
766 .subdevice = PCI_ANY_ID,
767 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
768 },
769
Pierre Ossman44894282008-04-04 19:36:59 +0200770 {
771 .vendor = PCI_VENDOR_ID_JMICRON,
772 .device = PCI_DEVICE_ID_JMICRON_JMB38X_MMC,
773 .subvendor = PCI_ANY_ID,
774 .subdevice = PCI_ANY_ID,
775 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
776 },
777
Harald Welte557b0692009-06-18 16:53:38 +0200778 {
Takashi Iwai8f230f42010-12-08 10:04:30 +0100779 .vendor = PCI_VENDOR_ID_JMICRON,
780 .device = PCI_DEVICE_ID_JMICRON_JMB388_SD,
781 .subvendor = PCI_ANY_ID,
782 .subdevice = PCI_ANY_ID,
783 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
784 },
785
786 {
787 .vendor = PCI_VENDOR_ID_JMICRON,
788 .device = PCI_DEVICE_ID_JMICRON_JMB388_ESD,
789 .subvendor = PCI_ANY_ID,
790 .subdevice = PCI_ANY_ID,
791 .driver_data = (kernel_ulong_t)&sdhci_jmicron,
792 },
793
794 {
Nicolas Pitrea7a61862009-12-14 18:01:26 -0800795 .vendor = PCI_VENDOR_ID_SYSKONNECT,
796 .device = 0x8000,
797 .subvendor = PCI_ANY_ID,
798 .subdevice = PCI_ANY_ID,
799 .driver_data = (kernel_ulong_t)&sdhci_syskt,
800 },
801
802 {
Harald Welte557b0692009-06-18 16:53:38 +0200803 .vendor = PCI_VENDOR_ID_VIA,
804 .device = 0x95d0,
805 .subvendor = PCI_ANY_ID,
806 .subdevice = PCI_ANY_ID,
807 .driver_data = (kernel_ulong_t)&sdhci_via,
808 },
809
Xiaochen Shen29229052010-10-04 15:24:52 +0100810 {
811 .vendor = PCI_VENDOR_ID_INTEL,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100812 .device = PCI_DEVICE_ID_INTEL_MRST_SD0,
813 .subvendor = PCI_ANY_ID,
814 .subdevice = PCI_ANY_ID,
815 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc0,
816 },
817
818 {
819 .vendor = PCI_VENDOR_ID_INTEL,
820 .device = PCI_DEVICE_ID_INTEL_MRST_SD1,
821 .subvendor = PCI_ANY_ID,
822 .subdevice = PCI_ANY_ID,
Jacob Pan35ac6f02010-11-09 13:57:29 +0000823 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
824 },
825
826 {
827 .vendor = PCI_VENDOR_ID_INTEL,
828 .device = PCI_DEVICE_ID_INTEL_MRST_SD2,
829 .subvendor = PCI_ANY_ID,
830 .subdevice = PCI_ANY_ID,
831 .driver_data = (kernel_ulong_t)&sdhci_intel_mrst_hc1_hc2,
Alan Coxf9ee3ea2010-10-04 15:25:11 +0100832 },
833
834 {
835 .vendor = PCI_VENDOR_ID_INTEL,
Xiaochen Shen29229052010-10-04 15:24:52 +0100836 .device = PCI_DEVICE_ID_INTEL_MFD_SD,
837 .subvendor = PCI_ANY_ID,
838 .subdevice = PCI_ANY_ID,
839 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sd,
840 },
841
842 {
843 .vendor = PCI_VENDOR_ID_INTEL,
844 .device = PCI_DEVICE_ID_INTEL_MFD_SDIO1,
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_sdio,
Xiaochen Shen29229052010-10-04 15:24:52 +0100848 },
849
850 {
851 .vendor = PCI_VENDOR_ID_INTEL,
852 .device = PCI_DEVICE_ID_INTEL_MFD_SDIO2,
853 .subvendor = PCI_ANY_ID,
854 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300855 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_sdio,
Xiaochen Shen29229052010-10-04 15:24:52 +0100856 },
857
858 {
859 .vendor = PCI_VENDOR_ID_INTEL,
860 .device = PCI_DEVICE_ID_INTEL_MFD_EMMC0,
861 .subvendor = PCI_ANY_ID,
862 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300863 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
Xiaochen Shen29229052010-10-04 15:24:52 +0100864 },
865
866 {
867 .vendor = PCI_VENDOR_ID_INTEL,
868 .device = PCI_DEVICE_ID_INTEL_MFD_EMMC1,
869 .subvendor = PCI_ANY_ID,
870 .subdevice = PCI_ANY_ID,
Adrian Hunter0d013bc2011-06-29 14:23:47 +0300871 .driver_data = (kernel_ulong_t)&sdhci_intel_mfd_emmc,
Xiaochen Shen29229052010-10-04 15:24:52 +0100872 },
873
Jennifer Li26daa1e2010-11-17 23:01:59 -0500874 {
Alexander Stein296e0b02012-03-14 08:38:58 +0100875 .vendor = PCI_VENDOR_ID_INTEL,
876 .device = PCI_DEVICE_ID_INTEL_PCH_SDIO0,
877 .subvendor = PCI_ANY_ID,
878 .subdevice = PCI_ANY_ID,
879 .driver_data = (kernel_ulong_t)&sdhci_intel_pch_sdio,
880 },
881
882 {
883 .vendor = PCI_VENDOR_ID_INTEL,
884 .device = PCI_DEVICE_ID_INTEL_PCH_SDIO1,
885 .subvendor = PCI_ANY_ID,
886 .subdevice = PCI_ANY_ID,
887 .driver_data = (kernel_ulong_t)&sdhci_intel_pch_sdio,
888 },
889
890 {
Adrian Hunter728ef3d2013-04-26 11:27:23 +0300891 .vendor = PCI_VENDOR_ID_INTEL,
892 .device = PCI_DEVICE_ID_INTEL_BYT_EMMC,
893 .subvendor = PCI_ANY_ID,
894 .subdevice = PCI_ANY_ID,
895 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc,
896 },
897
898 {
899 .vendor = PCI_VENDOR_ID_INTEL,
900 .device = PCI_DEVICE_ID_INTEL_BYT_SDIO,
901 .subvendor = PCI_ANY_ID,
902 .subdevice = PCI_ANY_ID,
903 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio,
904 },
905
906 {
907 .vendor = PCI_VENDOR_ID_INTEL,
908 .device = PCI_DEVICE_ID_INTEL_BYT_SD,
909 .subvendor = PCI_ANY_ID,
910 .subdevice = PCI_ANY_ID,
911 .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd,
912 },
913
914 {
Jennifer Li26daa1e2010-11-17 23:01:59 -0500915 .vendor = PCI_VENDOR_ID_O2,
916 .device = PCI_DEVICE_ID_O2_8120,
917 .subvendor = PCI_ANY_ID,
918 .subdevice = PCI_ANY_ID,
919 .driver_data = (kernel_ulong_t)&sdhci_o2,
920 },
921
922 {
923 .vendor = PCI_VENDOR_ID_O2,
924 .device = PCI_DEVICE_ID_O2_8220,
925 .subvendor = PCI_ANY_ID,
926 .subdevice = PCI_ANY_ID,
927 .driver_data = (kernel_ulong_t)&sdhci_o2,
928 },
929
930 {
931 .vendor = PCI_VENDOR_ID_O2,
932 .device = PCI_DEVICE_ID_O2_8221,
933 .subvendor = PCI_ANY_ID,
934 .subdevice = PCI_ANY_ID,
935 .driver_data = (kernel_ulong_t)&sdhci_o2,
936 },
937
938 {
939 .vendor = PCI_VENDOR_ID_O2,
940 .device = PCI_DEVICE_ID_O2_8320,
941 .subvendor = PCI_ANY_ID,
942 .subdevice = PCI_ANY_ID,
943 .driver_data = (kernel_ulong_t)&sdhci_o2,
944 },
945
946 {
947 .vendor = PCI_VENDOR_ID_O2,
948 .device = PCI_DEVICE_ID_O2_8321,
949 .subvendor = PCI_ANY_ID,
950 .subdevice = PCI_ANY_ID,
951 .driver_data = (kernel_ulong_t)&sdhci_o2,
952 },
953
Pierre Ossman22606402008-03-23 19:33:23 +0100954 { /* Generic SD host controller */
955 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
956 },
957
958 { /* end: all zeroes */ },
959};
960
961MODULE_DEVICE_TABLE(pci, pci_ids);
962
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +0100963/*****************************************************************************\
964 * *
965 * SDHCI core callbacks *
966 * *
967\*****************************************************************************/
968
969static int sdhci_pci_enable_dma(struct sdhci_host *host)
970{
971 struct sdhci_pci_slot *slot;
972 struct pci_dev *pdev;
973 int ret;
974
975 slot = sdhci_priv(host);
976 pdev = slot->chip->pdev;
977
978 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
979 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
Richard Röjforsa13abc72009-09-22 16:45:30 -0700980 (host->flags & SDHCI_USE_SDMA)) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +0100981 dev_warn(&pdev->dev, "Will use DMA mode even though HW "
982 "doesn't fully claim to support it.\n");
983 }
984
Yang Hongyang284901a2009-04-06 19:01:15 -0700985 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +0100986 if (ret)
987 return ret;
988
989 pci_set_master(pdev);
990
991 return 0;
992}
993
Sascha Hauer7bc088d2013-01-21 19:02:27 +0800994static int sdhci_pci_bus_width(struct sdhci_host *host, int width)
Major Lee68077b02011-06-29 14:23:46 +0300995{
996 u8 ctrl;
997
998 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
999
1000 switch (width) {
1001 case MMC_BUS_WIDTH_8:
1002 ctrl |= SDHCI_CTRL_8BITBUS;
1003 ctrl &= ~SDHCI_CTRL_4BITBUS;
1004 break;
1005 case MMC_BUS_WIDTH_4:
1006 ctrl |= SDHCI_CTRL_4BITBUS;
1007 ctrl &= ~SDHCI_CTRL_8BITBUS;
1008 break;
1009 default:
1010 ctrl &= ~(SDHCI_CTRL_8BITBUS | SDHCI_CTRL_4BITBUS);
1011 break;
1012 }
1013
1014 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
1015
1016 return 0;
1017}
1018
Adrian Hunter0f201652011-08-29 16:42:13 +03001019static void sdhci_pci_hw_reset(struct sdhci_host *host)
1020{
1021 struct sdhci_pci_slot *slot = sdhci_priv(host);
1022 int rst_n_gpio = slot->rst_n_gpio;
1023
1024 if (!gpio_is_valid(rst_n_gpio))
1025 return;
1026 gpio_set_value_cansleep(rst_n_gpio, 0);
1027 /* For eMMC, minimum is 1us but give it 10us for good measure */
1028 udelay(10);
1029 gpio_set_value_cansleep(rst_n_gpio, 1);
1030 /* For eMMC, minimum is 200us but give it 300us for good measure */
1031 usleep_range(300, 1000);
1032}
1033
Lars-Peter Clausenc9155682013-03-13 19:26:05 +01001034static const struct sdhci_ops sdhci_pci_ops = {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001035 .enable_dma = sdhci_pci_enable_dma,
Sascha Hauer7bc088d2013-01-21 19:02:27 +08001036 .platform_bus_width = sdhci_pci_bus_width,
Adrian Hunter0f201652011-08-29 16:42:13 +03001037 .hw_reset = sdhci_pci_hw_reset,
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001038};
1039
1040/*****************************************************************************\
1041 * *
1042 * Suspend/resume *
1043 * *
1044\*****************************************************************************/
1045
1046#ifdef CONFIG_PM
1047
Manuel Lauss29495aa2011-11-03 11:09:45 +01001048static int sdhci_pci_suspend(struct device *dev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001049{
Manuel Lauss29495aa2011-11-03 11:09:45 +01001050 struct pci_dev *pdev = to_pci_dev(dev);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001051 struct sdhci_pci_chip *chip;
1052 struct sdhci_pci_slot *slot;
Daniel Drake5f619702010-11-04 22:20:39 +00001053 mmc_pm_flag_t slot_pm_flags;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001054 mmc_pm_flag_t pm_flags = 0;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001055 int i, ret;
1056
1057 chip = pci_get_drvdata(pdev);
1058 if (!chip)
1059 return 0;
1060
Ameya Palandeb177bc92011-04-05 21:13:13 +03001061 for (i = 0; i < chip->num_slots; i++) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001062 slot = chip->slots[i];
1063 if (!slot)
1064 continue;
1065
Manuel Lauss29495aa2011-11-03 11:09:45 +01001066 ret = sdhci_suspend_host(slot->host);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001067
Axel Linb678b912011-12-03 15:28:05 +08001068 if (ret)
1069 goto err_pci_suspend;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001070
Daniel Drake5f619702010-11-04 22:20:39 +00001071 slot_pm_flags = slot->host->mmc->pm_flags;
1072 if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
1073 sdhci_enable_irq_wakeups(slot->host);
1074
1075 pm_flags |= slot_pm_flags;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001076 }
1077
Pierre Ossman44894282008-04-04 19:36:59 +02001078 if (chip->fixes && chip->fixes->suspend) {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001079 ret = chip->fixes->suspend(chip);
Axel Linb678b912011-12-03 15:28:05 +08001080 if (ret)
1081 goto err_pci_suspend;
Pierre Ossman44894282008-04-04 19:36:59 +02001082 }
1083
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001084 pci_save_state(pdev);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001085 if (pm_flags & MMC_PM_KEEP_POWER) {
Daniel Drake5f619702010-11-04 22:20:39 +00001086 if (pm_flags & MMC_PM_WAKE_SDIO_IRQ) {
1087 pci_pme_active(pdev, true);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001088 pci_enable_wake(pdev, PCI_D3hot, 1);
Daniel Drake5f619702010-11-04 22:20:39 +00001089 }
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001090 pci_set_power_state(pdev, PCI_D3hot);
1091 } else {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001092 pci_enable_wake(pdev, PCI_D3hot, 0);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001093 pci_disable_device(pdev);
Manuel Lauss29495aa2011-11-03 11:09:45 +01001094 pci_set_power_state(pdev, PCI_D3hot);
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001095 }
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001096
1097 return 0;
Axel Linb678b912011-12-03 15:28:05 +08001098
1099err_pci_suspend:
1100 while (--i >= 0)
1101 sdhci_resume_host(chip->slots[i]->host);
1102 return ret;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001103}
1104
Manuel Lauss29495aa2011-11-03 11:09:45 +01001105static int sdhci_pci_resume(struct device *dev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001106{
Manuel Lauss29495aa2011-11-03 11:09:45 +01001107 struct pci_dev *pdev = to_pci_dev(dev);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001108 struct sdhci_pci_chip *chip;
1109 struct sdhci_pci_slot *slot;
1110 int i, ret;
1111
1112 chip = pci_get_drvdata(pdev);
1113 if (!chip)
1114 return 0;
1115
1116 pci_set_power_state(pdev, PCI_D0);
1117 pci_restore_state(pdev);
1118 ret = pci_enable_device(pdev);
1119 if (ret)
1120 return ret;
1121
Pierre Ossman45211e22008-03-24 13:09:09 +01001122 if (chip->fixes && chip->fixes->resume) {
1123 ret = chip->fixes->resume(chip);
1124 if (ret)
1125 return ret;
1126 }
1127
Ameya Palandeb177bc92011-04-05 21:13:13 +03001128 for (i = 0; i < chip->num_slots; i++) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001129 slot = chip->slots[i];
1130 if (!slot)
1131 continue;
1132
1133 ret = sdhci_resume_host(slot->host);
1134 if (ret)
1135 return ret;
1136 }
1137
1138 return 0;
1139}
1140
1141#else /* CONFIG_PM */
1142
1143#define sdhci_pci_suspend NULL
1144#define sdhci_pci_resume NULL
1145
1146#endif /* CONFIG_PM */
1147
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001148#ifdef CONFIG_PM_RUNTIME
1149
1150static int sdhci_pci_runtime_suspend(struct device *dev)
1151{
1152 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
1153 struct sdhci_pci_chip *chip;
1154 struct sdhci_pci_slot *slot;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001155 int i, ret;
1156
1157 chip = pci_get_drvdata(pdev);
1158 if (!chip)
1159 return 0;
1160
1161 for (i = 0; i < chip->num_slots; i++) {
1162 slot = chip->slots[i];
1163 if (!slot)
1164 continue;
1165
1166 ret = sdhci_runtime_suspend_host(slot->host);
1167
Axel Linb678b912011-12-03 15:28:05 +08001168 if (ret)
1169 goto err_pci_runtime_suspend;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001170 }
1171
1172 if (chip->fixes && chip->fixes->suspend) {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001173 ret = chip->fixes->suspend(chip);
Axel Linb678b912011-12-03 15:28:05 +08001174 if (ret)
1175 goto err_pci_runtime_suspend;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001176 }
1177
1178 return 0;
Axel Linb678b912011-12-03 15:28:05 +08001179
1180err_pci_runtime_suspend:
1181 while (--i >= 0)
1182 sdhci_runtime_resume_host(chip->slots[i]->host);
1183 return ret;
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001184}
1185
1186static int sdhci_pci_runtime_resume(struct device *dev)
1187{
1188 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
1189 struct sdhci_pci_chip *chip;
1190 struct sdhci_pci_slot *slot;
1191 int i, ret;
1192
1193 chip = pci_get_drvdata(pdev);
1194 if (!chip)
1195 return 0;
1196
1197 if (chip->fixes && chip->fixes->resume) {
1198 ret = chip->fixes->resume(chip);
1199 if (ret)
1200 return ret;
1201 }
1202
1203 for (i = 0; i < chip->num_slots; i++) {
1204 slot = chip->slots[i];
1205 if (!slot)
1206 continue;
1207
1208 ret = sdhci_runtime_resume_host(slot->host);
1209 if (ret)
1210 return ret;
1211 }
1212
1213 return 0;
1214}
1215
1216static int sdhci_pci_runtime_idle(struct device *dev)
1217{
1218 return 0;
1219}
1220
1221#else
1222
1223#define sdhci_pci_runtime_suspend NULL
1224#define sdhci_pci_runtime_resume NULL
1225#define sdhci_pci_runtime_idle NULL
1226
1227#endif
1228
1229static const struct dev_pm_ops sdhci_pci_pm_ops = {
Manuel Lauss29495aa2011-11-03 11:09:45 +01001230 .suspend = sdhci_pci_suspend,
1231 .resume = sdhci_pci_resume,
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001232 .runtime_suspend = sdhci_pci_runtime_suspend,
1233 .runtime_resume = sdhci_pci_runtime_resume,
1234 .runtime_idle = sdhci_pci_runtime_idle,
1235};
1236
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001237/*****************************************************************************\
1238 * *
1239 * Device probing/removal *
1240 * *
1241\*****************************************************************************/
1242
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001243static struct sdhci_pci_slot *sdhci_pci_probe_slot(
Adrian Hunter52c506f2011-12-27 15:48:43 +02001244 struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
1245 int slotno)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001246{
1247 struct sdhci_pci_slot *slot;
1248 struct sdhci_host *host;
Adrian Hunter52c506f2011-12-27 15:48:43 +02001249 int ret, bar = first_bar + slotno;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001250
1251 if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
1252 dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
1253 return ERR_PTR(-ENODEV);
1254 }
1255
Adrian Hunter90b3e6c2012-10-18 09:54:31 +03001256 if (pci_resource_len(pdev, bar) < 0x100) {
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001257 dev_err(&pdev->dev, "Invalid iomem size. You may "
1258 "experience problems.\n");
1259 }
1260
1261 if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
1262 dev_err(&pdev->dev, "Vendor specific interface. Aborting.\n");
1263 return ERR_PTR(-ENODEV);
1264 }
1265
1266 if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) {
1267 dev_err(&pdev->dev, "Unknown interface. Aborting.\n");
1268 return ERR_PTR(-ENODEV);
1269 }
1270
1271 host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot));
1272 if (IS_ERR(host)) {
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001273 dev_err(&pdev->dev, "cannot allocate host\n");
Julia Lawalldc0fd7b2010-05-26 14:42:11 -07001274 return ERR_CAST(host);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001275 }
1276
1277 slot = sdhci_priv(host);
1278
1279 slot->chip = chip;
1280 slot->host = host;
1281 slot->pci_bar = bar;
Adrian Hunter0f201652011-08-29 16:42:13 +03001282 slot->rst_n_gpio = -EINVAL;
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001283 slot->cd_gpio = -EINVAL;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001284
Adrian Hunter52c506f2011-12-27 15:48:43 +02001285 /* Retrieve platform data if there is any */
1286 if (*sdhci_pci_get_data)
1287 slot->data = sdhci_pci_get_data(pdev, slotno);
1288
1289 if (slot->data) {
1290 if (slot->data->setup) {
1291 ret = slot->data->setup(slot->data);
1292 if (ret) {
1293 dev_err(&pdev->dev, "platform setup failed\n");
1294 goto free;
1295 }
1296 }
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001297 slot->rst_n_gpio = slot->data->rst_n_gpio;
1298 slot->cd_gpio = slot->data->cd_gpio;
Adrian Hunter52c506f2011-12-27 15:48:43 +02001299 }
1300
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001301 host->hw_name = "PCI";
1302 host->ops = &sdhci_pci_ops;
1303 host->quirks = chip->quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +02001304 host->quirks2 = chip->quirks2;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001305
1306 host->irq = pdev->irq;
1307
1308 ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
1309 if (ret) {
1310 dev_err(&pdev->dev, "cannot request region\n");
Adrian Hunter52c506f2011-12-27 15:48:43 +02001311 goto cleanup;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001312 }
1313
Arjan van de Ven092f82e2008-09-28 16:15:56 -07001314 host->ioaddr = pci_ioremap_bar(pdev, bar);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001315 if (!host->ioaddr) {
1316 dev_err(&pdev->dev, "failed to remap registers\n");
Chris Ball9fdcdbb2011-03-29 00:46:12 -04001317 ret = -ENOMEM;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001318 goto release;
1319 }
1320
Pierre Ossman44894282008-04-04 19:36:59 +02001321 if (chip->fixes && chip->fixes->probe_slot) {
1322 ret = chip->fixes->probe_slot(slot);
1323 if (ret)
1324 goto unmap;
1325 }
1326
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001327 if (gpio_is_valid(slot->rst_n_gpio)) {
1328 if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
1329 gpio_direction_output(slot->rst_n_gpio, 1);
1330 slot->host->mmc->caps |= MMC_CAP_HW_RESET;
1331 } else {
1332 dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
1333 slot->rst_n_gpio = -EINVAL;
1334 }
1335 }
1336
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001337 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
Aaron Lueed222a2013-03-05 11:24:52 +08001338 host->mmc->slotno = slotno;
Adrian Huntera08b17b2013-04-15 11:27:25 -04001339 host->mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP;
Nicolas Pitre2f4cbb32010-03-05 13:43:32 -08001340
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001341 ret = sdhci_add_host(host);
1342 if (ret)
Pierre Ossman44894282008-04-04 19:36:59 +02001343 goto remove;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001344
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001345 sdhci_pci_add_own_cd(slot);
1346
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001347 return slot;
1348
Pierre Ossman44894282008-04-04 19:36:59 +02001349remove:
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001350 if (gpio_is_valid(slot->rst_n_gpio))
1351 gpio_free(slot->rst_n_gpio);
1352
Pierre Ossman44894282008-04-04 19:36:59 +02001353 if (chip->fixes && chip->fixes->remove_slot)
Pierre Ossman1e728592008-04-16 19:13:13 +02001354 chip->fixes->remove_slot(slot, 0);
Pierre Ossman44894282008-04-04 19:36:59 +02001355
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001356unmap:
1357 iounmap(host->ioaddr);
1358
1359release:
1360 pci_release_region(pdev, bar);
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001361
Adrian Hunter52c506f2011-12-27 15:48:43 +02001362cleanup:
1363 if (slot->data && slot->data->cleanup)
1364 slot->data->cleanup(slot->data);
1365
Dan Carpenterc60a32c2009-04-10 23:31:10 +02001366free:
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001367 sdhci_free_host(host);
1368
1369 return ERR_PTR(ret);
1370}
1371
1372static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
1373{
Pierre Ossman1e728592008-04-16 19:13:13 +02001374 int dead;
1375 u32 scratch;
1376
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001377 sdhci_pci_remove_own_cd(slot);
1378
Pierre Ossman1e728592008-04-16 19:13:13 +02001379 dead = 0;
1380 scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
1381 if (scratch == (u32)-1)
1382 dead = 1;
1383
1384 sdhci_remove_host(slot->host, dead);
Pierre Ossman44894282008-04-04 19:36:59 +02001385
Adrian Hunterc5e027a2011-12-27 15:48:44 +02001386 if (gpio_is_valid(slot->rst_n_gpio))
1387 gpio_free(slot->rst_n_gpio);
1388
Pierre Ossman44894282008-04-04 19:36:59 +02001389 if (slot->chip->fixes && slot->chip->fixes->remove_slot)
Pierre Ossman1e728592008-04-16 19:13:13 +02001390 slot->chip->fixes->remove_slot(slot, dead);
Pierre Ossman44894282008-04-04 19:36:59 +02001391
Adrian Hunter52c506f2011-12-27 15:48:43 +02001392 if (slot->data && slot->data->cleanup)
1393 slot->data->cleanup(slot->data);
1394
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001395 pci_release_region(slot->chip->pdev, slot->pci_bar);
Pierre Ossman44894282008-04-04 19:36:59 +02001396
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001397 sdhci_free_host(slot->host);
1398}
1399
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001400static void sdhci_pci_runtime_pm_allow(struct device *dev)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001401{
1402 pm_runtime_put_noidle(dev);
1403 pm_runtime_allow(dev);
1404 pm_runtime_set_autosuspend_delay(dev, 50);
1405 pm_runtime_use_autosuspend(dev);
1406 pm_suspend_ignore_children(dev, 1);
1407}
1408
Bill Pemberton6e0ee712012-11-19 13:26:03 -05001409static void sdhci_pci_runtime_pm_forbid(struct device *dev)
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001410{
1411 pm_runtime_forbid(dev);
1412 pm_runtime_get_noresume(dev);
1413}
1414
Bill Pembertonc3be1ef2012-11-19 13:23:06 -05001415static int sdhci_pci_probe(struct pci_dev *pdev,
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001416 const struct pci_device_id *ent)
1417{
1418 struct sdhci_pci_chip *chip;
1419 struct sdhci_pci_slot *slot;
1420
Sergei Shtylyovcf5e23e2011-03-17 16:46:17 -04001421 u8 slots, first_bar;
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001422 int ret, i;
1423
1424 BUG_ON(pdev == NULL);
1425 BUG_ON(ent == NULL);
1426
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001427 dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n",
Sergei Shtylyovcf5e23e2011-03-17 16:46:17 -04001428 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001429
1430 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
1431 if (ret)
1432 return ret;
1433
1434 slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
1435 dev_dbg(&pdev->dev, "found %d slot(s)\n", slots);
1436 if (slots == 0)
1437 return -ENODEV;
1438
1439 BUG_ON(slots > MAX_SLOTS);
1440
1441 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar);
1442 if (ret)
1443 return ret;
1444
1445 first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK;
1446
1447 if (first_bar > 5) {
1448 dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n");
1449 return -ENODEV;
1450 }
1451
1452 ret = pci_enable_device(pdev);
1453 if (ret)
1454 return ret;
1455
1456 chip = kzalloc(sizeof(struct sdhci_pci_chip), GFP_KERNEL);
1457 if (!chip) {
1458 ret = -ENOMEM;
1459 goto err;
1460 }
1461
1462 chip->pdev = pdev;
Ameya Palandeb177bc92011-04-05 21:13:13 +03001463 chip->fixes = (const struct sdhci_pci_fixes *)ent->driver_data;
Adrian Hunterc43fd772011-10-17 10:52:44 +03001464 if (chip->fixes) {
Pierre Ossman22606402008-03-23 19:33:23 +01001465 chip->quirks = chip->fixes->quirks;
Adrian Hunterf3c55a72012-02-07 14:48:55 +02001466 chip->quirks2 = chip->fixes->quirks2;
Adrian Hunterc43fd772011-10-17 10:52:44 +03001467 chip->allow_runtime_pm = chip->fixes->allow_runtime_pm;
1468 }
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001469 chip->num_slots = slots;
1470
1471 pci_set_drvdata(pdev, chip);
1472
Pierre Ossman22606402008-03-23 19:33:23 +01001473 if (chip->fixes && chip->fixes->probe) {
1474 ret = chip->fixes->probe(chip);
1475 if (ret)
1476 goto free;
1477 }
1478
Alan Cox225d85f2010-10-04 15:24:21 +01001479 slots = chip->num_slots; /* Quirk may have changed this */
1480
Ameya Palandeb177bc92011-04-05 21:13:13 +03001481 for (i = 0; i < slots; i++) {
Adrian Hunter52c506f2011-12-27 15:48:43 +02001482 slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001483 if (IS_ERR(slot)) {
Ameya Palandeb177bc92011-04-05 21:13:13 +03001484 for (i--; i >= 0; i--)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001485 sdhci_pci_remove_slot(chip->slots[i]);
1486 ret = PTR_ERR(slot);
1487 goto free;
1488 }
1489
1490 chip->slots[i] = slot;
1491 }
1492
Adrian Hunterc43fd772011-10-17 10:52:44 +03001493 if (chip->allow_runtime_pm)
1494 sdhci_pci_runtime_pm_allow(&pdev->dev);
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001495
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001496 return 0;
1497
1498free:
1499 pci_set_drvdata(pdev, NULL);
1500 kfree(chip);
1501
1502err:
1503 pci_disable_device(pdev);
1504 return ret;
1505}
1506
Bill Pemberton6e0ee712012-11-19 13:26:03 -05001507static void sdhci_pci_remove(struct pci_dev *pdev)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001508{
1509 int i;
1510 struct sdhci_pci_chip *chip;
1511
1512 chip = pci_get_drvdata(pdev);
1513
1514 if (chip) {
Adrian Hunterc43fd772011-10-17 10:52:44 +03001515 if (chip->allow_runtime_pm)
1516 sdhci_pci_runtime_pm_forbid(&pdev->dev);
1517
Ameya Palandeb177bc92011-04-05 21:13:13 +03001518 for (i = 0; i < chip->num_slots; i++)
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001519 sdhci_pci_remove_slot(chip->slots[i]);
1520
1521 pci_set_drvdata(pdev, NULL);
1522 kfree(chip);
1523 }
1524
1525 pci_disable_device(pdev);
1526}
1527
1528static struct pci_driver sdhci_driver = {
Ameya Palandeb177bc92011-04-05 21:13:13 +03001529 .name = "sdhci-pci",
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001530 .id_table = pci_ids,
Ameya Palandeb177bc92011-04-05 21:13:13 +03001531 .probe = sdhci_pci_probe,
Bill Pemberton0433c142012-11-19 13:20:26 -05001532 .remove = sdhci_pci_remove,
Adrian Hunter66fd8ad2011-10-03 15:33:34 +03001533 .driver = {
1534 .pm = &sdhci_pci_pm_ops
1535 },
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001536};
1537
Sachin Kamatacc69642012-08-27 11:57:02 +05301538module_pci_driver(sdhci_driver);
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001539
Pierre Ossman32710e82009-04-08 20:14:54 +02001540MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
Pierre Ossmanb8c86fc2008-03-18 17:35:49 +01001541MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
1542MODULE_LICENSE("GPL");