diff options
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 039e87b71442..81d19d5683ac 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2533,6 +2533,91 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1518, quirk_i82576_sriov); | |||
2533 | 2533 | ||
2534 | #endif /* CONFIG_PCI_IOV */ | 2534 | #endif /* CONFIG_PCI_IOV */ |
2535 | 2535 | ||
2536 | /* | ||
2537 | * This is a quirk for the Ricoh MMC controller found as a part of | ||
2538 | * some mulifunction chips. | ||
2539 | |||
2540 | * This is very similiar and based on the ricoh_mmc driver written by | ||
2541 | * Philip Langdale. Thank you for these magic sequences. | ||
2542 | * | ||
2543 | * These chips implement the four main memory card controllers (SD, MMC, MS, xD) | ||
2544 | * and one or both of cardbus or firewire. | ||
2545 | * | ||
2546 | * It happens that they implement SD and MMC | ||
2547 | * support as separate controllers (and PCI functions). The linux SDHCI | ||
2548 | * driver supports MMC cards but the chip detects MMC cards in hardware | ||
2549 | * and directs them to the MMC controller - so the SDHCI driver never sees | ||
2550 | * them. | ||
2551 | * | ||
2552 | * To get around this, we must disable the useless MMC controller. | ||
2553 | * At that point, the SDHCI controller will start seeing them | ||
2554 | * It seems to be the case that the relevant PCI registers to deactivate the | ||
2555 | * MMC controller live on PCI function 0, which might be the cardbus controller | ||
2556 | * or the firewire controller, depending on the particular chip in question | ||
2557 | * | ||
2558 | * This has to be done early, because as soon as we disable the MMC controller | ||
2559 | * other pci functions shift up one level, e.g. function #2 becomes function | ||
2560 | * #1, and this will confuse the pci core. | ||
2561 | */ | ||
2562 | |||
2563 | #ifdef CONFIG_MMC_RICOH_MMC | ||
2564 | static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev) | ||
2565 | { | ||
2566 | /* disable via cardbus interface */ | ||
2567 | u8 write_enable; | ||
2568 | u8 write_target; | ||
2569 | u8 disable; | ||
2570 | |||
2571 | /* disable must be done via function #0 */ | ||
2572 | if (PCI_FUNC(dev->devfn)) | ||
2573 | return; | ||
2574 | |||
2575 | pci_read_config_byte(dev, 0xB7, &disable); | ||
2576 | if (disable & 0x02) | ||
2577 | return; | ||
2578 | |||
2579 | pci_read_config_byte(dev, 0x8E, &write_enable); | ||
2580 | pci_write_config_byte(dev, 0x8E, 0xAA); | ||
2581 | pci_read_config_byte(dev, 0x8D, &write_target); | ||
2582 | pci_write_config_byte(dev, 0x8D, 0xB7); | ||
2583 | pci_write_config_byte(dev, 0xB7, disable | 0x02); | ||
2584 | pci_write_config_byte(dev, 0x8E, write_enable); | ||
2585 | pci_write_config_byte(dev, 0x8D, write_target); | ||
2586 | |||
2587 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n"); | ||
2588 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2589 | } | ||
2590 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2591 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476); | ||
2592 | |||
2593 | static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | ||
2594 | { | ||
2595 | /* disable via firewire interface */ | ||
2596 | u8 write_enable; | ||
2597 | u8 disable; | ||
2598 | |||
2599 | /* disable must be done via function #0 */ | ||
2600 | if (PCI_FUNC(dev->devfn)) | ||
2601 | return; | ||
2602 | |||
2603 | pci_read_config_byte(dev, 0xCB, &disable); | ||
2604 | |||
2605 | if (disable & 0x02) | ||
2606 | return; | ||
2607 | |||
2608 | pci_read_config_byte(dev, 0xCA, &write_enable); | ||
2609 | pci_write_config_byte(dev, 0xCA, 0x57); | ||
2610 | pci_write_config_byte(dev, 0xCB, disable | 0x02); | ||
2611 | pci_write_config_byte(dev, 0xCA, write_enable); | ||
2612 | |||
2613 | dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n"); | ||
2614 | dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n"); | ||
2615 | } | ||
2616 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2617 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | ||
2618 | #endif /*CONFIG_MMC_RICOH_MMC*/ | ||
2619 | |||
2620 | |||
2536 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2621 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2537 | struct pci_fixup *end) | 2622 | struct pci_fixup *end) |
2538 | { | 2623 | { |