aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@nokia.com>2009-09-22 19:44:50 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:35 -0400
commit9b7c18e070d59ba0acfdb936fd613dfa1d2a4e7d (patch)
treebb816920c3fdafd27ee59b4e1256843d136c8c8d /arch
parentdd498effcfa6a196ba097adae3c5aa641115df88 (diff)
ARM: OMAP: mmc-twl4030: add regulator sleep / wake function
Add the ability for the driver to put the card power regulators to sleep and wake them up again. Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com> Acked-by: Matt Fleming <matt@console-pimps.org> Cc: Ian Molton <ian@mnementh.co.uk> Cc: "Roberto A. Foglietta" <roberto.foglietta@gmail.com> Cc: Jarkko Lavinen <jarkko.lavinen@nokia.com> Cc: Denis Karpov <ext-denis.2.karpov@nokia.com> Cc: Pierre Ossman <pierre@ossman.eu> Cc: Philip Langdale <philipl@overt.org> Cc: "Madhusudhan" <madhu.cr@ti.com> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.c57
-rw-r--r--arch/arm/plat-omap/include/mach/mmc.h2
2 files changed, 59 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c
index cb1cbd7934ae..c9c59a2db4e2 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -340,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v
340 return ret; 340 return ret;
341} 341}
342 342
343static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd,
344 int cardsleep)
345{
346 struct twl_mmc_controller *c = &hsmmc[0];
347 int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
348
349 return regulator_set_mode(c->vcc, mode);
350}
351
352static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd,
353 int cardsleep)
354{
355 struct twl_mmc_controller *c = NULL;
356 struct omap_mmc_platform_data *mmc = dev->platform_data;
357 int i, err, mode;
358
359 for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
360 if (mmc == hsmmc[i].mmc) {
361 c = &hsmmc[i];
362 break;
363 }
364 }
365
366 if (c == NULL)
367 return -ENODEV;
368
369 /*
370 * If we don't see a Vcc regulator, assume it's a fixed
371 * voltage always-on regulator.
372 */
373 if (!c->vcc)
374 return 0;
375
376 mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
377
378 if (!c->vcc_aux)
379 return regulator_set_mode(c->vcc, mode);
380
381 if (cardsleep) {
382 /* VCC can be turned off if card is asleep */
383 struct regulator *vcc_aux = c->vcc_aux;
384
385 c->vcc_aux = NULL;
386 if (sleep)
387 err = twl_mmc23_set_power(dev, slot, 0, 0);
388 else
389 err = twl_mmc23_set_power(dev, slot, 1, vdd);
390 c->vcc_aux = vcc_aux;
391 } else
392 err = regulator_set_mode(c->vcc, mode);
393 if (err)
394 return err;
395 return regulator_set_mode(c->vcc_aux, mode);
396}
397
343static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; 398static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
344 399
345void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) 400void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -433,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
433 case 1: 488 case 1:
434 /* on-chip level shifting via PBIAS0/PBIAS1 */ 489 /* on-chip level shifting via PBIAS0/PBIAS1 */
435 mmc->slots[0].set_power = twl_mmc1_set_power; 490 mmc->slots[0].set_power = twl_mmc1_set_power;
491 mmc->slots[0].set_sleep = twl_mmc1_set_sleep;
436 break; 492 break;
437 case 2: 493 case 2:
438 if (c->ext_clock) 494 if (c->ext_clock)
@@ -443,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
443 case 3: 499 case 3:
444 /* off-chip level shifting, or none */ 500 /* off-chip level shifting, or none */
445 mmc->slots[0].set_power = twl_mmc23_set_power; 501 mmc->slots[0].set_power = twl_mmc23_set_power;
502 mmc->slots[0].set_sleep = twl_mmc23_set_sleep;
446 break; 503 break;
447 default: 504 default:
448 pr_err("MMC%d configuration not supported!\n", c->mmc); 505 pr_err("MMC%d configuration not supported!\n", c->mmc);
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index 82f1e29f5e53..939029742758 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -95,6 +95,8 @@ struct omap_mmc_platform_data {
95 int (* set_bus_mode)(struct device *dev, int slot, int bus_mode); 95 int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
96 int (* set_power)(struct device *dev, int slot, int power_on, int vdd); 96 int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
97 int (* get_ro)(struct device *dev, int slot); 97 int (* get_ro)(struct device *dev, int slot);
98 int (*set_sleep)(struct device *dev, int slot, int sleep,
99 int vdd, int cardsleep);
98 100
99 /* return MMC cover switch state, can be NULL if not supported. 101 /* return MMC cover switch state, can be NULL if not supported.
100 * 102 *