]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/plat-omap/dsp/ipbuf.c
ARM: OMAP: DSPGW: cleanup
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / ipbuf.c
index ebb482b05f04d467665952fa0eabbfba44170ee2..3262a14417228bf14e80f6057399228d82404d87 100644 (file)
@@ -1,57 +1,57 @@
 /*
- * linux/arch/arm/mach-omap/dsp/ipbuf.c
+ * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
  *
- * IPBUF handler
+ * 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/06:  DSP Gateway version 3.3
  */
 
-#include <linux/init.h>
 #include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
-#include <asm/signal.h>
-#include <asm/arch/dsp.h>
+#include <asm/arch/mailbox.h>
+#include "dsp_mbcmd.h"
 #include "dsp.h"
 #include "ipbuf.h"
 
-struct ipbuf **ipbuf;
+static struct ipbuf_head *g_ipbuf;
 struct ipbcfg ipbcfg;
 struct ipbuf_sys *ipbuf_sys_da, *ipbuf_sys_ad;
 static struct ipblink ipb_free = IPBLINK_INIT;
 static int ipbuf_sys_hold_mem_active;
 
+static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
+                         char *buf);
+static struct device_attribute dev_attr_ipbuf = __ATTR_RO(ipbuf);
+
 void ipbuf_stop(void)
 {
        int i;
 
+       device_remove_file(&dsp_device.dev, &dev_attr_ipbuf);
+
        spin_lock(&ipb_free.lock);
-       INIT_IPBLINK(&ipb_free);
+       RESET_IPBLINK(&ipb_free);
        spin_unlock(&ipb_free.lock);
 
        ipbcfg.ln = 0;
-       if (ipbuf) {
-               kfree(ipbuf);
-               ipbuf = NULL;
+       if (g_ipbuf) {
+               kfree(g_ipbuf);
+               g_ipbuf = NULL;
        }
        for (i = 0; i < ipbuf_sys_hold_mem_active; i++) {
                dsp_mem_disable((void *)daram_base);
@@ -59,9 +59,9 @@ void ipbuf_stop(void)
        ipbuf_sys_hold_mem_active = 0;
 }
 
-int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
+int ipbuf_config(u16 ln, u16 lsz, void *base)
 {
-       unsigned long lsz_byte = ((unsigned long)lsz) << 1;
+       size_t lsz_byte = ((size_t)lsz) << 1;
        size_t size;
        int ret = 0;
        int i;
@@ -79,8 +79,8 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
        if (dsp_address_validate(base, size, "global ipbuf") < 0)
                return -EINVAL;
 
-       ipbuf = kmalloc(sizeof(void *) * ln, GFP_KERNEL);
-       if (ipbuf == NULL) {
+       g_ipbuf = kmalloc(sizeof(struct ipbuf_head) * ln, GFP_KERNEL);
+       if (g_ipbuf == NULL) {
                printk(KERN_ERR
                       "omapdsp: memory allocation for ipbuf failed.\n");
                return -ENOMEM;
@@ -90,7 +90,8 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
 
                top = base + (sizeof(struct ipbuf) + lsz_byte) * i;
                btm = base + (sizeof(struct ipbuf) + lsz_byte) * (i+1) - 1;
-               ipbuf[i] = (struct ipbuf *)top;
+               g_ipbuf[i].p = (struct ipbuf *)top;
+               g_ipbuf[i].bid = i;
                if (((unsigned long)top & 0xfffe0000) !=
                    ((unsigned long)btm & 0xfffe0000)) {
                        /*
@@ -99,7 +100,7 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
                         */
                        printk(KERN_ERR
                               "omapdsp: ipbuf[%d] crosses 64k-word boundary!\n"
-                              "  @0x%p, size=0x%08lx\n", i, top, lsz_byte);
+                              "  @0x%p, size=0x%08x\n", i, top, lsz_byte);
                        ret = -EINVAL;
                        goto free_out;
                }
@@ -115,15 +116,17 @@ int ipbuf_config(unsigned short ln, unsigned short lsz, void *base)
               "           %d words * %d lines at 0x%p.\n",
               ipbcfg.lsz, ipbcfg.ln, ipbcfg.base);
 
+       device_create_file(&dsp_device.dev, &dev_attr_ipbuf);
+
        return ret;
 
 free_out:
-       kfree(ipbuf);
-       ipbuf = NULL;
+       kfree(g_ipbuf);
+       g_ipbuf = NULL;
        return ret;
 }
 
-int ipbuf_sys_config(void *p, enum arm_dsp_dir dir)
+int ipbuf_sys_config(void *p, enum arm_dsp_dir_e dir)
 {
        char *dir_str = (dir == DIR_D2A) ? "D2A" : "A2D";
 
@@ -154,11 +157,11 @@ int ipbuf_sys_config(void *p, enum arm_dsp_dir dir)
                ipbuf_sys_da = p;
        else
                ipbuf_sys_ad = p;
-       
+
        return 0;
 }
 
-int ipbuf_p_validate(void *p, enum arm_dsp_dir dir)
+int ipbuf_p_validate(void *p, enum arm_dsp_dir_e dir)
 {
        char *dir_str = (dir == DIR_D2A) ? "D2A" : "A2D";
 
@@ -175,57 +178,60 @@ int ipbuf_p_validate(void *p, enum arm_dsp_dir dir)
 /*
  * Global IPBUF operations
  */
-unsigned short get_free_ipbuf(unsigned char tid)
+struct ipbuf_head *bid_to_ipbuf(u16 bid)
 {
-       unsigned short bid;
+       return &g_ipbuf[bid];
+}
+
+struct ipbuf_head *get_free_ipbuf(u8 tid)
+{
+       struct ipbuf_head *ipb_h;
 
        if (dsp_mem_enable_ipbuf() < 0)
-               return OMAP_DSP_BID_NULL;
+               return NULL;
 
        spin_lock(&ipb_free.lock);
 
        if (ipblink_empty(&ipb_free)) {
                /* FIXME: wait on queue when not available.  */
-               bid = OMAP_DSP_BID_NULL;
+               ipb_h = NULL;
                goto out;
        }
-       bid = ipb_free.top;
-       ipbuf[bid]->la = tid;   /* lock */
-       ipblink_del_top(&ipb_free, ipbuf);
+       ipb_h = &g_ipbuf[ipb_free.top];
+       ipb_h->p->la = tid;     /* lock */
+       __ipblink_del_top(&ipb_free);
 out:
        spin_unlock(&ipb_free.lock);
        dsp_mem_disable_ipbuf();
 
-       return bid;
+       return ipb_h;
 }
 
-void release_ipbuf(unsigned short bid)
+void release_ipbuf(struct ipbuf_head *ipb_h)
 {
-       if (ipbuf[bid]->la == OMAP_DSP_TID_FREE) {
+       if (ipb_h->p->la == TID_FREE) {
                printk(KERN_WARNING
                       "omapdsp: attempt to release unlocked IPBUF[%d].\n",
-                      bid);
+                      ipb_h->bid);
                /*
                 * FIXME: re-calc bsycnt
                 */
                return;
        }
-       ipbuf[bid]->la = OMAP_DSP_TID_FREE;
-       ipbuf[bid]->sa = OMAP_DSP_TID_FREE;
-       spin_lock(&ipb_free.lock);
-       ipblink_add_tail(&ipb_free, bid, ipbuf);
-       spin_unlock(&ipb_free.lock);
+       ipb_h->p->la = TID_FREE;
+       ipb_h->p->sa = TID_FREE;
+       ipblink_add_tail(&ipb_free, ipb_h->bid);
 }
 
-static int try_yld(unsigned short bid)
+static int try_yld(struct ipbuf_head *ipb_h)
 {
        int status;
 
-       ipbuf[bid]->sa = OMAP_DSP_TID_ANON;
-       status = dsp_mbsend(MBCMD(BKYLD), 0, bid);
+       ipb_h->p->sa = TID_ANON;
+       status = mbcompose_send(BKYLD, 0, ipb_h->bid);
        if (status < 0) {
                /* DSP is busy and ARM keeps this line. */
-               release_ipbuf(bid);
+               release_ipbuf(ipb_h);
                return status;
        }
 
@@ -239,12 +245,11 @@ static int try_yld(unsigned short bid)
 static void do_balance_ipbuf(void)
 {
        while (ipbcfg.bsycnt <= ipbcfg.ln / 4) {
-               unsigned short bid;
+               struct ipbuf_head *ipb_h;
 
-               bid = get_free_ipbuf(OMAP_DSP_TID_ANON);
-               if (bid == OMAP_DSP_BID_NULL)
+               if ((ipb_h = get_free_ipbuf(TID_ANON)) == NULL)
                        return;
-               if (try_yld(bid) < 0)
+               if (try_yld(ipb_h) < 0)
                        return;
        }
 }
@@ -258,31 +263,31 @@ void balance_ipbuf(void)
 }
 
 /* for process context */
-void unuse_ipbuf(unsigned short bid)
+void unuse_ipbuf(struct ipbuf_head *ipb_h)
 {
        if (ipbcfg.bsycnt > ipbcfg.ln / 4) {
                /* we don't have enough IPBUF lines. let's keep it. */
-               release_ipbuf(bid);
+               release_ipbuf(ipb_h);
        } else {
                /* we have enough IPBUF lines. let's return this line to DSP. */
-               ipbuf[bid]->la = OMAP_DSP_TID_ANON;
-               try_yld(bid);
+               ipb_h->p->la = TID_ANON;
+               try_yld(ipb_h);
                balance_ipbuf();
        }
 }
 
 /* for interrupt context */
-void unuse_ipbuf_nowait(unsigned short bid)
+void unuse_ipbuf_nowait(struct ipbuf_head *ipb_h)
 {
-       release_ipbuf(bid);
+       release_ipbuf(ipb_h);
        balance_ipbuf();
 }
 
 /*
- * functions called from mailbox1 interrupt routine
+ * functions called from mailbox interrupt routine
  */
 
-void mbx1_err_ipbfull(void)
+void mbx_err_ipbfull(void)
 {
        ipbcfg.cnt_full++;
 }
@@ -294,12 +299,13 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
                          char *buf)
 {
        int len = 0;
-       unsigned short bid;
+       u16 bid;
 
        for (bid = 0; bid < ipbcfg.ln; bid++) {
-               unsigned short la = ipbuf[bid]->la;
-               unsigned short ld = ipbuf[bid]->ld;
-               unsigned short c  = ipbuf[bid]->c;
+               struct ipbuf_head *ipb_h = &g_ipbuf[bid];
+               u16 la = ipb_h->p->la;
+               u16 ld = ipb_h->p->ld;
+               u16 c  = ipb_h->p->c;
 
                if (len > PAGE_SIZE - 100) {
                        len += sprintf(buf + len, "out of buffer.\n");
@@ -307,13 +313,13 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
                }
 
                len += sprintf(buf + len, "ipbuf[%d]: adr = 0x%p\n",
-                              bid, ipbuf[bid]);
-               if (la == OMAP_DSP_TID_FREE) {
+                              bid, ipb_h->p);
+               if (la == TID_FREE) {
                        len += sprintf(buf + len,
                                       "  DSPtask[%d]->Linux "
                                       "(already read and now free for Linux)\n",
                                       ld);
-               } else if (ld == OMAP_DSP_TID_FREE) {
+               } else if (ld == TID_FREE) {
                        len += sprintf(buf + len,
                                       "  Linux->DSPtask[%d] "
                                       "(already read and now free for DSP)\n",
@@ -333,7 +339,7 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
 
        len += sprintf(buf + len, "\nFree IPBUF link: ");
        spin_lock(&ipb_free.lock);
-       ipblink_for_each(bid, &ipb_free, ipbuf) {
+       ipblink_for_each(bid, &ipb_free) {
                len += sprintf(buf + len, "%d ", bid);
        }
        spin_unlock(&ipb_free.lock);
@@ -344,5 +350,3 @@ static ssize_t ipbuf_show(struct device *dev, struct device_attribute *attr,
 finish:
        return len;
 }
-
-struct device_attribute dev_attr_ipbuf = __ATTR_RO(ipbuf);