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