aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/sdhci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/sdhci-pci.c')
-rw-r--r--drivers/mmc/host/sdhci-pci.c100
1 files changed, 93 insertions, 7 deletions
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index e0356644d1aa..6701af629c30 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -16,6 +16,7 @@
16#include <linux/highmem.h> 16#include <linux/highmem.h>
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/slab.h>
19 20
20#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
21 22
@@ -80,9 +81,6 @@ struct sdhci_pci_chip {
80 81
81static int ricoh_probe(struct sdhci_pci_chip *chip) 82static int ricoh_probe(struct sdhci_pci_chip *chip)
82{ 83{
83 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
84 chip->quirks |= SDHCI_QUIRK_CLOCK_BEFORE_RESET;
85
86 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || 84 if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG ||
87 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) 85 chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY)
88 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; 86 chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET;
@@ -92,7 +90,9 @@ static int ricoh_probe(struct sdhci_pci_chip *chip)
92 90
93static const struct sdhci_pci_fixes sdhci_ricoh = { 91static const struct sdhci_pci_fixes sdhci_ricoh = {
94 .probe = ricoh_probe, 92 .probe = ricoh_probe,
95 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, 93 .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR |
94 SDHCI_QUIRK_FORCE_DMA |
95 SDHCI_QUIRK_CLOCK_BEFORE_RESET,
96}; 96};
97 97
98static const struct sdhci_pci_fixes sdhci_ene_712 = { 98static const struct sdhci_pci_fixes sdhci_ene_712 = {
@@ -285,6 +285,73 @@ static const struct sdhci_pci_fixes sdhci_jmicron = {
285 .resume = jmicron_resume, 285 .resume = jmicron_resume,
286}; 286};
287 287
288/* SysKonnect CardBus2SDIO extra registers */
289#define SYSKT_CTRL 0x200
290#define SYSKT_RDFIFO_STAT 0x204
291#define SYSKT_WRFIFO_STAT 0x208
292#define SYSKT_POWER_DATA 0x20c
293#define SYSKT_POWER_330 0xef
294#define SYSKT_POWER_300 0xf8
295#define SYSKT_POWER_184 0xcc
296#define SYSKT_POWER_CMD 0x20d
297#define SYSKT_POWER_START (1 << 7)
298#define SYSKT_POWER_STATUS 0x20e
299#define SYSKT_POWER_STATUS_OK (1 << 0)
300#define SYSKT_BOARD_REV 0x210
301#define SYSKT_CHIP_REV 0x211
302#define SYSKT_CONF_DATA 0x212
303#define SYSKT_CONF_DATA_1V8 (1 << 2)
304#define SYSKT_CONF_DATA_2V5 (1 << 1)
305#define SYSKT_CONF_DATA_3V3 (1 << 0)
306
307static int syskt_probe(struct sdhci_pci_chip *chip)
308{
309 if ((chip->pdev->class & 0x0000FF) == PCI_SDHCI_IFVENDOR) {
310 chip->pdev->class &= ~0x0000FF;
311 chip->pdev->class |= PCI_SDHCI_IFDMA;
312 }
313 return 0;
314}
315
316static int syskt_probe_slot(struct sdhci_pci_slot *slot)
317{
318 int tm, ps;
319
320 u8 board_rev = readb(slot->host->ioaddr + SYSKT_BOARD_REV);
321 u8 chip_rev = readb(slot->host->ioaddr + SYSKT_CHIP_REV);
322 dev_info(&slot->chip->pdev->dev, "SysKonnect CardBus2SDIO, "
323 "board rev %d.%d, chip rev %d.%d\n",
324 board_rev >> 4, board_rev & 0xf,
325 chip_rev >> 4, chip_rev & 0xf);
326 if (chip_rev >= 0x20)
327 slot->host->quirks |= SDHCI_QUIRK_FORCE_DMA;
328
329 writeb(SYSKT_POWER_330, slot->host->ioaddr + SYSKT_POWER_DATA);
330 writeb(SYSKT_POWER_START, slot->host->ioaddr + SYSKT_POWER_CMD);
331 udelay(50);
332 tm = 10; /* Wait max 1 ms */
333 do {
334 ps = readw(slot->host->ioaddr + SYSKT_POWER_STATUS);
335 if (ps & SYSKT_POWER_STATUS_OK)
336 break;
337 udelay(100);
338 } while (--tm);
339 if (!tm) {
340 dev_err(&slot->chip->pdev->dev,
341 "power regulator never stabilized");
342 writeb(0, slot->host->ioaddr + SYSKT_POWER_CMD);
343 return -ENODEV;
344 }
345
346 return 0;
347}
348
349static const struct sdhci_pci_fixes sdhci_syskt = {
350 .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER,
351 .probe = syskt_probe,
352 .probe_slot = syskt_probe_slot,
353};
354
288static int via_probe(struct sdhci_pci_chip *chip) 355static int via_probe(struct sdhci_pci_chip *chip)
289{ 356{
290 if (chip->pdev->revision == 0x10) 357 if (chip->pdev->revision == 0x10)
@@ -363,6 +430,14 @@ static const struct pci_device_id pci_ids[] __devinitdata = {
363 }, 430 },
364 431
365 { 432 {
433 .vendor = PCI_VENDOR_ID_SYSKONNECT,
434 .device = 0x8000,
435 .subvendor = PCI_ANY_ID,
436 .subdevice = PCI_ANY_ID,
437 .driver_data = (kernel_ulong_t)&sdhci_syskt,
438 },
439
440 {
366 .vendor = PCI_VENDOR_ID_VIA, 441 .vendor = PCI_VENDOR_ID_VIA,
367 .device = 0x95d0, 442 .device = 0x95d0,
368 .subvendor = PCI_ANY_ID, 443 .subvendor = PCI_ANY_ID,
@@ -426,6 +501,7 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
426{ 501{
427 struct sdhci_pci_chip *chip; 502 struct sdhci_pci_chip *chip;
428 struct sdhci_pci_slot *slot; 503 struct sdhci_pci_slot *slot;
504 mmc_pm_flag_t pm_flags = 0;
429 int i, ret; 505 int i, ret;
430 506
431 chip = pci_get_drvdata(pdev); 507 chip = pci_get_drvdata(pdev);
@@ -444,6 +520,8 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
444 sdhci_resume_host(chip->slots[i]->host); 520 sdhci_resume_host(chip->slots[i]->host);
445 return ret; 521 return ret;
446 } 522 }
523
524 pm_flags |= slot->host->mmc->pm_flags;
447 } 525 }
448 526
449 if (chip->fixes && chip->fixes->suspend) { 527 if (chip->fixes && chip->fixes->suspend) {
@@ -456,9 +534,15 @@ static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
456 } 534 }
457 535
458 pci_save_state(pdev); 536 pci_save_state(pdev);
459 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); 537 if (pm_flags & MMC_PM_KEEP_POWER) {
460 pci_disable_device(pdev); 538 if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
461 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 539 pci_enable_wake(pdev, PCI_D3hot, 1);
540 pci_set_power_state(pdev, PCI_D3hot);
541 } else {
542 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
543 pci_disable_device(pdev);
544 pci_set_power_state(pdev, pci_choose_state(pdev, state));
545 }
462 546
463 return 0; 547 return 0;
464} 548}
@@ -578,6 +662,8 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
578 goto unmap; 662 goto unmap;
579 } 663 }
580 664
665 host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
666
581 ret = sdhci_add_host(host); 667 ret = sdhci_add_host(host);
582 if (ret) 668 if (ret)
583 goto remove; 669 goto remove;