summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 13:46:56 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-25 13:46:56 -0700
commit7b6181e06841f5ad15c4ff708b967b4db65a64de (patch)
treebdfcf5b74b692f76581156e452d268b64c795200 /drivers/mmc
parent72e58063d63c5f0a7bf65312f1e3a5ed9bb5c2ff (diff)
parentbc487fb341af05120bccb9f59ce76302391dcc77 (diff)
Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6
* 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6: (163 commits) omap: complete removal of machine_desc.io_pg_offst and .phys_io omap: UART: fix wakeup registers for OMAP24xx UART2 omap: Fix spotty MMC voltages ASoC: OMAP4: MCPDM: Remove unnecessary include of plat/control.h serial: omap-serial: fix signess error OMAP3: DMA: Errata i541: sDMA FIFO draining does not finish omap: dma: Fix buffering disable bit setting for omap24xx omap: serial: Fix the boot-up crash/reboot without CONFIG_PM OMAP3: PM: fix scratchpad memory accesses for off-mode omap4: pandaboard: enable the ehci port on pandaboard omap4: pandaboard: Fix the init if CONFIG_MMC_OMAP_HS is not set omap4: pandaboard: remove unused hsmmc definition OMAP: McBSP: Remove null omap44xx ops comment OMAP: McBSP: Swap CLKS source definition OMAP: McBSP: Fix CLKR and FSR signal muxing OMAP2+: clock: reduce the amount of standard debugging while disabling unused clocks OMAP: control: move plat-omap/control.h to mach-omap2/control.h OMAP: split plat-omap/common.c OMAP: McBSP: implement functional clock switching via clock framework OMAP: McBSP: implement McBSP CLKR and FSR signal muxing via mach-omap2/mcbsp.c ... Fixed up trivial conflicts in arch/arm/mach-omap2/ {board-zoom-peripherals.c,devices.c} as per Tony
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4526d2791f2..4693e62145a 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -364,6 +364,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
{
struct regulator *reg;
int ret = 0;
+ int ocr_value = 0;
switch (host->id) {
case OMAP_MMC1_DEVID:
@@ -396,6 +397,17 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
}
} else {
host->vcc = reg;
+ ocr_value = mmc_regulator_get_ocrmask(reg);
+ if (!mmc_slot(host).ocr_mask) {
+ mmc_slot(host).ocr_mask = ocr_value;
+ } else {
+ if (!(mmc_slot(host).ocr_mask & ocr_value)) {
+ pr_err("MMC%d ocrmask %x is not supported\n",
+ host->id, mmc_slot(host).ocr_mask);
+ mmc_slot(host).ocr_mask = 0;
+ return -EINVAL;
+ }
+ }
mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg);
/* Allow an aux regulator */
@@ -982,6 +994,17 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host,
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | bit);
+ /*
+ * OMAP4 ES2 and greater has an updated reset logic.
+ * Monitor a 0->1 transition first
+ */
+ if (mmc_slot(host).features & HSMMC_HAS_UPDATED_RESET) {
+ while ((!(OMAP_HSMMC_READ(host, SYSCTL) & bit))
+ && (i++ < limit))
+ cpu_relax();
+ }
+ i = 0;
+
while ((OMAP_HSMMC_READ(host->base, SYSCTL) & bit) &&
(i++ < limit))
cpu_relax();
@@ -2003,6 +2026,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
if (res == NULL || irq < 0)
return -ENXIO;
+ res->start += pdata->reg_offset;
+ res->end += pdata->reg_offset;
res = request_mem_region(res->start, res->end - res->start + 1,
pdev->name);
if (res == NULL)
@@ -2116,23 +2141,9 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE;
- switch (mmc_slot(host).wires) {
- case 8:
- mmc->caps |= MMC_CAP_8_BIT_DATA;
- /* Fall through */
- case 4:
+ mmc->caps |= mmc_slot(host).caps;
+ if (mmc->caps & MMC_CAP_8_BIT_DATA)
mmc->caps |= MMC_CAP_4_BIT_DATA;
- break;
- case 1:
- /* Nothing to crib here */
- case 0:
- /* Assuming nothing was given by board, Core use's 1-Bit */
- break;
- default:
- /* Completely unexpected.. Core goes with 1-Bit Width */
- dev_crit(mmc_dev(host->mmc), "Invalid width %d\n used!"
- "using 1 instead\n", mmc_slot(host).wires);
- }
if (mmc_slot(host).nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;