diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h
index 3cb247b..15b9599 100644
--- a/arch/arm/mach-omap2/prm-regbits-44xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -81,6 +81,11 @@
 #define OMAP4430_AIPOFF_MASK						(1 << 8)
 
 /* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_DISABLED					0
+#define OMAP4430_AUTO_CTRL_VDD_SLEEP					1
+#define OMAP4430_AUTO_CTRL_VDD_RET					2
+
+/* Used by PRM_VOLTCTRL */
 #define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT				0
 #define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK				(0x3 << 0)
 
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index d217bbf..c607a0c 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -568,11 +568,63 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
 	__raw_writel(val, OMAP4_SCRM_CLKSETUPTIME);
 }
 
+/**
+ * omap4_vc_sleep - voltagedomain sleep entry callback
+ * @voltdm: domain which is entering idle
+ *
+ * This function is called once a voltagedomain is ready to enter idle.
+ * Sets up AUTO_RET / AUTO_SLEEP command to be sent through the I2C
+ * to the PMIC.
+ */
+static void omap4_vc_sleep(struct voltagedomain *voltdm)
+{
+	u32 val;
+	u32 voltctrl;
+
+	switch (voltdm->target_state) {
+	case PWRDM_POWER_OFF:
+	case PWRDM_POWER_RET:
+		val = OMAP4430_AUTO_CTRL_VDD_RET;
+		break;
+	default:
+		val = OMAP4430_AUTO_CTRL_VDD_SLEEP;
+		break;
+	}
+	voltctrl = voltdm->read(OMAP4_PRM_VOLTCTRL_OFFSET);
+
+	voltctrl &= ~(u32)voltdm->vc->voltctrl_mask;
+
+	voltctrl |= val << voltdm->vc->voltctrl_shift;
+
+	voltdm->write(voltctrl, OMAP4_PRM_VOLTCTRL_OFFSET);
+}
+
+/**
+ * omap4_vc_wakeup - voltagedomain wakeup callback
+ * @voltdm: domain which is leaving idle
+ *
+ * This function is called once a voltagedomain is becoming active.
+ * Disables AUTO_RET / AUTO_SLEEP for the domain.
+ */
+static void omap4_vc_wakeup(struct voltagedomain *voltdm)
+{
+	u32 voltctrl;
+
+	voltctrl = voltdm->read(OMAP4_PRM_VOLTCTRL_OFFSET);
+
+	voltctrl &= ~(u32)voltdm->vc->voltctrl_mask;
+
+	voltdm->write(voltctrl, OMAP4_PRM_VOLTCTRL_OFFSET);
+}
+
 /* OMAP4 specific voltage init functions */
 static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
 {
 	omap4_set_timings(voltdm, true);
 	omap4_set_timings(voltdm, false);
+
+	voltdm->sleep = omap4_vc_sleep;
+	voltdm->wakeup = omap4_vc_wakeup;
 }
 
 struct i2c_init_data {
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index 91c8d75..8357d57 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -79,6 +79,8 @@ struct omap_vc_common {
  * @smps_cmdra_reg: Offset of PRM_VC_SMPS_CMD_RA reg from PRM start
  * @cfg_channel_reg: VC channel configuration register
  * @cfg_channel_sa_shift: bit shift for slave address cfg_channel register
+ * @voltctrl_shift: bit shift for voltctrl register field
+ * @voltctrl_mask: bit mask for voltctrl register field
  * @flags: VC channel-specific flags (optional)
  */
 struct omap_vc_channel {
@@ -100,6 +102,8 @@ struct omap_vc_channel {
 	u8 smps_cmdra_reg;
 	u8 cfg_channel_reg;
 	u8 cfg_channel_sa_shift;
+	u8 voltctrl_shift;
+	u8 voltctrl_mask;
 	u8 flags;
 };
 
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index 085e5d6..a003a1f 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -59,6 +59,8 @@ struct omap_vc_channel omap4_vc_mpu = {
 	.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
 	.smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
 	.cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
+	.voltctrl_shift = OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT,
+	.voltctrl_mask = OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK,
 };
 
 struct omap_vc_channel omap4_vc_iva = {
@@ -72,6 +74,8 @@ struct omap_vc_channel omap4_vc_iva = {
 	.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
 	.smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
 	.cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
+	.voltctrl_shift = OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT,
+	.voltctrl_mask = OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK,
 };
 
 struct omap_vc_channel omap4_vc_core = {
@@ -85,6 +89,8 @@ struct omap_vc_channel omap4_vc_core = {
 	.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
 	.smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
 	.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
+	.voltctrl_shift = OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT,
+	.voltctrl_mask = OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK,
 };
 
 /*
