]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM:OMAP: Integrated blk request queues for mbox fwk
authorHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Fri, 9 Mar 2007 17:20:31 +0000 (22:50 +0530)
committerTony Lindgren <tony@atomide.com>
Tue, 20 Mar 2007 18:11:53 +0000 (14:11 -0400)
- Taken from maemo.org N800 kernel package.
- Use request queues
- move mbox initialization to late init.

Signed-off-by: Trilok Soni <soni.trilok@gmail.com>
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/plat-omap/dsp/dsp_common.h
arch/arm/plat-omap/dsp/dsp_core.c
arch/arm/plat-omap/dsp/dsp_mem.c
arch/arm/plat-omap/mailbox.c
arch/arm/plat-omap/mailbox.h
include/asm-arm/arch-omap/mailbox.h

index cad42995b0606d6be84cbe264e1979cfdcfb8900..d2ebb42abd3c30599e15f43dd2444839482a9840 100644 (file)
@@ -156,6 +156,31 @@ static inline void dsp_clk_autoidle(void)
 }
 #endif
 
+#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;
index 2da959b74cd5d3c4b17e7a23f41508595f578255..4002fc7ce3190c10b77c82f3fac3d537daaa946f 100644 (file)
@@ -516,14 +516,13 @@ int dsp_late_init(void)
 {
        int ret;
 
-       dsp_clk_autoidle();
+       /*dsp_clk_autoidle();*/
+       dsp_clk_enable();
 
-#ifdef CONFIG_ARCH_OMAP2
-       clk_enable(dsp_fck_handle);
-       clk_enable(dsp_ick_handle);
-       __dsp_per_enable();
-#endif
        dsp_mem_late_init();
+       ret = dsp_mbox_init();
+       if (ret)
+               goto fail_mbox;
 
 #ifdef CONFIG_ARCH_OMAP1
        dsp_set_idle_boot_base(IDLEPG_BASE, IDLEPG_SIZE);
@@ -531,9 +530,17 @@ int dsp_late_init(void)
        ret = dsp_kfunc_enable_devices(omap_dsp,
                                       DSP_KFUNC_DEV_TYPE_COMMON, 0);
        if (ret == 0)
-               omap_dsp->enabled = 0;
+               goto fail_kfunc;
+
+       omap_dsp->enabled = 1;
 
        return 0;
+
+fail_kfunc:
+       dsp_mbox_exit();
+fail_mbox:
+       dsp_clk_disable();
+       return ret;
 }
 
 extern int  dsp_ctl_core_init(void);
@@ -590,13 +597,9 @@ static int __init dsp_drv_probe(struct platform_device *pdev)
        mblog_init();
        if ((ret = dsp_taskmod_init()) < 0)
                goto fail4;
-       if ((ret = dsp_mbox_init()) < 0)
-               goto fail5;
 
        return 0;
 
- fail5:
-       dsp_taskmod_exit();
  fail4:
        mblog_exit();
        dsp_ctl_exit();
index f994e99f0c7ba7ceab95b8feee8a42714b1ec728..bae65f729cf54debdaec58a913aebf6608c6b775 100644 (file)
@@ -330,7 +330,7 @@ void mbox_fbctl_upd(void) { }
 static ssize_t dsp_mem_read(struct file *file, char __user *buf, size_t count,
                            loff_t *ppos)
 {
-       return __omap_mmu_mem_read(&dsp_mmu, buf, *ppos, count);
+       return __omap_mmu_mem_read(&dsp_mmu, (char __user *)buf, *ppos, count);
 }
 
 static ssize_t dsp_mem_write(struct file *file, const char __user *buf,
index c194c328bdd6c5c549b9725cfa45764a1d9dedec..416e05694e38baa1338a39e98159bac17cc3aff1 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
+#include <linux/blkdev.h>
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <asm/io.h>
 static struct omap_mbox *mboxes;
 static DEFINE_RWLOCK(mboxes_lock);
 
-static struct omap_mbox **find_mboxes(const char *name)
-{
-       struct omap_mbox **p;
-
-       for (p = &mboxes; *p; p = &(*p)->next) {
-               if (strcmp((*p)->name, name) == 0)
-                       break;
-       }
-
-       return p;
-}
-
-struct omap_mbox *omap_mbox_get(const char *name)
-{
-       struct omap_mbox *mbox;
-
-       read_lock(&mboxes_lock);
-       mbox = *(find_mboxes(name));
-       read_unlock(&mboxes_lock);
-
-       return mbox;
-}
-EXPORT_SYMBOL(omap_mbox_get);
-
 /* Mailbox Sequence Bit function */
 void omap_mbox_init_seq(struct omap_mbox *mbox)
 {
@@ -70,27 +47,18 @@ EXPORT_SYMBOL(omap_mbox_init_seq);
 /*
  * message sender
  */
-int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
+static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void *arg)
 {
-       int ret;
-       int i = 1000;
-       static DEFINE_MUTEX(msg_send_lock);
+       int ret = 0, i = 1000;
 
        while (mbox_fifo_full(mbox)) {
-               if (mbox->ops->type == OMAP_MBOX_TYPE2) {
-                       enable_mbox_irq(mbox, IRQ_TX);
-                       wait_event_interruptible(mbox->tx_waitq,
-                                                !mbox_fifo_full(mbox));
-               } else
-                       udelay(1);
-
+               if (mbox->ops->type == OMAP_MBOX_TYPE2)
+                       return -1;
                if (--i == 0)
                        return -1;
+               udelay(1);
        }
 
-
-       mutex_lock(&msg_send_lock);
-
        if (mbox->msg_sender_cb && arg) {
                ret = mbox->msg_sender_cb(arg);
                if (ret)
@@ -100,9 +68,24 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
        mbox_seq_toggle(mbox, &msg);
        mbox_fifo_write(mbox, msg);
  out:
-       mutex_unlock(&msg_send_lock);
+       return ret;
+}
 
-       return 0;
+int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg)
+{
+       struct request *rq;
+       int ret = 0;
+
+       rq = blk_get_request(mbox->txq, WRITE, GFP_ATOMIC);
+       if (unlikely(!rq)) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       rq->data = (void *)msg;
+       blk_insert_request(mbox->txq, rq, 0, arg);
+ fail:
+       return ret;
 }
 EXPORT_SYMBOL(omap_mbox_msg_send);
 
@@ -112,25 +95,27 @@ EXPORT_SYMBOL(omap_mbox_msg_send);
 static void mbox_msg_receiver(struct work_struct *work)
 {
        struct omap_mbox *mbox =
-               container_of(work, struct omap_mbox, msg_receive);
-       struct omap_mbq *mbq = mbox->mbq;
+           container_of(work, struct omap_mbox, msg_receive);
+       struct request_queue *q = mbox->rxq;
+       struct request *rq;
        mbox_msg_t msg;
-       int was_full;
 
-       while (!mbq_empty(mbq)) {
-               was_full = mbq_full(mbq);
-               msg = mbq_get(mbq);
-               if (was_full)   /* now we have a room in the mbq. */
-                       enable_mbox_irq(mbox, IRQ_RX);
+       if (mbox->msg_receive_cb == NULL) {
+               sysfs_notify(&mbox->dev.kobj, NULL, "mbox");
+               return;
+       }
 
-               if (unlikely(mbox_seq_test(mbox, msg))) {
-                       printk(KERN_ERR
-                              "mbox: illegal seq bit! ignoring this command. "
-                              "(%08x)\n", msg);
-                       continue;
-               }
+       while (1) {
+               rq = elv_next_request(q);
+               if (!rq)
+                       break;
+
+               msg = (mbox_msg_t)rq->data;
+
+               blkdev_dequeue_request(rq);
+               end_that_request_last(rq, 0);
 
-               if (likely(mbox->msg_receive_cb))
+               if (mbox->msg_receive_cb)
                        mbox->msg_receive_cb(msg);
        }
 }
@@ -138,39 +123,70 @@ static void mbox_msg_receiver(struct work_struct *work)
 /*
  * Mailbox interrupt handler
  */
-static irqreturn_t mbox_interrupt(int irq, void *p)
+static void mbox_txq_fn(request_queue_t *q)
 {
-       mbox_msg_t msg;
-       struct omap_mbox *mbox = (struct omap_mbox *)p;
+       struct omap_mbox *mbox = q->queuedata;
+       int ret;
+       struct request *rq;
 
-       if (is_mbox_irq(mbox, IRQ_TX)) {
-               disable_mbox_irq(mbox, IRQ_TX);
-               /*
-                * NOTE: this doesn't seeem to work as explained in the manual.
-                * IRQSTATUS:NOTFULL can't be cleared even we write 1 to that bit.
-                * It is always set when it's not full, regardless of IRQENABLE setting.
-                */
-               ack_mbox_irq(mbox, IRQ_TX);
-               wake_up_interruptible_all(&mbox->tx_waitq);
+       while ((rq = elv_next_request(q)) != NULL) {
+               ret = __mbox_msg_send(mbox, (mbox_msg_t)rq->data, rq->special);
+               if (ret) {
+                       blk_stop_queue(q);
+                       enable_mbox_irq(mbox, IRQ_TX);
+                       return;
+               }
+               blkdev_dequeue_request(rq);
+               end_that_request_last(rq, 0);
        }
+}
 
-       if (!is_mbox_irq(mbox, IRQ_RX))
-               return IRQ_HANDLED;
+static void mbox_rxq_fn(request_queue_t *q)
+{
+       struct request *rq;
+       struct omap_mbox *mbox = q->queuedata;
+       mbox_msg_t msg;
 
        while (!mbox_fifo_empty(mbox)) {
+               rq = blk_get_request(q, WRITE, GFP_ATOMIC);
+               if (unlikely(!rq))
+                       goto nomem;
+
                msg = mbox_fifo_read(mbox);
-               if (mbq_add(mbox->mbq, msg)) {  /* mbq full */
-                       disable_mbox_irq(mbox, IRQ_RX);
-                       goto flush_queue;
+               rq->data = (void *)msg;
+
+               if (unlikely(mbox_seq_test(mbox, msg))) {
+                       pr_info("mbox: Illegal seq bit!(%08x)\n", msg);
+                       if (mbox->err_notify)
+                               mbox->err_notify();
                }
+
+               blk_insert_request(mbox->rxq, rq, 0, NULL);
                if (mbox->ops->type == OMAP_MBOX_TYPE1)
                        break;
        }
 
        /* no more messages in the fifo. clear IRQ source. */
        ack_mbox_irq(mbox, IRQ_RX);
- flush_queue:
-       schedule_work(&mbox->msg_receive);
+       enable_mbox_irq(mbox, IRQ_RX);
+ nomem:
+       queue_work(mbox->workq, &mbox->msg_receive);
+}
+
+static irqreturn_t mbox_interrupt(int irq, void *p)
+{
+       struct omap_mbox *mbox = (struct omap_mbox *)p;
+
+       if (is_mbox_irq(mbox, IRQ_TX)) {
+               disable_mbox_irq(mbox, IRQ_TX);
+               ack_mbox_irq(mbox, IRQ_TX);
+               blk_start_queue(mbox->txq);
+       }
+
+       if (is_mbox_irq(mbox, IRQ_RX)) {
+               disable_mbox_irq(mbox, IRQ_RX);
+               blk_start_queue(mbox->rxq);
+       }
 
        return IRQ_HANDLED;
 }
@@ -178,32 +194,51 @@ static irqreturn_t mbox_interrupt(int irq, void *p)
 /*
  * sysfs files
  */
-static ssize_t mbox_attr_write(struct device *dev,
-                              struct device_attribute *attr,
-                              const char *buf, size_t count)
+static ssize_t
+omap_mbox_write(struct device *dev, struct device_attribute *attr,
+               const char * buf, size_t count)
 {
        int ret;
-       mbox_msg_t msg;
+       mbox_msg_t *p = (mbox_msg_t *)buf;
        struct omap_mbox *mbox = dev_get_drvdata(dev);
 
-       msg = (mbox_msg_t) simple_strtoul(buf, NULL, 16);
-
-       ret = omap_mbox_msg_send(mbox, msg, NULL);
-       if (ret)
-               return -1;
+       for (; count >= sizeof(mbox_msg_t); count -= sizeof(mbox_msg_t)) {
+               ret = omap_mbox_msg_send(mbox, be32_to_cpu(*p), NULL);
+               if (ret)
+                       return -EAGAIN;
+               p++;
+       }
 
-       return count;
+       return  (size_t)((char *)p - buf);
 }
 
-static ssize_t mbox_attr_read(struct device *dev, struct device_attribute *attr,
-                             char *buf)
+static ssize_t
+omap_mbox_read(struct device *dev, struct device_attribute *attr,
+              char * buf)
 {
+       struct request *rq;
+       mbox_msg_t *p = (mbox_msg_t *)buf;
        struct omap_mbox *mbox = dev_get_drvdata(dev);
+       struct request_queue *q = mbox->rxq;
+
+       while ((rq = elv_next_request(q)) != NULL) {
+               *p = (mbox_msg_t)rq->data;
+               blkdev_dequeue_request(rq);
+               end_that_request_last(rq, 0);
+
+               if (unlikely(mbox_seq_test(mbox, *p))) {
+                       pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p);
+                       continue;
+               }
+               p++;
+       }
+
+       pr_debug("%02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
 
-       return sprintf(buf, mbox->name);
+       return (size_t)((char *)p - buf);
 }
 
-static DEVICE_ATTR(mbox, S_IALLUGO, mbox_attr_read, mbox_attr_write);
+static DEVICE_ATTR(mbox, S_IRUGO | S_IWUSR, omap_mbox_read, omap_mbox_write);
 
 static ssize_t mbox_show(struct class *class, char *buf)
 {
@@ -213,12 +248,13 @@ static ssize_t mbox_show(struct class *class, char *buf)
 static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL);
 
 static struct class omap_mbox_class = {
-       .name = "mbox",
+       .name = "omap_mbox",
 };
 
 static int omap_mbox_init(struct omap_mbox *mbox)
 {
        int ret;
+       request_queue_t *q;
 
        if (likely(mbox->ops->startup)) {
                ret = mbox->ops->startup(mbox);
@@ -232,58 +268,117 @@ static int omap_mbox_init(struct omap_mbox *mbox)
 
        ret = device_register(&mbox->dev);
        if (unlikely(ret))
-               return ret;
+               goto fail_device_reg;
 
        ret = device_create_file(&mbox->dev, &dev_attr_mbox);
        if (unlikely(ret)) {
                printk(KERN_ERR
                       "device_create_file failed: %d\n", ret);
-               goto fail1;
+               goto fail_create_mbox;
        }
 
        spin_lock_init(&mbox->lock);
        INIT_WORK(&mbox->msg_receive, mbox_msg_receiver);
-       init_waitqueue_head(&mbox->tx_waitq);
-
-       ret = mbq_init(&mbox->mbq);
-       if (unlikely(ret))
-               goto fail2;
 
        ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
                          mbox->name, mbox);
        if (unlikely(ret)) {
                printk(KERN_ERR
                       "failed to register mailbox interrupt:%d\n", ret);
-               goto fail3;
+               goto fail_request_irq;
        }
-       disable_mbox_irq(mbox, IRQ_RX);
        enable_mbox_irq(mbox, IRQ_RX);
 
+       q = blk_init_queue(mbox_txq_fn, &mbox->lock);
+       if (!q)
+               goto fail_blkinit_txq;
+       mbox->txq = q;
+       q->queuedata = mbox;
+
+       q = blk_init_queue(mbox_rxq_fn, &mbox->lock);
+       if (!q)
+               goto fail_blkinit_rxq;
+       mbox->rxq = q;
+       q->queuedata = mbox;
+
        return 0;
 
- fail3:
-       kfree(mbox->mbq);
- fail2:
-       class_remove_file(&omap_mbox_class, &class_attr_mbox);
- fail1:
-       class_unregister(&omap_mbox_class);
+ fail_blkinit_rxq:
+       blk_cleanup_queue(mbox->txq);
+ fail_blkinit_txq:
+       free_irq(mbox->irq, mbox);
+ fail_request_irq:
+       device_remove_file(&mbox->dev, &dev_attr_mbox);
+ fail_create_mbox:
+       device_unregister(&mbox->dev);
+ fail_device_reg:
        if (unlikely(mbox->ops->shutdown))
                mbox->ops->shutdown(mbox);
 
        return ret;
 }
 
-static void omap_mbox_shutdown(struct omap_mbox *mbox)
+static void omap_mbox_fini(struct omap_mbox *mbox)
 {
+       blk_cleanup_queue(mbox->txq);
+       blk_cleanup_queue(mbox->rxq);
+
+       flush_workqueue(mbox->workq);
+       destroy_workqueue(mbox->workq);
+
        free_irq(mbox->irq, mbox);
-       kfree(mbox->mbq);
-       class_remove_file(&omap_mbox_class, &class_attr_mbox);
+       device_remove_file(&mbox->dev, &dev_attr_mbox);
        class_unregister(&omap_mbox_class);
 
        if (unlikely(mbox->ops->shutdown))
                mbox->ops->shutdown(mbox);
 }
 
+static struct omap_mbox **find_mboxes(const char *name)
+{
+       struct omap_mbox **p;
+
+       for (p = &mboxes; *p; p = &(*p)->next) {
+               if (strcmp((*p)->name, name) == 0)
+                       break;
+       }
+
+       return p;
+}
+
+struct omap_mbox *omap_mbox_get(const char *name)
+{
+       struct omap_mbox *mbox;
+       char queue_name[MBOX_NAME_LEN];
+       int ret;
+
+       read_lock(&mboxes_lock);
+       mbox = *(find_mboxes(name));
+       if (mbox == NULL) {
+               read_unlock(&mboxes_lock);
+               return ERR_PTR(-ENOENT);
+       }
+
+       strcpy(queue_name, "mailbox/");
+       strcat(queue_name, mbox->name);
+       mbox->workq = create_singlethread_workqueue(queue_name);
+
+       read_unlock(&mboxes_lock);
+
+       ret = omap_mbox_init(mbox);
+       if (ret)
+               return ERR_PTR(-ENODEV);
+
+       return mbox;
+}
+EXPORT_SYMBOL(omap_mbox_get);
+
+void omap_mbox_put(struct omap_mbox *mbox)
+{
+       omap_mbox_fini(mbox);
+}
+EXPORT_SYMBOL(omap_mbox_put);
+
 int omap_mbox_register(struct omap_mbox *mbox)
 {
        int ret = 0;
@@ -294,10 +389,6 @@ int omap_mbox_register(struct omap_mbox *mbox)
        if (mbox->next)
                return -EBUSY;
 
-       ret = omap_mbox_init(mbox);
-       if (ret)
-               return ret;
-
        write_lock(&mboxes_lock);
        tmp = find_mboxes(mbox->name);
        if (*tmp)
@@ -321,9 +412,6 @@ int omap_mbox_unregister(struct omap_mbox *mbox)
                        *tmp = mbox->next;
                        mbox->next = NULL;
                        write_unlock(&mboxes_lock);
-
-                       omap_mbox_shutdown(mbox);
-
                        return 0;
                }
                tmp = &(*tmp)->next;
index c3f8f2c56b4f15c17412014be824ee6f27724221..9b6027135dead90885c7d1a6c70639fc5bf4d669 100644 (file)
 #ifndef __ARCH_ARM_PLAT_MAILBOX_H
 #define __ARCH_ARM_PLAT_MAILBOX_H
 
-/*
- * Mailbox queue handling API
- */
-
-#define MBQ_DEPTH      16
-struct omap_mbq {
-       rwlock_t lock;
-       mbox_msg_t msg[MBQ_DEPTH];
-       mbox_msg_t *rp, *wp;
-       int cnt;
-};
-
-static inline int mbq_init(struct omap_mbq **addr)
-{
-       struct omap_mbq *m = kmalloc(sizeof(struct omap_mbq), GFP_KERNEL);
-       if (!m)
-               return -ENOMEM;
-
-       rwlock_init(&m->lock);
-
-       write_lock_irq(&m->lock);
-       m->rp = m->wp = &m->msg[0];
-       m->cnt = 0;
-       write_unlock_irq(&m->lock);
-
-       *addr = m;
-
-       return 0;
-}
-
-static inline int mbq_empty(struct omap_mbq *mbq)
-{
-       int ret;
-
-       read_lock_irq(&mbq->lock);
-       ret = (mbq->cnt == 0);
-       read_unlock_irq(&mbq->lock);
-
-       return ret;
-}
-
-static inline int mbq_full(struct omap_mbq *mbq)
-{
-       int ret;
-
-       read_lock_irq(&mbq->lock);
-       ret = (mbq->cnt == MBQ_DEPTH);
-       read_unlock_irq(&mbq->lock);
-
-       return ret;
-}
-
-static inline int mbq_add(struct omap_mbq *mbq, mbox_msg_t msg)
-{
-       int ret = 0;
-
-       write_lock_irq(&mbq->lock);
-
-       *mbq->wp = msg;
-       if (++mbq->wp == &mbq->msg[MBQ_DEPTH])
-               mbq->wp = &mbq->msg[0];
-
-       if (++mbq->cnt == MBQ_DEPTH)    /* full */
-               ret = -1;
-
-       write_unlock_irq(&mbq->lock);
-
-       return ret;
-}
-
-static inline mbox_msg_t mbq_get(struct omap_mbq *mbq)
-{
-       mbox_msg_t msg;
-
-       write_lock_irq(&mbq->lock);
-
-       msg = *mbq->rp;
-
-       if (++mbq->rp == &mbq->msg[MBQ_DEPTH])
-               mbq->rp = &mbq->msg[0];
-       mbq->cnt--;
-
-       write_unlock_irq(&mbq->lock);
-
-       return msg;
-}
-
-static inline void mbq_exit(struct omap_mbq **addr)
-{
-       if (*addr)
-               kfree(*addr);
-}
+#define MBOX_NAME_LEN 255
 
 /*
  * Mailbox sequence bit API
index 87395ea58b2d5db22bbfd6fe6183b7e8fd8e0b12..8d12ced432b39f511d05d7f454ce0e47fb2ba9ef 100644 (file)
@@ -5,11 +5,11 @@
 
 #include <linux/wait.h>
 #include <linux/workqueue.h>
+#include <linux/blkdev.h>
 
 typedef u32 mbox_msg_t;
 typedef void (mbox_receiver_t)(mbox_msg_t msg);
 struct omap_mbox;
-struct omap_mbq;
 
 typedef int __bitwise omap_mbox_irq_t;
 #define IRQ_TX ((__force omap_mbox_irq_t) 1)
@@ -21,48 +21,52 @@ typedef int __bitwise omap_mbox_type_t;
 
 struct omap_mbox_ops {
        omap_mbox_type_t        type;
-       int (*startup)(struct omap_mbox *mbox);
-       void (*shutdown)(struct omap_mbox *mbox);
+       int             (*startup)(struct omap_mbox *mbox);
+       void            (*shutdown)(struct omap_mbox *mbox);
        /* fifo */
-       mbox_msg_t (*fifo_read)(struct omap_mbox *mbox);
-       void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
-       int (*fifo_empty)(struct omap_mbox *mbox);
-       int (*fifo_full)(struct omap_mbox *mbox);
+       mbox_msg_t      (*fifo_read)(struct omap_mbox *mbox);
+       void            (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
+       int             (*fifo_empty)(struct omap_mbox *mbox);
+       int             (*fifo_full)(struct omap_mbox *mbox);
        /* irq */
-       void (*enable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-       void (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-       void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
-       int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+       void            (*enable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+       void            (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+       void            (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+       int             (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
 };
 
 struct omap_mbox {
-       char *name;
-       spinlock_t lock;
-       unsigned int irq;
-       struct omap_mbox_ops *ops;
+       char                    *name;
+       spinlock_t              lock;
+       unsigned int            irq;
 
-       wait_queue_head_t tx_waitq;
+       struct workqueue_struct *workq;
+       struct work_struct      msg_receive;
 
-       struct work_struct msg_receive;
-       void (*msg_receive_cb)(mbox_msg_t);
-       struct omap_mbq *mbq;
+       request_queue_t         *txq, *rxq;
 
-       int (*msg_sender_cb)(void*);
+       void    (*msg_receive_cb)(mbox_msg_t);
+       int     (*msg_sender_cb)(void*);
 
-       mbox_msg_t seq_snd, seq_rcv;
+       struct omap_mbox_ops    *ops;
 
-       struct device dev;
+       mbox_msg_t              seq_snd, seq_rcv;
 
-       void *priv;
+       struct device           dev;
 
-       struct omap_mbox *next;
+       struct omap_mbox        *next;
+       void                    *priv;
+
+       void                    (*err_notify)(void);
 };
 
-int omap_mbox_msg_send(struct omap_mbox *mbox_h, mbox_msg_t msg, void* arg);
-void omap_mbox_init_seq(struct omap_mbox *mbox);
+int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg, void *);
+void omap_mbox_init_seq(struct omap_mbox *);
+
+struct omap_mbox *omap_mbox_get(const char *);
+void omap_mbox_put(struct omap_mbox *);
 
-struct omap_mbox *omap_mbox_get(const char *name);
-int omap_mbox_register(struct omap_mbox *mbox);
-int omap_mbox_unregister(struct omap_mbox *mbox);
+int omap_mbox_register(struct omap_mbox *);
+int omap_mbox_unregister(struct omap_mbox *);
 
 #endif /* MAILBOX_H */