]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/plat-omap/dsp/dsp_ctl.c
ARM: OMAP: DSPGW: rename mbx -> mbox
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / dsp_ctl.c
index 5738d143b736b3b129e7489f9fa0ad592eb6d786..d4dfc48287e0810f72d23e115c40fd0f41d6f6bf 100644 (file)
 /*
- * linux/arch/arm/mach-omap/dsp/dsp_ctl.c
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
  *
- * OMAP DSP control device 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/09:  DSP Gateway version 3.3
  */
 
 #include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/device.h>
-#include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/ioctls.h>
-#include <asm/hardware/clock.h>
-#include <asm/arch/dsp.h>
+#include <asm/arch/mailbox.h>
 #include "hardware_dsp.h"
+#include "dsp_mbcmd.h"
 #include "dsp.h"
 #include "ipbuf.h"
+#include "ioctl.h"
+
+enum dsp_space_e {
+       SPACE_MEM,
+       SPACE_IO,
+};
+
+#ifdef CONFIG_OMAP_DSP_FBEXPORT
+static enum fbstat_e {
+       FBSTAT_DISABLED = 0,
+       FBSTAT_ENABLED,
+       FBSTAT_MAX,
+} fbstat = FBSTAT_ENABLED;
+#endif
+
+static enum cfgstat_e cfgstat;
+int mbox_revision;
+static u8 n_stask;
 
+static ssize_t ifver_show(struct device *dev, struct device_attribute *attr,
+                         char *buf);
+static ssize_t cpustat_show(struct device *dev, struct device_attribute *attr,
+                           char *buf);
+static ssize_t icrmask_show(struct device *dev, struct device_attribute *attr,
+                           char *buf);
+static ssize_t icrmask_store(struct device *dev, struct device_attribute *attr,
+                            const char *buf, size_t count);
 static ssize_t loadinfo_show(struct device *dev, struct device_attribute *attr,
                             char *buf);
-static struct device_attribute dev_attr_loadinfo = __ATTR_RO(loadinfo);
-extern struct device_attribute dev_attr_ipbuf;
 
-static enum cfgstat {
-       CFG_ERR,
-       CFG_READY,
-       CFG_SUSPEND
-} cfgstat;
-int mbx_revision;
-static DECLARE_WAIT_QUEUE_HEAD(ioctl_wait_q);
-static unsigned short ioctl_wait_cmd;
-static DECLARE_MUTEX(ioctl_sem);
+#define __ATTR_RW(_name, _mode) { \
+       .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },     \
+       .show   = _name##_show,                                 \
+       .store  = _name##_store,                                        \
+}
 
-static unsigned char n_stask;
+static struct device_attribute dev_attr_ifver     = __ATTR_RO(ifver);
+static struct device_attribute dev_attr_cpustat   = __ATTR_RO(cpustat);
+static struct device_attribute dev_attr_icrmask   = __ATTR_RW(icrmask, 0644);
+static struct device_attribute dev_attr_loadinfo  = __ATTR_RO(loadinfo);
 
 /*
- * control functions
+ * misc interactive mailbox command operations
  */
-static short varread_val[5]; /* maximum */
+static struct misc_mb_wait_struct {
+       struct mutex lock;
+       wait_queue_head_t wait_q;
+       u8 cmd_h;
+       u8 cmd_l;
+       u16 *retvp;
+} misc_mb_wait = {
+       .lock = __MUTEX_INITIALIZER(misc_mb_wait.lock),
+       .wait_q = __WAIT_QUEUE_HEAD_INITIALIZER(misc_mb_wait.wait_q),
+};
 
-static int dsp_regread(unsigned short cmd_l, unsigned short adr,
-                      unsigned short *val)
+static int __misc_mbcompose_send_and_wait(u8 cmd_h, u8 cmd_l, u16 data,
+                                         u16 *retvp)
 {
-       struct mbcmd mb;
+       struct mbcmd mb = MBCMD_INIT(cmd_h, cmd_l, data);
        int ret = 0;
 
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
+       if (mutex_lock_interruptible(&misc_mb_wait.lock))
+               return -EINTR;
 
-       ioctl_wait_cmd = MBCMD(REGRW);
-       mbcmd_set(mb, MBCMD(REGRW), cmd_l, adr);
-       dsp_mbcmd_send_and_wait(&mb, &ioctl_wait_q);
+       misc_mb_wait.cmd_h = mb.cmd_h;
+       misc_mb_wait.cmd_l = mb.cmd_l;
+       misc_mb_wait.retvp = retvp;
+       dsp_mbcmd_send_and_wait(&mb, &misc_mb_wait.wait_q);
 
-       if (ioctl_wait_cmd != 0) {
-               printk(KERN_ERR "omapdsp: register read error!\n");
+       if (misc_mb_wait.cmd_h != 0)
                ret = -EINVAL;
-               goto up_out;
+
+       mutex_unlock(&misc_mb_wait.lock);
+       return ret;
+}
+
+#define misc_mbcompose_send_and_wait(cmd_h, cmd_l, data, retvp) \
+               __misc_mbcompose_send_and_wait(MBOX_CMD_DSP_##cmd_h, (cmd_l), \
+                                              (data), (retvp));
+
+static int misc_mbcmd_response(struct mbcmd *mb, int argc, int match_cmd_l_flag)
+{
+       volatile u16 *buf;
+       int i;
+
+       /* if match_cmd_l_v flag is set, cmd_l needs to be matched as well. */
+       if (!waitqueue_active(&misc_mb_wait.wait_q) ||
+           (misc_mb_wait.cmd_h != mb->cmd_h) ||
+           (match_cmd_l_flag && (misc_mb_wait.cmd_l != mb->cmd_l))) {
+               const struct cmdinfo *ci = cmdinfo[mb->cmd_h];
+               char cmdstr[32];
+
+               if (ci->cmd_l_type == CMD_L_TYPE_SUBCMD)
+                       sprintf(cmdstr, "%s:%s", ci->name, subcmd_name(mb));
+               else
+                       strcpy(cmdstr, ci->name);
+               printk(KERN_WARNING
+                      "mbox: unexpected command %s received!\n", cmdstr);
+               return -1;
        }
 
-       *val = varread_val[0];
+       /*
+        * if argc == 1, receive data through mbox:data register.
+        * if argc > 1, receive through ipbuf_sys.
+        */
+       if (argc == 1)
+               misc_mb_wait.retvp[0] = mb->data;
+       else if (argc > 1) {
+               if (dsp_mem_enable(ipbuf_sys_da) < 0) {
+                       printk(KERN_ERR "mbox: %s - ipbuf_sys_da read failed!\n",
+                              cmdinfo[mb->cmd_h]->name);
+                       return -1;
+               }
+               if (sync_with_dsp(&ipbuf_sys_da->s, TID_ANON, 10) < 0) {
+                       printk(KERN_ERR "mbox: %s - IPBUF sync failed!\n",
+                              cmdinfo[mb->cmd_h]->name);
+                       dsp_mem_disable(ipbuf_sys_da);
+                       return -1;
+               }
+               /* need word access. do not use memcpy. */
+               buf = ipbuf_sys_da->d;
+               for (i = 0; i < argc; i++)
+                       misc_mb_wait.retvp[i] = buf[i];
+               release_ipbuf_pvt(ipbuf_sys_da);
+               dsp_mem_disable(ipbuf_sys_da);
+       }
+
+       misc_mb_wait.cmd_h = 0;
+       wake_up_interruptible(&misc_mb_wait.wait_q);
+       return 0;
+}
+
+static int dsp_regread(enum dsp_space_e space, u16 adr, u16 *val)
+{
+       u8 cmd_l = (space == SPACE_MEM) ? REGRW_MEMR : REGRW_IOR;
+       int ret;
+
+       ret = misc_mbcompose_send_and_wait(REGRW, cmd_l, adr, val);
+       if ((ret < 0) && (ret != -EINTR))
+               printk(KERN_ERR "omapdsp: register read error!\n");
 
-up_out:
-       up(&ioctl_sem);
        return ret;
 }
 
-static int dsp_regwrite(unsigned short cmd_l, unsigned short adr,
-                       unsigned short val)
+static int dsp_regwrite(enum dsp_space_e space, u16 adr, u16 val)
 {
-       struct mbcmd mb;
+       u8 cmd_l = (space == SPACE_MEM) ? REGRW_MEMW : REGRW_IOW;
        struct mb_exarg arg = {
-               .tid  = OMAP_DSP_TID_ANON,
+               .tid  = TID_ANON,
                .argc = 1,
                .argv = &val,
        };
 
-       mbcmd_set(mb, MBCMD(REGRW), cmd_l, adr);
-       dsp_mbcmd_send_exarg(&mb, &arg);
+       mbcompose_send_exarg(REGRW, cmd_l, adr, &arg);
        return 0;
 }
 
-static int dsp_getvar(unsigned char varid, unsigned short *val, int sz)
+static int dsp_getvar(u8 varid, u16 *val)
 {
-       struct mbcmd mb;
-       int ret = 0;
-
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
-
-       ioctl_wait_cmd = MBCMD(GETVAR);
-       mbcmd_set(mb, MBCMD(GETVAR), varid, 0);
-       dsp_mbcmd_send_and_wait(&mb, &ioctl_wait_q);
+       int ret;
 
-       if (ioctl_wait_cmd != 0) {
+       ret = misc_mbcompose_send_and_wait(GETVAR, varid, 0, val);
+       if ((ret < 0) && (ret != -EINTR))
                printk(KERN_ERR "omapdsp: variable read error!\n");
-               ret = -EINVAL;
-               goto up_out;
-       }
-
-       memcpy(val, varread_val, sz * sizeof(short));
 
-up_out:
-       up(&ioctl_sem);
        return ret;
 }
 
-static int dsp_setvar(unsigned char varid, unsigned short val)
+static int dsp_setvar(u8 varid, u16 val)
 {
-       dsp_mbsend(MBCMD(SETVAR), varid, val);
+       mbcompose_send(SETVAR, varid, val);
        return 0;
 }
 
-static int dspcfg(void)
+/*
+ * dsp_cfg() return value
+ *  = 0: OK
+ *  = 1: failed, but state is clear. (DSPCFG command failed)
+ *  < 0: failed. need cleanup.
+ */
+static int dsp_cfg(void)
 {
-       struct mbcmd mb;
        int ret = 0;
 
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
-
-       if (cfgstat != CFG_ERR) {
-               printk(KERN_ERR
-                      "omapdsp: DSP has been already configured. "
-                      "do unconfig!\n");
-               ret = -EBUSY;
-               goto up_out;
-       }
-
+#ifdef CONFIG_ARCH_OMAP1
        /* for safety */
        dsp_mem_usecount_clear();
+#endif
 
        /*
         * DSPCFG command and dsp_mem_start() must be called
@@ -162,215 +233,270 @@ static int dspcfg(void)
         */
        dsp_mem_enable((void *)dspmem_base);
 
-       dsp_mb_start();
+       dsp_mbox_start();
        dsp_twch_start();
        dsp_mem_start();
        dsp_err_start();
 
-       mbx_revision = -1;
-       ioctl_wait_cmd = MBCMD(DSPCFG);
-       mbcmd_set(mb, MBCMD(DSPCFG), OMAP_DSP_MBCMD_DSPCFG_REQ, 0);
-       dsp_mbcmd_send_and_wait(&mb, &ioctl_wait_q);
+       mbox_revision = -1;
 
-       if (ioctl_wait_cmd != 0) {
-               printk(KERN_ERR "omapdsp: configuration error!\n");
-               ret = -EINVAL;
-               cfgstat = CFG_ERR;
-               goto up_out;
+       ret = misc_mbcompose_send_and_wait(DSPCFG, DSPCFG_REQ, 0, NULL);
+       if (ret < 0) {
+               if (ret != -EINTR)
+                       printk(KERN_ERR "omapdsp: configuration error!\n");
+               ret = 1;
+               goto out;
        }
 
-#ifdef OLD_BINARY_SUPPORT
+#if defined(CONFIG_ARCH_OMAP1) && defined(OLD_BINARY_SUPPORT)
        /*
         * MBREV 3.2 or earlier doesn't assume DMA domain is on
         * when DSPCFG command is sent
         */
-       if ((mbx_revision == MBREV_3_0) ||
-           (mbx_revision == MBREV_3_2)) {
-               ret = dsp_mbsend(MBCMD(PM), OMAP_DSP_MBCMD_PM_ENABLE,
-                                DSPREG_ICR_DMA_IDLE_DOMAIN);
+       if ((mbox_revision == MBREV_3_0) ||
+           (mbox_revision == MBREV_3_2)) {
+               if ((ret = mbcompose_send(PM, PM_ENABLE, DSPREG_ICR_DMA)) < 0)
+                       goto out;
        }
 #endif
 
-       if ((ret = dsp_task_config_all(n_stask)) < 0) {
-               up(&ioctl_sem);
-               dspuncfg();
-               dsp_mem_disable((void *)dspmem_base);
-               return -EINVAL;
-       }
+       if ((ret = dsp_task_config_all(n_stask)) < 0)
+               goto out;
 
-       cfgstat = CFG_READY;
+       /* initialization */
+#ifdef CONFIG_OMAP_DSP_FBEXPORT
+       fbstat = FBSTAT_ENABLED;
+#endif
 
        /* send parameter */
-       if ((ret = dsp_setvar(OMAP_DSP_MBCMD_VARID_ICRMASK,
-                             dsp_cpustat_get_icrmask())) < 0)
-               goto up_out;
+       if ((ret = dsp_setvar(VARID_ICRMASK, dsp_cpustat_get_icrmask())) < 0)
+               goto out;
 
        /* create runtime sysfs entries */
        device_create_file(&dsp_device.dev, &dev_attr_loadinfo);
-       device_create_file(&dsp_device.dev, &dev_attr_ipbuf);
 
-up_out:
+out:
        dsp_mem_disable((void *)dspmem_base);
-       up(&ioctl_sem);
        return ret;
 }
 
-int dspuncfg(void)
+static int dsp_uncfg(void)
 {
        if (dsp_taskmod_busy()) {
                printk(KERN_WARNING "omapdsp: tasks are busy.\n");
                return -EBUSY;
        }
 
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
-
        /* FIXME: lock task module */
 
        /* remove runtime sysfs entries */
        device_remove_file(&dsp_device.dev, &dev_attr_loadinfo);
-       device_remove_file(&dsp_device.dev, &dev_attr_ipbuf);
 
-       dsp_mb_stop();
+       dsp_mbox_stop();
        dsp_twch_stop();
        dsp_mem_stop();
        dsp_err_stop();
        dsp_dbg_stop();
        dsp_task_unconfig_all();
        ipbuf_stop();
-       cfgstat = CFG_ERR;
 
-       up(&ioctl_sem);
        return 0;
 }
 
-int dsp_is_ready(void)
+static int dsp_suspend(void)
 {
-       return (cfgstat == CFG_READY) ? 1 : 0;
+       int ret;
+
+       ret = misc_mbcompose_send_and_wait(SUSPEND, 0, 0, NULL);
+       if (ret < 0) {
+               if (ret != -EINVAL)
+                       printk(KERN_ERR "omapdsp: DSP suspend error!\n");
+               return ret;
+       }
+
+       udelay(100);    /* wait for DSP-side execution */
+       return 0;
 }
 
-/*
- * polls all tasks
- */
-int dsp_poll(void)
+int dsp_cfgstat_request(enum cfgstat_e st_req)
 {
-       struct mbcmd mb;
-       int ret = 0;
+       static DEFINE_MUTEX(cfgstat_lock);
+       int ret = 0, ret_override = 0;
 
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
+       if (mutex_lock_interruptible(&cfgstat_lock))
+               return -EINTR;
 
-       ioctl_wait_cmd = MBCMD(POLL);
-       mbcmd_set(mb, MBCMD(POLL), 0, 0);
-       dsp_mbcmd_send_and_wait(&mb, &ioctl_wait_q);
+again:
+       switch (st_req) {
 
-       if (ioctl_wait_cmd != 0) {
-               printk(KERN_ERR "omapdsp: poll error!\n");
-               ret = -EINVAL;
-               goto up_out;
-       }
+       /* cfgstat takes CLEAN, READY or SUSPEND,
+          while st_req can take SUSPEND in addition. */
 
-up_out:
-       up(&ioctl_sem);
-       return ret;
-}
+       case CFGSTAT_CLEAN:
+               if (cfgstat == CFGSTAT_CLEAN)
+                       goto up_out;
+               if ((ret = dsp_uncfg()) < 0)
+                       goto up_out;
+               break;
 
-void dsp_runlevel(unsigned char level)
-{
-       if (level == OMAP_DSP_MBCMD_RUNLEVEL_RECOVERY)
-               dsp_mbsend_recovery(MBCMD(RUNLEVEL), level, 0);
-       else
-               dsp_mbsend(MBCMD(RUNLEVEL), level, 0);
-}
+       case CFGSTAT_READY:
+               if (cfgstat != CFGSTAT_CLEAN) {
+                       printk(KERN_ERR "omapdsp: DSP is ready already!\n");
+                       ret = -EINVAL;
+                       goto up_out;
+               }
 
-static enum cfgstat cfgstat_save_suspend;
+               ret = dsp_cfg();
+               if (ret > 0) {  /* failed, but state is clear. */
+                       ret = -EINVAL;
+                       goto up_out;
+               } else if (ret < 0) {   /* failed, need cleanup. */
+                       st_req = CFGSTAT_CLEAN;
+                       ret_override = ret;
+                       goto again;
+               }
+               break;
 
-/*
- * suspend / resume callbacks
- * DSP is not reset within this code, but done in omap_pm_suspend.
- * so if these functions are called as OMAP_DSP_IOCTL_SUSPEND,
- * DSP should be reset / unreset out of these functions.
- */
-int dsp_suspend(void)
-{
-       struct mbcmd mb;
-       int ret = 0;
+       /*
+        * suspend / resume
+        * DSP is not reset within this code, but done in omap_pm_suspend.
+        * so if these functions are called from sysfs,
+        * DSP should be reset / unreset out of these functions.
+        */
+       case CFGSTAT_SUSPEND:
+               switch (cfgstat) {
+
+               case CFGSTAT_CLEAN:
+                       if (dsp_cpustat_get_stat() == CPUSTAT_RUN) {
+                               printk(KERN_WARNING
+                                      "omapdsp: illegal operation -- trying "
+                                      "suspend DSP while it is running but "
+                                      "not configured.\n"
+                                      "  Resetting DSP.\n");
+                               dsp_cpustat_request(CPUSTAT_RESET);
+                               ret = -EINVAL;
+                       }
+                       goto up_out;
 
-       if (cfgstat == CFG_SUSPEND) {
-               printk(KERN_ERR "omapdsp: DSP is already in suspend state.\n");
-               return -EINVAL;
-       }
+               case CFGSTAT_READY:
+                       if ((ret = dsp_suspend()) < 0)
+                               goto up_out;
+                       break;
 
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
+               case CFGSTAT_SUSPEND:
+                       goto up_out;
 
-       cfgstat_save_suspend = cfgstat;
-       if (!dsp_is_ready()) {
-               if (dsp_cpustat_get_stat() == CPUSTAT_RUN) {
+               default:
+                       BUG();
+
+               }
+
+               break;
+
+       case CFGSTAT_RESUME:
+               if (cfgstat != CFGSTAT_SUSPEND) {
                        printk(KERN_WARNING
-                              "omapdsp: illegal operation: trying suspend DSP "
-                              "while it is running but has not configured "
-                              "yet.\n"
-                              "  Resetting DSP...\n");
+                              "omapdsp: DSP resume request, but DSP is not in "
+                              "suspend state.\n");
+                       ret = -EINVAL;
+                       goto up_out;
                }
-               goto transition;
-       }
+               st_req = CFGSTAT_READY;
+               break;
 
-       ioctl_wait_cmd = MBCMD(SUSPEND);
-       mbcmd_set(mb, MBCMD(SUSPEND), 0, 0);
-       dsp_mbcmd_send_and_wait(&mb, &ioctl_wait_q);
+       default:
+               BUG();
 
-       if (ioctl_wait_cmd != 0) {
-               printk(KERN_ERR "omapdsp: DSP suspend error!\n");
-               ret = -EINVAL;
-               goto up_out;
        }
 
-       udelay(100);
-transition:
-       cfgstat = CFG_SUSPEND;
+       cfgstat = st_req;
 up_out:
-       up(&ioctl_sem);
+       mutex_unlock(&cfgstat_lock);
+       return ret_override ? ret_override : ret;
+}
+
+enum cfgstat_e dsp_cfgstat_get_stat(void)
+{
+       return cfgstat;
+}
+
+/*
+ * polls all tasks
+ */
+static int dsp_poll(void)
+{
+       int ret;
+
+       ret = misc_mbcompose_send_and_wait(POLL, 0, 0, NULL);
+       if ((ret < 0) && (ret != -EINTR))
+               printk(KERN_ERR "omapdsp: poll error!\n");
+
        return ret;
 }
 
-int dsp_resume(void)
+int dsp_set_runlevel(u8 level)
 {
-       if (cfgstat != CFG_SUSPEND) {
-               printk(KERN_ERR "omapdsp: DSP is not in suspend state.\n");
-               return -EINVAL;
+       if (level == RUNLEVEL_RECOVERY) {
+               if (mbcompose_send_recovery(RUNLEVEL, level, 0) < 0)
+                       return -EINVAL;
+       } else {
+               if ((level < RUNLEVEL_USER) ||
+                   (level > RUNLEVEL_SUPER))
+                       return -EINVAL;
+               if (mbcompose_send(RUNLEVEL, level, 0) < 0)
+                       return -EINVAL;
        }
 
-       cfgstat = cfgstat_save_suspend;
        return 0;
 }
 
+#ifdef CONFIG_OMAP_DSP_FBEXPORT
 static void dsp_fbctl_enable(void)
 {
-       dsp_mbsend(MBCMD(KFUNC), OMAP_DSP_MBCMD_KFUNC_FBCTL,
-                  OMAP_DSP_MBCMD_FBCTL_ENABLE);
+       mbcompose_send(KFUNC, KFUNC_FBCTL, FBCTL_ENABLE);
 }
 
 static int dsp_fbctl_disable(void)
 {
+       int ret;
+
+       ret = misc_mbcompose_send_and_wait(KFUNC, KFUNC_FBCTL, FBCTL_DISABLE,
+                                          NULL);
+       if ((ret < 0) && (ret != -EINTR))
+               printk(KERN_ERR "omapdsp: fb disable error!\n");
+
+       return 0;
+}
+
+static int dsp_fbstat_request(enum fbstat_e st)
+{
+       static DEFINE_MUTEX(fbstat_lock);
        int ret = 0;
-       struct mbcmd mb;
 
-       if (down_interruptible(&ioctl_sem))
-               return -ERESTARTSYS;
+       if (mutex_lock_interruptible(&fbstat_lock))
+               return -EINTR;
 
-       ioctl_wait_cmd = MBCMD(KFUNC);
-       mbcmd_set(mb, MBCMD(KFUNC), OMAP_DSP_MBCMD_KFUNC_FBCTL,
-                 OMAP_DSP_MBCMD_FBCTL_DISABLE);
-       dsp_mbcmd_send_and_wait(&mb, &ioctl_wait_q);
-       if (ioctl_wait_cmd != 0) {
-               printk(KERN_ERR "omapdsp: fb disable error!\n");
-               ret = -EINVAL;
+       if (st == fbstat)
+               goto up_out;
+
+       switch (st) {
+       case FBSTAT_ENABLED:
+               dsp_fbctl_enable();
+               break;
+       case FBSTAT_DISABLED:
+               if ((ret = dsp_fbctl_disable()) < 0)
+                       goto up_out;
+               break;
+       default:
+               BUG();
        }
-       up(&ioctl_sem);
 
-       return ret;
+       fbstat = st;
+up_out:
+       mutex_unlock(&fbstat_lock);
+       return 0;
 }
+#endif /* CONFIG_OMAP_DSP_FBEXPORT */
 
 /*
  * DSP control device file operations
@@ -384,55 +510,60 @@ static int dsp_ctl_ioctl(struct inode *inode, struct file *file,
        /*
         * command level 1: commands which don't need lock
         */
-       case OMAP_DSP_IOCTL_RUN:
+       case DSPCTL_IOCTL_RUN:
                dsp_cpustat_request(CPUSTAT_RUN);
                break;
 
-       case OMAP_DSP_IOCTL_RESET:
+       case DSPCTL_IOCTL_RESET:
                dsp_cpustat_request(CPUSTAT_RESET);
                break;
 
-       case OMAP_DSP_IOCTL_SETRSTVECT:
-               ret = dsp_set_rstvect((unsigned long)arg);
+       case DSPCTL_IOCTL_SETRSTVECT:
+               ret = dsp_set_rstvect((dsp_long_t)arg);
                break;
 
-       case OMAP_DSP_IOCTL_CPU_IDLE:
+#ifdef CONFIG_ARCH_OMAP1
+       case DSPCTL_IOCTL_CPU_IDLE:
                dsp_cpustat_request(CPUSTAT_CPU_IDLE);
                break;
 
-       case OMAP_DSP_IOCTL_GBL_IDLE:
+       case DSPCTL_IOCTL_GBL_IDLE:
                dsp_cpustat_request(CPUSTAT_GBL_IDLE);
                break;
 
-       case OMAP_DSP_IOCTL_MPUI_WORDSWAP_ON:
+       case DSPCTL_IOCTL_MPUI_WORDSWAP_ON:
                mpui_wordswap_on();
                break;
 
-       case OMAP_DSP_IOCTL_MPUI_WORDSWAP_OFF:
+       case DSPCTL_IOCTL_MPUI_WORDSWAP_OFF:
                mpui_wordswap_off();
                break;
 
-       case OMAP_DSP_IOCTL_MPUI_BYTESWAP_ON:
+       case DSPCTL_IOCTL_MPUI_BYTESWAP_ON:
                mpui_byteswap_on();
                break;
 
-       case OMAP_DSP_IOCTL_MPUI_BYTESWAP_OFF:
+       case DSPCTL_IOCTL_MPUI_BYTESWAP_OFF:
                mpui_byteswap_off();
                break;
+#endif /* CONFIG_ARCH_OMAP1 */
+
+       case DSPCTL_IOCTL_TASKCNT:
+               ret = dsp_task_count();
+               break;
 
-       case OMAP_DSP_IOCTL_MBSEND:
+       case DSPCTL_IOCTL_MBSEND:
                {
                        struct omap_dsp_mailbox_cmd u_cmd;
-                       struct mbcmd_hw mb;
+                       mbox_msg_t msg;
                        if (copy_from_user(&u_cmd, (void *)arg, sizeof(u_cmd)))
                                return -EFAULT;
-                       mb.cmd  = u_cmd.cmd;
-                       mb.data = u_cmd.data;
-                       ret = dsp_mbcmd_send((struct mbcmd *)&mb);
+                       msg = (u_cmd.cmd << 16) | u_cmd.data;
+                       ret = dsp_mbcmd_send((struct mbcmd *)&msg);
                        break;
                }
 
-       case OMAP_DSP_IOCTL_SETVAR:
+       case DSPCTL_IOCTL_SETVAR:
                {
                        struct omap_dsp_varinfo var;
                        if (copy_from_user(&var, (void *)arg, sizeof(var)))
@@ -441,126 +572,119 @@ static int dsp_ctl_ioctl(struct inode *inode, struct file *file,
                        break;
                }
 
-       case OMAP_DSP_IOCTL_RUNLEVEL:
-               dsp_runlevel(arg);
+       case DSPCTL_IOCTL_RUNLEVEL:
+               ret = dsp_set_runlevel(arg);
                break;
 
-       case OMAP_DSP_IOCTL_FBEN:
-               dsp_fbctl_enable();
-               return 0;
+#ifdef CONFIG_OMAP_DSP_FBEXPORT
+       case DSPCTL_IOCTL_FBEN:
+               ret = dsp_fbstat_request(FBSTAT_ENABLED);
+               break;
+#endif
 
        /*
         * command level 2: commands which need lock
         */
-       case OMAP_DSP_IOCTL_DSPCFG:
-               ret = dspcfg();
-               break;
-
-       case OMAP_DSP_IOCTL_DSPUNCFG:
-               ret = dspuncfg();
+       case DSPCTL_IOCTL_DSPCFG:
+               ret = dsp_cfgstat_request(CFGSTAT_READY);
                break;
 
-       case OMAP_DSP_IOCTL_TASKCNT:
-               ret = dsp_task_count();
+       case DSPCTL_IOCTL_DSPUNCFG:
+               ret = dsp_cfgstat_request(CFGSTAT_CLEAN);
                break;
 
-       case OMAP_DSP_IOCTL_POLL:
+       case DSPCTL_IOCTL_POLL:
                ret = dsp_poll();
                break;
 
-       case OMAP_DSP_IOCTL_FBDIS:
-               ret = dsp_fbctl_disable();
+#ifdef CONFIG_OMAP_DSP_FBEXPORT
+       case DSPCTL_IOCTL_FBDIS:
+               ret = dsp_fbstat_request(FBSTAT_DISABLED);
                break;
+#endif
 
-       /*
-        * FIXME: cpu status control for suspend - resume
-        */
-       case OMAP_DSP_IOCTL_SUSPEND:
-               if ((ret = dsp_suspend()) < 0)
+       case DSPCTL_IOCTL_SUSPEND:
+               if ((ret = dsp_cfgstat_request(CFGSTAT_SUSPEND)) < 0)
                        break;
                dsp_cpustat_request(CPUSTAT_RESET);
                break;
 
-       case OMAP_DSP_IOCTL_RESUME:
-               if ((ret = dsp_resume()) < 0)
+       case DSPCTL_IOCTL_RESUME:
+               if ((ret = dsp_cfgstat_request(CFGSTAT_RESUME)) < 0)
                        break;
                dsp_cpustat_request(CPUSTAT_RUN);
                break;
 
-       case OMAP_DSP_IOCTL_REGMEMR:
+       case DSPCTL_IOCTL_REGMEMR:
                {
                        struct omap_dsp_reginfo *u_reg = (void *)arg;
-                       unsigned short adr, val;
+                       u16 adr, val;
 
-                       if (copy_from_user(&adr, &u_reg->adr, sizeof(short)))
+                       if (copy_from_user(&adr, &u_reg->adr, sizeof(u16)))
                                return -EFAULT;
-                       if ((ret = dsp_regread(OMAP_DSP_MBCMD_REGRW_MEMR,
-                                              adr, &val)) < 0)
+                       if ((ret = dsp_regread(SPACE_MEM, adr, &val)) < 0)
                                return ret;
-                       if (copy_to_user(&u_reg->val, &val, sizeof(short)))
+                       if (copy_to_user(&u_reg->val, &val, sizeof(u16)))
                                return -EFAULT;
                        break;
                }
 
-       case OMAP_DSP_IOCTL_REGMEMW:
+       case DSPCTL_IOCTL_REGMEMW:
                {
                        struct omap_dsp_reginfo reg;
 
                        if (copy_from_user(&reg, (void *)arg, sizeof(reg)))
                                return -EFAULT;
-                       ret = dsp_regwrite(OMAP_DSP_MBCMD_REGRW_MEMW,
-                                          reg.adr, reg.val);
+                       ret = dsp_regwrite(SPACE_MEM, reg.adr, reg.val);
                        break;
                }
 
-       case OMAP_DSP_IOCTL_REGIOR:
+       case DSPCTL_IOCTL_REGIOR:
                {
                        struct omap_dsp_reginfo *u_reg = (void *)arg;
-                       unsigned short adr, val;
+                       u16 adr, val;
 
-                       if (copy_from_user(&adr, &u_reg->adr, sizeof(short)))
+                       if (copy_from_user(&adr, &u_reg->adr, sizeof(u16)))
                                return -EFAULT;
-                       if ((ret = dsp_regread(OMAP_DSP_MBCMD_REGRW_IOR,
-                                              adr, &val)) < 0)
+                       if ((ret = dsp_regread(SPACE_IO, adr, &val)) < 0)
                                return ret;
-                       if (copy_to_user(&u_reg->val, &val, sizeof(short)))
+                       if (copy_to_user(&u_reg->val, &val, sizeof(u16)))
                                return -EFAULT;
                        break;
                }
 
-       case OMAP_DSP_IOCTL_REGIOW:
+       case DSPCTL_IOCTL_REGIOW:
                {
                        struct omap_dsp_reginfo reg;
 
                        if (copy_from_user(&reg, (void *)arg, sizeof(reg)))
                                return -EFAULT;
-                       ret = dsp_regwrite(OMAP_DSP_MBCMD_REGRW_IOW,
-                                          reg.adr, reg.val);
+                       ret = dsp_regwrite(SPACE_IO, reg.adr, reg.val);
                        break;
                }
 
-       case OMAP_DSP_IOCTL_GETVAR:
+       case DSPCTL_IOCTL_GETVAR:
                {
                        struct omap_dsp_varinfo *u_var = (void *)arg;
-                       unsigned char varid;
-                       unsigned short val[5]; /* maximum */
+                       u8 varid;
+                       u16 val[5]; /* maximum */
                        int argc;
 
-                       if (copy_from_user(&varid, &u_var->varid, sizeof(char)))
+                       if (copy_from_user(&varid, &u_var->varid, sizeof(u8)))
                                return -EFAULT;
                        switch (varid) {
-                       case OMAP_DSP_MBCMD_VARID_ICRMASK:
+                       case VARID_ICRMASK:
                                argc = 1;
                                break;
-                       case OMAP_DSP_MBCMD_VARID_LOADINFO:
+                       case VARID_LOADINFO:
                                argc = 5;
                                break;
                        default:
                                return -EINVAL;
                        }
-                       if ((ret = dsp_getvar(varid, val, argc)) < 0)
+                       if ((ret = dsp_getvar(varid, val)) < 0)
                                return ret;
-                       if (copy_to_user(&u_var->val, val, sizeof(short) * argc))
+                       if (copy_to_user(&u_var->val, val, sizeof(u16) * argc))
                                return -EFAULT;
                        break;
                }
@@ -573,56 +697,47 @@ static int dsp_ctl_ioctl(struct inode *inode, struct file *file,
 }
 
 /*
- * functions called from mailbox1 interrupt routine
+ * functions called from mailbox interrupt routine
  */
-void mbx1_suspend(struct mbcmd *mb)
+void mbox_suspend(struct mbcmd *mb)
+{
+       misc_mbcmd_response(mb, 0, 0);
+}
+
+void mbox_dspcfg(struct mbcmd *mb)
 {
-       if (!waitqueue_active(&ioctl_wait_q) ||
-           (ioctl_wait_cmd != MBCMD(SUSPEND))) {
+       u8 last   = mb->cmd_l & 0x80;
+       u8 cfgcmd = mb->cmd_l & 0x7f;
+       static dsp_long_t tmp_ipb_adr;
+
+       if (!waitqueue_active(&misc_mb_wait.wait_q) ||
+           (misc_mb_wait.cmd_h != MBOX_CMD_DSP_DSPCFG)) {
                printk(KERN_WARNING
-                      "mbx: SUSPEND command received, "
+                      "mbox: DSPCFG command received, "
                       "but nobody is waiting for it...\n");
                return;
        }
 
-       ioctl_wait_cmd = 0;
-       wake_up_interruptible(&ioctl_wait_q);
-}
-
-void mbx1_dspcfg(struct mbcmd *mb)
-{
-       unsigned char last   = mb->cmd_l & 0x80;
-       unsigned char cfgcmd = mb->cmd_l & 0x7f;
-       static unsigned long tmp_ipb_adr;
-
        /* mailbox protocol check */
-       if (cfgcmd == OMAP_DSP_MBCMD_DSPCFG_PROTREV) {
-               if (!waitqueue_active(&ioctl_wait_q) ||
-                   (ioctl_wait_cmd != MBCMD(DSPCFG))) {
-                       printk(KERN_WARNING
-                              "mbx: DSPCFG command received, "
-                              "but nobody is waiting for it...\n");
-                       return;
-               }
-
-               mbx_revision = mb->data;
-               if (mbx_revision == OMAP_DSP_MBPROT_REVISION)
+       if (cfgcmd == DSPCFG_PROTREV) {
+               mbox_revision = mb->data;
+               if (mbox_revision == MBPROT_REVISION)
                        return;
 #ifdef OLD_BINARY_SUPPORT
-               else if ((mbx_revision == MBREV_3_0) ||
-                        (mbx_revision == MBREV_3_2)) {
+               else if ((mbox_revision == MBREV_3_0) ||
+                        (mbox_revision == MBREV_3_2)) {
                        printk(KERN_WARNING
-                              "mbx: ***** old DSP binary *****\n"
+                              "mbox: ***** old DSP binary *****\n"
                               "  Please update your DSP application.\n");
                        return;
                }
 #endif
                else {
                        printk(KERN_ERR
-                              "mbx: protocol revision check error!\n"
+                              "mbox: protocol revision check error!\n"
                               "  expected=0x%04x, received=0x%04x\n",
-                              OMAP_DSP_MBPROT_REVISION, mb->data);
-                       mbx_revision = -1;
+                              MBPROT_REVISION, mb->data);
+                       mbox_revision = -1;
                        goto abort1;
                }
        }
@@ -631,57 +746,54 @@ void mbx1_dspcfg(struct mbcmd *mb)
         * following commands are accepted only after
         * revision check has been passed.
         */
-       if (!mbx_revision < 0) {
+       if (!mbox_revision < 0) {
                printk(KERN_INFO
-                      "mbx: DSPCFG command received, "
+                      "mbox: DSPCFG command received, "
                       "but revision check has not been passed.\n");
                return;
        }
 
-       if (!waitqueue_active(&ioctl_wait_q) ||
-           (ioctl_wait_cmd != MBCMD(DSPCFG))) {
-               printk(KERN_WARNING
-                      "mbx: DSPCFG command received, "
-                      "but nobody is waiting for it...\n");
-               return;
-       }
-
        switch (cfgcmd) {
-       case OMAP_DSP_MBCMD_DSPCFG_SYSADRH:
-               tmp_ipb_adr = (unsigned long)mb->data << 16;
+       case DSPCFG_SYSADRH:
+               tmp_ipb_adr = (u32)mb->data << 16;
                break;
 
-       case OMAP_DSP_MBCMD_DSPCFG_SYSADRL:
+       case DSPCFG_SYSADRL:
                tmp_ipb_adr |= mb->data;
                break;
 
-       case OMAP_DSP_MBCMD_DSPCFG_ABORT:
+       case DSPCFG_ABORT:
                goto abort1;
 
        default:
                printk(KERN_ERR
-                      "mbx: Unknown CFG command: cmd_l=0x%02x, data=0x%04x\n",
+                      "mbox: Unknown CFG command: cmd_l=0x%02x, data=0x%04x\n",
                       mb->cmd_l, mb->data);
                return;
        }
 
        if (last) {
                void *badr;
-               unsigned short bln;
-               unsigned short bsz;
-               volatile unsigned short *buf;
+               u16 bln;
+               u16 bsz;
+               volatile u16 *buf;
                void *ipb_sys_da, *ipb_sys_ad;
-               void *mbseq;
+               void *mbseq;     /* FIXME: 3.4 obsolete */
                short *dbg_buf;
-               unsigned short dbg_buf_sz, dbg_line_sz;
+               u16 dbg_buf_sz, dbg_line_sz;
                struct mem_sync_struct mem_sync, *mem_syncp;
 
                ipb_sys_da = dspword_to_virt(tmp_ipb_adr);
                if (ipbuf_sys_config(ipb_sys_da, DIR_D2A) < 0)
                        goto abort1;
 
-               if (sync_with_dsp(&ipbuf_sys_da->s, OMAP_DSP_TID_ANON, 10) < 0) {
-                       printk(KERN_ERR "mbx: DSPCFG - IPBUF sync failed!\n");
+               if (dsp_mem_enable(ipbuf_sys_da) < 0) {
+                       printk(KERN_ERR "mbox: DSPCFG - ipbuf_sys_da read failed!\n");
+                       goto abort1;
+               }
+               if (sync_with_dsp(&ipbuf_sys_da->s, TID_ANON, 10) < 0) {
+                       printk(KERN_ERR "mbox: DSPCFG - IPBUF sync failed!\n");
+                       dsp_mem_disable(ipbuf_sys_da);
                        goto abort1;
                }
                /*
@@ -689,7 +801,7 @@ void mbx1_dspcfg(struct mbcmd *mb)
                 * we must read with 16bit-access
                 */
 #ifdef OLD_BINARY_SUPPORT
-               if (mbx_revision == OMAP_DSP_MBPROT_REVISION) {
+               if (mbox_revision == MBPROT_REVISION) {
 #endif
                        buf = ipbuf_sys_da->d;
                        n_stask        = buf[0];
@@ -707,7 +819,7 @@ void mbx1_dspcfg(struct mbcmd *mb)
                        mem_sync.SDRAM = MKVIRT(buf[19], buf[20]);
                        mem_syncp = &mem_sync;
 #ifdef OLD_BINARY_SUPPORT
-               } else if (mbx_revision == MBREV_3_2) {
+               } else if (mbox_revision == MBREV_3_2) {
                        buf = ipbuf_sys_da->d;
                        n_stask     = buf[0];
                        bln         = buf[1];
@@ -720,7 +832,7 @@ void mbx1_dspcfg(struct mbcmd *mb)
                        dbg_buf_sz  = 0;
                        dbg_line_sz = 0;
                        mem_syncp   = NULL;
-               } else if (mbx_revision == MBREV_3_0) {
+               } else if (mbox_revision == MBREV_3_0) {
                        buf = ipbuf_sys_da->d;
                        n_stask     = buf[0];
                        bln         = buf[1];
@@ -734,11 +846,14 @@ void mbx1_dspcfg(struct mbcmd *mb)
                        dbg_buf_sz  = 0;
                        dbg_line_sz = 0;
                        mem_syncp   = NULL;
-               } else /* should not occur */
+               } else { /* should not occur */
+                       dsp_mem_disable(ipbuf_sys_da);
                        goto abort1;
+               }
 #endif /* OLD_BINARY_SUPPORT */
 
                release_ipbuf_pvt(ipbuf_sys_da);
+               dsp_mem_disable(ipbuf_sys_da);
 
                /*
                 * following configurations need to be done before
@@ -748,107 +863,76 @@ void mbx1_dspcfg(struct mbcmd *mb)
                        goto abort1;
                if (ipbuf_config(bln, bsz, badr) < 0)
                        goto abort1;
-               if (dsp_mb_config(mbseq) < 0)
+               if (dsp_mbox_config(mbseq) < 0)
                        goto abort2;
                if (dsp_dbg_config(dbg_buf, dbg_buf_sz, dbg_line_sz) < 0)
                        goto abort2;
                if (dsp_mem_sync_config(mem_syncp) < 0)
                        goto abort2;
 
-               ioctl_wait_cmd = 0;
-               wake_up_interruptible(&ioctl_wait_q);
+               misc_mb_wait.cmd_h = 0;
+               wake_up_interruptible(&misc_mb_wait.wait_q);
        }
        return;
 
 abort2:
        ipbuf_stop();
 abort1:
-       wake_up_interruptible(&ioctl_wait_q);
+       wake_up_interruptible(&misc_mb_wait.wait_q);
        return;
 }
 
-void mbx1_poll(struct mbcmd *mb)
+void mbox_poll(struct mbcmd *mb)
 {
-       if (!waitqueue_active(&ioctl_wait_q) ||
-           (ioctl_wait_cmd != MBCMD(POLL))) {
-               printk(KERN_WARNING
-                      "mbx: POLL command received, "
-                      "but nobody is waiting for it...\n");
-               return;
-       }
-
-       ioctl_wait_cmd = 0;
-       wake_up_interruptible(&ioctl_wait_q);
+       misc_mbcmd_response(mb, 0, 0);
 }
 
-void mbx1_regrw(struct mbcmd *mb)
+void mbox_regrw(struct mbcmd *mb)
 {
-       if (!waitqueue_active(&ioctl_wait_q) ||
-           (ioctl_wait_cmd != MBCMD(REGRW))) {
-               printk(KERN_WARNING
-                      "mbx: REGRW command received, "
-                      "but nobody is waiting for it...\n");
-               return;
-       }
-
        switch (mb->cmd_l) {
-       case OMAP_DSP_MBCMD_REGRW_DATA:
-               ioctl_wait_cmd = 0;
-               varread_val[0] = mb->data;
-               wake_up_interruptible(&ioctl_wait_q);
-               return;
-
+       case REGRW_DATA:
+               misc_mbcmd_response(mb, 1, 0);
+               break;
        default:
                printk(KERN_ERR
-                      "mbx: Illegal REGRW command: "
+                      "mbox: Illegal REGRW command: "
                       "cmd_l=0x%02x, data=0x%04x\n", mb->cmd_l, mb->data);
                return;
        }
 }
 
-void mbx1_getvar(struct mbcmd *mb)
+void mbox_getvar(struct mbcmd *mb)
 {
-       unsigned char varid = mb->cmd_l;
-       int i;
-       volatile unsigned short *buf;
-
-       if (!waitqueue_active(&ioctl_wait_q) ||
-           (ioctl_wait_cmd != MBCMD(GETVAR))) {
-               printk(KERN_WARNING
-                      "mbx: GETVAR command received, "
-                      "but nobody is waiting for it...\n");
-               return;
-       }
-
-       ioctl_wait_cmd = 0;
-       switch (varid) {
-       case OMAP_DSP_MBCMD_VARID_ICRMASK:
-               varread_val[0] = mb->data;
+       switch (mb->cmd_l) {
+       case VARID_ICRMASK:
+               misc_mbcmd_response(mb, 1, 1);
                break;
-       case OMAP_DSP_MBCMD_VARID_LOADINFO:
-               {
-                       if (sync_with_dsp(&ipbuf_sys_da->s, OMAP_DSP_TID_ANON, 10) < 0) {
-                               printk(KERN_ERR
-                                      "mbx: GETVAR - IPBUF sync failed!\n");
-                               return;
-                       }
-                       /* need word access. do not use memcpy. */
-                       buf = ipbuf_sys_da->d;
-                       for (i = 0; i < 5; i++) {
-                               varread_val[i] = buf[i];
-                       }
-                       release_ipbuf_pvt(ipbuf_sys_da);
-                       break;
-               }
+       case VARID_LOADINFO:
+               misc_mbcmd_response(mb, 5, 1);
+               break;
+       default:
+               printk(KERN_ERR
+                      "mbox: Illegal GETVAR command: "
+                      "cmd_l=0x%02x, data=0x%04x\n", mb->cmd_l, mb->data);
+               return;
        }
-       wake_up_interruptible(&ioctl_wait_q);
+}
 
-       return;
+void mbox_fbctl_disable(struct mbcmd *mb)
+{
+       misc_mbcmd_response(mb, 0, 0);
 }
 
+struct file_operations dsp_ctl_fops = {
+       .owner   = THIS_MODULE,
+       .ioctl   = dsp_ctl_ioctl,
+};
+
 /*
  * sysfs files
  */
+
+/* ifver */
 static ssize_t ifver_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
 {
@@ -860,9 +944,9 @@ static ssize_t ifver_show(struct device *dev, struct device_attribute *attr,
         * 3.2: sysfs / udev support
         *      KMEM_RESERVE / KMEM_RELEASE ioctls for mem device
         * 3.3: added following ioctls
-        *      OMAP_DSP_IOCTL_GBL_IDLE
-        *      OMAP_DSP_IOCTL_CPU_IDLE (instead of OMAP_DSP_IOCTL_IDLE)
-        *      OMAP_DSP_IOCTL_POLL
+        *      DSPCTL_IOCTL_GBL_IDLE
+        *      DSPCTL_IOCTL_CPU_IDLE (instead of DSPCTL_IOCTL_IDLE)
+        *      DSPCTL_IOCTL_POLL
         */
 
        /*
@@ -877,16 +961,23 @@ static ssize_t ifver_show(struct device *dev, struct device_attribute *attr,
        return len;
 }
 
-static struct device_attribute dev_attr_ifver = __ATTR_RO(ifver);
+/* cpustat */
+static char *cpustat_name[CPUSTAT_MAX] = {
+       [CPUSTAT_RESET]    = "reset",
+#ifdef CONFIG_ARCH_OMAP1
+       [CPUSTAT_GBL_IDLE] = "gbl_idle",
+       [CPUSTAT_CPU_IDLE] = "cpu_idle",
+#endif
+       [CPUSTAT_RUN]      = "run",
+};
 
 static ssize_t cpustat_show(struct device *dev, struct device_attribute *attr,
                            char *buf)
 {
-       return sprintf(buf, "%s\n", cpustat_name(dsp_cpustat_get_stat()));
+       return sprintf(buf, "%s\n", cpustat_name[dsp_cpustat_get_stat()]);
 }
 
-static struct device_attribute dev_attr_cpustat = __ATTR_RO(cpustat);
-
+/* icrmask */
 static ssize_t icrmask_show(struct device *dev, struct device_attribute *attr,
                            char *buf)
 {
@@ -896,38 +987,43 @@ static ssize_t icrmask_show(struct device *dev, struct device_attribute *attr,
 static ssize_t icrmask_store(struct device *dev, struct device_attribute *attr,
                             const char *buf, size_t count)
 {
-       unsigned short mask;
+       u16 mask;
        int ret;
 
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
        mask = simple_strtol(buf, NULL, 16);
        dsp_cpustat_set_icrmask(mask);
 
-       if (dsp_is_ready()) {
-               ret = dsp_setvar(OMAP_DSP_MBCMD_VARID_ICRMASK, mask);
+       if (dsp_cfgstat_get_stat() == CFGSTAT_READY) {
+               ret = dsp_setvar(VARID_ICRMASK, mask);
                if (ret < 0)
                        return ret;
        }
 
-       return strlen(buf);
+       return count;
 }
 
-static struct device_attribute dev_attr_icrmask = 
-       __ATTR(icrmask, S_IWUSR | S_IRUGO, icrmask_show, icrmask_store);
-
+/* loadinfo */
 static ssize_t loadinfo_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
 {
        int len;
        int ret;
-       static unsigned short val[5];
+       u16 val[5];
 
-       if ((ret = dsp_getvar(OMAP_DSP_MBCMD_VARID_LOADINFO, val, 5)) < 0)
+       if ((ret = dsp_getvar(VARID_LOADINFO, val)) < 0)
                return ret;
 
-       /* load info value range is 0(free) - 10000(busy) */
+       /*
+        * load info value range is 0(free) - 10000(busy):
+        * if CPU load is not measured on DSP, it sets 0xffff at val[0].
+        */
+
+       if (val[0] == 0xffff) {
+               len = sprintf(buf,
+                             "currently DSP load info is not available.\n");
+               goto out;
+       }
+
        len = sprintf(buf,
                      "DSP load info:\n"
                      "  10ms average = %3d.%02d%%\n"
@@ -936,72 +1032,15 @@ static ssize_t loadinfo_show(struct device *dev, struct device_attribute *attr,
                      val[0]/100, val[0]%100,
                      val[1]/100, val[1]%100, val[2]/100, val[2]%100,
                      val[3]/100, val[3]%100, val[4]/100, val[4]%100);
+out:
        return len;
 }
 
-/*
- * This is declared at the top of this file.
- *
- * static struct device_attribute dev_attr_loadinfo = __ATTR_RO(loadinfo);
- */
-
-void mbx1_fbctl_disable(void)
-{
-       if (!waitqueue_active(&ioctl_wait_q) ||
-           (ioctl_wait_cmd != MBCMD(KFUNC))) {
-               printk(KERN_WARNING
-                      "mbx: KFUNC:FBCTL command received, "
-                      "but nobody is waiting for it...\n");
-               return;
-       }
-       ioctl_wait_cmd = 0;
-       wake_up_interruptible(&ioctl_wait_q);
-}
-
-#ifdef CONFIG_PROC_FS
-/* for backward compatibility */
-static int version_read_proc(char *page, char **start, off_t off, int count,
-                            int *eof, void *data)
-{
-       /*
-        * This entry is read by 3.1 tools only, so leave it as is.
-        * 3.2 and later will read from sysfs file.
-        */
-       return sprintf(page, "3.1\n");
-}
-
-static void __init dsp_ctl_create_proc(void)
-{
-       struct proc_dir_entry *ent;
-
-       /* version */
-       ent = create_proc_read_entry("version", 0, procdir_dsp,
-                                    version_read_proc, NULL);
-       if (ent == NULL) {
-               printk(KERN_ERR
-                      "omapdsp: failed to register proc device: version\n");
-       }
-}
-
-static void dsp_ctl_remove_proc(void)
-{
-       remove_proc_entry("version", procdir_dsp);
-}
-#endif /* CONFIG_PROC_FS */
-
-struct file_operations dsp_ctl_fops = {
-       .owner   = THIS_MODULE,
-       .ioctl   = dsp_ctl_ioctl,
-};
-
 void __init dsp_ctl_init(void)
 {
        device_create_file(&dsp_device.dev, &dev_attr_ifver);
        device_create_file(&dsp_device.dev, &dev_attr_cpustat);
        device_create_file(&dsp_device.dev, &dev_attr_icrmask);
-#ifdef CONFIG_PROC_FS
-       dsp_ctl_create_proc();
-#endif
 }
 
 void dsp_ctl_exit(void)
@@ -1009,7 +1048,4 @@ void dsp_ctl_exit(void)
        device_remove_file(&dsp_device.dev, &dev_attr_ifver);
        device_remove_file(&dsp_device.dev, &dev_attr_cpustat);
        device_remove_file(&dsp_device.dev, &dev_attr_icrmask);
-#ifdef CONFIG_PROC_FS
-       dsp_ctl_remove_proc();
-#endif
 }