diff options
Diffstat (limited to 'add-support-for-ricoh-e822-sdhci.patch')
-rw-r--r-- | add-support-for-ricoh-e822-sdhci.patch | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/add-support-for-ricoh-e822-sdhci.patch b/add-support-for-ricoh-e822-sdhci.patch new file mode 100644 index 0000000..93bc459 --- /dev/null +++ b/add-support-for-ricoh-e822-sdhci.patch @@ -0,0 +1,141 @@ +diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c +index e035664..3d7f790 100644 +--- a/drivers/mmc/host/sdhci-pci.c ++++ b/drivers/mmc/host/sdhci-pci.c +@@ -86,7 +86,30 @@ static int ricoh_probe(struct sdhci_pci_chip *chip) + if (chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG || + chip->pdev->subsystem_vendor == PCI_VENDOR_ID_SONY) + chip->quirks |= SDHCI_QUIRK_NO_CARD_NO_RESET; ++ return 0; ++} ++ ++static int ricoh_mmc_probe_slot(struct sdhci_pci_slot *slot) ++{ ++ slot->host->caps = ++ ((0x21 << SDHCI_TIMEOUT_CLK_SHIFT) ++ & SDHCI_TIMEOUT_CLK_MASK) | ++ ++ ((0x21 << SDHCI_CLOCK_BASE_SHIFT) ++ & SDHCI_CLOCK_BASE_MASK) | + ++ SDHCI_TIMEOUT_CLK_UNIT | ++ SDHCI_CAN_VDD_330 | ++ SDHCI_CAN_DO_SDMA; ++ return 0; ++} ++ ++static int ricoh_mmc_resume(struct sdhci_pci_chip *chip) ++{ ++ /* Apply a delay to allow controller to settle */ ++ /* Otherwise it becomes confused if card state changed ++ during suspend */ ++ msleep(500); + return 0; + } + +@@ -95,6 +118,15 @@ static const struct sdhci_pci_fixes sdhci_ricoh = { + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR, + }; + ++static const struct sdhci_pci_fixes sdhci_ricoh_mmc = { ++ .probe_slot = ricoh_mmc_probe_slot, ++ .resume = ricoh_mmc_resume, ++ .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | ++ SDHCI_QUIRK_CLOCK_BEFORE_RESET | ++ SDHCI_QUIRK_NO_CARD_NO_RESET | ++ SDHCI_QUIRK_MISSING_CAPS ++}; ++ + static const struct sdhci_pci_fixes sdhci_ene_712 = { + .quirks = SDHCI_QUIRK_SINGLE_POWER_WRITE | + SDHCI_QUIRK_BROKEN_DMA, +@@ -307,6 +339,22 @@ static const struct pci_device_id pci_ids[] __devinitdata = { + }, + + { ++ .vendor = PCI_VENDOR_ID_RICOH, ++ .device = 0x843, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc, ++ }, ++ ++ { ++ .vendor = PCI_VENDOR_ID_RICOH, ++ .device = 0xe822, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .driver_data = (kernel_ulong_t)&sdhci_ricoh_mmc, ++ }, ++ ++ { + .vendor = PCI_VENDOR_ID_ENE, + .device = PCI_DEVICE_ID_ENE_CB712_SD, + .subvendor = PCI_ANY_ID, +diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c +index c279fbc..7d4bff0 100644 +--- a/drivers/mmc/host/sdhci.c ++++ b/drivers/mmc/host/sdhci.c +@@ -1147,6 +1147,11 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + ++ if (ios->bus_width == MMC_BUS_WIDTH_8) ++ ctrl |= SDHCI_CTRL_8BITBUS; ++ else ++ ctrl &= ~SDHCI_CTRL_8BITBUS; ++ + if (ios->bus_width == MMC_BUS_WIDTH_4) + ctrl |= SDHCI_CTRL_4BITBUS; + else +@@ -1678,7 +1683,8 @@ int sdhci_add_host(struct sdhci_host *host) + host->version); + } + +- caps = sdhci_readl(host, SDHCI_CAPABILITIES); ++ caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : ++ sdhci_readl(host, SDHCI_CAPABILITIES); + + if (host->quirks & SDHCI_QUIRK_FORCE_DMA) + host->flags |= SDHCI_USE_SDMA; +diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h +index ce5f1d7..b5e2761 100644 +--- a/drivers/mmc/host/sdhci.h ++++ b/drivers/mmc/host/sdhci.h +@@ -70,6 +70,7 @@ + #define SDHCI_CTRL_ADMA1 0x08 + #define SDHCI_CTRL_ADMA32 0x10 + #define SDHCI_CTRL_ADMA64 0x18 ++#define SDHCI_CTRL_8BITBUS 0x20 + + #define SDHCI_POWER_CONTROL 0x29 + #define SDHCI_POWER_ON 0x01 +@@ -125,7 +126,7 @@ + #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ +- SDHCI_INT_DATA_END_BIT | SDHCI_ADMA_ERROR) ++ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR) + #define SDHCI_INT_ALL_MASK ((unsigned int)-1) + + #define SDHCI_ACMD12_ERR 0x3C +@@ -235,6 +236,10 @@ struct sdhci_host { + /* Controller uses SDCLK instead of TMCLK for data timeouts */ + #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK (1<<24) + ++/* RHEL6 miss some quirks */ ++ ++/* Controller is missing device caps. Use caps provided by host */ ++#define SDHCI_QUIRK_MISSING_CAPS (1<<28) + int irq; /* Device IRQ */ + void __iomem * ioaddr; /* Mapped address */ + +@@ -286,6 +291,8 @@ struct sdhci_host { + + struct timer_list timer; /* Timer for timeouts */ + ++ unsigned int caps; /* Alternative capabilities */ ++ + unsigned long private[0] ____cacheline_aligned; + }; + |