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>
This commit is contained in:
parent
dd498effcf
commit
9b7c18e070
|
@ -340,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd,
|
||||||
|
int cardsleep)
|
||||||
|
{
|
||||||
|
struct twl_mmc_controller *c = &hsmmc[0];
|
||||||
|
int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
|
||||||
|
|
||||||
|
return regulator_set_mode(c->vcc, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd,
|
||||||
|
int cardsleep)
|
||||||
|
{
|
||||||
|
struct twl_mmc_controller *c = NULL;
|
||||||
|
struct omap_mmc_platform_data *mmc = dev->platform_data;
|
||||||
|
int i, err, mode;
|
||||||
|
|
||||||
|
for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
|
||||||
|
if (mmc == hsmmc[i].mmc) {
|
||||||
|
c = &hsmmc[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == NULL)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we don't see a Vcc regulator, assume it's a fixed
|
||||||
|
* voltage always-on regulator.
|
||||||
|
*/
|
||||||
|
if (!c->vcc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
|
||||||
|
|
||||||
|
if (!c->vcc_aux)
|
||||||
|
return regulator_set_mode(c->vcc, mode);
|
||||||
|
|
||||||
|
if (cardsleep) {
|
||||||
|
/* VCC can be turned off if card is asleep */
|
||||||
|
struct regulator *vcc_aux = c->vcc_aux;
|
||||||
|
|
||||||
|
c->vcc_aux = NULL;
|
||||||
|
if (sleep)
|
||||||
|
err = twl_mmc23_set_power(dev, slot, 0, 0);
|
||||||
|
else
|
||||||
|
err = twl_mmc23_set_power(dev, slot, 1, vdd);
|
||||||
|
c->vcc_aux = vcc_aux;
|
||||||
|
} else
|
||||||
|
err = regulator_set_mode(c->vcc, mode);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
return regulator_set_mode(c->vcc_aux, mode);
|
||||||
|
}
|
||||||
|
|
||||||
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
|
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
|
||||||
|
|
||||||
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
||||||
|
@ -433,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
||||||
case 1:
|
case 1:
|
||||||
/* on-chip level shifting via PBIAS0/PBIAS1 */
|
/* on-chip level shifting via PBIAS0/PBIAS1 */
|
||||||
mmc->slots[0].set_power = twl_mmc1_set_power;
|
mmc->slots[0].set_power = twl_mmc1_set_power;
|
||||||
|
mmc->slots[0].set_sleep = twl_mmc1_set_sleep;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (c->ext_clock)
|
if (c->ext_clock)
|
||||||
|
@ -443,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
||||||
case 3:
|
case 3:
|
||||||
/* off-chip level shifting, or none */
|
/* off-chip level shifting, or none */
|
||||||
mmc->slots[0].set_power = twl_mmc23_set_power;
|
mmc->slots[0].set_power = twl_mmc23_set_power;
|
||||||
|
mmc->slots[0].set_sleep = twl_mmc23_set_sleep;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("MMC%d configuration not supported!\n", c->mmc);
|
pr_err("MMC%d configuration not supported!\n", c->mmc);
|
||||||
|
|
|
@ -95,6 +95,8 @@ struct omap_mmc_platform_data {
|
||||||
int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
|
int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
|
||||||
int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
|
int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
|
||||||
int (* get_ro)(struct device *dev, int slot);
|
int (* get_ro)(struct device *dev, int slot);
|
||||||
|
int (*set_sleep)(struct device *dev, int slot, int sleep,
|
||||||
|
int vdd, int cardsleep);
|
||||||
|
|
||||||
/* return MMC cover switch state, can be NULL if not supported.
|
/* return MMC cover switch state, can be NULL if not supported.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue