]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/mmc/host/sdhci-pci.c
sdhci: remove forced dma quirks
[linux-2.6-omap-h63xx.git] / drivers / mmc / host / sdhci-pci.c
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
41 static 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,
47                 .driver_data    = SDHCI_QUIRK_CLOCK_BEFORE_RESET,
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,
55                 .driver_data    = SDHCI_QUIRK_NO_CARD_NO_RESET,
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
122 MODULE_DEVICE_TABLE(pci, pci_ids);
123
124 struct sdhci_pci_chip;
125
126 struct sdhci_pci_slot {
127         struct sdhci_pci_chip   *chip;
128         struct sdhci_host       *host;
129
130         int                     pci_bar;
131 };
132
133 struct 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
147 static 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
172 static 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
184 static 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
216 static 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
258 static 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
325 unmap:
326         iounmap(host->ioaddr);
327
328 release:
329         pci_release_region(pdev, bar);
330         sdhci_free_host(host);
331
332         return ERR_PTR(ret);
333 }
334
335 static 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
342 static 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
411 free:
412         pci_set_drvdata(pdev, NULL);
413         kfree(chip);
414
415 err:
416         pci_disable_device(pdev);
417         return ret;
418 }
419
420 static 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
438 static 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
453 static int __init sdhci_drv_init(void)
454 {
455         return pci_register_driver(&sdhci_driver);
456 }
457
458 static void __exit sdhci_drv_exit(void)
459 {
460         pci_unregister_driver(&sdhci_driver);
461 }
462
463 module_init(sdhci_drv_init);
464 module_exit(sdhci_drv_exit);
465
466 MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
467 MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
468 MODULE_LICENSE("GPL");