]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/plat-omap/dsp/dsp_core.c
ARM: OMAP: mailbox restructure
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / dsp_core.c
index 65ce66422189e3014496f99bc71fba8ef6408e9e..f0b303f9c660e6497653693bd601de0e6a5fc42c 100644 (file)
 /*
- * linux/arch/arm/mach-omap/dsp/dsp_core.c
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
  *
- * OMAP DSP driver
+ * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
  *
- * Copyright (C) 2002-2005 Nokia Corporation
+ * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
  *
- * Written by 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 free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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.
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
  *
- * 2005/06/07:  DSP Gateway version 3.3
  */
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/platform_device.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
 #include <linux/mutex.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/signal.h>
+#include <linux/err.h>
+#include <linux/clk.h>
 #include <asm/delay.h>
-#include <asm/irq.h>
+#include <asm/arch/mailbox.h>
 #include <asm/arch/dsp_common.h>
-#include <asm/arch/dsp.h>
-#include "hardware_dsp.h"
+#include "dsp_mbcmd.h"
 #include "dsp.h"
 #include "ipbuf.h"
-
+#include "dsp_common.h"
 
 MODULE_AUTHOR("Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>");
 MODULE_DESCRIPTION("OMAP DSP driver module");
 MODULE_LICENSE("GPL");
 
-enum mbseq_check_level {
-       MBSEQ_CHECK_NONE,       /* no check */
-       MBSEQ_CHECK_VERBOSE,    /* discard the illegal command and
-                                  error report */
-       MBSEQ_CHECK_SILENT,     /* discard the illegal command */
-};
-
-static enum mbseq_check_level mbseq_check_level = MBSEQ_CHECK_VERBOSE;
-
-static int mbx1_valid;
+struct omap_mbox *mbox_dsp;
 static struct sync_seq *mbseq;
-static unsigned short mbseq_expect_tmp;
-static unsigned short *mbseq_expect = &mbseq_expect_tmp;
+static u16 mbseq_expect_tmp;
+static u16 *mbseq_expect = &mbseq_expect_tmp;
 
 /*
  * mailbox commands
  */
-extern void mbx1_wdsnd(struct mbcmd *mb);
-extern void mbx1_wdreq(struct mbcmd *mb);
-extern void mbx1_bksnd(struct mbcmd *mb);
-extern void mbx1_bkreq(struct mbcmd *mb);
-extern void mbx1_bkyld(struct mbcmd *mb);
-extern void mbx1_bksndp(struct mbcmd *mb);
-extern void mbx1_bkreqp(struct mbcmd *mb);
-extern void mbx1_tctl(struct mbcmd *mb);
-extern void mbx1_poll(struct mbcmd *mb);
+extern void mbox_wdsnd(struct mbcmd *mb);
+extern void mbox_wdreq(struct mbcmd *mb);
+extern void mbox_bksnd(struct mbcmd *mb);
+extern void mbox_bkreq(struct mbcmd *mb);
+extern void mbox_bkyld(struct mbcmd *mb);
+extern void mbox_bksndp(struct mbcmd *mb);
+extern void mbox_bkreqp(struct mbcmd *mb);
+extern void mbox_tctl(struct mbcmd *mb);
+extern void mbox_poll(struct mbcmd *mb);
 #ifdef OLD_BINARY_SUPPORT
 /* v3.3 obsolete */
-extern void mbx1_wdt(struct mbcmd *mb);
+extern void mbox_wdt(struct mbcmd *mb);
 #endif
-extern void mbx1_suspend(struct mbcmd *mb);
-static void mbx1_kfunc(struct mbcmd *mb);
-extern void mbx1_tcfg(struct mbcmd *mb);
-extern void mbx1_tadd(struct mbcmd *mb);
-extern void mbx1_tdel(struct mbcmd *mb);
-extern void mbx1_dspcfg(struct mbcmd *mb);
-extern void mbx1_regrw(struct mbcmd *mb);
-extern void mbx1_getvar(struct mbcmd *mb);
-extern void mbx1_err(struct mbcmd *mb);
-extern void mbx1_dbg(struct mbcmd *mb);
+extern void mbox_suspend(struct mbcmd *mb);
+static void mbox_kfunc(struct mbcmd *mb);
+extern void mbox_tcfg(struct mbcmd *mb);
+extern void mbox_tadd(struct mbcmd *mb);
+extern void mbox_tdel(struct mbcmd *mb);
+extern void mbox_dspcfg(struct mbcmd *mb);
+extern void mbox_regrw(struct mbcmd *mb);
+extern void mbox_getvar(struct mbcmd *mb);
+extern void mbox_err(struct mbcmd *mb);
+extern void mbox_dbg(struct mbcmd *mb);
 
 static const struct cmdinfo
-       cif_null     = { "Unknown",  CMD_L_TYPE_NULL,   NULL         },
-       cif_wdsnd    = { "WDSND",    CMD_L_TYPE_TID,    mbx1_wdsnd   },
-       cif_wdreq    = { "WDREQ",    CMD_L_TYPE_TID,    mbx1_wdreq   },
-       cif_bksnd    = { "BKSND",    CMD_L_TYPE_TID,    mbx1_bksnd   },
-       cif_bkreq    = { "BKREQ",    CMD_L_TYPE_TID,    mbx1_bkreq   },
-       cif_bkyld    = { "BKYLD",    CMD_L_TYPE_NULL,   mbx1_bkyld   },
-       cif_bksndp   = { "BKSNDP",   CMD_L_TYPE_TID,    mbx1_bksndp  },
-       cif_bkreqp   = { "BKREQP",   CMD_L_TYPE_TID,    mbx1_bkreqp  },
-       cif_tctl     = { "TCTL",     CMD_L_TYPE_TID,    mbx1_tctl    },
-       cif_poll     = { "POLL",     CMD_L_TYPE_NULL,   mbx1_poll    },
+       cif_wdsnd    = { "WDSND",    CMD_L_TYPE_TID,    mbox_wdsnd   },
+       cif_wdreq    = { "WDREQ",    CMD_L_TYPE_TID,    mbox_wdreq   },
+       cif_bksnd    = { "BKSND",    CMD_L_TYPE_TID,    mbox_bksnd   },
+       cif_bkreq    = { "BKREQ",    CMD_L_TYPE_TID,    mbox_bkreq   },
+       cif_bkyld    = { "BKYLD",    CMD_L_TYPE_NULL,   mbox_bkyld   },
+       cif_bksndp   = { "BKSNDP",   CMD_L_TYPE_TID,    mbox_bksndp  },
+       cif_bkreqp   = { "BKREQP",   CMD_L_TYPE_TID,    mbox_bkreqp  },
+       cif_tctl     = { "TCTL",     CMD_L_TYPE_TID,    mbox_tctl    },
+       cif_poll     = { "POLL",     CMD_L_TYPE_NULL,   mbox_poll    },
 #ifdef OLD_BINARY_SUPPORT
        /* v3.3 obsolete */
-       cif_wdt      = { "WDT",      CMD_L_TYPE_NULL,   mbx1_wdt     },
+       cif_wdt      = { "WDT",      CMD_L_TYPE_NULL,   mbox_wdt     },
 #endif
-       cif_runlevel = { "RUNLEVEL", CMD_L_TYPE_SUBCMD, NULL         },
-       cif_pm       = { "PM",       CMD_L_TYPE_SUBCMD, NULL         },
-       cif_suspend  = { "SUSPEND",  CMD_L_TYPE_NULL,   mbx1_suspend },
-       cif_kfunc    = { "KFUNC",    CMD_L_TYPE_SUBCMD, mbx1_kfunc   },
-       cif_tcfg     = { "TCFG",     CMD_L_TYPE_TID,    mbx1_tcfg    },
-       cif_tadd     = { "TADD",     CMD_L_TYPE_TID,    mbx1_tadd    },
-       cif_tdel     = { "TDEL",     CMD_L_TYPE_TID,    mbx1_tdel    },
-       cif_tstop    = { "TSTOP",    CMD_L_TYPE_TID,    NULL         },
-       cif_dspcfg   = { "DSPCFG",   CMD_L_TYPE_SUBCMD, mbx1_dspcfg  },
-       cif_regrw    = { "REGRW",    CMD_L_TYPE_SUBCMD, mbx1_regrw   },
-       cif_getvar   = { "GETVAR",   CMD_L_TYPE_SUBCMD, mbx1_getvar  },
-       cif_setvar   = { "SETVAR",   CMD_L_TYPE_SUBCMD, NULL         },
-       cif_err      = { "ERR",      CMD_L_TYPE_SUBCMD, mbx1_err     },
-       cif_dbg      = { "DBG",      CMD_L_TYPE_NULL,   mbx1_dbg     };
-
-const struct cmdinfo *cmdinfo[128] = {
-/*00*/ &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-/*10*/ &cif_wdsnd, &cif_wdreq, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-/*20*/ &cif_bksnd, &cif_bkreq, &cif_null, &cif_bkyld,
-       &cif_bksndp, &cif_bkreqp, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-/*30*/ &cif_tctl, &cif_null, &cif_poll, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-/*40*/ &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
+       cif_runlevel = { "RUNLEVEL", CMD_L_TYPE_SUBCMD, NULL        },
+       cif_pm       = { "PM",       CMD_L_TYPE_SUBCMD, NULL        },
+       cif_suspend  = { "SUSPEND",  CMD_L_TYPE_NULL,   mbox_suspend },
+       cif_kfunc    = { "KFUNC",    CMD_L_TYPE_SUBCMD, mbox_kfunc   },
+       cif_tcfg     = { "TCFG",     CMD_L_TYPE_TID,    mbox_tcfg    },
+       cif_tadd     = { "TADD",     CMD_L_TYPE_TID,    mbox_tadd    },
+       cif_tdel     = { "TDEL",     CMD_L_TYPE_TID,    mbox_tdel    },
+       cif_tstop    = { "TSTOP",    CMD_L_TYPE_TID,    NULL        },
+       cif_dspcfg   = { "DSPCFG",   CMD_L_TYPE_SUBCMD, mbox_dspcfg  },
+       cif_regrw    = { "REGRW",    CMD_L_TYPE_SUBCMD, mbox_regrw   },
+       cif_getvar   = { "GETVAR",   CMD_L_TYPE_SUBCMD, mbox_getvar  },
+       cif_setvar   = { "SETVAR",   CMD_L_TYPE_SUBCMD, NULL        },
+       cif_err      = { "ERR",      CMD_L_TYPE_SUBCMD, mbox_err     },
+       cif_dbg      = { "DBG",      CMD_L_TYPE_NULL,   mbox_dbg     };
+
+#define MBOX_CMD_MAX   0x80
+const struct cmdinfo *cmdinfo[MBOX_CMD_MAX] = {
+       [MBOX_CMD_DSP_WDSND]    = &cif_wdsnd,
+       [MBOX_CMD_DSP_WDREQ]    = &cif_wdreq,
+       [MBOX_CMD_DSP_BKSND]    = &cif_bksnd,
+       [MBOX_CMD_DSP_BKREQ]    = &cif_bkreq,
+       [MBOX_CMD_DSP_BKYLD]    = &cif_bkyld,
+       [MBOX_CMD_DSP_BKSNDP]   = &cif_bksndp,
+       [MBOX_CMD_DSP_BKREQP]   = &cif_bkreqp,
+       [MBOX_CMD_DSP_TCTL]     = &cif_tctl,
+       [MBOX_CMD_DSP_POLL]     = &cif_poll,
 #ifdef OLD_BINARY_SUPPORT
-       /* v3.3 obsolete */
-/*50*/ &cif_wdt, &cif_runlevel, &cif_pm, &cif_suspend,
-#else
-/*50*/ &cif_null, &cif_runlevel, &cif_pm, &cif_suspend,
+       [MBOX_CMD_DSP_WDT]      = &cif_wdt, /* v3.3 obsolete */
 #endif
-       &cif_kfunc, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-/*60*/ &cif_tcfg, &cif_null, &cif_tadd, &cif_tdel,
-       &cif_null, &cif_tstop, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null,
-/*70*/ &cif_dspcfg, &cif_null, &cif_regrw, &cif_null,
-       &cif_getvar, &cif_setvar, &cif_null, &cif_null,
-       &cif_err, &cif_dbg, &cif_null, &cif_null,
-       &cif_null, &cif_null, &cif_null, &cif_null
+       [MBOX_CMD_DSP_RUNLEVEL] = &cif_runlevel,
+       [MBOX_CMD_DSP_PM]       = &cif_pm,
+       [MBOX_CMD_DSP_SUSPEND]  = &cif_suspend,
+       [MBOX_CMD_DSP_KFUNC]    = &cif_kfunc,
+       [MBOX_CMD_DSP_TCFG]     = &cif_tcfg,
+       [MBOX_CMD_DSP_TADD]     = &cif_tadd,
+       [MBOX_CMD_DSP_TDEL]     = &cif_tdel,
+       [MBOX_CMD_DSP_TSTOP]    = &cif_tstop,
+       [MBOX_CMD_DSP_DSPCFG]   = &cif_dspcfg,
+       [MBOX_CMD_DSP_REGRW]    = &cif_regrw,
+       [MBOX_CMD_DSP_GETVAR]   = &cif_getvar,
+       [MBOX_CMD_DSP_SETVAR]   = &cif_setvar,
+       [MBOX_CMD_DSP_ERR]      = &cif_err,
+       [MBOX_CMD_DSP_DBG]      = &cif_dbg,
 };
 
-int sync_with_dsp(unsigned short *syncwd, unsigned short tid, int try_cnt)
+int sync_with_dsp(u16 *adr, u16 val, int try_cnt)
 {
        int try;
 
-       if (*(volatile unsigned short *)syncwd == tid)
+       if (*(volatile u16 *)adr == val)
                return 0;
 
        for (try = 0; try < try_cnt; try++) {
                udelay(1);
-               if (*(volatile unsigned short *)syncwd == tid) {
+               if (*(volatile u16 *)adr == val) {
                        /* success! */
                        printk(KERN_INFO
                               "omapdsp: sync_with_dsp(): try = %d\n", try);
@@ -181,73 +152,11 @@ int sync_with_dsp(unsigned short *syncwd, unsigned short tid, int try_cnt)
        return -1;
 }
 
-static __inline__ int mbsync_irq_save(unsigned long *flags, int try_cnt)
-{
-       int cnt;
-
-       local_irq_save(*flags);
-       if (omap_readw(MAILBOX_ARM2DSP1_Flag) == 0)
-               return 0;
-       /*
-        * mailbox is busy. wait for some usecs...
-        */
-       local_irq_restore(*flags);
-       for (cnt = 0; cnt < try_cnt; cnt++) {
-               udelay(1);
-               local_irq_save(*flags);
-               if (omap_readw(MAILBOX_ARM2DSP1_Flag) == 0)     /* success! */
-                       return 0;
-               local_irq_restore(*flags);
-       }
-
-       /* fail! */
-       return -1;
-}
-
-#ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSE
-#define print_mb_busy_abort(mb) \
-       printk(KERN_DEBUG \
-              "mbx: mailbox is busy. %s is aborting.\n", cmd_name(*mb))
-#define print_mb_mmu_abort(mb) \
-       printk(KERN_DEBUG \
-              "mbx: mmu interrupt is set. %s is aborting.\n", cmd_name(*mb))
-#else /* CONFIG_OMAP_DSP_MBCMD_VERBOSE */
-#define print_mb_busy_abort(mb)        do {} while(0)
-#define print_mb_mmu_abort(mb) do {} while(0)
-#endif /* !CONFIG_OMAP_DSP_MBCMD_VERBOSE */
-
-int __mbcmd_send(struct mbcmd *mb)
-{
-       struct mbcmd_hw *mb_hw = (struct mbcmd_hw *)mb;
-       unsigned long flags;
-
-       /*
-        * DSP mailbox interrupt latency must be less than 1ms.
-        */
-       if (mbsync_irq_save(&flags, 1000) < 0) {
-               print_mb_busy_abort(mb);
-               return -1;
-       }
-
-       if (mbseq) {
-               mb->seq = mbseq->ad_arm;
-               mbseq->ad_arm++;
-       } else
-               mb->seq = 0;
-       mblog_add(mb, DIR_A2D);
-       mblog_printcmd(mb, DIR_A2D);
-
-       omap_writew(mb_hw->data, MAILBOX_ARM2DSP1);
-       omap_writew(mb_hw->cmd, MAILBOX_ARM2DSP1b);
-
-       local_irq_restore(flags);
-       return 0;
-}
-
 /*
- * __dsp_mbcmd_send(): mailbox dispatcher
+ * __dsp_mbcmd_send_exarg(): mailbox dispatcher
  */
-int __dsp_mbcmd_send(struct mbcmd *mb, struct mb_exarg *arg, int recovery_flag)
+int __dsp_mbcmd_send_exarg(struct mbcmd *mb, struct mb_exarg *arg,
+                          int recovery_flag)
 {
        static DEFINE_MUTEX(mbsend_lock);
        int ret = 0;
@@ -256,8 +165,10 @@ int __dsp_mbcmd_send(struct mbcmd *mb, struct mb_exarg *arg, int recovery_flag)
         * while MMU fault is set,
         * only recovery command can be executed
         */
-       if (dsp_err_mmu_isset() && !recovery_flag) {
-               print_mb_mmu_abort(mb);
+       if (dsp_err_isset(ERRCODE_MMU) && !recovery_flag) {
+               printk(KERN_ERR
+                      "mbox: mmu interrupt is set. %s is aborting.\n",
+                      cmd_name(*mb));
                return -1;
        }
 
@@ -276,7 +187,7 @@ int __dsp_mbcmd_send(struct mbcmd *mb, struct mb_exarg *arg, int recovery_flag)
                 * Therefore, we can call this function here safely.
                 */
                dsp_mem_enable(ipbuf_sys_ad);
-               if (sync_with_dsp(&ipbuf_sys_ad->s, OMAP_DSP_TID_FREE, 10) < 0) {
+               if (sync_with_dsp(&ipbuf_sys_ad->s, TID_FREE, 10) < 0) {
                        printk(KERN_ERR "omapdsp: ipbuf_sys_ad is busy.\n");
                        dsp_mem_disable(ipbuf_sys_ad);
                        ret = -EBUSY;
@@ -289,15 +200,20 @@ int __dsp_mbcmd_send(struct mbcmd *mb, struct mb_exarg *arg, int recovery_flag)
                dsp_mem_disable(ipbuf_sys_ad);
        }
 
-       ret = __mbcmd_send(mb);
+       if (mbseq)
+               mbseq->ad_arm++;
+
+       mblog_add(mb, DIR_A2D);
+
+       ret = omap_mbox_msg_send(mbox_dsp, *(mbox_msg_t *)mb);
 
 out:
        mutex_unlock(&mbsend_lock);
        return ret;
 }
 
-int __dsp_mbcmd_send_and_wait(struct mbcmd *mb, struct mb_exarg *arg,
-                             wait_queue_head_t *q)
+int dsp_mbcmd_send_and_wait_exarg(struct mbcmd *mb, struct mb_exarg *arg,
+                                 wait_queue_head_t *q)
 {
        long current_state;
        DECLARE_WAITQUEUE(wait, current);
@@ -317,35 +233,46 @@ int __dsp_mbcmd_send_and_wait(struct mbcmd *mb, struct mb_exarg *arg,
        return 0;
 }
 
-int __dsp_mbsend(unsigned char cmdh, unsigned char cmdl, unsigned short data,
-                int recovery_flag)
+/*
+ * mbcmd receiver
+ */
+static void mbcmd_receiver(mbox_msg_t msg)
 {
-       struct mbcmd mb;
+       struct mbcmd *mb = (struct mbcmd *)&msg;
+
+       if (cmdinfo[mb->cmd_h] == NULL) {
+               printk(KERN_ERR
+                      "invalid message (%08x) for mbcmd_receiver().\n", msg);
+               return;
+       }
+
+       (*mbseq_expect)++;
 
-       mbcmd_set(mb, cmdh, cmdl, data);
-       return __dsp_mbcmd_send(&mb, NULL, recovery_flag);
+       mblog_add(mb, DIR_D2A);
+
+       /* call handler for the command */
+       if (cmdinfo[mb->cmd_h]->handler)
+               cmdinfo[mb->cmd_h]->handler(mb);
+       else
+               printk(KERN_ERR "mbox: %s is not allowed from DSP.\n",
+                      cmd_name(*mb));
 }
 
 static int mbsync_hold_mem_active;
 
-void dsp_mb_start(void)
+void dsp_mbox_start(void)
 {
-       mbx1_valid = 1; /* start interpreting */
+       omap_mbox_init_seq(mbox_dsp);
        mbseq_expect_tmp = 0;
 }
 
-void dsp_mb_stop(void)
+void dsp_mbox_stop(void)
 {
-       mbx1_valid = 0; /* stop interpreting */
-       if (mbsync_hold_mem_active) {
-               dsp_mem_disable((void *)daram_base);
-               mbsync_hold_mem_active = 0;
-       }
        mbseq = NULL;
        mbseq_expect = &mbseq_expect_tmp;
 }
 
-int dsp_mb_config(void *p)
+int dsp_mbox_config(void *p)
 {
        unsigned long flags;
 
@@ -373,106 +300,62 @@ int dsp_mb_config(void *p)
        return 0;
 }
 
-/*
- * mbq: mailbox queue
- */
-#define MBQ_DEPTH      16
-struct mbq {
-       struct mbcmd mb[MBQ_DEPTH];
-       int rp, wp, full;
-} mbq = {
-       .rp = 0,
-       .wp = 0,
-};
-
-#define mbq_inc(p)     do { if (++(p) == MBQ_DEPTH) (p) = 0; } while(0)
-
-/*
- * workqueue for mbx1
- */
-static void do_mbx1(void)
+static int __init dsp_mbox_init(void)
 {
-       int empty = 0;
-
-       disable_irq(INT_D2A_MB1);
-       if ((mbq.rp == mbq.wp) && !mbq.full)
-               empty = 1;
-       enable_irq(INT_D2A_MB1);
+       mbox_dsp->mbox = omap_mbox_get("dsp");
+       if (IS_ERR(mbox_dsp)) {
+               printk(KERN_ERR "failed to get mailbox handler for DSP.\n");
+               return -ENODEV;
+       }
 
-       while (!empty) {
-               struct mbcmd *mb;
+       mbox_dsp->mbox->msg_receive_cb = mbcmd_receiver;
 
-               mb = &mbq.mb[mbq.rp];
+       return 0;
+}
 
-               mblog_add(mb, DIR_D2A);
-               mblog_printcmd(mb, DIR_D2A);
+static void dsp_mbox_exit(void)
+{
+       mbox_dsp->mbox->msg_receive_cb = NULL;
 
-               /*
-                * call handler for each command
-                */
-               if (cmdinfo[mb->cmd_h]->handler)
-                       cmdinfo[mb->cmd_h]->handler(mb);
-               else if (cmdinfo[mb->cmd_h] != &cif_null)
-                       printk(KERN_ERR "mbx: %s is not allowed from DSP.\n",
-                              cmd_name(*mb));
-               else
-                       printk(KERN_ERR
-                              "mbx: Unrecognized command: "
-                              "cmd=0x%04x, data=0x%04x\n",
-                              ((struct mbcmd_hw *)mb)->cmd & 0x7fff, mb->data);
-
-               disable_irq(INT_D2A_MB1);
-               mbq_inc(mbq.rp);
-               if (mbq.rp == mbq.wp)
-                       empty = 1;
-               /* if mbq has been full, now we have a room. */
-               if (mbq.full) {
-                       mbq.full = 0;
-                       enable_irq(INT_D2A_MB1);
-               }
-               enable_irq(INT_D2A_MB1);
+       if (mbsync_hold_mem_active) {
+               dsp_mem_disable((void *)daram_base);
+               mbsync_hold_mem_active = 0;
        }
 }
 
-static DECLARE_WORK(mbx1_work, (void (*)(void *))do_mbx1, NULL);
-
 /*
  * kernel function dispatcher
  */
-extern void mbx1_fbctl_upd(void);
-extern void mbx1_fbctl_disable(void);
+extern void mbox_fbctl_upd(void);
+extern void mbox_fbctl_disable(struct mbcmd *mb);
 
-static void mbx1_kfunc_fbctl(unsigned short data)
+static void mbox_kfunc_fbctl(struct mbcmd *mb)
 {
-       switch (data) {
-       case OMAP_DSP_MBCMD_FBCTL_UPD:
-               mbx1_fbctl_upd();
+       switch (mb->data) {
+       case FBCTL_UPD:
+               mbox_fbctl_upd();
                break;
-       case OMAP_DSP_MBCMD_FBCTL_DISABLE:
-               mbx1_fbctl_disable();
+       case FBCTL_DISABLE:
+               mbox_fbctl_disable(mb);
                break;
        default:
                printk(KERN_ERR
-                      "mailbox: Unknown FBCTL from DSP: 0x%04x\n", data);
+                      "mbox: Unknown FBCTL from DSP: 0x%04x\n", mb->data);
        }
 }
 
-static void mbx1_kfunc_audio_pwr(unsigned short data)
+static void mbox_kfunc_audio_pwr(unsigned short data)
 {
-       struct mbcmd mb;
-
        switch (data) {
-       case OMAP_DSP_MBCMD_AUDIO_PWR_UP:
+       case AUDIO_PWR_UP:
                omap_dsp_audio_pwr_up_request(0);
                /* send back ack */
-               mbcmd_set(mb, MBCMD(KFUNC), OMAP_DSP_MBCMD_KFUNC_AUDIO_PWR,
-                         OMAP_DSP_MBCMD_AUDIO_PWR_UP);
-               dsp_mbcmd_send(&mb);
+               mbcompose_send(KFUNC, KFUNC_AUDIO_PWR, AUDIO_PWR_UP);
                break;
-       case OMAP_DSP_MBCMD_AUDIO_PWR_DOWN1:
+       case AUDIO_PWR_DOWN1:
                omap_dsp_audio_pwr_down_request(1);
                break;
-       case OMAP_DSP_MBCMD_AUDIO_PWR_DOWN2:
+       case AUDIO_PWR_DOWN2:
                omap_dsp_audio_pwr_down_request(2);
                break;
        default:
@@ -481,118 +364,21 @@ static void mbx1_kfunc_audio_pwr(unsigned short data)
        }
 }
 
-static void mbx1_kfunc(struct mbcmd *mb)
+static void mbox_kfunc(struct mbcmd *mb)
 {
        switch (mb->cmd_l) {
-       case OMAP_DSP_MBCMD_KFUNC_FBCTL:
-               mbx1_kfunc_fbctl(mb->data);
+       case KFUNC_FBCTL:
+               mbox_kfunc_fbctl(mb);
                break;
-       case OMAP_DSP_MBCMD_KFUNC_AUDIO_PWR:
-               mbx1_kfunc_audio_pwr(mb->data);
+       case KFUNC_AUDIO_PWR:
+               mbox_kfunc_audio_pwr(mb->data);
                break;
        default:
                printk(KERN_ERR
-                      "mailbox: Unknown kfunc from DSP: 0x%02x\n", mb->cmd_l);
-       }
-}
-
-/*
- * mailbox interrupt handler
- */
-static irqreturn_t mbx1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       union {
-               struct mbcmd sw;
-               struct mbcmd_hw hw;
-       } *mb = (void *)&mbq.mb[mbq.wp];
-
-#if (INT_D2A_MB1 == INT_DSP_MAILBOX1)
-       mb->hw.data = omap_readw(MAILBOX_DSP2ARM1);
-       mb->hw.cmd  = omap_readw(MAILBOX_DSP2ARM1b);
-#elif (INT_D2A_MB1 == INT_DSP_MAILBOX2)
-       mb->hw.data = omap_readw(MAILBOX_DSP2ARM2);
-       mb->hw.cmd  = omap_readw(MAILBOX_DSP2ARM2b);
-#endif
-
-       /* if mbx1 has not been validated yet, discard. */
-       if (!mbx1_valid)
-               return IRQ_HANDLED;
-
-       if (mb->sw.seq != (*mbseq_expect & 1)) {
-               switch (mbseq_check_level) {
-               case MBSEQ_CHECK_NONE:
-                       break;
-               case MBSEQ_CHECK_VERBOSE:
-                       printk(KERN_INFO
-                              "mbx: illegal seq bit!!!  ignoring this command."
-                              " (%04x:%04x)\n", mb->hw.cmd, mb->hw.data);
-                       return IRQ_HANDLED;
-               case MBSEQ_CHECK_SILENT:
-                       return IRQ_HANDLED;
-               }
-       }
-
-       (*mbseq_expect)++;
-
-       mbq_inc(mbq.wp);
-       if (mbq.wp == mbq.rp) { /* mbq is full */
-               mbq.full = 1;
-               disable_irq(INT_D2A_MB1);
-       }
-       schedule_work(&mbx1_work);
-
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t mbx2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       unsigned short cmd, data;
-
-#if (INT_D2A_MB1 == INT_DSP_MAILBOX1)
-       data = omap_readw(MAILBOX_DSP2ARM2);
-       cmd  = omap_readw(MAILBOX_DSP2ARM2b);
-#elif (INT_D2A_MB1 == INT_DSP_MAILBOX2)
-       data = omap_readw(MAILBOX_DSP2ARM1);
-       cmd  = omap_readw(MAILBOX_DSP2ARM1b);
-#endif
-       printk(KERN_DEBUG
-              "mailbox2 interrupt!  cmd=%04x, data=%04x\n", cmd, data);
-
-       return IRQ_HANDLED;
-}
-
-#if 0
-static void mpuio_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       printk(KERN_INFO "MPUIO interrupt!\n");
-}
-#endif
-
-#ifdef CONFIG_PROC_FS
-struct proc_dir_entry *procdir_dsp = NULL;
-
-static void dsp_create_procdir_dsp(void)
-{
-       procdir_dsp = proc_mkdir("dsp", 0);
-       if (procdir_dsp == NULL) {
-               printk(KERN_ERR
-                      "omapdsp: failed to register proc directory: dsp\n");
+                      "mbox: Unknown KFUNC from DSP: 0x%02x\n", mb->cmd_l);
        }
 }
 
-static void dsp_remove_procdir_dsp(void)
-{
-       procdir_dsp = NULL;
-       remove_proc_entry("dsp", 0);
-}
-#else /* CONFIG_PROC_FS */
-#define dsp_create_procdir_dsp()       do { } while (0)
-#define dsp_remove_procdir_dsp()       do { } while (0)
-#endif /* CONFIG_PROC_FS */
-
-extern irqreturn_t dsp_mmu_interrupt(int irq, void *dev_id,
-                                    struct pt_regs *regs);
-
 extern int  dsp_ctl_core_init(void);
 extern void dsp_ctl_core_exit(void);
 extern void dsp_ctl_init(void);
@@ -614,21 +400,16 @@ static void dsp_dev_release(struct device *dev)
 /*
  * driver functions
  */
-#if (INT_D2A_MB1 == INT_DSP_MAILBOX1)
-#      define INT_D2A_MB2 INT_DSP_MAILBOX2
-#elif(INT_D2A_MB1 == INT_DSP_MAILBOX2) /* swap MB1 and MB2 */
-#      define INT_D2A_MB2 INT_DSP_MAILBOX1
-#endif
-
 static int __init dsp_drv_probe(struct platform_device *pdev)
 {
        int ret;
 
        printk(KERN_INFO "OMAP DSP driver initialization\n");
-
-       //__dsp_enable(); // XXX
-
-       dsp_create_procdir_dsp();
+#ifdef CONFIG_ARCH_OMAP2
+       clk_enable(dsp_fck_handle);
+       clk_enable(dsp_ick_handle);
+       __dsp_per_enable();
+#endif
 
        if ((ret = dsp_ctl_core_init()) < 0)
                goto fail1;
@@ -638,52 +419,11 @@ static int __init dsp_drv_probe(struct platform_device *pdev)
        mblog_init();
        if ((ret = dsp_taskmod_init()) < 0)
                goto fail3;
-
-       /*
-        * mailbox interrupt handlers registration
-        */
-       ret = request_irq(INT_D2A_MB1, mbx1_interrupt, SA_INTERRUPT, "dsp",
-                         &pdev->dev);
-       if (ret) {
-               printk(KERN_ERR
-                      "failed to register mailbox1 interrupt: %d\n", ret);
+       if ((ret = dsp_mbox_init()) < 0)
                goto fail4;
-       }
-
-       ret = request_irq(INT_D2A_MB2, mbx2_interrupt, SA_INTERRUPT, "dsp",
-                         &pdev->dev);
-       if (ret) {
-               printk(KERN_ERR
-                      "failed to register mailbox2 interrupt: %d\n", ret);
-               goto fail5;
-       }
-
-       ret = request_irq(INT_DSP_MMU, dsp_mmu_interrupt, SA_INTERRUPT, "dsp",
-                         &pdev->dev);
-       if (ret) {
-               printk(KERN_ERR
-                      "failed to register DSP MMU interrupt: %d\n", ret);
-               goto fail6;
-       }
-
-       /* MMU interrupt is not enabled until DSP runs */
-       disable_irq(INT_DSP_MMU);
-
-#if 0
-       ret = request_irq(INT_MPUIO, mpuio_interrupt, SA_INTERRUPT, "dsp", dev);
-       if (ret) {
-               printk(KERN_ERR
-                      "failed to register MPUIO interrupt: %d\n", ret);
-               goto fail7;
-       }
-#endif
 
        return 0;
 
-fail6:
-       free_irq(INT_D2A_MB2, &pdev->dev);
-fail5:
-       free_irq(INT_D2A_MB1, &pdev->dev);
 fail4:
        dsp_taskmod_exit();
 fail3:
@@ -693,9 +433,11 @@ fail3:
 fail2:
        dsp_ctl_core_exit();
 fail1:
-       dsp_remove_procdir_dsp();
-
-       //__dsp_disable(); // XXX
+#ifdef CONFIG_ARCH_OMAP2
+       __dsp_per_disable();
+       clk_disable(dsp_ick_handle);
+       clk_disable(dsp_fck_handle);
+#endif
        return ret;
 }
 
@@ -703,41 +445,34 @@ static int dsp_drv_remove(struct platform_device *pdev)
 {
        dsp_cpustat_request(CPUSTAT_RESET);
 
-#if 0
-       free_irq(INT_MPUIO, dev);
-#endif
-       free_irq(INT_DSP_MMU, &pdev->dev);
-       free_irq(INT_D2A_MB2, &pdev->dev);
-       free_irq(INT_D2A_MB1, &pdev->dev);
-
-       /* recover disable_depth */
-       enable_irq(INT_DSP_MMU);
-
-       dspuncfg();
+       dsp_cfgstat_request(CFGSTAT_CLEAN);
+       dsp_mbox_exit();
        dsp_taskmod_exit();
        mblog_exit();
        dsp_ctl_exit();
        dsp_mem_exit();
 
        dsp_ctl_core_exit();
-       dsp_remove_procdir_dsp();
-
-       //__dsp_disable(); // XXX
 
+#ifdef CONFIG_ARCH_OMAP2
+       __dsp_per_disable();
+       clk_disable(dsp_ick_handle);
+       clk_disable(dsp_fck_handle);
+#endif
        return 0;
 }
 
 #ifdef CONFIG_PM
 static int dsp_drv_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       dsp_suspend();
+       dsp_cfgstat_request(CFGSTAT_SUSPEND);
 
        return 0;
 }
 
 static int dsp_drv_resume(struct platform_device *pdev)
 {
-       dsp_resume();
+       dsp_cfgstat_request(CFGSTAT_RESUME);
 
        return 0;
 }
@@ -747,14 +482,6 @@ static int dsp_drv_resume(struct platform_device *pdev)
 #endif /* CONFIG_PM */
 
 static struct resource dsp_resources[] = {
-       {
-               .start = INT_DSP_MAILBOX1,
-               .flags = IORESOURCE_IRQ,
-       },
-       {
-               .start = INT_DSP_MAILBOX2,
-               .flags = IORESOURCE_IRQ,
-       },
        {
                .start = INT_DSP_MMU,
                .flags = IORESOURCE_IRQ,
@@ -785,6 +512,12 @@ static int __init omap_dsp_mod_init(void)
 {
        int ret;
 
+       mbox_dsp = mbox_get("DSP");
+       if (IS_ERR(mbox_dsp)) {
+               printk(KERN_ERR "failed to get mailbox handler for DSP.\n");
+               goto fail1;
+       }
+
        ret = platform_device_register(&dsp_device);
        if (ret) {
                printk(KERN_ERR "failed to register the DSP device: %d\n", ret);