diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index dd1335e..0a87269 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -19,6 +19,7 @@
 #include "control.h"
 #include "iomap.h"
 #include <linux/platform_data/omap3-iva.h>
+#include <linux/platform_data/omap3-d2d.h>
 
 #include <plat/omap_hwmod.h>
 #include <mach/irqs.h>
@@ -2025,6 +2026,7 @@ static struct omap_hwmod_rst_info omap3xxx_sad2d_resets[] = {
 
 static struct omap_hwmod_class omap3xxx_sad2d_class = {
 	.name			= "sad2d",
+	.setup_preprogram	= hwmod_sad2d_preprogram,
 };
 
 static struct omap_hwmod omap3xxx_sad2d_hwmod = {
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index d407b32..f987c0d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -333,30 +333,6 @@ restore:
 
 #endif /* CONFIG_SUSPEND */
 
-static void __init omap3_d2d_idle(void)
-{
-	u16 mask, padconf;
-
-	/* In a stand alone OMAP3430 where there is not a stacked
-	 * modem for the D2D Idle Ack and D2D MStandby must be pulled
-	 * high. S CONTROL_PADCONF_SAD2D_IDLEACK and
-	 * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */
-	mask = (1 << 4) | (1 << 3); /* pull-up, enabled */
-	padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY);
-	padconf |= mask;
-	omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY);
-
-	padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK);
-	padconf |= mask;
-	omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
-
-	/* reset modem */
-	omap2_prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK |
-			  OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK,
-			  CORE_MOD, OMAP2_RM_RSTCTRL);
-	omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
-}
-
 static void __init prcm_setup_regs(void)
 {
 	u32 omap3630_en_uart4_mask = cpu_is_omap3630() ?
@@ -429,8 +405,6 @@ static void __init prcm_setup_regs(void)
 
 	/* Clear any pending PRCM interrupts */
 	omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
-
-	omap3_d2d_idle();
 }
 
 void omap3_pm_off_mode_enable(int enable)
diff --git a/include/linux/platform_data/omap3-d2d.h b/include/linux/platform_data/omap3-d2d.h
new file mode 100644
index 0000000..d8b44bb
--- /dev/null
+++ b/include/linux/platform_data/omap3-d2d.h
@@ -0,0 +1,61 @@
+/*
+ * OMAP3 Die 2 Die IP block integration
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Tero Kristo
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef __LINUX_PLATFORM_DATA_OMAP3_D2D_H__
+#define __LINUX_PLATFORM_DATA_OMAP3_D2D_H__
+
+#include <linux/kernel.h>
+
+#include <plat/omap_hwmod.h>
+
+/**
+ * hwmod_sad2d_preprogram - programs pull ups for sad2d interface
+ * @oh: pointer to iva2 hwmod
+ *
+ * In a stand alone OMAP3430 chip without a stacked modem, the D2D
+ * Idle Ack and D2D MStandy pads must be pulled
+ * high. So program CONTROL_PADCONF_SAD2D_IDLEACK and
+ * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. Always returns 0.
+ */
+static int __maybe_unused hwmod_sad2d_preprogram(struct omap_hwmod *oh)
+{
+	u16 mask, padconf;
+	int i;
+
+	mask = (1 << 4) | (1 << 3); /* pull-up, enabled */
+	padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY);
+	padconf |= mask;
+	omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY);
+
+	padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK);
+	padconf |= mask;
+	omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
+
+	/* reset modem */
+	for (i = 0; i < oh->rst_lines_cnt; i++)
+		omap_hwmod_assert_hardreset(oh, oh->rst_lines[i].name);
+
+	for (i = 0; i < oh->rst_lines_cnt; i++)
+		omap_hwmod_deassert_hardreset(oh, oh->rst_lines[i].name);
+
+	return 0;
+}
+
+#endif /* __LINUX_PLATFORM_DATA_OMAP3_D2D_H__ */
