sdhci: remove forced dma quirks
[linux-2.6-block.git] / drivers / mmc / host / sdhci-pci.c
CommitLineData
b8c86fc5
PO
1/* 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>
17#include <linux/pci.h>
18#include <linux/dma-mapping.h>
19
20#include <linux/mmc/host.h>
21
22#include <asm/scatterlist.h>
23#include <asm/io.h>
24
25#include "sdhci.h"
26
27/*
28 * PCI registers
29 */
30
31#define PCI_SDHCI_IFPIO 0x00
32#define PCI_SDHCI_IFDMA 0x01
33#define PCI_SDHCI_IFVENDOR 0x02
34
35#define PCI_SLOT_INFO 0x40 /* 8 bits */
36#define PCI_SLOT_INFO_SLOTS(x) ((x >> 4) & 7)
37#define PCI_SLOT_INFO_FIRST_BAR_MASK 0x07
38
39#define MAX_SLOTS 8
40
41static const struct pci_device_id pci_ids[] __devinitdata = {
42 {
43 .vendor = PCI_VENDOR_ID_RICOH,
44 .device = PCI_DEVICE_ID_RICOH_R5C822,
45 .subvendor = PCI_VENDOR_ID_IBM,
46 .subdevice = PCI_ANY_ID,
3815a0eb 47 .driver_data = SDHCI_QUIRK_CLOCK_BEFORE_RESET,
b8c86fc5
PO
48 },
49
50 {
51 .vendor = PCI_VENDOR_ID_RICOH,
52 .device = PCI_DEVICE_ID_RICOH_R5C822,
53 .subvendor = PCI_VENDOR_ID_SAMSUNG,
54 .subdevice = PCI_ANY_ID,
3815a0eb 55 .driver_data = SDHCI_QUIRK_NO_CARD_NO_RESET,
b8c86fc5
PO
56 },
57
58 {
59 .vendor = PCI_VENDOR_ID_ENE,
60 .device = PCI_DEVICE_ID_ENE_CB712_SD,
61 .subvendor = PCI_ANY_ID,
62 .subdevice = PCI_ANY_ID,
63 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE |
64 SDHCI_QUIRK_BROKEN_DMA,
65 },
66
67 {
68 .vendor = PCI_VENDOR_ID_ENE,
69 .device = PCI_DEVICE_ID_ENE_CB712_SD_2,
70 .subvendor = PCI_ANY_ID,
71 .subdevice = PCI_ANY_ID,
72 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE |
73 SDHCI_QUIRK_BROKEN_DMA,
74 },
75
76 {
77 .vendor = PCI_VENDOR_ID_ENE,
78 .device = PCI_DEVICE_ID_ENE_CB714_SD,
79 .subvendor = PCI_ANY_ID,
80 .subdevice = PCI_ANY_ID,
81 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE |
82 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS |
83 SDHCI_QUIRK_BROKEN_DMA,
84 },
85
86 {
87 .vendor = PCI_VENDOR_ID_ENE,
88 .device = PCI_DEVICE_ID_ENE_CB714_SD_2,
89 .subvendor = PCI_ANY_ID,
90 .subdevice = PCI_ANY_ID,
91 .driver_data = SDHCI_QUIRK_SINGLE_POWER_WRITE |
92 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS |
93 SDHCI_QUIRK_BROKEN_DMA,
94 },
95
96 {
97 .vendor = PCI_VENDOR_ID_MARVELL,
98 .device = PCI_DEVICE_ID_MARVELL_CAFE_SD,
99 .subvendor = PCI_ANY_ID,
100 .subdevice = PCI_ANY_ID,
101 .driver_data = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER |
102 SDHCI_QUIRK_INCR_TIMEOUT_CONTROL,
103 },
104
105 {
106 .vendor = PCI_VENDOR_ID_JMICRON,
107 .device = PCI_DEVICE_ID_JMICRON_JMB38X_SD,
108 .subvendor = PCI_ANY_ID,
109 .subdevice = PCI_ANY_ID,
110 .driver_data = SDHCI_QUIRK_32BIT_DMA_ADDR |
111 SDHCI_QUIRK_32BIT_DMA_SIZE |
112 SDHCI_QUIRK_RESET_AFTER_REQUEST,
113 },
114
115 { /* Generic SD host controller */
116 PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00)
117 },
118
119 { /* end: all zeroes */ },
120};
121
122MODULE_DEVICE_TABLE(pci, pci_ids);
123
124struct sdhci_pci_chip;
125
126struct sdhci_pci_slot {
127 struct sdhci_pci_chip *chip;
128 struct sdhci_host *host;
129
130 int pci_bar;
131};
132
133struct sdhci_pci_chip {
134 struct pci_dev *pdev;
135 unsigned int quirks;
136
137 int num_slots; /* Slots on controller */
138 struct sdhci_pci_slot *slots[MAX_SLOTS]; /* Pointers to host slots */
139};
140
141/*****************************************************************************\
142 * *
143 * SDHCI core callbacks *
144 * *
145\*****************************************************************************/
146
147static int sdhci_pci_enable_dma(struct sdhci_host *host)
148{
149 struct sdhci_pci_slot *slot;
150 struct pci_dev *pdev;
151 int ret;
152
153 slot = sdhci_priv(host);
154 pdev = slot->chip->pdev;
155
156 if (((pdev->class & 0xFFFF00) == (PCI_CLASS_SYSTEM_SDHCI << 8)) &&
157 ((pdev->class & 0x0000FF) != PCI_SDHCI_IFDMA) &&
158 (host->flags & SDHCI_USE_DMA)) {
159 dev_warn(&pdev->dev, "Will use DMA mode even though HW "
160 "doesn't fully claim to support it.\n");
161 }
162
163 ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
164 if (ret)
165 return ret;
166
167 pci_set_master(pdev);
168
169 return 0;
170}
171
172static struct sdhci_ops sdhci_pci_ops = {
173 .enable_dma = sdhci_pci_enable_dma,
174};
175
176/*****************************************************************************\
177 * *
178 * Suspend/resume *
179 * *
180\*****************************************************************************/
181
182#ifdef CONFIG_PM
183
184static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
185{
186 struct sdhci_pci_chip *chip;
187 struct sdhci_pci_slot *slot;
188 int i, ret;
189
190 chip = pci_get_drvdata(pdev);
191 if (!chip)
192 return 0;
193
194 for (i = 0;i < chip->num_slots;i++) {
195 slot = chip->slots[i];
196 if (!slot)
197 continue;
198
199 ret = sdhci_suspend_host(slot->host, state);
200
201 if (ret) {
202 for (i--;i >= 0;i--)
203 sdhci_resume_host(chip->slots[i]->host);
204 return ret;
205 }
206 }
207
208 pci_save_state(pdev);
209 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
210 pci_disable_device(pdev);
211 pci_set_power_state(pdev, pci_choose_state(pdev, state));
212
213 return 0;
214}
215
216static int sdhci_pci_resume (struct pci_dev *pdev)
217{
218 struct sdhci_pci_chip *chip;
219 struct sdhci_pci_slot *slot;
220 int i, ret;
221
222 chip = pci_get_drvdata(pdev);
223 if (!chip)
224 return 0;
225
226 pci_set_power_state(pdev, PCI_D0);
227 pci_restore_state(pdev);
228 ret = pci_enable_device(pdev);
229 if (ret)
230 return ret;
231
232 for (i = 0;i < chip->num_slots;i++) {
233 slot = chip->slots[i];
234 if (!slot)
235 continue;
236
237 ret = sdhci_resume_host(slot->host);
238 if (ret)
239 return ret;
240 }
241
242 return 0;
243}
244
245#else /* CONFIG_PM */
246
247#define sdhci_pci_suspend NULL
248#define sdhci_pci_resume NULL
249
250#endif /* CONFIG_PM */
251
252/*****************************************************************************\
253 * *
254 * Device probing/removal *
255 * *
256\*****************************************************************************/
257
258static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
259 struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar)
260{
261 struct sdhci_pci_slot *slot;
262 struct sdhci_host *host;
263
264 resource_size_t addr;
265
266 int ret;
267
268 if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
269 dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
270 return ERR_PTR(-ENODEV);
271 }
272
273 if (pci_resource_len(pdev, bar) != 0x100) {
274 dev_err(&pdev->dev, "Invalid iomem size. You may "
275 "experience problems.\n");
276 }
277
278 if ((pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
279 dev_err(&pdev->dev, "Vendor specific interface. Aborting.\n");
280 return ERR_PTR(-ENODEV);
281 }
282
283 if ((pdev->class & 0x0000FF) > PCI_SDHCI_IFVENDOR) {
284 dev_err(&pdev->dev, "Unknown interface. Aborting.\n");
285 return ERR_PTR(-ENODEV);
286 }
287
288 host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdhci_pci_slot));
289 if (IS_ERR(host)) {
290 ret = PTR_ERR(host);
291 goto unmap;
292 }
293
294 slot = sdhci_priv(host);
295
296 slot->chip = chip;
297 slot->host = host;
298 slot->pci_bar = bar;
299
300 host->hw_name = "PCI";
301 host->ops = &sdhci_pci_ops;
302 host->quirks = chip->quirks;
303
304 host->irq = pdev->irq;
305
306 ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
307 if (ret) {
308 dev_err(&pdev->dev, "cannot request region\n");
309 return ERR_PTR(ret);
310 }
311
312 addr = pci_resource_start(pdev, bar);
313 host->ioaddr = ioremap_nocache(addr, pci_resource_len(pdev, bar));
314 if (!host->ioaddr) {
315 dev_err(&pdev->dev, "failed to remap registers\n");
316 goto release;
317 }
318
319 ret = sdhci_add_host(host);
320 if (ret)
321 goto unmap;
322
323 return slot;
324
325unmap:
326 iounmap(host->ioaddr);
327
328release:
329 pci_release_region(pdev, bar);
330 sdhci_free_host(host);
331
332 return ERR_PTR(ret);
333}
334
335static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
336{
337 sdhci_remove_host(slot->host);
338 pci_release_region(slot->chip->pdev, slot->pci_bar);
339 sdhci_free_host(slot->host);
340}
341
342static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
343 const struct pci_device_id *ent)
344{
345 struct sdhci_pci_chip *chip;
346 struct sdhci_pci_slot *slot;
347
348 u8 slots, rev, first_bar;
349 int ret, i;
350
351 BUG_ON(pdev == NULL);
352 BUG_ON(ent == NULL);
353
354 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
355
356 dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n",
357 (int)pdev->vendor, (int)pdev->device, (int)rev);
358
359 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
360 if (ret)
361 return ret;
362
363 slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
364 dev_dbg(&pdev->dev, "found %d slot(s)\n", slots);
365 if (slots == 0)
366 return -ENODEV;
367
368 BUG_ON(slots > MAX_SLOTS);
369
370 ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar);
371 if (ret)
372 return ret;
373
374 first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK;
375
376 if (first_bar > 5) {
377 dev_err(&pdev->dev, "Invalid first BAR. Aborting.\n");
378 return -ENODEV;
379 }
380
381 ret = pci_enable_device(pdev);
382 if (ret)
383 return ret;
384
385 chip = kzalloc(sizeof(struct sdhci_pci_chip), GFP_KERNEL);
386 if (!chip) {
387 ret = -ENOMEM;
388 goto err;
389 }
390
391 chip->pdev = pdev;
392 chip->quirks = ent->driver_data;
393 chip->num_slots = slots;
394
395 pci_set_drvdata(pdev, chip);
396
397 for (i = 0;i < slots;i++) {
398 slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i);
399 if (IS_ERR(slot)) {
400 for (i--;i >= 0;i--)
401 sdhci_pci_remove_slot(chip->slots[i]);
402 ret = PTR_ERR(slot);
403 goto free;
404 }
405
406 chip->slots[i] = slot;
407 }
408
409 return 0;
410
411free:
412 pci_set_drvdata(pdev, NULL);
413 kfree(chip);
414
415err:
416 pci_disable_device(pdev);
417 return ret;
418}
419
420static void __devexit sdhci_pci_remove(struct pci_dev *pdev)
421{
422 int i;
423 struct sdhci_pci_chip *chip;
424
425 chip = pci_get_drvdata(pdev);
426
427 if (chip) {
428 for (i = 0;i < chip->num_slots; i++)
429 sdhci_pci_remove_slot(chip->slots[i]);
430
431 pci_set_drvdata(pdev, NULL);
432 kfree(chip);
433 }
434
435 pci_disable_device(pdev);
436}
437
438static struct pci_driver sdhci_driver = {
439 .name = "sdhci-pci",
440 .id_table = pci_ids,
441 .probe = sdhci_pci_probe,
442 .remove = __devexit_p(sdhci_pci_remove),
443 .suspend = sdhci_pci_suspend,
444 .resume = sdhci_pci_resume,
445};
446
447/*****************************************************************************\
448 * *
449 * Driver init/exit *
450 * *
451\*****************************************************************************/
452
453static int __init sdhci_drv_init(void)
454{
455 return pci_register_driver(&sdhci_driver);
456}
457
458static void __exit sdhci_drv_exit(void)
459{
460 pci_unregister_driver(&sdhci_driver);
461}
462
463module_init(sdhci_drv_init);
464module_exit(sdhci_drv_exit);
465
466MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
467MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
468MODULE_LICENSE("GPL");