diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index fff4a0e0bce7f17d0ffcba0cd3ab8c28ca0e30ae..86d1ce2ad43f71837086b1f77b8ae92e312a9b28 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -20,3 +20,7 @@ obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
+
+# DSP subsystem
+obj-y += dsp/
+obj-$(CONFIG_OMAP_DSP) += mailbox.o
diff --git a/arch/arm/plat-omap/dsp/Kconfig b/arch/arm/plat-omap/dsp/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..0d62beee8a39ca60e43489b820fb20e19ba157cc
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/Kconfig
@@ -0,0 +1,31 @@
+
+config OMAP_DSP
+	tristate "OMAP DSP driver (DSP Gateway)"
+	depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP24XX
+	select OMAP_MMU_FWK
+	select OMAP_MBOX_FWK
+	help
+	  This enables OMAP DSP driver, DSP Gateway.
+
+config OMAP_DSP_MBCMD_VERBOSE
+	bool "Mailbox Command Verbose LOG"
+	depends on OMAP_DSP
+	help
+          This enables kernel log output in the Mailbox command exchanges
+	  in the DSP Gateway driver.
+
+config OMAP_DSP_TASK_MULTIOPEN
+	bool "DSP Task Multiopen Capability"
+	depends on OMAP_DSP
+	help
+          This enables DSP tasks to be opened by multiple times at a time.
+	  Otherwise, they can be opened only once at a time.
+
+config OMAP_DSP_FBEXPORT
+	bool "Framebuffer export to DSP"
+	depends on OMAP_DSP && FB
+	help
+          This enables to map the frame buffer to DSP.
+	  By doing this, DSP can access the frame buffer directly without
+	  bothering ARM.
+
diff --git a/arch/arm/plat-omap/dsp/Makefile b/arch/arm/plat-omap/dsp/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..c7d86f358b575befe498979593c14dbb20f64897
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the OMAP DSP driver.
+#
+
+# The target object and module list name.
+
+obj-y := dsp_common.o
+
+obj-$(CONFIG_OMAP_DSP) += dsp.o
+
+# Declare multi-part drivers
+
+dsp-objs	:= dsp_core.o ipbuf.o mblog.o task.o \
+		   dsp_ctl_core.o dsp_ctl.o taskwatch.o error.o dsp_mem.o \
+		   uaccess_dsp.o
diff --git a/arch/arm/plat-omap/dsp/dsp_common.c b/arch/arm/plat-omap/dsp/dsp_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..cfb2bbc0e49b7f56f3d85fb9491de80f351370ba
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/dsp_common.c
@@ -0,0 +1,617 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; 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
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+#include <asm/irq.h>
+#ifdef CONFIG_ARCH_OMAP1
+#include <asm/arch/tc.h>
+#endif
+#include "dsp_common.h"
+
+#if defined(CONFIG_ARCH_OMAP1)
+#define dsp_boot_config(mode)	omap_writew((mode), MPUI_DSP_BOOT_CONFIG)
+#elif defined(CONFIG_ARCH_OMAP2)
+#define dsp_boot_config(mode)	writel((mode), DSP_IPI_DSPBOOTCONFIG)
+#endif
+
+struct omap_dsp *omap_dsp;
+
+#if defined(CONFIG_ARCH_OMAP1)
+struct clk *dsp_ck_handle;
+struct clk *api_ck_handle;
+#elif defined(CONFIG_ARCH_OMAP2)
+struct clk *dsp_fck_handle;
+struct clk *dsp_ick_handle;
+#endif
+dsp_long_t dspmem_base, dspmem_size,
+	   daram_base, daram_size,
+	   saram_base, saram_size;
+
+static struct cpustat {
+	struct mutex lock;
+	enum cpustat_e stat;
+	enum cpustat_e req;
+	u16 icrmask;
+#ifdef CONFIG_ARCH_OMAP1
+	struct {
+		int mpui;
+		int mem;
+		int mem_delayed;
+	} usecount;
+	int (*mem_req_cb)(void);
+	void (*mem_rel_cb)(void);
+#endif
+} cpustat = {
+	.stat = CPUSTAT_RESET,
+	.icrmask = 0xffff,
+};
+
+int dsp_set_rstvect(dsp_long_t adr)
+{
+	unsigned long *dst_adr;
+
+	if (adr >= DSPSPACE_SIZE)
+		return -EINVAL;
+
+	dst_adr = dspbyte_to_virt(DSP_BOOT_ADR_DIRECT);
+	/* word swap */
+	*dst_adr = ((adr & 0xffff) << 16) | (adr >> 16);
+	/* fill 8 bytes! */
+	*(dst_adr + 1) = 0;
+	/* direct boot */
+	dsp_boot_config(DSP_BOOT_CONFIG_DIRECT);
+
+	return 0;
+}
+
+dsp_long_t dsp_get_rstvect(void)
+{
+	unsigned long *dst_adr;
+
+	dst_adr = dspbyte_to_virt(DSP_BOOT_ADR_DIRECT);
+	return ((*dst_adr & 0xffff) << 16) | (*dst_adr >> 16);
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+static void simple_load_code(unsigned char *src_c, u16 *dst, int len)
+{
+	int i;
+	u16 *src = (u16 *)src_c;
+	int len_w;
+
+	/* len must be multiple of 2. */
+	if (len & 1)
+		BUG();
+
+	len_w = len / 2;
+	for (i = 0; i < len_w; i++) {
+		/* byte swap copy */
+		*dst = ((*src & 0x00ff) << 8) |
+		       ((*src & 0xff00) >> 8);
+		src++;
+		dst++;
+	}
+}
+
+/* program size must be multiple of 2 */
+#define GBL_IDLE_TEXT_SIZE	52
+#define GBL_IDLE_TEXT_INIT { \
+	/* SAM */ \
+	0x3c, 0x4a,			/* 0x3c4a:     MOV 0x4, AR2 */ \
+	0xf4, 0x41, 0xfc, 0xff,		/* 0xf441fcff: AND 0xfcff, *AR2 */ \
+	/* disable WDT */ \
+	0x76, 0x34, 0x04, 0xb8,		/* 0x763404b8: MOV 0x3404, AR3 */ \
+	0xfb, 0x61, 0x00, 0xf5,		/* 0xfb6100f5: MOV 0x00f5, *AR3 */ \
+	0x9a,				/* 0x9a:       PORT */ \
+	0xfb, 0x61, 0x00, 0xa0,		/* 0xfb6100a0: MOV 0x00a0, *AR3 */ \
+	0x9a,				/* 0x9a:       PORT */ \
+	/* *IER0 = 0, *IER1 = 0 */ \
+	0x3c, 0x0b,			/* 0x3c0b:     MOV 0x0, AR3 */ \
+	0xe6, 0x61, 0x00,		/* 0xe66100:   MOV 0, *AR3 */ \
+	0x76, 0x00, 0x45, 0xb8,		/* 0x76004508: MOV 0x45, AR3 */ \
+	0xe6, 0x61, 0x00,		/* 0xe66100:   MOV 0, *AR3 */ \
+	/* *ICR = 0xffff */ \
+	0x3c, 0x1b,			/* 0x3c1b:     MOV 0x1, AR3 */ \
+	0xfb, 0x61, 0xff, 0xff,		/* 0xfb61ffff: MOV 0xffff, *AR3 */ \
+	0x9a,				/* 0x9a:       PORT */ \
+	/* HOM */ \
+	0xf5, 0x41, 0x03, 0x00,		/* 0xf5410300: OR 0x0300, *AR2 */ \
+	/* idle and loop forever */ \
+	0x7a, 0x00, 0x00, 0x0c,		/* 0x7a00000c: IDLE */ \
+	0x4a, 0x7a,			/* 0x4a7a:     B -6 (infinite loop) */ \
+	0x20, 0x20, 0x20,		/* 0x20:       NOP */ \
+}
+
+/* program size must be multiple of 2 */
+#define CPU_IDLE_TEXT_SIZE	48
+#define CPU_IDLE_TEXT_INIT(icrh, icrl) { \
+	/* SAM */ \
+	0x3c, 0x4b,			/* 0x3c4b:     MOV 0x4, AR3 */ \
+	0xf4, 0x61, 0xfc, 0xff,		/* 0xf461fcff: AND 0xfcff, *AR3 */ \
+	/* disable WDT */ \
+	0x76, 0x34, 0x04, 0xb8,		/* 0x763404b8: MOV 0x3404, AR3 */ \
+	0xfb, 0x61, 0x00, 0xf5,		/* 0xfb6100f5: MOV 0x00f5, *AR3 */ \
+	0x9a,				/* 0x9a:       PORT */ \
+	0xfb, 0x61, 0x00, 0xa0,		/* 0xfb6100a0: MOV 0x00a0, *AR3 */ \
+	0x9a,				/* 0x9a:       PORT */ \
+	/* *IER0 = 0, *IER1 = 0 */ \
+	0x3c, 0x0b,			/* 0x3c0b:     MOV 0x0, AR3 */ \
+	0xe6, 0x61, 0x00,		/* 0xe66100:   MOV 0, *AR3 */ \
+	0x76, 0x00, 0x45, 0xb8,		/* 0x76004508: MOV 0x45, AR3 */ \
+	0xe6, 0x61, 0x00,		/* 0xe66100:   MOV 0, *AR3 */ \
+	/* set ICR = icr */ \
+	0x3c, 0x1b,			/* 0x3c1b:     MOV AR3 0x1 */ \
+	0xfb, 0x61, (icrh), (icrl),	/* 0xfb61****: MOV *AR3, icr */ \
+	0x9a,				/* 0x9a:       PORT */ \
+	/* idle and loop forever */ \
+	0x7a, 0x00, 0x00, 0x0c,		/* 0x7a00000c: IDLE */ \
+	0x4a, 0x7a,			/* 0x4a7a:     B -6 (infinite loop) */ \
+	0x20, 0x20, 0x20		/* 0x20: nop */ \
+}
+
+/*
+ * idle_boot base:
+ * Initialized with DSP_BOOT_ADR_MPUI (=0x010000).
+ * This value is used before DSP Gateway driver is initialized.
+ * DSP Gateway driver will overwrite this value with other value,
+ * to avoid confliction with the user program.
+ */
+static dsp_long_t idle_boot_base = DSP_BOOT_ADR_MPUI;
+
+static void dsp_gbl_idle(void)
+{
+	unsigned char idle_text[GBL_IDLE_TEXT_SIZE] = GBL_IDLE_TEXT_INIT;
+
+	__dsp_reset();
+	clk_enable(api_ck_handle);
+
+#if 0
+	dsp_boot_config(DSP_BOOT_CONFIG_IDLE);
+#endif
+	simple_load_code(idle_text, dspbyte_to_virt(idle_boot_base),
+			 GBL_IDLE_TEXT_SIZE);
+	if (idle_boot_base == DSP_BOOT_ADR_MPUI)
+		dsp_boot_config(DSP_BOOT_CONFIG_MPUI);
+	else
+		dsp_set_rstvect(idle_boot_base);
+
+	__dsp_run();
+	udelay(100);	/* to make things stable */
+	clk_disable(api_ck_handle);
+}
+
+static void dsp_cpu_idle(void)
+{
+	u16 icr_tmp;
+	unsigned char icrh, icrl;
+
+	__dsp_reset();
+	clk_enable(api_ck_handle);
+
+	/*
+	 * icr settings:
+	 * DMA should not sleep for DARAM/SARAM access
+	 * DPLL should not sleep while any other domain is active
+	 */
+	icr_tmp = cpustat.icrmask & ~(DSPREG_ICR_DMA | DSPREG_ICR_DPLL);
+	icrh = icr_tmp >> 8;
+	icrl = icr_tmp & 0xff;
+	{
+		unsigned char idle_text[CPU_IDLE_TEXT_SIZE] = CPU_IDLE_TEXT_INIT(icrh, icrl);
+		simple_load_code(idle_text, dspbyte_to_virt(idle_boot_base),
+				 CPU_IDLE_TEXT_SIZE);
+	}
+	if (idle_boot_base == DSP_BOOT_ADR_MPUI)
+		dsp_boot_config(DSP_BOOT_CONFIG_MPUI);
+	else
+		dsp_set_rstvect(idle_boot_base);
+	__dsp_run();
+	udelay(100);	/* to make things stable */
+	clk_disable(api_ck_handle);
+}
+
+void dsp_set_idle_boot_base(dsp_long_t adr, size_t size)
+{
+	if (adr == idle_boot_base)
+		return;
+	idle_boot_base = adr;
+	if ((size < GBL_IDLE_TEXT_SIZE) ||
+	    (size < CPU_IDLE_TEXT_SIZE)) {
+		printk(KERN_ERR
+		       "omapdsp: size for idle program is not enough!\n");
+		BUG();
+	}
+
+	/* restart idle program with new base address */
+	if (cpustat.stat == CPUSTAT_GBL_IDLE)
+		dsp_gbl_idle();
+	if (cpustat.stat == CPUSTAT_CPU_IDLE)
+		dsp_cpu_idle();
+}
+
+void dsp_reset_idle_boot_base(void)
+{
+	idle_boot_base = DSP_BOOT_ADR_MPUI;
+}
+#else
+void dsp_reset_idle_boot_base(void) { }
+#endif /* CONFIG_ARCH_OMAP1 */
+
+static int init_done;
+
+static int __init omap_dsp_init(void)
+{
+	mutex_init(&cpustat.lock);
+
+	dspmem_size = 0;
+#ifdef CONFIG_ARCH_OMAP15XX
+	if (cpu_is_omap15xx()) {
+		dspmem_base = OMAP1510_DSP_BASE;
+		dspmem_size = OMAP1510_DSP_SIZE;
+		daram_base = OMAP1510_DARAM_BASE;
+		daram_size = OMAP1510_DARAM_SIZE;
+		saram_base = OMAP1510_SARAM_BASE;
+		saram_size = OMAP1510_SARAM_SIZE;
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	if (cpu_is_omap16xx()) {
+		dspmem_base = OMAP16XX_DSP_BASE;
+		dspmem_size = OMAP16XX_DSP_SIZE;
+		daram_base = OMAP16XX_DARAM_BASE;
+		daram_size = OMAP16XX_DARAM_SIZE;
+		saram_base = OMAP16XX_SARAM_BASE;
+		saram_size = OMAP16XX_SARAM_SIZE;
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP24XX
+	if (cpu_is_omap24xx()) {
+		dspmem_base = DSP_MEM_24XX_VIRT;
+		dspmem_size = DSP_MEM_24XX_SIZE;
+		daram_base = OMAP24XX_DARAM_BASE;
+		daram_size = OMAP24XX_DARAM_SIZE;
+		saram_base = OMAP24XX_SARAM_BASE;
+		saram_size = OMAP24XX_SARAM_SIZE;
+	}
+#endif
+	if (dspmem_size == 0) {
+		printk(KERN_ERR "omapdsp: unsupported omap architecture.\n");
+		return -ENODEV;
+	}
+
+#if defined(CONFIG_ARCH_OMAP1)
+	dsp_ck_handle = clk_get(NULL, "dsp_ck");
+	if (IS_ERR(dsp_ck_handle)) {
+		printk(KERN_ERR "omapdsp: could not acquire dsp_ck handle.\n");
+		return PTR_ERR(dsp_ck_handle);
+	}
+
+	api_ck_handle = clk_get(NULL, "api_ck");
+	if (IS_ERR(api_ck_handle)) {
+		printk(KERN_ERR "omapdsp: could not acquire api_ck handle.\n");
+		if (dsp_ck_handle != NULL)
+			clk_put(dsp_ck_handle);
+		return PTR_ERR(api_ck_handle);
+	}
+
+	/* This is needed for McBSP init, released in late_initcall */
+	clk_enable(api_ck_handle);
+
+	__dsp_enable();
+	mpui_byteswap_off();
+	mpui_wordswap_on();
+	tc_wordswap();
+#elif defined(CONFIG_ARCH_OMAP2)
+	dsp_fck_handle = clk_get(NULL, "dsp_fck");
+	if (IS_ERR(dsp_fck_handle)) {
+		printk(KERN_ERR "omapdsp: could not acquire dsp_fck handle.\n");
+		return PTR_ERR(dsp_fck_handle);
+	}
+
+	dsp_ick_handle = clk_get(NULL, "dsp_ick");
+	if (IS_ERR(dsp_ick_handle)) {
+		printk(KERN_ERR "omapdsp: could not acquire dsp_ick handle.\n");
+		if (dsp_fck_handle != NULL)
+			clk_put(dsp_fck_handle);
+		return PTR_ERR(dsp_ick_handle);
+	}
+#endif
+
+	init_done = 1;
+	pr_info("omap_dsp_init() done\n");
+	return 0;
+}
+
+#if defined(CONFIG_ARCH_OMAP1)
+static int __dsp_late_init(void)
+{
+	clk_disable(api_ck_handle);
+	return 0;
+}
+late_initcall(__dsp_late_init);
+#endif
+
+static void dsp_cpustat_update(void)
+{
+	if (!init_done)
+		omap_dsp_init();
+
+	if (cpustat.req == CPUSTAT_RUN) {
+		if (cpustat.stat < CPUSTAT_RUN) {
+#if defined(CONFIG_ARCH_OMAP1)
+			__dsp_reset();
+			clk_enable(api_ck_handle);
+			udelay(10);
+			__dsp_run();
+#elif defined(CONFIG_ARCH_OMAP2)
+			__dsp_core_disable();
+			udelay(10);
+			__dsp_core_enable();
+#endif
+			cpustat.stat = CPUSTAT_RUN;
+		}
+		return;
+	}
+
+	/* cpustat.req < CPUSTAT_RUN */
+
+	if (cpustat.stat == CPUSTAT_RUN) {
+#ifdef CONFIG_ARCH_OMAP1
+		clk_disable(api_ck_handle);
+#endif
+	}
+
+#ifdef CONFIG_ARCH_OMAP1
+	/*
+	 * (1) when ARM wants DARAM access, MPUI should be SAM and
+	 *     DSP needs to be on.
+	 * (2) if any bits of icr is masked, we can not enter global idle.
+	 */
+	if ((cpustat.req == CPUSTAT_CPU_IDLE) ||
+	    (cpustat.usecount.mem > 0) ||
+	    (cpustat.usecount.mem_delayed > 0) ||
+	    ((cpustat.usecount.mpui > 0) && (cpustat.icrmask != 0xffff))) {
+		if (cpustat.stat != CPUSTAT_CPU_IDLE) {
+			dsp_cpu_idle();
+			cpustat.stat = CPUSTAT_CPU_IDLE;
+		}
+		return;
+	}
+
+	/*
+	 * when ARM only needs MPUI access, MPUI can be HOM and
+	 * DSP can be idling.
+	 */
+	if ((cpustat.req == CPUSTAT_GBL_IDLE) ||
+	    (cpustat.usecount.mpui > 0)) {
+		if (cpustat.stat != CPUSTAT_GBL_IDLE) {
+			dsp_gbl_idle();
+			cpustat.stat = CPUSTAT_GBL_IDLE;
+		}
+		return;
+	}
+#endif /* CONFIG_ARCH_OMAP1 */
+
+	/*
+	 * no user, no request
+	 */
+	if (cpustat.stat != CPUSTAT_RESET) {
+#if defined(CONFIG_ARCH_OMAP1)
+		__dsp_reset();
+#elif defined(CONFIG_ARCH_OMAP2)
+		__dsp_core_disable();
+#endif
+		cpustat.stat = CPUSTAT_RESET;
+	}
+}
+
+void dsp_cpustat_request(enum cpustat_e req)
+{
+	mutex_lock(&cpustat.lock);
+	cpustat.req = req;
+	dsp_cpustat_update();
+	mutex_unlock(&cpustat.lock);
+}
+
+enum cpustat_e dsp_cpustat_get_stat(void)
+{
+	return cpustat.stat;
+}
+
+u16 dsp_cpustat_get_icrmask(void)
+{
+	return cpustat.icrmask;
+}
+
+void dsp_cpustat_set_icrmask(u16 mask)
+{
+	mutex_lock(&cpustat.lock);
+	cpustat.icrmask = mask;
+	dsp_cpustat_update();
+	mutex_unlock(&cpustat.lock);
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+void omap_dsp_request_mpui(void)
+{
+	mutex_lock(&cpustat.lock);
+	if (cpustat.usecount.mpui++ == 0)
+		dsp_cpustat_update();
+	mutex_unlock(&cpustat.lock);
+}
+
+void omap_dsp_release_mpui(void)
+{
+	mutex_lock(&cpustat.lock);
+	if (cpustat.usecount.mpui-- == 0) {
+		printk(KERN_ERR
+		       "omapdsp: unbalanced mpui request/release detected.\n"
+		       "         cpustat.usecount.mpui is going to be "
+		       "less than zero! ... fixed to be zero.\n");
+		cpustat.usecount.mpui = 0;
+	}
+	if (cpustat.usecount.mpui == 0)
+		dsp_cpustat_update();
+	mutex_unlock(&cpustat.lock);
+}
+
+int omap_dsp_request_mem(void)
+{
+	int ret = 0;
+
+	mutex_lock(&cpustat.lock);
+	if ((cpustat.usecount.mem++ == 0) &&
+	    (cpustat.usecount.mem_delayed == 0)) {
+		if (cpustat.mem_req_cb) {
+			if ((ret = cpustat.mem_req_cb()) < 0) {
+				cpustat.usecount.mem--;
+				goto out;
+			}
+		}
+		dsp_cpustat_update();
+	}
+out:
+	mutex_unlock(&cpustat.lock);
+
+	return ret;
+}
+
+/*
+ * release_mem will be delayed.
+ */
+static void do_release_mem(struct work_struct *dummy)
+{
+	mutex_lock(&cpustat.lock);
+	cpustat.usecount.mem_delayed = 0;
+	if (cpustat.usecount.mem == 0) {
+		dsp_cpustat_update();
+		if (cpustat.mem_rel_cb)
+			cpustat.mem_rel_cb();
+	}
+	mutex_unlock(&cpustat.lock);
+}
+
+static DECLARE_DELAYED_WORK(mem_rel_work, do_release_mem);
+
+int omap_dsp_release_mem(void)
+{
+	mutex_lock(&cpustat.lock);
+
+	/* cancel previous release work */
+	cancel_delayed_work(&mem_rel_work);
+	cpustat.usecount.mem_delayed = 0;
+
+	if (cpustat.usecount.mem-- == 0) {
+		printk(KERN_ERR
+		       "omapdsp: unbalanced memory request/release detected.\n"
+		       "         cpustat.usecount.mem is going to be "
+		       "less than zero! ... fixed to be zero.\n");
+		cpustat.usecount.mem = 0;
+	}
+	if (cpustat.usecount.mem == 0) {
+		cpustat.usecount.mem_delayed = 1;
+		schedule_delayed_work(&mem_rel_work, HZ);
+	}
+
+	mutex_unlock(&cpustat.lock);
+
+	return 0;
+}
+
+void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void))
+{
+	mutex_lock(&cpustat.lock);
+
+	cpustat.mem_req_cb = req_cb;
+	cpustat.mem_rel_cb = rel_cb;
+
+	/*
+	 * This function must be called while mem is enabled!
+	 */
+	BUG_ON(cpustat.usecount.mem == 0);
+
+	mutex_unlock(&cpustat.lock);
+}
+
+void dsp_unregister_mem_cb(void)
+{
+	mutex_lock(&cpustat.lock);
+	cpustat.mem_req_cb = NULL;
+	cpustat.mem_rel_cb = NULL;
+	mutex_unlock(&cpustat.lock);
+}
+#else
+void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void)) { }
+void dsp_unregister_mem_cb(void) { }
+#endif /* CONFIG_ARCH_OMAP1 */
+
+arch_initcall(omap_dsp_init);
+
+#ifdef CONFIG_ARCH_OMAP1
+EXPORT_SYMBOL(omap_dsp_request_mpui);
+EXPORT_SYMBOL(omap_dsp_release_mpui);
+EXPORT_SYMBOL(omap_dsp_request_mem);
+EXPORT_SYMBOL(omap_dsp_release_mem);
+#endif /* CONFIG_ARCH_OMAP1 */
+
+#ifdef CONFIG_OMAP_DSP_MODULE
+#if defined(CONFIG_ARCH_OMAP1)
+EXPORT_SYMBOL(dsp_ck_handle);
+EXPORT_SYMBOL(api_ck_handle);
+#elif defined(CONFIG_ARCH_OMAP2)
+EXPORT_SYMBOL(dsp_fck_handle);
+EXPORT_SYMBOL(dsp_ick_handle);
+#endif
+EXPORT_SYMBOL(omap_dsp);
+EXPORT_SYMBOL(dspmem_base);
+EXPORT_SYMBOL(dspmem_size);
+EXPORT_SYMBOL(daram_base);
+EXPORT_SYMBOL(daram_size);
+EXPORT_SYMBOL(saram_base);
+EXPORT_SYMBOL(saram_size);
+EXPORT_SYMBOL(dsp_set_rstvect);
+EXPORT_SYMBOL(dsp_get_rstvect);
+#ifdef CONFIG_ARCH_OMAP1
+EXPORT_SYMBOL(dsp_set_idle_boot_base);
+EXPORT_SYMBOL(dsp_reset_idle_boot_base);
+#endif /* CONFIG_ARCH_OMAP1 */
+EXPORT_SYMBOL(dsp_cpustat_request);
+EXPORT_SYMBOL(dsp_cpustat_get_stat);
+EXPORT_SYMBOL(dsp_cpustat_get_icrmask);
+EXPORT_SYMBOL(dsp_cpustat_set_icrmask);
+EXPORT_SYMBOL(dsp_register_mem_cb);
+EXPORT_SYMBOL(dsp_unregister_mem_cb);
+
+EXPORT_SYMBOL(__cpu_flush_kern_tlb_range);
+EXPORT_SYMBOL(cpu_architecture);
+EXPORT_SYMBOL(pmd_clear_bad);
+#endif
diff --git a/arch/arm/plat-omap/dsp/dsp_common.h b/arch/arm/plat-omap/dsp/dsp_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..898c9eab6bee15e6e5befed6bea1ebe95409fee4
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/dsp_common.h
@@ -0,0 +1,220 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; 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 DRIVER_DSP_COMMON_H
+#define DRIVER_DSP_COMMON_H
+
+#include <linux/clk.h>
+#include <asm/arch/mmu.h>
+#include "hardware_dsp.h"
+
+#define DSPSPACE_SIZE	0x1000000
+
+#define omap_set_bit_regw(b,r) \
+	do { omap_writew(omap_readw(r) | (b), (r)); } while(0)
+#define omap_clr_bit_regw(b,r) \
+	do { omap_writew(omap_readw(r) & ~(b), (r)); } while(0)
+#define omap_set_bit_regl(b,r) \
+	do { omap_writel(omap_readl(r) | (b), (r)); } while(0)
+#define omap_clr_bit_regl(b,r) \
+	do { omap_writel(omap_readl(r) & ~(b), (r)); } while(0)
+#define omap_set_bits_regl(val,mask,r) \
+	do { omap_writel((omap_readl(r) & ~(mask)) | (val), (r)); } while(0)
+
+#define dspword_to_virt(dw)	((void *)(dspmem_base + ((dw) << 1)))
+#define dspbyte_to_virt(db)	((void *)(dspmem_base + (db)))
+#define virt_to_dspword(va) \
+	((dsp_long_t)(((unsigned long)(va) - dspmem_base) >> 1))
+#define virt_to_dspbyte(va) \
+	((dsp_long_t)((unsigned long)(va) - dspmem_base))
+#define is_dsp_internal_mem(va) \
+	(((unsigned long)(va) >= dspmem_base) &&  \
+	 ((unsigned long)(va) < dspmem_base + dspmem_size))
+#define is_dspbyte_internal_mem(db)	((db) < dspmem_size)
+#define is_dspword_internal_mem(dw)	(((dw) << 1) < dspmem_size)
+
+#ifdef CONFIG_ARCH_OMAP1
+/*
+ * MPUI byteswap/wordswap on/off
+ *   default setting: wordswap = all, byteswap = APIMEM only
+ */
+#define mpui_wordswap_on() \
+	omap_set_bits_regl(MPUI_CTRL_WORDSWAP_ALL, MPUI_CTRL_WORDSWAP_MASK, \
+			   MPUI_CTRL)
+
+#define mpui_wordswap_off() \
+	omap_set_bits_regl(MPUI_CTRL_WORDSWAP_NONE, MPUI_CTRL_WORDSWAP_MASK, \
+			   MPUI_CTRL)
+
+#define mpui_byteswap_on() \
+	omap_set_bits_regl(MPUI_CTRL_BYTESWAP_API, MPUI_CTRL_BYTESWAP_MASK, \
+			   MPUI_CTRL)
+
+#define mpui_byteswap_off() \
+	omap_set_bits_regl(MPUI_CTRL_BYTESWAP_NONE, MPUI_CTRL_BYTESWAP_MASK, \
+			   MPUI_CTRL)
+
+/*
+ * TC wordswap on / off
+ */
+#define tc_wordswap() \
+	do { \
+		omap_writel(TC_ENDIANISM_SWAP_WORD | TC_ENDIANISM_EN, \
+			    TC_ENDIANISM); \
+	} while(0)
+
+#define tc_noswap()	omap_clr_bit_regl(TC_ENDIANISM_EN, TC_ENDIANISM)
+
+/*
+ * enable priority registers, EMIF, MPUI control logic
+ */
+#define __dsp_enable()	omap_set_bit_regw(ARM_RSTCT1_DSP_RST, ARM_RSTCT1)
+#define __dsp_disable()	omap_clr_bit_regw(ARM_RSTCT1_DSP_RST, ARM_RSTCT1)
+#define __dsp_run()	omap_set_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1)
+#define __dsp_reset()	omap_clr_bit_regw(ARM_RSTCT1_DSP_EN, ARM_RSTCT1)
+#endif /* CONFIG_ARCH_OMAP1 */
+
+#ifdef CONFIG_ARCH_OMAP2
+/*
+ * PRCM / IPI control logic
+ */
+#define RSTCTRL_RST1_DSP	0x00000001
+#define RSTCTRL_RST2_DSP	0x00000002
+#define __dsp_core_enable() \
+	do { RM_RSTCTRL_DSP &= ~RSTCTRL_RST1_DSP; } while (0)
+#define __dsp_core_disable() \
+	do { RM_RSTCTRL_DSP |= RSTCTRL_RST1_DSP; } while (0)
+#define __dsp_per_enable() \
+	do { RM_RSTCTRL_DSP &= ~RSTCTRL_RST2_DSP; } while (0)
+#define __dsp_per_disable() \
+	do { RM_RSTCTRL_DSP |= RSTCTRL_RST2_DSP; } while (0)
+#endif /* CONFIG_ARCH_OMAP2 */
+
+typedef u32 dsp_long_t;	/* must have ability to carry TADD_ABORTADR */
+
+#if defined(CONFIG_ARCH_OMAP1)
+extern struct clk *dsp_ck_handle;
+extern struct clk *api_ck_handle;
+#elif defined(CONFIG_ARCH_OMAP2)
+extern struct clk *dsp_fck_handle;
+extern struct clk *dsp_ick_handle;
+#endif
+extern dsp_long_t dspmem_base, dspmem_size,
+		  daram_base, daram_size,
+		  saram_base, saram_size;
+
+enum cpustat_e {
+	CPUSTAT_RESET = 0,
+#ifdef CONFIG_ARCH_OMAP1
+	CPUSTAT_GBL_IDLE,
+	CPUSTAT_CPU_IDLE,
+#endif
+	CPUSTAT_RUN,
+	CPUSTAT_MAX
+};
+
+int dsp_set_rstvect(dsp_long_t adr);
+dsp_long_t dsp_get_rstvect(void);
+void dsp_set_idle_boot_base(dsp_long_t adr, size_t size);
+void dsp_reset_idle_boot_base(void);
+void dsp_cpustat_request(enum cpustat_e req);
+enum cpustat_e dsp_cpustat_get_stat(void);
+u16 dsp_cpustat_get_icrmask(void);
+void dsp_cpustat_set_icrmask(u16 mask);
+void dsp_register_mem_cb(int (*req_cb)(void), void (*rel_cb)(void));
+void dsp_unregister_mem_cb(void);
+
+#if defined(CONFIG_ARCH_OMAP1)
+static inline void dsp_clk_enable(void) {}
+static inline void dsp_clk_disable(void) {}
+#elif defined(CONFIG_ARCH_OMAP2)
+static inline void dsp_clk_enable(void)
+{
+	/*XXX should be handled in mach-omap[1,2] XXX*/
+	PM_PWSTCTRL_DSP = (1 << 18) | (1 << 0);
+	CM_AUTOIDLE_DSP |= (1 << 1);
+	CM_CLKSTCTRL_DSP |= (1 << 0);
+
+	clk_enable(dsp_fck_handle);
+	clk_enable(dsp_ick_handle);
+	__dsp_per_enable();
+}
+static inline void dsp_clk_disable(void)
+{
+	__dsp_per_disable();
+	clk_disable(dsp_ick_handle);
+	clk_disable(dsp_fck_handle);
+
+	PM_PWSTCTRL_DSP = (1 << 18) | (3 << 0);
+}
+#endif
+
+struct dsp_kfunc_device {
+	char		*name;
+	struct clk	*fck;
+	struct clk	*ick;;
+	spinlock_t	 lock;
+	int		 enabled;
+	int		 type;
+#define DSP_KFUNC_DEV_TYPE_COMMON	1
+#define DSP_KFUNC_DEV_TYPE_AUDIO	2
+
+	struct list_head	entry;
+
+	int	(*probe)(struct dsp_kfunc_device *, int);
+	int	(*remove)(struct dsp_kfunc_device *, int);
+	int	(*enable)(struct dsp_kfunc_device *, int);
+	int	(*disable)(struct dsp_kfunc_device *, int);
+};
+
+extern int dsp_kfunc_device_register(struct dsp_kfunc_device *);
+
+struct dsp_platform_data {
+	struct list_head kdev_list;
+};
+
+struct omap_dsp {
+	struct mutex		lock;
+	int			enabled;	/* stored peripheral status */
+	struct omap_mmu		*mmu;
+	struct omap_mbox	*mbox;
+	struct device		*dev;
+	struct list_head	*kdev_list;
+	int			initialized;
+};
+
+#if defined(CONFIG_ARCH_OMAP1)
+#define command_dvfs_stop(m) (0)
+#define command_dvfs_start(m) (0)
+#elif defined(CONFIG_ARCH_OMAP2)
+#define command_dvfs_stop(m) \
+	(((m)->cmd_l == KFUNC_POWER) && ((m)->data == DVFS_STOP))
+#define command_dvfs_start(m) \
+	(((m)->cmd_l == KFUNC_POWER) && ((m)->data == DVFS_START))
+#endif
+
+extern struct omap_dsp *omap_dsp;
+
+extern int dsp_late_init(void);
+
+#endif /* DRIVER_DSP_COMMON_H */
diff --git a/arch/arm/plat-omap/dsp/hardware_dsp.h b/arch/arm/plat-omap/dsp/hardware_dsp.h
new file mode 100644
index 0000000000000000000000000000000000000000..a15d9afa737c8c58c3b6d3418bcae701faa535e3
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/hardware_dsp.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; 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 __OMAP_DSP_HARDWARE_DSP_H
+#define __OMAP_DSP_HARDWARE_DSP_H
+
+#ifdef CONFIG_ARCH_OMAP1
+#include "omap1_dsp.h"
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+#include "omap2_dsp.h"
+#endif
+
+#endif /* __OMAP_DSP_HARDWARE_DSP_H */
diff --git a/arch/arm/plat-omap/dsp/omap1_dsp.h b/arch/arm/plat-omap/dsp/omap1_dsp.h
new file mode 100644
index 0000000000000000000000000000000000000000..45fdb507d99b077fcd13f62e716d8fbfa2e72ae9
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/omap1_dsp.h
@@ -0,0 +1,188 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; 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 __OMAP_DSP_OMAP1_DSP_H
+#define __OMAP_DSP_OMAP1_DSP_H
+
+#ifdef CONFIG_ARCH_OMAP15XX
+#define OMAP1510_DARAM_BASE	(OMAP1510_DSP_BASE + 0x0)
+#define OMAP1510_DARAM_SIZE	0x10000
+#define OMAP1510_SARAM_BASE	(OMAP1510_DSP_BASE + 0x10000)
+#define OMAP1510_SARAM_SIZE	0x18000
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+#define OMAP16XX_DARAM_BASE	(OMAP16XX_DSP_BASE + 0x0)
+#define OMAP16XX_DARAM_SIZE	0x10000
+#define OMAP16XX_SARAM_BASE	(OMAP16XX_DSP_BASE + 0x10000)
+#define OMAP16XX_SARAM_SIZE	0x18000
+#endif
+
+/*
+ * Reset Control
+ */
+#define ARM_RSTCT1_SW_RST		0x0008
+#define ARM_RSTCT1_DSP_RST		0x0004
+#define ARM_RSTCT1_DSP_EN		0x0002
+#define ARM_RSTCT1_ARM_RST		0x0001
+
+/*
+ * MPUI
+ */
+#define MPUI_CTRL_WORDSWAP_MASK		0x00600000
+#define MPUI_CTRL_WORDSWAP_ALL		0x00000000
+#define MPUI_CTRL_WORDSWAP_NONAPI	0x00200000
+#define MPUI_CTRL_WORDSWAP_API		0x00400000
+#define MPUI_CTRL_WORDSWAP_NONE		0x00600000
+#define MPUI_CTRL_AP_MASK		0x001c0000
+#define MPUI_CTRL_AP_MDH		0x00000000
+#define MPUI_CTRL_AP_MHD		0x00040000
+#define MPUI_CTRL_AP_DMH		0x00080000
+#define MPUI_CTRL_AP_HMD		0x000c0000
+#define MPUI_CTRL_AP_DHM		0x00100000
+#define MPUI_CTRL_AP_HDM		0x00140000
+#define MPUI_CTRL_BYTESWAP_MASK		0x00030000
+#define MPUI_CTRL_BYTESWAP_NONE		0x00000000
+#define MPUI_CTRL_BYTESWAP_NONAPI	0x00010000
+#define MPUI_CTRL_BYTESWAP_ALL		0x00020000
+#define MPUI_CTRL_BYTESWAP_API		0x00030000
+#define MPUI_CTRL_TIMEOUT_MASK		0x0000ff00
+#define MPUI_CTRL_APIF_HNSTB_DIV_MASK	0x000000f0
+#define MPUI_CTRL_S_NABORT_GL		0x00000008
+#define MPUI_CTRL_S_NABORT_32BIT	0x00000004
+#define MPUI_CTRL_EN_TIMEOUT		0x00000002
+#define MPUI_CTRL_HF_MCUCLK		0x00000001
+#define DSP_BOOT_CONFIG_DIRECT		0x00000000
+#define DSP_BOOT_CONFIG_PSD_DIRECT	0x00000001
+#define DSP_BOOT_CONFIG_IDLE		0x00000002
+#define DSP_BOOT_CONFIG_DL16		0x00000003
+#define DSP_BOOT_CONFIG_DL32		0x00000004
+#define DSP_BOOT_CONFIG_MPUI		0x00000005
+#define DSP_BOOT_CONFIG_INTERNAL	0x00000006
+
+/*
+ * DSP boot mode
+ *   direct:        0xffff00
+ *   pseudo direct: 0x080000
+ *   MPUI:          branch 0x010000
+ *   internel:      branch 0x024000
+ */
+#define DSP_BOOT_ADR_DIRECT		0xffff00
+#define DSP_BOOT_ADR_PSD_DIRECT		0x080000
+#define DSP_BOOT_ADR_MPUI		0x010000
+#define DSP_BOOT_ADR_INTERNAL		0x024000
+
+/*
+ * TC
+ */
+#define TC_ENDIANISM_SWAP		0x00000002
+#define TC_ENDIANISM_SWAP_WORD		0x00000002
+#define TC_ENDIANISM_SWAP_BYTE		0x00000000
+#define TC_ENDIANISM_EN			0x00000001
+
+/*
+ * DSP MMU
+ */
+#define DSP_MMU_BASE			(0xfefed200)
+#define DSP_MMU_PREFETCH		(DSP_MMU_BASE + 0x00)
+#define DSP_MMU_WALKING_ST		(DSP_MMU_BASE + 0x04)
+#define DSP_MMU_CNTL			(DSP_MMU_BASE + 0x08)
+#define DSP_MMU_FAULT_AD_H		(DSP_MMU_BASE + 0x0c)
+#define DSP_MMU_FAULT_AD_L		(DSP_MMU_BASE + 0x10)
+#define DSP_MMU_FAULT_ST		(DSP_MMU_BASE + 0x14)
+#define DSP_MMU_IT_ACK			(DSP_MMU_BASE + 0x18)
+#define DSP_MMU_TTB_H			(DSP_MMU_BASE + 0x1c)
+#define DSP_MMU_TTB_L			(DSP_MMU_BASE + 0x20)
+#define DSP_MMU_LOCK			(DSP_MMU_BASE + 0x24)
+#define DSP_MMU_LD_TLB			(DSP_MMU_BASE + 0x28)
+#define DSP_MMU_CAM_H			(DSP_MMU_BASE + 0x2c)
+#define DSP_MMU_CAM_L			(DSP_MMU_BASE + 0x30)
+#define DSP_MMU_RAM_H			(DSP_MMU_BASE + 0x34)
+#define DSP_MMU_RAM_L			(DSP_MMU_BASE + 0x38)
+#define DSP_MMU_GFLUSH			(DSP_MMU_BASE + 0x3c)
+#define DSP_MMU_FLUSH_ENTRY		(DSP_MMU_BASE + 0x40)
+#define DSP_MMU_READ_CAM_H		(DSP_MMU_BASE + 0x44)
+#define DSP_MMU_READ_CAM_L		(DSP_MMU_BASE + 0x48)
+#define DSP_MMU_READ_RAM_H		(DSP_MMU_BASE + 0x4c)
+#define DSP_MMU_READ_RAM_L		(DSP_MMU_BASE + 0x50)
+
+#define DSP_MMU_CNTL_BURST_16MNGT_EN	0x0020
+#define DSP_MMU_CNTL_WTL_EN		0x0004
+#define DSP_MMU_CNTL_MMU_EN		0x0002
+#define DSP_MMU_CNTL_RESET_SW		0x0001
+
+#define DSP_MMU_FAULT_AD_H_DP		0x0100
+#define DSP_MMU_FAULT_AD_H_ADR_MASK	0x00ff
+
+#define DSP_MMU_FAULT_ST_PREF		0x0008
+#define DSP_MMU_FAULT_ST_PERM		0x0004
+#define DSP_MMU_FAULT_ST_TLB_MISS	0x0002
+#define DSP_MMU_FAULT_ST_TRANS		0x0001
+
+#define DSP_MMU_IT_ACK_IT_ACK		0x0001
+
+#define DSP_MMU_LOCK_BASE_MASK		0xfc00
+#define DSP_MMU_LOCK_BASE_SHIFT		10
+#define DSP_MMU_LOCK_VICTIM_MASK	0x03f0
+#define DSP_MMU_LOCK_VICTIM_SHIFT	4
+
+#define DSP_MMU_CAM_H_VA_TAG_H_MASK		0x0003
+
+#define DSP_MMU_CAM_L_VA_TAG_L1_MASK		0xc000
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_1MB	0x0000
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_64KB	0x3c00
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_4KB	0x3fc0
+#define DSP_MMU_CAM_L_VA_TAG_L2_MASK_1KB	0x3ff0
+#define DSP_MMU_CAM_L_P				0x0008
+#define DSP_MMU_CAM_L_V				0x0004
+#define DSP_MMU_CAM_L_PAGESIZE_MASK		0x0003
+#define DSP_MMU_CAM_L_PAGESIZE_1MB		0x0000
+#define DSP_MMU_CAM_L_PAGESIZE_64KB		0x0001
+#define DSP_MMU_CAM_L_PAGESIZE_4KB		0x0002
+#define DSP_MMU_CAM_L_PAGESIZE_1KB		0x0003
+
+#define DSP_MMU_RAM_L_RAM_LSB_MASK	0xfc00
+#define DSP_MMU_RAM_L_AP_MASK		0x0300
+#define DSP_MMU_RAM_L_AP_NA		0x0000
+#define DSP_MMU_RAM_L_AP_RO		0x0200
+#define DSP_MMU_RAM_L_AP_FA		0x0300
+
+#define DSP_MMU_GFLUSH_GFLUSH		0x0001
+
+#define DSP_MMU_FLUSH_ENTRY_FLUSH_ENTRY	0x0001
+
+#define DSP_MMU_LD_TLB_RD		0x0002
+#define DSP_MMU_LD_TLB_LD		0x0001
+
+/*
+ * DSP ICR
+ */
+#define DSPREG_ICR_RESERVED_BITS	0xffc0
+#define DSPREG_ICR_EMIF			0x0020
+#define DSPREG_ICR_DPLL			0x0010
+#define DSPREG_ICR_PER			0x0008
+#define DSPREG_ICR_CACHE		0x0004
+#define DSPREG_ICR_DMA			0x0002
+#define DSPREG_ICR_CPU			0x0001
+
+#endif /* __OMAP_DSP_OMAP1_DSP_H */
diff --git a/arch/arm/plat-omap/dsp/omap2_dsp.h b/arch/arm/plat-omap/dsp/omap2_dsp.h
new file mode 100644
index 0000000000000000000000000000000000000000..28a98ad55005e5e116a48af62d04213806225af0
--- /dev/null
+++ b/arch/arm/plat-omap/dsp/omap2_dsp.h
@@ -0,0 +1,158 @@
+/*
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
+ *
+ * Copyright (C) 2006 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; 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 __OMAP_DSP_OMAP2_DSP_H
+#define __OMAP_DSP_OMAP2_DSP_H
+
+#ifdef CONFIG_ARCH_OMAP24XX
+#define OMAP24XX_DARAM_BASE	(DSP_MEM_24XX_VIRT + 0x0)
+#define OMAP24XX_DARAM_SIZE	0x10000
+#define OMAP24XX_SARAM_BASE	(DSP_MEM_24XX_VIRT + 0x10000)
+#define OMAP24XX_SARAM_SIZE	0x18000
+#endif
+
+#include <asm/arch/hardware.h>
+#include "../../mach-omap2/prcm-regs.h"
+
+/*
+ * DSP IPI registers: mapped to 0xe1000000 -- use readX(), writeX()
+ */
+#define DSP_IPI_BASE			DSP_IPI_24XX_VIRT
+#define DSP_IPI_REVISION		(DSP_IPI_BASE + 0x00)
+#define DSP_IPI_SYSCONFIG		(DSP_IPI_BASE + 0x10)
+#define DSP_IPI_INDEX			(DSP_IPI_BASE + 0x40)
+#define DSP_IPI_ENTRY			(DSP_IPI_BASE + 0x44)
+#define DSP_IPI_ENABLE			(DSP_IPI_BASE + 0x48)
+#define DSP_IPI_IOMAP			(DSP_IPI_BASE + 0x4c)
+#define DSP_IPI_DSPBOOTCONFIG		(DSP_IPI_BASE + 0x50)
+
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_MASK	0x00000003
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_8	0x00000000
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_16	0x00000001
+#define DSP_IPI_ENTRY_ELMSIZEVALUE_32	0x00000002
+
+#define DSP_BOOT_CONFIG_DIRECT		0x00000000
+#define DSP_BOOT_CONFIG_PSD_DIRECT	0x00000001
+#define DSP_BOOT_CONFIG_IDLE		0x00000002
+#define DSP_BOOT_CONFIG_DL16		0x00000003
+#define DSP_BOOT_CONFIG_DL32		0x00000004
+#define DSP_BOOT_CONFIG_API		0x00000005
+#define DSP_BOOT_CONFIG_INTERNAL	0x00000006
+
+/*
+ * DSP boot mode
+ *   direct:        0xffff00
+ *   pseudo direct: 0x080000
+ *   API:           branch 0x010000
+ *   internel:      branch 0x024000
+ */
+#define DSP_BOOT_ADR_DIRECT		0xffff00
+#define DSP_BOOT_ADR_PSD_DIRECT		0x080000
+#define DSP_BOOT_ADR_API		0x010000
+#define DSP_BOOT_ADR_INTERNAL		0x024000
+
+/*
+ * DSP MMU: mapped to 0xe2000000 -- use readX(), writeX()
+ */
+#define DSP_MMU_BASE			DSP_MMU_24XX_VIRT
+#define DSP_MMU_REVISION		(DSP_MMU_BASE + 0x00)
+#define DSP_MMU_SYSCONFIG		(DSP_MMU_BASE + 0x10)
+#define DSP_MMU_SYSSTATUS		(DSP_MMU_BASE + 0x14)
+#define DSP_MMU_IRQSTATUS		(DSP_MMU_BASE + 0x18)
+#define DSP_MMU_IRQENABLE		(DSP_MMU_BASE + 0x1c)
+#define DSP_MMU_WALKING_ST		(DSP_MMU_BASE + 0x40)
+#define DSP_MMU_CNTL			(DSP_MMU_BASE + 0x44)
+#define DSP_MMU_FAULT_AD		(DSP_MMU_BASE + 0x48)
+#define DSP_MMU_TTB			(DSP_MMU_BASE + 0x4c)
+#define DSP_MMU_LOCK			(DSP_MMU_BASE + 0x50)
+#define DSP_MMU_LD_TLB			(DSP_MMU_BASE + 0x54)
+#define DSP_MMU_CAM			(DSP_MMU_BASE + 0x58)
+#define DSP_MMU_RAM			(DSP_MMU_BASE + 0x5c)
+#define DSP_MMU_GFLUSH			(DSP_MMU_BASE + 0x60)
+#define DSP_MMU_FLUSH_ENTRY		(DSP_MMU_BASE + 0x64)
+#define DSP_MMU_READ_CAM		(DSP_MMU_BASE + 0x68)
+#define DSP_MMU_READ_RAM		(DSP_MMU_BASE + 0x6c)
+#define DSP_MMU_EMU_FAULT_AD		(DSP_MMU_BASE + 0x70)
+
+#define DSP_MMU_SYSCONFIG_CLOCKACTIVITY_MASK	0x00000300
+#define DSP_MMU_SYSCONFIG_IDLEMODE_MASK		0x00000018
+#define DSP_MMU_SYSCONFIG_SOFTRESET		0x00000002
+#define DSP_MMU_SYSCONFIG_AUTOIDLE		0x00000001
+
+#define DSP_MMU_IRQ_MULTIHITFAULT	0x00000010
+#define DSP_MMU_IRQ_TABLEWALKFAULT	0x00000008
+#define DSP_MMU_IRQ_EMUMISS		0x00000004
+#define DSP_MMU_IRQ_TRANSLATIONFAULT	0x00000002
+#define DSP_MMU_IRQ_TLBMISS		0x00000001
+
+#define DSP_MMU_CNTL_EMUTLBUPDATE	0x00000008
+#define DSP_MMU_CNTL_TWLENABLE		0x00000004
+#define DSP_MMU_CNTL_MMUENABLE		0x00000002
+
+#define DSP_MMU_LOCK_BASE_MASK		0x00007c00
+#define DSP_MMU_LOCK_BASE_SHIFT		10
+#define DSP_MMU_LOCK_VICTIM_MASK	0x000001f0
+#define DSP_MMU_LOCK_VICTIM_SHIFT	4
+
+#define DSP_MMU_CAM_VATAG_MASK		0xfffff000
+#define DSP_MMU_CAM_P			0x00000008
+#define DSP_MMU_CAM_V			0x00000004
+#define DSP_MMU_CAM_PAGESIZE_MASK	0x00000003
+#define DSP_MMU_CAM_PAGESIZE_1MB	0x00000000
+#define DSP_MMU_CAM_PAGESIZE_64KB	0x00000001
+#define DSP_MMU_CAM_PAGESIZE_4KB	0x00000002
+#define DSP_MMU_CAM_PAGESIZE_16MB	0x00000003
+
+#define DSP_MMU_RAM_PADDR_MASK		0xfffff000
+#define DSP_MMU_RAM_ENDIANNESS		0x00000200
+#define DSP_MMU_RAM_ENDIANNESS_BIG	0x00000200
+#define DSP_MMU_RAM_ENDIANNESS_LITTLE	0x00000000
+#define DSP_MMU_RAM_ELEMENTSIZE_MASK	0x00000180
+#define DSP_MMU_RAM_ELEMENTSIZE_8	0x00000000
+#define DSP_MMU_RAM_ELEMENTSIZE_16	0x00000080
+#define DSP_MMU_RAM_ELEMENTSIZE_32	0x00000100
+#define DSP_MMU_RAM_ELEMENTSIZE_NONE	0x00000180
+#define DSP_MMU_RAM_MIXED		0x00000040
+
+#define DSP_MMU_GFLUSH_GFLUSH		0x00000001
+
+#define DSP_MMU_FLUSH_ENTRY_FLUSH_ENTRY	0x00000001
+
+#define DSP_MMU_LD_TLB_LD		0x00000001
+
+/*
+ * DSP ICR
+ */
+#define DSPREG_ICR_RESERVED_BITS	0xfc00
+#define DSPREG_ICR_HWA			0x0200
+#define DSPREG_ICR_IPORT		0x0100
+#define DSPREG_ICR_MPORT		0x0080
+#define DSPREG_ICR_XPORT		0x0040
+#define DSPREG_ICR_DPORT		0x0020
+#define DSPREG_ICR_DPLL			0x0010
+#define DSPREG_ICR_PER			0x0008
+#define DSPREG_ICR_CACHE		0x0004
+#define DSPREG_ICR_DMA			0x0002
+#define DSPREG_ICR_CPU			0x0001
+
+#endif /* __OMAP_DSP_OMAP2_DSP_H */
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index f7b9ccdaacbcff0c0a446488f1436fa10ff236c3..4221b464ca17976a2d9ac7346f754fd127a45973 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -197,6 +197,7 @@ static int omap_mcbsp_check(unsigned int id)
 static void omap_mcbsp_dsp_request(void)
 {
 	if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+		omap_dsp_request_mem();
 		clk_enable(mcbsp_dsp_ck);
 		clk_enable(mcbsp_api_ck);
 
@@ -215,6 +216,7 @@ static void omap_mcbsp_dsp_request(void)
 static void omap_mcbsp_dsp_free(void)
 {
 	if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+		omap_dsp_release_mem();
 		clk_disable(mcbsp_dspxor_ck);
 		clk_disable(mcbsp_dsp_ck);
 		clk_disable(mcbsp_api_ck);