diff options
author | David S. Miller <davem@davemloft.net> | 2009-09-24 18:13:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-24 18:13:11 -0400 |
commit | 8b3f6af86378d0a10ca2f1ded1da124aef13b62c (patch) | |
tree | de6ca90295730343c495be8d98be8efa322140ef /arch/arm/mach-omap2/mmc-twl4030.c | |
parent | 139d6065c83071d5f66cd013a274a43699f8e2c1 (diff) | |
parent | 94e0fb086fc5663c38bbc0fe86d698be8314f82f (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/cpc-usb/TODO
drivers/staging/cpc-usb/cpc-usb_drv.c
drivers/staging/cpc-usb/cpc.h
drivers/staging/cpc-usb/cpc_int.h
drivers/staging/cpc-usb/cpcusb.h
Diffstat (limited to 'arch/arm/mach-omap2/mmc-twl4030.c')
-rw-r--r-- | arch/arm/mach-omap2/mmc-twl4030.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c index 3c04c2f1b23f..c9c59a2db4e2 100644 --- a/arch/arm/mach-omap2/mmc-twl4030.c +++ b/arch/arm/mach-omap2/mmc-twl4030.c | |||
@@ -198,6 +198,18 @@ static int twl_mmc_resume(struct device *dev, int slot) | |||
198 | #define twl_mmc_resume NULL | 198 | #define twl_mmc_resume NULL |
199 | #endif | 199 | #endif |
200 | 200 | ||
201 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | ||
202 | |||
203 | static int twl4030_mmc_get_context_loss(struct device *dev) | ||
204 | { | ||
205 | /* FIXME: PM DPS not implemented yet */ | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | #else | ||
210 | #define twl4030_mmc_get_context_loss NULL | ||
211 | #endif | ||
212 | |||
201 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, | 213 | static int twl_mmc1_set_power(struct device *dev, int slot, int power_on, |
202 | int vdd) | 214 | int vdd) |
203 | { | 215 | { |
@@ -328,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v | |||
328 | return ret; | 340 | return ret; |
329 | } | 341 | } |
330 | 342 | ||
343 | static 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 | |||
352 | static 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 | |||
331 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; | 398 | static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; |
332 | 399 | ||
333 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | 400 | void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) |
@@ -390,6 +457,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
390 | } else | 457 | } else |
391 | mmc->slots[0].switch_pin = -EINVAL; | 458 | mmc->slots[0].switch_pin = -EINVAL; |
392 | 459 | ||
460 | mmc->get_context_loss_count = | ||
461 | twl4030_mmc_get_context_loss; | ||
462 | |||
393 | /* write protect normally uses an OMAP gpio */ | 463 | /* write protect normally uses an OMAP gpio */ |
394 | if (gpio_is_valid(c->gpio_wp)) { | 464 | if (gpio_is_valid(c->gpio_wp)) { |
395 | gpio_request(c->gpio_wp, "mmc_wp"); | 465 | gpio_request(c->gpio_wp, "mmc_wp"); |
@@ -400,6 +470,12 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
400 | } else | 470 | } else |
401 | mmc->slots[0].gpio_wp = -EINVAL; | 471 | mmc->slots[0].gpio_wp = -EINVAL; |
402 | 472 | ||
473 | if (c->nonremovable) | ||
474 | mmc->slots[0].nonremovable = 1; | ||
475 | |||
476 | if (c->power_saving) | ||
477 | mmc->slots[0].power_saving = 1; | ||
478 | |||
403 | /* NOTE: MMC slots should have a Vcc regulator set up. | 479 | /* NOTE: MMC slots should have a Vcc regulator set up. |
404 | * This may be from a TWL4030-family chip, another | 480 | * This may be from a TWL4030-family chip, another |
405 | * controllable regulator, or a fixed supply. | 481 | * controllable regulator, or a fixed supply. |
@@ -412,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
412 | case 1: | 488 | case 1: |
413 | /* on-chip level shifting via PBIAS0/PBIAS1 */ | 489 | /* on-chip level shifting via PBIAS0/PBIAS1 */ |
414 | 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; | ||
415 | break; | 492 | break; |
416 | case 2: | 493 | case 2: |
417 | if (c->ext_clock) | 494 | if (c->ext_clock) |
@@ -422,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers) | |||
422 | case 3: | 499 | case 3: |
423 | /* off-chip level shifting, or none */ | 500 | /* off-chip level shifting, or none */ |
424 | 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; | ||
425 | break; | 503 | break; |
426 | default: | 504 | default: |
427 | pr_err("MMC%d configuration not supported!\n", c->mmc); | 505 | pr_err("MMC%d configuration not supported!\n", c->mmc); |