summary refs log tree commit diff
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig3
-rw-r--r--arch/arm/plat-omap/clock.c51
-rw-r--r--arch/arm/plat-omap/counter_32k.c123
-rw-r--r--arch/arm/plat-omap/dmtimer.c213
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev.h13
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h1
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h4
-rw-r--r--arch/arm/plat-omap/include/plat/common.h6
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h35
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h251
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h20
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h6
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h18
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h74
-rw-r--r--arch/arm/plat-omap/include/plat/nand.h6
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h8
-rw-r--r--arch/arm/plat-omap/include/plat/omap4-keypad.h3
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h9
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h35
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h1
-rw-r--r--arch/arm/plat-omap/iovmm.c6
-rw-r--r--arch/arm/plat-omap/mcbsp.c604
-rw-r--r--arch/arm/plat-omap/omap_device.c147
-rw-r--r--arch/arm/plat-omap/sram.c15
24 files changed, 610 insertions, 1042 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 49a4c75243fc..6e6735f04ee3 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -211,9 +211,6 @@ choice
 	depends on ARCH_OMAP
 	default OMAP_PM_NOOP
 
-config OMAP_PM_NONE
-	bool "No PM layer"
-
 config OMAP_PM_NOOP
 	bool "No-op/debug PM layer"
 
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index c9122dd6ee8d..3ba4d11ca73e 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -475,18 +475,48 @@ int __init clk_init(struct clk_functions * custom_clocks)
 /*
  *	debugfs support to trace clock tree hierarchy and attributes
  */
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
 static struct dentry *clk_debugfs_root;
 
+static int clk_dbg_show_summary(struct seq_file *s, void *unused)
+{
+	struct clk *c;
+	struct clk *pa;
+
+	seq_printf(s, "%-30s %-30s %-10s %s\n",
+		"clock-name", "parent-name", "rate", "use-count");
+
+	list_for_each_entry(c, &clocks, node) {
+		pa = c->parent;
+		seq_printf(s, "%-30s %-30s %-10lu %d\n",
+			c->name, pa ? pa->name : "none", c->rate, c->usecount);
+	}
+
+	return 0;
+}
+
+static int clk_dbg_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, clk_dbg_show_summary, inode->i_private);
+}
+
+static const struct file_operations debug_clock_fops = {
+	.open           = clk_dbg_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
 static int clk_debugfs_register_one(struct clk *c)
 {
 	int err;
-	struct dentry *d, *child, *child_tmp;
+	struct dentry *d;
 	struct clk *pa = c->parent;
-	char s[255];
-	char *p = s;
 
-	p += sprintf(p, "%s", c->name);
-	d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
+	d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root);
 	if (!d)
 		return -ENOMEM;
 	c->dent = d;
@@ -509,10 +539,7 @@ static int clk_debugfs_register_one(struct clk *c)
 	return 0;
 
 err_out:
-	d = c->dent;
-	list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
-		debugfs_remove(child);
-	debugfs_remove(c->dent);
+	debugfs_remove_recursive(c->dent);
 	return err;
 }
 
@@ -551,6 +578,12 @@ static int __init clk_debugfs_init(void)
 		if (err)
 			goto err_out;
 	}
+
+	d = debugfs_create_file("summary", S_IRUGO,
+		d, NULL, &debug_clock_fops);
+	if (!d)
+		return -ENOMEM;
+
 	return 0;
 err_out:
 	debugfs_remove_recursive(clk_debugfs_root);
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index f7fed6080190..a6cbb712da51 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -18,6 +18,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/sched.h>
+#include <linux/clocksource.h>
 
 #include <asm/sched_clock.h>
 
@@ -26,87 +27,16 @@
 
 #include <plat/clock.h>
 
-
 /*
  * 32KHz clocksource ... always available, on pretty most chips except
  * OMAP 730 and 1510.  Other timers could be used as clocksources, with
  * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
  * but systems won't necessarily want to spend resources that way.
  */
+static void __iomem *timer_32k_base;
 
 #define OMAP16XX_TIMER_32K_SYNCHRONIZED		0xfffbc410
 
-#include <linux/clocksource.h>
-
-/*
- * offset_32k holds the init time counter value. It is then subtracted
- * from every counter read to achieve a counter that counts time from the
- * kernel boot (needed for sched_clock()).
- */
-static u32 offset_32k __read_mostly;
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static cycle_t notrace omap16xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
-}
-#else
-#define omap16xx_32k_read	NULL
-#endif
-
-#ifdef CONFIG_SOC_OMAP2420
-static cycle_t notrace omap2420_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2420_32k_read	NULL
-#endif
-
-#ifdef CONFIG_SOC_OMAP2430
-static cycle_t notrace omap2430_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2430_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-static cycle_t notrace omap34xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap34xx_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static cycle_t notrace omap44xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap44xx_32k_read	NULL
-#endif
-
-/*
- * Kernel assumes that sched_clock can be called early but may not have
- * things ready yet.
- */
-static cycle_t notrace omap_32k_read_dummy(struct clocksource *cs)
-{
-	return 0;
-}
-
-static struct clocksource clocksource_32k = {
-	.name		= "32k_counter",
-	.rating		= 250,
-	.read		= omap_32k_read_dummy,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 /*
  * Returns current time from boot in nsecs. It's OK for this to wrap
  * around for now, as it's just a relative time stamp.
@@ -122,11 +52,11 @@ static DEFINE_CLOCK_DATA(cd);
 
 static inline unsigned long long notrace _omap_32k_sched_clock(void)
 {
-	u32 cyc = clocksource_32k.read(&clocksource_32k);
+	u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
 	return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
 }
 
-#ifndef CONFIG_OMAP_MPU_TIMER
+#if defined(CONFIG_OMAP_32K_TIMER) && !defined(CONFIG_OMAP_MPU_TIMER)
 unsigned long long notrace sched_clock(void)
 {
 	return _omap_32k_sched_clock();
@@ -140,7 +70,7 @@ unsigned long long notrace omap_32k_sched_clock(void)
 
 static void notrace omap_update_sched_clock(void)
 {
-	u32 cyc = clocksource_32k.read(&clocksource_32k);
+	u32 cyc = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
 	update_sched_clock(&cd, cyc, (u32)~0);
 }
 
@@ -153,6 +83,7 @@ static void notrace omap_update_sched_clock(void)
  */
 static struct timespec persistent_ts;
 static cycles_t cycles, last_cycles;
+static unsigned int persistent_mult, persistent_shift;
 void read_persistent_clock(struct timespec *ts)
 {
 	unsigned long long nsecs;
@@ -160,11 +91,10 @@ void read_persistent_clock(struct timespec *ts)
 	struct timespec *tsp = &persistent_ts;
 
 	last_cycles = cycles;
-	cycles = clocksource_32k.read(&clocksource_32k);
+	cycles = timer_32k_base ? __raw_readl(timer_32k_base) : 0;
 	delta = cycles - last_cycles;
 
-	nsecs = clocksource_cyc2ns(delta,
-				   clocksource_32k.mult, clocksource_32k.shift);
+	nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
 
 	timespec_add_ns(tsp, nsecs);
 	*ts = *tsp;
@@ -176,29 +106,46 @@ int __init omap_init_clocksource_32k(void)
 			"%s: can't register clocksource!\n";
 
 	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
+		u32 pbase;
+		unsigned long size = SZ_4K;
+		void __iomem *base;
 		struct clk *sync_32k_ick;
 
-		if (cpu_is_omap16xx())
-			clocksource_32k.read = omap16xx_32k_read;
-		else if (cpu_is_omap2420())
-			clocksource_32k.read = omap2420_32k_read;
+		if (cpu_is_omap16xx()) {
+			pbase = OMAP16XX_TIMER_32K_SYNCHRONIZED;
+			size = SZ_1K;
+		} else if (cpu_is_omap2420())
+			pbase = OMAP2420_32KSYNCT_BASE + 0x10;
 		else if (cpu_is_omap2430())
-			clocksource_32k.read = omap2430_32k_read;
+			pbase = OMAP2430_32KSYNCT_BASE + 0x10;
 		else if (cpu_is_omap34xx())
-			clocksource_32k.read = omap34xx_32k_read;
+			pbase = OMAP3430_32KSYNCT_BASE + 0x10;
 		else if (cpu_is_omap44xx())
-			clocksource_32k.read = omap44xx_32k_read;
+			pbase = OMAP4430_32KSYNCT_BASE + 0x10;
 		else
 			return -ENODEV;
 
+		/* For this to work we must have a static mapping in io.c for this area */
+		base = ioremap(pbase, size);
+		if (!base)
+			return -ENODEV;
+
 		sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
 		if (!IS_ERR(sync_32k_ick))
 			clk_enable(sync_32k_ick);
 
-		offset_32k = clocksource_32k.read(&clocksource_32k);
+		timer_32k_base = base;
+
+		/*
+		 * 120000 rough estimate from the calculations in
+		 * __clocksource_updatefreq_scale.
+		 */
+		clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
+				32768, NSEC_PER_SEC, 120000);
 
-		if (clocksource_register_hz(&clocksource_32k, 32768))
-			printk(err, clocksource_32k.name);
+		if (clocksource_mmio_init(base, "32k_counter", 32768, 250, 32,
+					  clocksource_mmio_readl_up))
+			printk(err, "32k_counter");
 
 		init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
 				       32768, SC_MULT, SC_SHIFT);
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index ee9f6ebba29b..75a847dd776a 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -41,127 +41,6 @@
 #include <plat/dmtimer.h>
 #include <mach/irqs.h>
 
-/* register offsets */
-#define _OMAP_TIMER_ID_OFFSET		0x00
-#define _OMAP_TIMER_OCP_CFG_OFFSET	0x10
-#define _OMAP_TIMER_SYS_STAT_OFFSET	0x14
-#define _OMAP_TIMER_STAT_OFFSET		0x18
-#define _OMAP_TIMER_INT_EN_OFFSET	0x1c
-#define _OMAP_TIMER_WAKEUP_EN_OFFSET	0x20
-#define _OMAP_TIMER_CTRL_OFFSET		0x24
-#define		OMAP_TIMER_CTRL_GPOCFG		(1 << 14)
-#define		OMAP_TIMER_CTRL_CAPTMODE	(1 << 13)
-#define		OMAP_TIMER_CTRL_PT		(1 << 12)
-#define		OMAP_TIMER_CTRL_TCM_LOWTOHIGH	(0x1 << 8)
-#define		OMAP_TIMER_CTRL_TCM_HIGHTOLOW	(0x2 << 8)
-#define		OMAP_TIMER_CTRL_TCM_BOTHEDGES	(0x3 << 8)
-#define		OMAP_TIMER_CTRL_SCPWM		(1 << 7)
-#define		OMAP_TIMER_CTRL_CE		(1 << 6) /* compare enable */
-#define		OMAP_TIMER_CTRL_PRE		(1 << 5) /* prescaler enable */
-#define		OMAP_TIMER_CTRL_PTV_SHIFT	2 /* prescaler value shift */
-#define		OMAP_TIMER_CTRL_POSTED		(1 << 2)
-#define		OMAP_TIMER_CTRL_AR		(1 << 1) /* auto-reload enable */
-#define		OMAP_TIMER_CTRL_ST		(1 << 0) /* start timer */
-#define _OMAP_TIMER_COUNTER_OFFSET	0x28
-#define _OMAP_TIMER_LOAD_OFFSET		0x2c
-#define _OMAP_TIMER_TRIGGER_OFFSET	0x30
-#define _OMAP_TIMER_WRITE_PEND_OFFSET	0x34
-#define		WP_NONE			0	/* no write pending bit */
-#define		WP_TCLR			(1 << 0)
-#define		WP_TCRR			(1 << 1)
-#define		WP_TLDR			(1 << 2)
-#define		WP_TTGR			(1 << 3)
-#define		WP_TMAR			(1 << 4)
-#define		WP_TPIR			(1 << 5)
-#define		WP_TNIR			(1 << 6)
-#define		WP_TCVR			(1 << 7)
-#define		WP_TOCR			(1 << 8)
-#define		WP_TOWR			(1 << 9)
-#define _OMAP_TIMER_MATCH_OFFSET	0x38
-#define _OMAP_TIMER_CAPTURE_OFFSET	0x3c
-#define _OMAP_TIMER_IF_CTRL_OFFSET	0x40
-#define _OMAP_TIMER_CAPTURE2_OFFSET		0x44	/* TCAR2, 34xx only */
-#define _OMAP_TIMER_TICK_POS_OFFSET		0x48	/* TPIR, 34xx only */
-#define _OMAP_TIMER_TICK_NEG_OFFSET		0x4c	/* TNIR, 34xx only */
-#define _OMAP_TIMER_TICK_COUNT_OFFSET		0x50	/* TCVR, 34xx only */
-#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET	0x54	/* TOCR, 34xx only */
-#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET	0x58	/* TOWR, 34xx only */
-
-/* register offsets with the write pending bit encoded */
-#define	WPSHIFT					16
-
-#define OMAP_TIMER_ID_REG			(_OMAP_TIMER_ID_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_OCP_CFG_REG			(_OMAP_TIMER_OCP_CFG_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_SYS_STAT_REG			(_OMAP_TIMER_SYS_STAT_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_STAT_REG			(_OMAP_TIMER_STAT_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_INT_EN_REG			(_OMAP_TIMER_INT_EN_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_WAKEUP_EN_REG		(_OMAP_TIMER_WAKEUP_EN_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_CTRL_REG			(_OMAP_TIMER_CTRL_OFFSET \
-							| (WP_TCLR << WPSHIFT))
-
-#define OMAP_TIMER_COUNTER_REG			(_OMAP_TIMER_COUNTER_OFFSET \
-							| (WP_TCRR << WPSHIFT))
-
-#define OMAP_TIMER_LOAD_REG			(_OMAP_TIMER_LOAD_OFFSET \
-							| (WP_TLDR << WPSHIFT))
-
-#define OMAP_TIMER_TRIGGER_REG			(_OMAP_TIMER_TRIGGER_OFFSET \
-							| (WP_TTGR << WPSHIFT))
-
-#define OMAP_TIMER_WRITE_PEND_REG		(_OMAP_TIMER_WRITE_PEND_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_MATCH_REG			(_OMAP_TIMER_MATCH_OFFSET \
-							| (WP_TMAR << WPSHIFT))
-
-#define OMAP_TIMER_CAPTURE_REG			(_OMAP_TIMER_CAPTURE_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_IF_CTRL_REG			(_OMAP_TIMER_IF_CTRL_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_CAPTURE2_REG			(_OMAP_TIMER_CAPTURE2_OFFSET \
-							| (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_TICK_POS_REG			(_OMAP_TIMER_TICK_POS_OFFSET \
-							| (WP_TPIR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_NEG_REG			(_OMAP_TIMER_TICK_NEG_OFFSET \
-							| (WP_TNIR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_COUNT_REG		(_OMAP_TIMER_TICK_COUNT_OFFSET \
-							| (WP_TCVR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_INT_MASK_SET_REG				\
-		(_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\
-		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
-
-struct omap_dm_timer {
-	unsigned long phys_base;
-	int irq;
-#ifdef CONFIG_ARCH_OMAP2PLUS
-	struct clk *iclk, *fclk;
-#endif
-	void __iomem *io_base;
-	unsigned reserved:1;
-	unsigned enabled:1;
-	unsigned posted:1;
-};
-
 static int dm_timer_count;
 
 #ifdef CONFIG_ARCH_OMAP1
@@ -291,11 +170,7 @@ static spinlock_t dm_timer_lock;
  */
 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
 {
-	if (timer->posted)
-		while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
-				& (reg >> WPSHIFT))
-			cpu_relax();
-	return readl(timer->io_base + (reg & 0xff));
+	return __omap_dm_timer_read(timer->io_base, reg, timer->posted);
 }
 
 /*
@@ -307,11 +182,7 @@ static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
 						u32 value)
 {
-	if (timer->posted)
-		while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
-				& (reg >> WPSHIFT))
-			cpu_relax();
-	writel(value, timer->io_base + (reg & 0xff));
+	__omap_dm_timer_write(timer->io_base, reg, value, timer->posted);
 }
 
 static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
@@ -330,7 +201,7 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
 
 static void omap_dm_timer_reset(struct omap_dm_timer *timer)
 {
-	u32 l;
+	int autoidle = 0, wakeup = 0;
 
 	if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
 		omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
@@ -338,28 +209,21 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer)
 	}
 	omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
 
-	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
-	l |= 0x02 << 3;  /* Set to smart-idle mode */
-	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
-
-	/* Enable autoidle on OMAP2 / OMAP3 */
-	if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		l |= 0x1 << 0;
+	/* Enable autoidle on OMAP2+ */
+	if (cpu_class_is_omap2())
+		autoidle = 1;
 
 	/*
 	 * Enable wake-up on OMAP2 CPUs.
 	 */
 	if (cpu_class_is_omap2())
-		l |= 1 << 2;
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
+		wakeup = 1;
 
-	/* Match hardware reset default of posted mode */
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
-			OMAP_TIMER_CTRL_POSTED);
+	__omap_dm_timer_reset(timer->io_base, autoidle, wakeup);
 	timer->posted = 1;
 }
 
-static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
+void omap_dm_timer_prepare(struct omap_dm_timer *timer)
 {
 	omap_dm_timer_enable(timer);
 	omap_dm_timer_reset(timer);
@@ -531,25 +395,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 
 void omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
-	u32 l;
+	unsigned long rate = 0;
 
-	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
-	if (l & OMAP_TIMER_CTRL_ST) {
-		l &= ~0x1;
-		omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 #ifdef CONFIG_ARCH_OMAP2PLUS
-		/* Readback to make sure write has completed */
-		omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
-		 /*
-		  * Wait for functional clock period x 3.5 to make sure that
-		  * timer is stopped
-		  */
-		udelay(3500000 / clk_get_rate(timer->fclk) + 1);
+	rate = clk_get_rate(timer->fclk);
 #endif
-	}
-	/* Ack possibly pending interrupt */
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
-			OMAP_TIMER_INT_OVERFLOW);
+
+	__omap_dm_timer_stop(timer->io_base, timer->posted, rate);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
@@ -572,22 +424,11 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
-	int ret = -EINVAL;
-
 	if (source < 0 || source >= 3)
 		return -EINVAL;
 
-	clk_disable(timer->fclk);
-	ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
-	clk_enable(timer->fclk);
-
-	/*
-	 * When the functional clock disappears, too quick writes seem
-	 * to cause an abort. XXX Is this still necessary?
-	 */
-	__delay(300000);
-
-	return ret;
+	return __omap_dm_timer_set_source(timer->fclk,
+						dm_source_clocks[source]);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
@@ -625,8 +466,7 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
 	}
 	l |= OMAP_TIMER_CTRL_ST;
 
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+	__omap_dm_timer_load_start(timer->io_base, l, load, timer->posted);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
 
@@ -679,8 +519,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
 void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
 				  unsigned int value)
 {
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
+	__omap_dm_timer_int_enable(timer->io_base, value);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
 
@@ -696,17 +535,13 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
 
 void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
+	__omap_dm_timer_write_status(timer->io_base, value);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
 
 unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
-	unsigned int l;
-
-	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
-
-	return l;
+	return __omap_dm_timer_read_counter(timer->io_base, timer->posted);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
 
@@ -737,7 +572,7 @@ int omap_dm_timers_active(void)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
-int __init omap_dm_timer_init(void)
+static int __init omap_dm_timer_init(void)
 {
 	struct omap_dm_timer *timer;
 	int i, map_size = SZ_8K;	/* Module 4KB + L4 4KB except on omap1 */
@@ -790,8 +625,16 @@ int __init omap_dm_timer_init(void)
 			sprintf(clk_name, "gpt%d_fck", i + 1);
 			timer->fclk = clk_get(NULL, clk_name);
 		}
+
+		/* One or two timers may be set up early for sys_timer */
+		if (sys_timer_reserved & (1  << i)) {
+			timer->reserved = 1;
+			timer->posted = 1;
+		}
 #endif
 	}
 
 	return 0;
 }
+
+arch_initcall(omap_dm_timer_init);
diff --git a/arch/arm/plat-omap/include/plat/clkdev.h b/arch/arm/plat-omap/include/plat/clkdev.h
deleted file mode 100644
index 730c49d1ebd8..000000000000
--- a/arch/arm/plat-omap/include/plat/clkdev.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __MACH_CLKDEV_H
-#define __MACH_CLKDEV_H
-
-static inline int __clk_get(struct clk *clk)
-{
-	return 1;
-}
-
-static inline void __clk_put(struct clk *clk)
-{
-}
-
-#endif
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
index f1899a3e4174..387a9638991b 100644
--- a/arch/arm/plat-omap/include/plat/clkdev_omap.h
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -39,6 +39,7 @@ struct omap_clk {
 #define CK_36XX		(1 << 10)	/* 36xx/37xx-specific clocks */
 #define CK_443X		(1 << 11)
 #define CK_TI816X	(1 << 12)
+#define CK_446X		(1 << 13)
 
 
 #define CK_34XX		(CK_3430ES1 | CK_3430ES2PLUS)
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index 006e599c6613..df4b9683f17f 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -58,10 +58,12 @@ struct clkops {
 #define RATE_IN_36XX		(1 << 4)
 #define RATE_IN_4430		(1 << 5)
 #define RATE_IN_TI816X		(1 << 6)
+#define RATE_IN_4460		(1 << 7)
 
 #define RATE_IN_24XX		(RATE_IN_242X | RATE_IN_243X)
 #define RATE_IN_34XX		(RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
 #define RATE_IN_3XXX		(RATE_IN_34XX | RATE_IN_36XX)
+#define RATE_IN_44XX		(RATE_IN_4430 | RATE_IN_4460)
 
 /* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
 #define RATE_IN_3430ES2PLUS_36XX	(RATE_IN_3430ES2PLUS | RATE_IN_36XX)
@@ -152,7 +154,7 @@ struct dpll_data {
 	u16			max_multiplier;
 	u8			last_rounded_n;
 	u8			min_divider;
-	u8			max_divider;
+	u16			max_divider;
 	u8			modes;
 #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 	void __iomem		*autoidle_reg;
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 5288130be96e..4564cc697d7f 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -34,7 +34,11 @@
 struct sys_timer;
 
 extern void omap_map_common_io(void);
-extern struct sys_timer omap_timer;
+extern struct sys_timer omap1_timer;
+extern struct sys_timer omap2_timer;
+extern struct sys_timer omap3_timer;
+extern struct sys_timer omap3_secure_timer;
+extern struct sys_timer omap4_timer;
 extern bool omap_32k_timer_init(void);
 extern int __init omap_init_clocksource_32k(void);
 extern unsigned long long notrace omap_32k_sched_clock(void);
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 8198bb6cdb5e..67b3d75884cd 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -88,6 +88,7 @@ unsigned int omap_rev(void);
  * cpu_is_omap243x():	True for OMAP2430
  * cpu_is_omap343x():	True for OMAP3430
  * cpu_is_omap443x():	True for OMAP4430
+ * cpu_is_omap446x():	True for OMAP4460
  */
 #define GET_OMAP_CLASS	(omap_rev() & 0xff)
 
@@ -123,6 +124,7 @@ IS_OMAP_SUBCLASS(243x, 0x243)
 IS_OMAP_SUBCLASS(343x, 0x343)
 IS_OMAP_SUBCLASS(363x, 0x363)
 IS_OMAP_SUBCLASS(443x, 0x443)
+IS_OMAP_SUBCLASS(446x, 0x446)
 
 IS_TI_SUBCLASS(816x, 0x816)
 
@@ -137,6 +139,7 @@ IS_TI_SUBCLASS(816x, 0x816)
 #define cpu_is_ti816x()			0
 #define cpu_is_omap44xx()		0
 #define cpu_is_omap443x()		0
+#define cpu_is_omap446x()		0
 
 #if defined(MULTI_OMAP1)
 # if defined(CONFIG_ARCH_OMAP730)
@@ -361,8 +364,10 @@ IS_OMAP_TYPE(3517, 0x3517)
 # if defined(CONFIG_ARCH_OMAP4)
 # undef cpu_is_omap44xx
 # undef cpu_is_omap443x
+# undef cpu_is_omap446x
 # define cpu_is_omap44xx()		is_omap44xx()
 # define cpu_is_omap443x()		is_omap443x()
+# define cpu_is_omap446x()		is_omap446x()
 # endif
 
 /* Macros to detect if we have OMAP1 or OMAP2 */
@@ -410,6 +415,9 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define OMAP4430_REV_ES2_1	(OMAP443X_CLASS | (0x21 << 8))
 #define OMAP4430_REV_ES2_2	(OMAP443X_CLASS | (0x22 << 8))
 
+#define OMAP446X_CLASS		0x44600044
+#define OMAP4460_REV_ES1_0	(OMAP446X_CLASS | (0x10 << 8))
+
 /*
  * omap_chip bits
  *
@@ -439,13 +447,15 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define CHIP_IS_OMAP4430ES2_1		(1 << 12)
 #define CHIP_IS_OMAP4430ES2_2		(1 << 13)
 #define CHIP_IS_TI816X			(1 << 14)
+#define CHIP_IS_OMAP4460ES1_0		(1 << 15)
 
 #define CHIP_IS_OMAP24XX		(CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
 
 #define CHIP_IS_OMAP4430		(CHIP_IS_OMAP4430ES1 |		\
 					 CHIP_IS_OMAP4430ES2 |		\
 					 CHIP_IS_OMAP4430ES2_1 |	\
-					 CHIP_IS_OMAP4430ES2_2)
+					 CHIP_IS_OMAP4430ES2_2 |	\
+					 CHIP_IS_OMAP4460ES1_0)
 
 /*
  * "GE" here represents "greater than or equal to" in terms of ES
@@ -468,7 +478,7 @@ void omap2_check_revision(void);
 /*
  * Runtime detection of OMAP3 features
  */
-extern u32 omap3_features;
+extern u32 omap_features;
 
 #define OMAP3_HAS_L2CACHE		BIT(0)
 #define OMAP3_HAS_IVA			BIT(1)
@@ -478,11 +488,15 @@ extern u32 omap3_features;
 #define OMAP3_HAS_192MHZ_CLK		BIT(5)
 #define OMAP3_HAS_IO_WAKEUP		BIT(6)
 #define OMAP3_HAS_SDRC			BIT(7)
+#define OMAP4_HAS_MPU_1GHZ		BIT(8)
+#define OMAP4_HAS_MPU_1_2GHZ		BIT(9)
+#define OMAP4_HAS_MPU_1_5GHZ		BIT(10)
+
 
 #define OMAP3_HAS_FEATURE(feat,flag)			\
 static inline unsigned int omap3_has_ ##feat(void)	\
 {							\
-	return (omap3_features & OMAP3_HAS_ ##flag);	\
+	return omap_features & OMAP3_HAS_ ##flag;	\
 }							\
 
 OMAP3_HAS_FEATURE(l2cache, L2CACHE)
@@ -494,4 +508,19 @@ OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
 OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
 OMAP3_HAS_FEATURE(sdrc, SDRC)
 
+/*
+ * Runtime detection of OMAP4 features
+ */
+extern u32 omap_features;
+
+#define OMAP4_HAS_FEATURE(feat, flag)			\
+static inline unsigned int omap4_has_ ##feat(void)	\
+{							\
+	return omap_features & OMAP4_HAS_ ##flag;	\
+}							\
+
+OMAP4_HAS_FEATURE(mpu_1ghz, MPU_1GHZ)
+OMAP4_HAS_FEATURE(mpu_1_2ghz, MPU_1_2GHZ)
+OMAP4_HAS_FEATURE(mpu_1_5ghz, MPU_1_5GHZ)
+
 #endif
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index d6c70d2f4030..eb5d16c60cd9 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -32,6 +32,10 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
 #ifndef __ASM_ARCH_DMTIMER_H
 #define __ASM_ARCH_DMTIMER_H
 
@@ -56,12 +60,8 @@
  */
 #define OMAP_TIMER_IP_VERSION_1                        0x1
 struct omap_dm_timer;
-extern struct omap_dm_timer *gptimer_wakeup;
-extern struct sys_timer omap_timer;
 struct clk;
 
-int omap_dm_timer_init(void);
-
 struct omap_dm_timer *omap_dm_timer_request(void);
 struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 void omap_dm_timer_free(struct omap_dm_timer *timer);
@@ -93,5 +93,248 @@ void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value
 
 int omap_dm_timers_active(void);
 
+/*
+ * Do not use the defines below, they are not needed. They should be only
+ * used by dmtimer.c and sys_timer related code.
+ */
+
+/* register offsets */
+#define _OMAP_TIMER_ID_OFFSET		0x00
+#define _OMAP_TIMER_OCP_CFG_OFFSET	0x10
+#define _OMAP_TIMER_SYS_STAT_OFFSET	0x14
+#define _OMAP_TIMER_STAT_OFFSET		0x18
+#define _OMAP_TIMER_INT_EN_OFFSET	0x1c
+#define _OMAP_TIMER_WAKEUP_EN_OFFSET	0x20
+#define _OMAP_TIMER_CTRL_OFFSET		0x24
+#define		OMAP_TIMER_CTRL_GPOCFG		(1 << 14)
+#define		OMAP_TIMER_CTRL_CAPTMODE	(1 << 13)
+#define		OMAP_TIMER_CTRL_PT		(1 << 12)
+#define		OMAP_TIMER_CTRL_TCM_LOWTOHIGH	(0x1 << 8)
+#define		OMAP_TIMER_CTRL_TCM_HIGHTOLOW	(0x2 << 8)
+#define		OMAP_TIMER_CTRL_TCM_BOTHEDGES	(0x3 << 8)
+#define		OMAP_TIMER_CTRL_SCPWM		(1 << 7)
+#define		OMAP_TIMER_CTRL_CE		(1 << 6) /* compare enable */
+#define		OMAP_TIMER_CTRL_PRE		(1 << 5) /* prescaler enable */
+#define		OMAP_TIMER_CTRL_PTV_SHIFT	2 /* prescaler value shift */
+#define		OMAP_TIMER_CTRL_POSTED		(1 << 2)
+#define		OMAP_TIMER_CTRL_AR		(1 << 1) /* auto-reload enable */
+#define		OMAP_TIMER_CTRL_ST		(1 << 0) /* start timer */
+#define _OMAP_TIMER_COUNTER_OFFSET	0x28
+#define _OMAP_TIMER_LOAD_OFFSET		0x2c
+#define _OMAP_TIMER_TRIGGER_OFFSET	0x30
+#define _OMAP_TIMER_WRITE_PEND_OFFSET	0x34
+#define		WP_NONE			0	/* no write pending bit */
+#define		WP_TCLR			(1 << 0)
+#define		WP_TCRR			(1 << 1)
+#define		WP_TLDR			(1 << 2)
+#define		WP_TTGR			(1 << 3)
+#define		WP_TMAR			(1 << 4)
+#define		WP_TPIR			(1 << 5)
+#define		WP_TNIR			(1 << 6)
+#define		WP_TCVR			(1 << 7)
+#define		WP_TOCR			(1 << 8)
+#define		WP_TOWR			(1 << 9)
+#define _OMAP_TIMER_MATCH_OFFSET	0x38
+#define _OMAP_TIMER_CAPTURE_OFFSET	0x3c
+#define _OMAP_TIMER_IF_CTRL_OFFSET	0x40
+#define _OMAP_TIMER_CAPTURE2_OFFSET		0x44	/* TCAR2, 34xx only */
+#define _OMAP_TIMER_TICK_POS_OFFSET		0x48	/* TPIR, 34xx only */
+#define _OMAP_TIMER_TICK_NEG_OFFSET		0x4c	/* TNIR, 34xx only */
+#define _OMAP_TIMER_TICK_COUNT_OFFSET		0x50	/* TCVR, 34xx only */
+#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET	0x54	/* TOCR, 34xx only */
+#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET	0x58	/* TOWR, 34xx only */
+
+/* register offsets with the write pending bit encoded */
+#define	WPSHIFT					16
+
+#define OMAP_TIMER_ID_REG			(_OMAP_TIMER_ID_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_OCP_CFG_REG			(_OMAP_TIMER_OCP_CFG_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_SYS_STAT_REG			(_OMAP_TIMER_SYS_STAT_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_STAT_REG			(_OMAP_TIMER_STAT_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_INT_EN_REG			(_OMAP_TIMER_INT_EN_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_WAKEUP_EN_REG		(_OMAP_TIMER_WAKEUP_EN_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_CTRL_REG			(_OMAP_TIMER_CTRL_OFFSET \
+							| (WP_TCLR << WPSHIFT))
+
+#define OMAP_TIMER_COUNTER_REG			(_OMAP_TIMER_COUNTER_OFFSET \
+							| (WP_TCRR << WPSHIFT))
+
+#define OMAP_TIMER_LOAD_REG			(_OMAP_TIMER_LOAD_OFFSET \
+							| (WP_TLDR << WPSHIFT))
+
+#define OMAP_TIMER_TRIGGER_REG			(_OMAP_TIMER_TRIGGER_OFFSET \
+							| (WP_TTGR << WPSHIFT))
+
+#define OMAP_TIMER_WRITE_PEND_REG		(_OMAP_TIMER_WRITE_PEND_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_MATCH_REG			(_OMAP_TIMER_MATCH_OFFSET \
+							| (WP_TMAR << WPSHIFT))
+
+#define OMAP_TIMER_CAPTURE_REG			(_OMAP_TIMER_CAPTURE_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_IF_CTRL_REG			(_OMAP_TIMER_IF_CTRL_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_CAPTURE2_REG			(_OMAP_TIMER_CAPTURE2_OFFSET \
+							| (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_TICK_POS_REG			(_OMAP_TIMER_TICK_POS_OFFSET \
+							| (WP_TPIR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_NEG_REG			(_OMAP_TIMER_TICK_NEG_OFFSET \
+							| (WP_TNIR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_COUNT_REG		(_OMAP_TIMER_TICK_COUNT_OFFSET \
+							| (WP_TCVR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_INT_MASK_SET_REG				\
+		(_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG				\
+		(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
+
+struct omap_dm_timer {
+	unsigned long phys_base;
+	int irq;
+#ifdef CONFIG_ARCH_OMAP2PLUS
+	struct clk *iclk, *fclk;
+#endif
+	void __iomem *io_base;
+	unsigned long rate;
+	unsigned reserved:1;
+	unsigned enabled:1;
+	unsigned posted:1;
+};
+
+extern u32 sys_timer_reserved;
+void omap_dm_timer_prepare(struct omap_dm_timer *timer);
+
+static inline u32 __omap_dm_timer_read(void __iomem *base, u32 reg,
+						int posted)
+{
+	if (posted)
+		while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
+				& (reg >> WPSHIFT))
+			cpu_relax();
+
+	return __raw_readl(base + (reg & 0xff));
+}
+
+static inline void __omap_dm_timer_write(void __iomem *base, u32 reg, u32 val,
+						int posted)
+{
+	if (posted)
+		while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
+				& (reg >> WPSHIFT))
+			cpu_relax();
+
+	__raw_writel(val, base + (reg & 0xff));
+}
+
+/* Assumes the source clock has been set by caller */
+static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle,
+						int wakeup)
+{
+	u32 l;
+
+	l = __omap_dm_timer_read(base, OMAP_TIMER_OCP_CFG_REG, 0);
+	l |= 0x02 << 3;  /* Set to smart-idle mode */
+	l |= 0x2 << 8;   /* Set clock activity to perserve f-clock on idle */
+
+	if (autoidle)
+		l |= 0x1 << 0;
+
+	if (wakeup)
+		l |= 1 << 2;
+
+	__omap_dm_timer_write(base, OMAP_TIMER_OCP_CFG_REG, l, 0);
+
+	/* Match hardware reset default of posted mode */
+	__omap_dm_timer_write(base, OMAP_TIMER_IF_CTRL_REG,
+					OMAP_TIMER_CTRL_POSTED, 0);
+}
+
+static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
+						struct clk *parent)
+{
+	int ret;
+
+	clk_disable(timer_fck);
+	ret = clk_set_parent(timer_fck, parent);
+	clk_enable(timer_fck);
+
+	/*
+	 * When the functional clock disappears, too quick writes seem
+	 * to cause an abort. XXX Is this still necessary?
+	 */
+	__delay(300000);
+
+	return ret;
+}
+
+static inline void __omap_dm_timer_stop(void __iomem *base, int posted,
+						unsigned long rate)
+{
+	u32 l;
+
+	l = __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
+	if (l & OMAP_TIMER_CTRL_ST) {
+		l &= ~0x1;
+		__omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, l, posted);
+#ifdef CONFIG_ARCH_OMAP2PLUS
+		/* Readback to make sure write has completed */
+		__omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
+		/*
+		 * Wait for functional clock period x 3.5 to make sure that
+		 * timer is stopped
+		 */
+		udelay(3500000 / rate + 1);
+#endif
+	}
+
+	/* Ack possibly pending interrupt */
+	__omap_dm_timer_write(base, OMAP_TIMER_STAT_REG,
+					OMAP_TIMER_INT_OVERFLOW, 0);
+}
+
+static inline void __omap_dm_timer_load_start(void __iomem *base, u32 ctrl,
+						unsigned int load, int posted)
+{
+	__omap_dm_timer_write(base, OMAP_TIMER_COUNTER_REG, load, posted);
+	__omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, ctrl, posted);
+}
+
+static inline void __omap_dm_timer_int_enable(void __iomem *base,
+						unsigned int value)
+{
+	__omap_dm_timer_write(base, OMAP_TIMER_INT_EN_REG, value, 0);
+	__omap_dm_timer_write(base, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
+}
+
+static inline unsigned int __omap_dm_timer_read_counter(void __iomem *base,
+							int posted)
+{
+	return __omap_dm_timer_read(base, OMAP_TIMER_COUNTER_REG, posted);
+}
+
+static inline void __omap_dm_timer_write_status(void __iomem *base,
+						unsigned int value)
+{
+	__omap_dm_timer_write(base, OMAP_TIMER_STAT_REG, value, 0);
+}
 
 #endif /* __ASM_ARCH_DMTIMER_H */
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
index ec97e00cb581..91e8de3db085 100644
--- a/arch/arm/plat-omap/include/plat/gpio.h
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -174,12 +174,32 @@ struct omap_gpio_dev_attr {
 	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */
 };
 
+struct omap_gpio_reg_offs {
+	u16 revision;
+	u16 direction;
+	u16 datain;
+	u16 dataout;
+	u16 set_dataout;
+	u16 clr_dataout;
+	u16 irqstatus;
+	u16 irqstatus2;
+	u16 irqenable;
+	u16 set_irqenable;
+	u16 clr_irqenable;
+	u16 debounce;
+	u16 debounce_en;
+
+	bool irqenable_inv;
+};
+
 struct omap_gpio_platform_data {
 	u16 virtual_irq_start;
 	int bank_type;
 	int bank_width;		/* GPIO bank width */
 	int bank_stride;	/* Only needed for omap1 MPUIO */
 	bool dbck_flag;		/* dbck required or not - True for OMAP3&4 */
+
+	struct omap_gpio_reg_offs *regs;
 };
 
 /* TODO: Analyze removing gpio_bank_count usage from driver code */
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h
index 878d632c4092..7c22b9e10dc3 100644
--- a/arch/arm/plat-omap/include/plat/i2c.h
+++ b/arch/arm/plat-omap/include/plat/i2c.h
@@ -22,6 +22,7 @@
 #define __ASM__ARCH_OMAP_I2C_H
 
 #include <linux/i2c.h>
+#include <linux/i2c-omap.h>
 
 #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
 extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
@@ -46,10 +47,13 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
  */
 struct omap_i2c_dev_attr {
 	u8	fifo_depth;
-	u8	flags;
+	u32	flags;
 };
 
 void __init omap1_i2c_mux_pins(int bus_id);
 void __init omap2_i2c_mux_pins(int bus_id);
 
+struct omap_hwmod;
+int omap_i2c_reset(struct omap_hwmod *oh);
+
 #endif /* __ASM__ARCH_OMAP_I2C_H */
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index 5a25098ea7ea..926d25c780f3 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -407,11 +407,19 @@
 #endif
 #define TWL6030_IRQ_END		(TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
 
+#define TWL6040_CODEC_IRQ_BASE	TWL6030_IRQ_END
+#ifdef CONFIG_TWL6040_CODEC
+#define TWL6040_CODEC_NR_IRQS	6
+#else
+#define TWL6040_CODEC_NR_IRQS	0
+#endif
+#define TWL6040_CODEC_IRQ_END	(TWL6040_CODEC_IRQ_BASE + TWL6040_CODEC_NR_IRQS)
+
 /* Total number of interrupts depends on the enabled blocks above */
-#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
+#if (TWL4030_GPIO_IRQ_END > TWL6040_CODEC_IRQ_END)
 #define TWL_IRQ_END 		TWL4030_GPIO_IRQ_END
 #else
-#define TWL_IRQ_END		TWL6030_IRQ_END
+#define TWL_IRQ_END		TWL6040_CODEC_IRQ_END
 #endif
 
 /* GPMC related */
@@ -428,7 +436,11 @@
 #define INTCPS_NR_IRQS		96
 
 #ifndef __ASSEMBLY__
-extern void omap_init_irq(void);
+extern void __iomem *omap_irq_base;
+void omap1_init_irq(void);
+void omap2_init_irq(void);
+void omap3_init_irq(void);
+void ti816x_init_irq(void);
 extern int omap_irq_pending(void);
 void omap_intc_save_context(void);
 void omap_intc_restore_context(void);
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index f8f690ab2997..9882c657b2d4 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -24,7 +24,6 @@
 #ifndef __ASM_ARCH_OMAP_MCBSP_H
 #define __ASM_ARCH_OMAP_MCBSP_H
 
-#include <linux/completion.h>
 #include <linux/spinlock.h>
 
 #include <mach/hardware.h>
@@ -34,7 +33,7 @@
 #define OMAP_MCBSP_PLATFORM_DEVICE(port_nr)		\
 static struct platform_device omap_mcbsp##port_nr = {	\
 	.name	= "omap-mcbsp-dai",			\
-	.id	= OMAP_MCBSP##port_nr,			\
+	.id	= port_nr - 1,			\
 }
 
 #define MCBSP_CONFIG_TYPE2	0x2
@@ -333,18 +332,6 @@ struct omap_mcbsp_reg_cfg {
 };
 
 typedef enum {
-	OMAP_MCBSP1 = 0,
-	OMAP_MCBSP2,
-	OMAP_MCBSP3,
-	OMAP_MCBSP4,
-	OMAP_MCBSP5
-} omap_mcbsp_id;
-
-typedef int __bitwise omap_mcbsp_io_type_t;
-#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
-#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
-
-typedef enum {
 	OMAP_MCBSP_WORD_8 = 0,
 	OMAP_MCBSP_WORD_12,
 	OMAP_MCBSP_WORD_16,
@@ -353,38 +340,6 @@ typedef enum {
 	OMAP_MCBSP_WORD_32,
 } omap_mcbsp_word_length;
 
-typedef enum {
-	OMAP_MCBSP_CLK_RISING = 0,
-	OMAP_MCBSP_CLK_FALLING,
-} omap_mcbsp_clk_polarity;
-
-typedef enum {
-	OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
-	OMAP_MCBSP_FS_ACTIVE_LOW,
-} omap_mcbsp_fs_polarity;
-
-typedef enum {
-	OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
-	OMAP_MCBSP_CLK_STP_MODE_DELAY,
-} omap_mcbsp_clk_stp_mode;
-
-
-/******* SPI specific mode **********/
-typedef enum {
-	OMAP_MCBSP_SPI_MASTER = 0,
-	OMAP_MCBSP_SPI_SLAVE,
-} omap_mcbsp_spi_mode;
-
-struct omap_mcbsp_spi_cfg {
-	omap_mcbsp_spi_mode		spi_mode;
-	omap_mcbsp_clk_polarity		rx_clock_polarity;
-	omap_mcbsp_clk_polarity		tx_clock_polarity;
-	omap_mcbsp_fs_polarity		fsx_polarity;
-	u8				clk_div;
-	omap_mcbsp_clk_stp_mode		clk_stp_mode;
-	omap_mcbsp_word_length		word_length;
-};
-
 /* Platform specific configuration */
 struct omap_mcbsp_ops {
 	void (*request)(unsigned int);
@@ -422,25 +377,13 @@ struct omap_mcbsp {
 	void __iomem *io_base;
 	u8 id;
 	u8 free;
-	omap_mcbsp_word_length rx_word_length;
-	omap_mcbsp_word_length tx_word_length;
 
-	omap_mcbsp_io_type_t io_type; /* IRQ or poll */
-	/* IRQ based TX/RX */
 	int rx_irq;
 	int tx_irq;
 
 	/* DMA stuff */
 	u8 dma_rx_sync;
-	short dma_rx_lch;
 	u8 dma_tx_sync;
-	short dma_tx_lch;
-
-	/* Completion queues */
-	struct completion tx_irq_completion;
-	struct completion rx_irq_completion;
-	struct completion tx_dma_completion;
-	struct completion rx_dma_completion;
 
 	/* Protect the field .free, while checking if the mcbsp is in use */
 	spinlock_t lock;
@@ -499,24 +442,9 @@ int omap_mcbsp_request(unsigned int id);
 void omap_mcbsp_free(unsigned int id);
 void omap_mcbsp_start(unsigned int id, int tx, int rx);
 void omap_mcbsp_stop(unsigned int id, int tx, int rx);
-void omap_mcbsp_xmit_word(unsigned int id, u32 word);
-u32 omap_mcbsp_recv_word(unsigned int id);
-
-int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
-int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
-int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
-int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
-
 
 /* McBSP functional clock source changing function */
 extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
-/* SPI specific API */
-void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
-
-/* Polled read/write functions */
-int omap_mcbsp_pollread(unsigned int id, u16 * buf);
-int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
-int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
 
 /* McBSP signal muxing API */
 void omap2_mcbsp1_mux_clkr_src(u8 mux);
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
index d86d1ecf0068..67fc5060183e 100644
--- a/arch/arm/plat-omap/include/plat/nand.h
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -19,15 +19,11 @@ enum nand_io {
 };
 
 struct omap_nand_platform_data {
-	unsigned int		options;
 	int			cs;
-	int			gpio_irq;
 	struct mtd_partition	*parts;
 	struct gpmc_timings	*gpmc_t;
 	int			nr_parts;
-	int			(*nand_setup)(void);
-	int			(*dev_ready)(struct omap_nand_platform_data *);
-	int			dma_channel;
+	bool			dev_ready;
 	int			gpmc_irq;
 	enum nand_io		xfer_type;
 	unsigned long		phys_base;
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index c0a752053039..0840df813f4f 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -40,11 +40,7 @@
  * framework starts.  The "_if_" is to avoid name collisions with the
  * PM idle-loop code.
  */
-#ifdef CONFIG_OMAP_PM_NONE
-#define omap_pm_if_early_init() 0
-#else
 int __init omap_pm_if_early_init(void);
-#endif
 
 /**
  * omap_pm_if_init - OMAP PM init code called after clock fw init
@@ -52,11 +48,7 @@ int __init omap_pm_if_early_init(void);
  * The main initialization code.  OPP tables are passed in here.  The
  * "_if_" is to avoid name collisions with the PM idle-loop code.
  */
-#ifdef CONFIG_OMAP_PM_NONE
-#define omap_pm_if_init() 0
-#else
 int __init omap_pm_if_init(void);
-#endif
 
 /**
  * omap_pm_if_exit - OMAP PM exit code
diff --git a/arch/arm/plat-omap/include/plat/omap4-keypad.h b/arch/arm/plat-omap/include/plat/omap4-keypad.h
index 2b1d9bc1eebb..9fe6c8783236 100644
--- a/arch/arm/plat-omap/include/plat/omap4-keypad.h
+++ b/arch/arm/plat-omap/include/plat/omap4-keypad.h
@@ -10,5 +10,6 @@ struct omap4_keypad_platform_data {
 	u8 cols;
 };
 
-extern int omap4_keyboard_init(struct omap4_keypad_platform_data *);
+extern int omap4_keyboard_init(struct omap4_keypad_platform_data *,
+				struct omap_board_data *);
 #endif
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349ff9fd8..ee405b36df4b 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -44,6 +44,10 @@ extern struct device omap_device_parent;
 #define OMAP_DEVICE_STATE_IDLE		2
 #define OMAP_DEVICE_STATE_SHUTDOWN	3
 
+/* omap_device.flags values */
+#define OMAP_DEVICE_SUSPENDED BIT(0)
+#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1)
+
 /**
  * struct omap_device - omap_device wrapper for platform_devices
  * @pdev: platform_device
@@ -73,6 +77,7 @@ struct omap_device {
 	s8				pm_lat_level;
 	u8				hwmods_cnt;
 	u8				_state;
+	u8                              flags;
 };
 
 /* Device driver interface (call via platform_data fn ptrs) */
@@ -117,6 +122,10 @@ int omap_device_enable_hwmods(struct omap_device *od);
 int omap_device_disable_clocks(struct omap_device *od);
 int omap_device_enable_clocks(struct omap_device *od);
 
+static inline void omap_device_disable_idle_on_suspend(struct omap_device *od)
+{
+	od->flags |= OMAP_DEVICE_NO_IDLE_ON_SUSPEND;
+}
 
 /*
  * Entries should be kept in latency order ascending
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 1adea9c62984..0e329ca88a70 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -2,6 +2,7 @@
  * omap_hwmod macros, structures
  *
  * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
  * Paul Walmsley
  *
  * Created in collaboration with (alphabetical order): BenoƮt Cousson,
@@ -77,9 +78,13 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
 #define HWMOD_IDLEMODE_FORCE		(1 << 0)
 #define HWMOD_IDLEMODE_NO		(1 << 1)
 #define HWMOD_IDLEMODE_SMART		(1 << 2)
-/* Slave idle mode flag only */
 #define HWMOD_IDLEMODE_SMART_WKUP	(1 << 3)
 
+/* modulemode control type (SW or HW) */
+#define MODULEMODE_HWCTRL		1
+#define MODULEMODE_SWCTRL		2
+
+
 /**
  * struct omap_hwmod_mux_info - hwmod specific mux configuration
  * @pads:              array of omap_device_pad entries
@@ -98,7 +103,7 @@ struct omap_hwmod_mux_info {
 /**
  * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
  * @name: name of the IRQ channel (module local name)
- * @irq_ch: IRQ channel ID
+ * @irq: IRQ channel ID (should be non-negative except -1 = terminator)
  *
  * @name should be something short, e.g., "tx" or "rx".  It is for use
  * by platform_get_resource_byname().  It is defined locally to the
@@ -106,13 +111,13 @@ struct omap_hwmod_mux_info {
  */
 struct omap_hwmod_irq_info {
 	const char	*name;
-	u16		irq;
+	s16		irq;
 };
 
 /**
  * struct omap_hwmod_dma_info - DMA channels used by the hwmod
  * @name: name of the DMA channel (module local name)
- * @dma_req: DMA request ID
+ * @dma_req: DMA request ID (should be non-negative except -1 = terminator)
  *
  * @name should be something short, e.g., "tx" or "rx".  It is for use
  * by platform_get_resource_byname().  It is defined locally to the
@@ -120,7 +125,7 @@ struct omap_hwmod_irq_info {
  */
 struct omap_hwmod_dma_info {
 	const char	*name;
-	u16		dma_req;
+	s16		dma_req;
 };
 
 /**
@@ -220,7 +225,6 @@ struct omap_hwmod_addr_space {
  * @clk: interface clock: OMAP clock name
  * @_clk: pointer to the interface struct clk (filled in at runtime)
  * @fw: interface firewall data
- * @addr_cnt: ARRAY_SIZE(@addr)
  * @width: OCP data width
  * @user: initiators using this interface (see OCP_USER_* macros above)
  * @flags: OCP interface flags (see OCPIF_* macros above)
@@ -239,7 +243,6 @@ struct omap_hwmod_ocp_if {
 	union {
 		struct omap_hwmod_omap2_firewall omap2;
 	}				fw;
-	u8				addr_cnt;
 	u8				width;
 	u8				user;
 	u8				flags;
@@ -258,6 +261,7 @@ struct omap_hwmod_ocp_if {
 #define MSTANDBY_FORCE		(HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
 #define MSTANDBY_NO		(HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
 #define MSTANDBY_SMART		(HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_SMART_WKUP	(HWMOD_IDLEMODE_SMART_WKUP << MASTER_STANDBY_SHIFT)
 
 /* omap_hwmod_sysconfig.sysc_flags capability flags */
 #define SYSC_HAS_AUTOIDLE	(1 << 0)
@@ -362,9 +366,11 @@ struct omap_hwmod_omap2_prcm {
  * @submodule_wkdep_bit: bit shift of the WKDEP range
  */
 struct omap_hwmod_omap4_prcm {
-	void __iomem	*clkctrl_reg;
-	void __iomem	*rstctrl_reg;
+	u16		clkctrl_offs;
+	u16		rstctrl_offs;
+	u16		context_offs;
 	u8		submodule_wkdep_bit;
+	u8		modulemode;
 };
 
 
@@ -468,8 +474,8 @@ struct omap_hwmod_class {
  * @name: name of the hwmod
  * @class: struct omap_hwmod_class * to the class of this hwmod
  * @od: struct omap_device currently associated with this hwmod (internal use)
- * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
- * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_cnt)
+ * @mpu_irqs: ptr to an array of MPU IRQs
+ * @sdma_reqs: ptr to an array of System DMA request IDs
  * @prcm: PRCM data pertaining to this hwmod
  * @main_clk: main clock: OMAP clock name
  * @_clk: pointer to the main struct clk (filled in at runtime)
@@ -482,8 +488,6 @@ struct omap_hwmod_class {
  * @_sysc_cache: internal-use hwmod flags
  * @_mpu_rt_va: cached register target start address (internal use)
  * @_mpu_port_index: cached MPU register target slave ID (internal use)
- * @mpu_irqs_cnt: number of @mpu_irqs
- * @sdma_reqs_cnt: number of @sdma_reqs
  * @opt_clks_cnt: number of @opt_clks
  * @master_cnt: number of @master entries
  * @slaves_cnt: number of @slave entries
@@ -519,6 +523,8 @@ struct omap_hwmod {
 	const char			*main_clk;
 	struct clk			*_clk;
 	struct omap_hwmod_opt_clk	*opt_clks;
+	char				*clkdm_name;
+	struct clockdomain		*clkdm;
 	char				*vdd_name;
 	struct voltagedomain		*voltdm;
 	struct omap_hwmod_ocp_if	**masters; /* connect to *_IA */
@@ -531,8 +537,6 @@ struct omap_hwmod {
 	u16				flags;
 	u8				_mpu_port_index;
 	u8				response_lat;
-	u8				mpu_irqs_cnt;
-	u8				sdma_reqs_cnt;
 	u8				rst_lines_cnt;
 	u8				opt_clks_cnt;
 	u8				masters_cnt;
@@ -572,6 +576,7 @@ void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
 
 void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
 u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
+int omap_hwmod_softreset(struct omap_hwmod *oh);
 
 int omap_hwmod_count_resources(struct omap_hwmod *oh);
 int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
index ac4b60d9aa29..a067484cc4a2 100644
--- a/arch/arm/plat-omap/include/plat/uncompress.h
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -148,6 +148,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
 		/* omap3 based boards using UART3 */
 		DEBUG_LL_OMAP3(3, cm_t35);
 		DEBUG_LL_OMAP3(3, cm_t3517);
+		DEBUG_LL_OMAP3(3, cm_t3730);
 		DEBUG_LL_OMAP3(3, craneboard);
 		DEBUG_LL_OMAP3(3, devkit8000);
 		DEBUG_LL_OMAP3(3, igep0020);
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 83a37c54342f..c60737c49a32 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -72,7 +72,7 @@ static size_t sgtable_len(const struct sg_table *sgt)
 	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
 		size_t bytes;
 
-		bytes = sg_dma_len(sg);
+		bytes = sg->length;
 
 		if (!iopgsz_ok(bytes)) {
 			pr_err("%s: sg[%d] not iommu pagesize(%x)\n",
@@ -198,7 +198,7 @@ static void *vmap_sg(const struct sg_table *sgt)
 		int err;
 
 		pa = sg_phys(sg);
-		bytes = sg_dma_len(sg);
+		bytes = sg->length;
 
 		BUG_ON(bytes != PAGE_SIZE);
 
@@ -476,7 +476,7 @@ static int map_iovm_area(struct iommu *obj, struct iovm_struct *new,
 		struct iotlb_entry e;
 
 		pa = sg_phys(sg);
-		bytes = sg_dma_len(sg);
+		bytes = sg->length;
 
 		flags &= ~IOVMF_PGSZ_MASK;
 		pgsz = bytes_to_iopgsz(bytes);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 5587acf0eb2c..6c62af108710 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -16,8 +16,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <linux/wait.h>
-#include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/clk.h>
@@ -25,7 +23,6 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 
-#include <plat/dma.h>
 #include <plat/mcbsp.h>
 #include <plat/omap_device.h>
 #include <linux/pm_runtime.h>
@@ -136,8 +133,6 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
 			irqst_spcr2);
 		/* Writing zero to XSYNC_ERR clears the IRQ */
 		MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
-	} else {
-		complete(&mcbsp_tx->tx_irq_completion);
 	}
 
 	return IRQ_HANDLED;
@@ -156,41 +151,11 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
 			irqst_spcr1);
 		/* Writing zero to RSYNC_ERR clears the IRQ */
 		MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
-	} else {
-		complete(&mcbsp_rx->rx_irq_completion);
 	}
 
 	return IRQ_HANDLED;
 }
 
-static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
-{
-	struct omap_mcbsp *mcbsp_dma_tx = data;
-
-	dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
-		MCBSP_READ(mcbsp_dma_tx, SPCR2));
-
-	/* We can free the channels */
-	omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
-	mcbsp_dma_tx->dma_tx_lch = -1;
-
-	complete(&mcbsp_dma_tx->tx_dma_completion);
-}
-
-static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
-{
-	struct omap_mcbsp *mcbsp_dma_rx = data;
-
-	dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
-		MCBSP_READ(mcbsp_dma_rx, SPCR2));
-
-	/* We can free the channels */
-	omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
-	mcbsp_dma_rx->dma_rx_lch = -1;
-
-	complete(&mcbsp_dma_rx->rx_dma_completion);
-}
-
 /*
  * omap_mcbsp_config simply write a config to the
  * appropriate McBSP.
@@ -758,37 +723,6 @@ static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
 static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
 #endif
 
-/*
- * We can choose between IRQ based or polled IO.
- * This needs to be called before omap_mcbsp_request().
- */
-int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
-{
-	struct omap_mcbsp *mcbsp;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	spin_lock(&mcbsp->lock);
-
-	if (!mcbsp->free) {
-		dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
-			mcbsp->id);
-		spin_unlock(&mcbsp->lock);
-		return -EINVAL;
-	}
-
-	mcbsp->io_type = io_type;
-
-	spin_unlock(&mcbsp->lock);
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_mcbsp_set_io_type);
-
 int omap_mcbsp_request(unsigned int id)
 {
 	struct omap_mcbsp *mcbsp;
@@ -833,29 +767,24 @@ int omap_mcbsp_request(unsigned int id)
 	MCBSP_WRITE(mcbsp, SPCR1, 0);
 	MCBSP_WRITE(mcbsp, SPCR2, 0);
 
-	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
-		/* We need to get IRQs here */
-		init_completion(&mcbsp->tx_irq_completion);
-		err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
-					0, "McBSP", (void *)mcbsp);
+	err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
+				0, "McBSP", (void *)mcbsp);
+	if (err != 0) {
+		dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
+				"for McBSP%d\n", mcbsp->tx_irq,
+				mcbsp->id);
+		goto err_clk_disable;
+	}
+
+	if (mcbsp->rx_irq) {
+		err = request_irq(mcbsp->rx_irq,
+				omap_mcbsp_rx_irq_handler,
+				0, "McBSP", (void *)mcbsp);
 		if (err != 0) {
-			dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
-					"for McBSP%d\n", mcbsp->tx_irq,
+			dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
+					"for McBSP%d\n", mcbsp->rx_irq,
 					mcbsp->id);
-			goto err_clk_disable;
-		}
-
-		if (mcbsp->rx_irq) {
-			init_completion(&mcbsp->rx_irq_completion);
-			err = request_irq(mcbsp->rx_irq,
-					omap_mcbsp_rx_irq_handler,
-					0, "McBSP", (void *)mcbsp);
-			if (err != 0) {
-				dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
-						"for McBSP%d\n", mcbsp->rx_irq,
-						mcbsp->id);
-				goto err_free_irq;
-			}
+			goto err_free_irq;
 		}
 	}
 
@@ -901,12 +830,9 @@ void omap_mcbsp_free(unsigned int id)
 
 	pm_runtime_put_sync(mcbsp->dev);
 
-	if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
-		/* Free IRQs */
-		if (mcbsp->rx_irq)
-			free_irq(mcbsp->rx_irq, (void *)mcbsp);
-		free_irq(mcbsp->tx_irq, (void *)mcbsp);
-	}
+	if (mcbsp->rx_irq)
+		free_irq(mcbsp->rx_irq, (void *)mcbsp);
+	free_irq(mcbsp->tx_irq, (void *)mcbsp);
 
 	reg_cache = mcbsp->reg_cache;
 
@@ -943,9 +869,6 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
 	if (cpu_is_omap34xx())
 		omap_st_start(mcbsp);
 
-	mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
-	mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
-
 	/* Only enable SRG, if McBSP is master */
 	w = MCBSP_READ_CACHE(mcbsp, PCR0);
 	if (w & (FSXM | FSRM | CLKXM | CLKRM))
@@ -1043,484 +966,32 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
 }
 EXPORT_SYMBOL(omap_mcbsp_stop);
 
-/* polled mcbsp i/o operations */
-int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
-{
-	struct omap_mcbsp *mcbsp;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	MCBSP_WRITE(mcbsp, DXR1, buf);
-	/* if frame sync error - clear the error */
-	if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
-		/* clear error */
-		MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
-		/* resend */
-		return -1;
-	} else {
-		/* wait for transmit confirmation */
-		int attemps = 0;
-		while (!(MCBSP_READ(mcbsp, SPCR2) & XRDY)) {
-			if (attemps++ > 1000) {
-				MCBSP_WRITE(mcbsp, SPCR2,
-						MCBSP_READ_CACHE(mcbsp, SPCR2) &
-						(~XRST));
-				udelay(10);
-				MCBSP_WRITE(mcbsp, SPCR2,
-						MCBSP_READ_CACHE(mcbsp, SPCR2) |
-						(XRST));
-				udelay(10);
-				dev_err(mcbsp->dev, "Could not write to"
-					" McBSP%d Register\n", mcbsp->id);
-				return -2;
-			}
-		}
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_mcbsp_pollwrite);
-
-int omap_mcbsp_pollread(unsigned int id, u16 *buf)
-{
-	struct omap_mcbsp *mcbsp;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	/* if frame sync error - clear the error */
-	if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
-		/* clear error */
-		MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
-		/* resend */
-		return -1;
-	} else {
-		/* wait for receive confirmation */
-		int attemps = 0;
-		while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) {
-			if (attemps++ > 1000) {
-				MCBSP_WRITE(mcbsp, SPCR1,
-						MCBSP_READ_CACHE(mcbsp, SPCR1) &
-						(~RRST));
-				udelay(10);
-				MCBSP_WRITE(mcbsp, SPCR1,
-						MCBSP_READ_CACHE(mcbsp, SPCR1) |
-						(RRST));
-				udelay(10);
-				dev_err(mcbsp->dev, "Could not read from"
-					" McBSP%d Register\n", mcbsp->id);
-				return -2;
-			}
-		}
-	}
-	*buf = MCBSP_READ(mcbsp, DRR1);
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_mcbsp_pollread);
-
-/*
- * IRQ based word transmission.
- */
-void omap_mcbsp_xmit_word(unsigned int id, u32 word)
-{
-	struct omap_mcbsp *mcbsp;
-	omap_mcbsp_word_length word_length;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return;
-	}
-
-	mcbsp = id_to_mcbsp_ptr(id);
-	word_length = mcbsp->tx_word_length;
-
-	wait_for_completion(&mcbsp->tx_irq_completion);
-
-	if (word_length > OMAP_MCBSP_WORD_16)
-		MCBSP_WRITE(mcbsp, DXR2, word >> 16);
-	MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
-}
-EXPORT_SYMBOL(omap_mcbsp_xmit_word);
-
-u32 omap_mcbsp_recv_word(unsigned int id)
-{
-	struct omap_mcbsp *mcbsp;
-	u16 word_lsb, word_msb = 0;
-	omap_mcbsp_word_length word_length;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	word_length = mcbsp->rx_word_length;
-
-	wait_for_completion(&mcbsp->rx_irq_completion);
-
-	if (word_length > OMAP_MCBSP_WORD_16)
-		word_msb = MCBSP_READ(mcbsp, DRR2);
-	word_lsb = MCBSP_READ(mcbsp, DRR1);
-
-	return (word_lsb | (word_msb << 16));
-}
-EXPORT_SYMBOL(omap_mcbsp_recv_word);
-
-int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
-{
-	struct omap_mcbsp *mcbsp;
-	omap_mcbsp_word_length tx_word_length;
-	omap_mcbsp_word_length rx_word_length;
-	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-	tx_word_length = mcbsp->tx_word_length;
-	rx_word_length = mcbsp->rx_word_length;
-
-	if (tx_word_length != rx_word_length)
-		return -EINVAL;
-
-	/* First we wait for the transmitter to be ready */
-	spcr2 = MCBSP_READ(mcbsp, SPCR2);
-	while (!(spcr2 & XRDY)) {
-		spcr2 = MCBSP_READ(mcbsp, SPCR2);
-		if (attempts++ > 1000) {
-			/* We must reset the transmitter */
-			MCBSP_WRITE(mcbsp, SPCR2,
-				    MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
-			udelay(10);
-			MCBSP_WRITE(mcbsp, SPCR2,
-				    MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
-			udelay(10);
-			dev_err(mcbsp->dev, "McBSP%d transmitter not "
-				"ready\n", mcbsp->id);
-			return -EAGAIN;
-		}
-	}
-
-	/* Now we can push the data */
-	if (tx_word_length > OMAP_MCBSP_WORD_16)
-		MCBSP_WRITE(mcbsp, DXR2, word >> 16);
-	MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
-
-	/* We wait for the receiver to be ready */
-	spcr1 = MCBSP_READ(mcbsp, SPCR1);
-	while (!(spcr1 & RRDY)) {
-		spcr1 = MCBSP_READ(mcbsp, SPCR1);
-		if (attempts++ > 1000) {
-			/* We must reset the receiver */
-			MCBSP_WRITE(mcbsp, SPCR1,
-				    MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
-			udelay(10);
-			MCBSP_WRITE(mcbsp, SPCR1,
-				    MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
-			udelay(10);
-			dev_err(mcbsp->dev, "McBSP%d receiver not "
-				"ready\n", mcbsp->id);
-			return -EAGAIN;
-		}
-	}
-
-	/* Receiver is ready, let's read the dummy data */
-	if (rx_word_length > OMAP_MCBSP_WORD_16)
-		word_msb = MCBSP_READ(mcbsp, DRR2);
-	word_lsb = MCBSP_READ(mcbsp, DRR1);
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
-
-int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
-{
-	struct omap_mcbsp *mcbsp;
-	u32 clock_word = 0;
-	omap_mcbsp_word_length tx_word_length;
-	omap_mcbsp_word_length rx_word_length;
-	u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	tx_word_length = mcbsp->tx_word_length;
-	rx_word_length = mcbsp->rx_word_length;
-
-	if (tx_word_length != rx_word_length)
-		return -EINVAL;
-
-	/* First we wait for the transmitter to be ready */
-	spcr2 = MCBSP_READ(mcbsp, SPCR2);
-	while (!(spcr2 & XRDY)) {
-		spcr2 = MCBSP_READ(mcbsp, SPCR2);
-		if (attempts++ > 1000) {
-			/* We must reset the transmitter */
-			MCBSP_WRITE(mcbsp, SPCR2,
-				    MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
-			udelay(10);
-			MCBSP_WRITE(mcbsp, SPCR2,
-				    MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
-			udelay(10);
-			dev_err(mcbsp->dev, "McBSP%d transmitter not "
-				"ready\n", mcbsp->id);
-			return -EAGAIN;
-		}
-	}
-
-	/* We first need to enable the bus clock */
-	if (tx_word_length > OMAP_MCBSP_WORD_16)
-		MCBSP_WRITE(mcbsp, DXR2, clock_word >> 16);
-	MCBSP_WRITE(mcbsp, DXR1, clock_word & 0xffff);
-
-	/* We wait for the receiver to be ready */
-	spcr1 = MCBSP_READ(mcbsp, SPCR1);
-	while (!(spcr1 & RRDY)) {
-		spcr1 = MCBSP_READ(mcbsp, SPCR1);
-		if (attempts++ > 1000) {
-			/* We must reset the receiver */
-			MCBSP_WRITE(mcbsp, SPCR1,
-				    MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
-			udelay(10);
-			MCBSP_WRITE(mcbsp, SPCR1,
-				    MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
-			udelay(10);
-			dev_err(mcbsp->dev, "McBSP%d receiver not "
-				"ready\n", mcbsp->id);
-			return -EAGAIN;
-		}
-	}
-
-	/* Receiver is ready, there is something for us */
-	if (rx_word_length > OMAP_MCBSP_WORD_16)
-		word_msb = MCBSP_READ(mcbsp, DRR2);
-	word_lsb = MCBSP_READ(mcbsp, DRR1);
-
-	word[0] = (word_lsb | (word_msb << 16));
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
-
 /*
- * Simple DMA based buffer rx/tx routines.
- * Nothing fancy, just a single buffer tx/rx through DMA.
- * The DMA resources are released once the transfer is done.
- * For anything fancier, you should use your own customized DMA
- * routines and callbacks.
+ * The following functions are only required on an OMAP1-only build.
+ * mach-omap2/mcbsp.c contains the real functions
  */
-int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
-				unsigned int length)
+#ifndef CONFIG_ARCH_OMAP2PLUS
+int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
 {
-	struct omap_mcbsp *mcbsp;
-	int dma_tx_ch;
-	int src_port = 0;
-	int dest_port = 0;
-	int sync_dev = 0;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
-				omap_mcbsp_tx_dma_callback,
-				mcbsp,
-				&dma_tx_ch)) {
-		dev_err(mcbsp->dev, " Unable to request DMA channel for "
-				"McBSP%d TX. Trying IRQ based TX\n",
-				mcbsp->id);
-		return -EAGAIN;
-	}
-	mcbsp->dma_tx_lch = dma_tx_ch;
-
-	dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
-		dma_tx_ch);
-
-	init_completion(&mcbsp->tx_dma_completion);
-
-	if (cpu_class_is_omap1()) {
-		src_port = OMAP_DMA_PORT_TIPB;
-		dest_port = OMAP_DMA_PORT_EMIFF;
-	}
-	if (cpu_class_is_omap2())
-		sync_dev = mcbsp->dma_tx_sync;
-
-	omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
-				     OMAP_DMA_DATA_TYPE_S16,
-				     length >> 1, 1,
-				     OMAP_DMA_SYNC_ELEMENT,
-	 sync_dev, 0);
-
-	omap_set_dma_dest_params(mcbsp->dma_tx_lch,
-				 src_port,
-				 OMAP_DMA_AMODE_CONSTANT,
-				 mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
-				 0, 0);
-
-	omap_set_dma_src_params(mcbsp->dma_tx_lch,
-				dest_port,
-				OMAP_DMA_AMODE_POST_INC,
-				buffer,
-				0, 0);
-
-	omap_start_dma(mcbsp->dma_tx_lch);
-	wait_for_completion(&mcbsp->tx_dma_completion);
-
-	return 0;
+	WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
+	     __func__);
+	return -EINVAL;
 }
-EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
 
-int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
-				unsigned int length)
+void omap2_mcbsp1_mux_clkr_src(u8 mux)
 {
-	struct omap_mcbsp *mcbsp;
-	int dma_rx_ch;
-	int src_port = 0;
-	int dest_port = 0;
-	int sync_dev = 0;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return -ENODEV;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
-				omap_mcbsp_rx_dma_callback,
-				mcbsp,
-				&dma_rx_ch)) {
-		dev_err(mcbsp->dev, "Unable to request DMA channel for "
-				"McBSP%d RX. Trying IRQ based RX\n",
-				mcbsp->id);
-		return -EAGAIN;
-	}
-	mcbsp->dma_rx_lch = dma_rx_ch;
-
-	dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
-		dma_rx_ch);
-
-	init_completion(&mcbsp->rx_dma_completion);
-
-	if (cpu_class_is_omap1()) {
-		src_port = OMAP_DMA_PORT_TIPB;
-		dest_port = OMAP_DMA_PORT_EMIFF;
-	}
-	if (cpu_class_is_omap2())
-		sync_dev = mcbsp->dma_rx_sync;
-
-	omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
-					OMAP_DMA_DATA_TYPE_S16,
-					length >> 1, 1,
-					OMAP_DMA_SYNC_ELEMENT,
-					sync_dev, 0);
-
-	omap_set_dma_src_params(mcbsp->dma_rx_lch,
-				src_port,
-				OMAP_DMA_AMODE_CONSTANT,
-				mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
-				0, 0);
-
-	omap_set_dma_dest_params(mcbsp->dma_rx_lch,
-					dest_port,
-					OMAP_DMA_AMODE_POST_INC,
-					buffer,
-					0, 0);
-
-	omap_start_dma(mcbsp->dma_rx_lch);
-	wait_for_completion(&mcbsp->rx_dma_completion);
-
-	return 0;
+	WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
+	     __func__);
+	return;
 }
-EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
 
-/*
- * SPI wrapper.
- * Since SPI setup is much simpler than the generic McBSP one,
- * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
- * Once this is done, you can call omap_mcbsp_start().
- */
-void omap_mcbsp_set_spi_mode(unsigned int id,
-				const struct omap_mcbsp_spi_cfg *spi_cfg)
+void omap2_mcbsp1_mux_fsr_src(u8 mux)
 {
-	struct omap_mcbsp *mcbsp;
-	struct omap_mcbsp_reg_cfg mcbsp_cfg;
-
-	if (!omap_mcbsp_check_valid_id(id)) {
-		printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
-		return;
-	}
-	mcbsp = id_to_mcbsp_ptr(id);
-
-	memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
-
-	/* SPI has only one frame */
-	mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
-	mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
-
-	/* Clock stop mode */
-	if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
-		mcbsp_cfg.spcr1 |= (1 << 12);
-	else
-		mcbsp_cfg.spcr1 |= (3 << 11);
-
-	/* Set clock parities */
-	if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
-		mcbsp_cfg.pcr0 |= CLKRP;
-	else
-		mcbsp_cfg.pcr0 &= ~CLKRP;
-
-	if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
-		mcbsp_cfg.pcr0 &= ~CLKXP;
-	else
-		mcbsp_cfg.pcr0 |= CLKXP;
-
-	/* Set SCLKME to 0 and CLKSM to 1 */
-	mcbsp_cfg.pcr0 &= ~SCLKME;
-	mcbsp_cfg.srgr2 |= CLKSM;
-
-	/* Set FSXP */
-	if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
-		mcbsp_cfg.pcr0 &= ~FSXP;
-	else
-		mcbsp_cfg.pcr0 |= FSXP;
-
-	if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
-		mcbsp_cfg.pcr0 |= CLKXM;
-		mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
-		mcbsp_cfg.pcr0 |= FSXM;
-		mcbsp_cfg.srgr2 &= ~FSGM;
-		mcbsp_cfg.xcr2 |= XDATDLY(1);
-		mcbsp_cfg.rcr2 |= RDATDLY(1);
-	} else {
-		mcbsp_cfg.pcr0 &= ~CLKXM;
-		mcbsp_cfg.srgr1 |= CLKGDV(1);
-		mcbsp_cfg.pcr0 &= ~FSXM;
-		mcbsp_cfg.xcr2 &= ~XDATDLY(3);
-		mcbsp_cfg.rcr2 &= ~RDATDLY(3);
-	}
-
-	mcbsp_cfg.xcr2 &= ~XPHASE;
-	mcbsp_cfg.rcr2 &= ~RPHASE;
-
-	omap_mcbsp_config(id, &mcbsp_cfg);
+	WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
+	     __func__);
+	return;
 }
-EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
+#endif
 
 #ifdef CONFIG_ARCH_OMAP3
 #define max_thres(m)			(mcbsp->pdata->buffer_size)
@@ -1833,8 +1304,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 	spin_lock_init(&mcbsp->lock);
 	mcbsp->id = id + 1;
 	mcbsp->free = true;
-	mcbsp->dma_tx_lch = -1;
-	mcbsp->dma_rx_lch = -1;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
 	if (!res) {
@@ -1860,9 +1329,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
 	else
 		mcbsp->phys_dma_base = res->start;
 
-	/* Default I/O is IRQ based */
-	mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
-
 	mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
 	mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
 
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 49fc0df0c21f..b6b409744954 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -236,61 +236,71 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
 	return 0;
 }
 
-static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
+static void _add_clkdev(struct omap_device *od, const char *clk_alias,
+		       const char *clk_name)
 {
-	return container_of(pdev, struct omap_device, pdev);
+	struct clk *r;
+	struct clk_lookup *l;
+
+	if (!clk_alias || !clk_name)
+		return;
+
+	pr_debug("omap_device: %s: Creating %s -> %s\n",
+		 dev_name(&od->pdev.dev), clk_alias, clk_name);
+
+	r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias);
+	if (!IS_ERR(r)) {
+		pr_warning("omap_device: %s: alias %s already exists\n",
+			   dev_name(&od->pdev.dev), clk_alias);
+		clk_put(r);
+		return;
+	}
+
+	r = omap_clk_get_by_name(clk_name);
+	if (IS_ERR(r)) {
+		pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
+		       dev_name(&od->pdev.dev), clk_name);
+		return;
+	}
+
+	l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev));
+	if (!l) {
+		pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
+		       dev_name(&od->pdev.dev), clk_alias);
+		return;
+	}
+
+	clkdev_add(l);
 }
 
 /**
- * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks
+ * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks
+ * and main clock
  * @od: struct omap_device *od
+ * @oh: struct omap_hwmod *oh
  *
- * For every optional clock present per hwmod per omap_device, this function
- * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role>
- * if it does not exist already.
+ * For the main clock and every optional clock present per hwmod per
+ * omap_device, this function adds an entry in the clkdev table of the
+ * form <dev-id=dev_name, con-id=role> if it does not exist already.
  *
  * The function is called from inside omap_device_build_ss(), after
  * omap_device_register.
  *
  * This allows drivers to get a pointer to its optional clocks based on its role
  * by calling clk_get(<dev*>, <role>).
+ * In the case of the main clock, a "fck" alias is used.
  *
  * No return value.
  */
-static void _add_optional_clock_clkdev(struct omap_device *od,
-				      struct omap_hwmod *oh)
+static void _add_hwmod_clocks_clkdev(struct omap_device *od,
+				     struct omap_hwmod *oh)
 {
 	int i;
 
-	for (i = 0; i < oh->opt_clks_cnt; i++) {
-		struct omap_hwmod_opt_clk *oc;
-		struct clk *r;
-		struct clk_lookup *l;
+	_add_clkdev(od, "fck", oh->main_clk);
 
-		oc = &oh->opt_clks[i];
-
-		if (!oc->_clk)
-			continue;
-
-		r = clk_get_sys(dev_name(&od->pdev.dev), oc->role);
-		if (!IS_ERR(r))
-			continue; /* clkdev entry exists */
-
-		r = omap_clk_get_by_name((char *)oc->clk);
-		if (IS_ERR(r)) {
-			pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
-			       dev_name(&od->pdev.dev), oc->clk);
-			continue;
-		}
-
-		l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev));
-		if (!l) {
-			pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
-			       dev_name(&od->pdev.dev), oc->role);
-			return;
-		}
-		clkdev_add(l);
-	}
+	for (i = 0; i < oh->opt_clks_cnt; i++)
+		_add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
 }
 
 
@@ -316,7 +326,7 @@ u32 omap_device_get_context_loss_count(struct platform_device *pdev)
 	struct omap_device *od;
 	u32 ret = 0;
 
-	od = _find_by_pdev(pdev);
+	od = to_omap_device(pdev);
 
 	if (od->hwmods_cnt)
 		ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
@@ -497,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
 
 	for (i = 0; i < oh_cnt; i++) {
 		hwmods[i]->od = od;
-		_add_optional_clock_clkdev(od, hwmods[i]);
+		_add_hwmod_clocks_clkdev(od, hwmods[i]);
 	}
 
 	if (ret)
@@ -537,6 +547,7 @@ int omap_early_device_register(struct omap_device *od)
 	return 0;
 }
 
+#ifdef CONFIG_PM_RUNTIME
 static int _od_runtime_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -563,13 +574,55 @@ static int _od_runtime_resume(struct device *dev)
 
 	return pm_generic_runtime_resume(dev);
 }
+#endif
+
+#ifdef CONFIG_SUSPEND
+static int _od_suspend_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *od = to_omap_device(pdev);
+	int ret;
+
+	if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)
+		return pm_generic_suspend_noirq(dev);
+
+	ret = pm_generic_suspend_noirq(dev);
+
+	if (!ret && !pm_runtime_status_suspended(dev)) {
+		if (pm_generic_runtime_suspend(dev) == 0) {
+			omap_device_idle(pdev);
+			od->flags |= OMAP_DEVICE_SUSPENDED;
+		}
+	}
+
+	return ret;
+}
+
+static int _od_resume_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *od = to_omap_device(pdev);
+
+	if (od->flags & OMAP_DEVICE_NO_IDLE_ON_SUSPEND)
+		return pm_generic_resume_noirq(dev);
+
+	if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
+	    !pm_runtime_status_suspended(dev)) {
+		od->flags &= ~OMAP_DEVICE_SUSPENDED;
+		omap_device_enable(pdev);
+		pm_generic_runtime_resume(dev);
+	}
+
+	return pm_generic_resume_noirq(dev);
+}
+#endif
 
-static struct dev_power_domain omap_device_power_domain = {
+static struct dev_pm_domain omap_device_pm_domain = {
 	.ops = {
-		.runtime_suspend = _od_runtime_suspend,
-		.runtime_idle = _od_runtime_idle,
-		.runtime_resume = _od_runtime_resume,
+		SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
+				   _od_runtime_idle)
 		USE_PLATFORM_PM_SLEEP_OPS
+		SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq)
 	}
 };
 
@@ -586,7 +639,7 @@ int omap_device_register(struct omap_device *od)
 	pr_debug("omap_device: %s: registering\n", od->pdev.name);
 
 	od->pdev.dev.parent = &omap_device_parent;
-	od->pdev.dev.pwr_domain = &omap_device_power_domain;
+	od->pdev.dev.pm_domain = &omap_device_pm_domain;
 	return platform_device_register(&od->pdev);
 }
 
@@ -611,7 +664,7 @@ int omap_device_enable(struct platform_device *pdev)
 	int ret;
 	struct omap_device *od;
 
-	od = _find_by_pdev(pdev);
+	od = to_omap_device(pdev);
 
 	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
 		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
@@ -650,7 +703,7 @@ int omap_device_idle(struct platform_device *pdev)
 	int ret;
 	struct omap_device *od;
 
-	od = _find_by_pdev(pdev);
+	od = to_omap_device(pdev);
 
 	if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
 		WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
@@ -681,7 +734,7 @@ int omap_device_shutdown(struct platform_device *pdev)
 	int ret, i;
 	struct omap_device *od;
 
-	od = _find_by_pdev(pdev);
+	od = to_omap_device(pdev);
 
 	if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
 	    od->_state != OMAP_DEVICE_STATE_IDLE) {
@@ -722,7 +775,7 @@ int omap_device_align_pm_lat(struct platform_device *pdev,
 	int ret = -EINVAL;
 	struct omap_device *od;
 
-	od = _find_by_pdev(pdev);
+	od = to_omap_device(pdev);
 
 	if (new_wakeup_lat_limit == od->dev_wakeup_lat)
 		return 0;
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 6af3d0b1f8d0..363c91e44efb 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -394,20 +394,15 @@ void omap3_sram_restore_context(void)
 }
 #endif /* CONFIG_PM */
 
-static int __init omap34xx_sram_init(void)
-{
-	_omap3_sram_configure_core_dpll =
-		omap_sram_push(omap3_sram_configure_core_dpll,
-			       omap3_sram_configure_core_dpll_sz);
-	omap_push_sram_idle();
-	return 0;
-}
-#else
+#endif /* CONFIG_ARCH_OMAP3 */
+
 static inline int omap34xx_sram_init(void)
 {
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+	omap3_sram_restore_context();
+#endif
 	return 0;
 }
-#endif
 
 int __init omap_sram_init(void)
 {