]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: audio driver: convert semaphores to completions
authorVladimir Barinov <vbarinov@ru.mvista.com>
Thu, 22 Sep 2005 21:03:22 +0000 (14:03 -0700)
committerKevin Hilman <kevin@hilman.org>
Thu, 22 Sep 2005 21:03:22 +0000 (14:03 -0700)
Signed-off-by: Vladimir Barinov <vbarinov@ru.mvista.com>
Signed-off-by: Kevin Hilman <kevin@hilman.org>
sound/oss/omap-audio-dma-intfc.c
sound/oss/omap-audio.c
sound/oss/omap-audio.h

index 6ccab9a5af3c97230d855cbc83830a52b2a6eadb..f5e324e5ada30d0bcb74bff079e5ffaf6735cbe1 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/sysrq.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/completion.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -210,7 +211,8 @@ int audio_setup_buf(audio_stream_t * s)
        s->started = 0;
        s->bytecount = 0;
        s->fragcount = 0;
-       sema_init(&s->sem, s->nbfrags);
+       init_completion(&s->wfc);
+       s->wfc.done = s->nbfrags;
        FN_OUT(0);
        return 0;
       err:
@@ -469,7 +471,9 @@ void audio_prime_rx(audio_state_t * state)
                audio_process_dma(state->output_stream);
        }
        is->pending_frags = is->nbfrags;
-       sema_init(&is->sem, 0);
+       init_completion(&is->wfc);
+       is->wfc.done = 0;
+
        is->active = 1;
        audio_process_dma(is);
 
@@ -535,7 +539,9 @@ int audio_sync(struct file *file)
         */
        b = &s->buffers[s->usr_head];
        if (b->offset &= ~3) {
-               down(&s->sem);
+               /* Wait for a buffer to become free */
+               if (wait_for_completion_interruptible(&s->wfc))
+                       return 0;
                /*
                 * HACK ALERT !
                 * To avoid increased complexity in the rest of the code
@@ -568,7 +574,7 @@ int audio_sync(struct file *file)
        /* Let's wait for all buffers to complete */
        set_current_state(TASK_INTERRUPTIBLE);
        add_wait_queue(&s->wq, &wait);
-       while ((s->pending_frags || (atomic_read(&s->sem.count) < s->nbfrags))
+       while ((s->pending_frags || (s->wfc.done < s->nbfrags))
               && !signal_pending(current)) {
                schedule();
                set_current_state(TASK_INTERRUPTIBLE);
@@ -652,7 +658,8 @@ void audio_reset(audio_stream_t * s)
                s->buffers[s->usr_head].offset = 0;
                s->usr_head = s->dma_head;
                s->pending_frags = 0;
-               sema_init(&s->sem, s->nbfrags);
+               init_completion(&s->wfc);
+               s->wfc.done = s->nbfrags;
        }
        s->active = 0;
        s->stopped = 0;
@@ -864,7 +871,6 @@ static void sound_dma_irq_handler(int sound_curr_lch, u16 ch_status, void *data)
                tasklet_schedule(&audio_isr_work2);
                work_item_running = 0;
        }
-
        FN_OUT(0);
        return;
 }
@@ -893,14 +899,13 @@ static void audio_dma_callback(int lch, u16 ch_status, void *data)
                        s->dma_tail = 0;
 
                if (!s->mapped)
-                       up(&s->sem);
+                       complete(&s->wfc);
                else
                        s->pending_frags++;
 
                wake_up(&s->wq);
        }
 
-       audio_process_dma(s);
        
        FN_OUT(0);
        return;
index bd10ae6a3d4542cebb7fd1f84c1973b2c888b879..afcf98d86000417c9d7eaeb91ae9820c3990cf94 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/completion.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -442,6 +443,7 @@ int audio_register_codec(audio_state_t * codec_state)
        }
 
        memcpy(&audio_state, codec_state, sizeof(audio_state_t));
+       sema_init(&audio_state.sem, 1);
 
        ret = platform_device_register(&omap_audio_device);
        if (ret != 0) {
@@ -531,13 +533,12 @@ audio_write(struct file *file, const char __user *buffer,
                /* Wait for a buffer to become free */
                if (file->f_flags & O_NONBLOCK) {
                        ret = -EAGAIN;
-                       if (down_trylock(&s->sem))
-                               break;
-               } else {
-                       ret = -ERESTARTSYS;
-                       if (down_interruptible(&s->sem))
+                       if (!s->wfc.done)
                                break;
                }
+               ret = -ERESTARTSYS;
+               if (wait_for_completion_interruptible(&s->wfc))
+                       break;
 
                /* Feed the current buffer */
                chunksize = s->fragsize - b->offset;
@@ -546,7 +547,7 @@ audio_write(struct file *file, const char __user *buffer,
                DPRINTK("write %d to %d\n", chunksize, s->usr_head);
                if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
                        printk(KERN_ERR "Audio: CopyFrom User failed \n");
-                       up(&s->sem);
+                       complete(&s->wfc);
                        return -EFAULT;
                }
 
@@ -555,7 +556,7 @@ audio_write(struct file *file, const char __user *buffer,
                b->offset += chunksize;
 
                if (b->offset < s->fragsize) {
-                       up(&s->sem);
+                       complete(&s->wfc);
                        break;
                }
 
@@ -617,13 +618,12 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                /* Wait for a buffer to become full */
                if (file->f_flags & O_NONBLOCK) {
                        ret = -EAGAIN;
-                       if (down_trylock(&s->sem))
-                               break;
-               } else {
-                       ret = -ERESTARTSYS;
-                       if (down_interruptible(&s->sem))
+                       if (!s->wfc.done)
                                break;
                }
+               ret = -ERESTARTSYS;
+               if (wait_for_completion_interruptible(&s->wfc))
+                       break;
 
                /* Grab data from the current buffer */
                chunksize = s->fragsize - b->offset;
@@ -631,14 +631,14 @@ audio_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
                        chunksize = count;
                DPRINTK("read %d from %d\n", chunksize, s->usr_head);
                if (copy_to_user(buffer, b->data + b->offset, chunksize)) {
-                       up(&s->sem);
+                       complete(&s->wfc);
                        return -EFAULT;
                }
                buffer += chunksize;
                count -= chunksize;
                b->offset += chunksize;
                if (b->offset < s->fragsize) {
-                       up(&s->sem);
+                       complete(&s->wfc);
                        break;
                }
 
@@ -748,12 +748,12 @@ audio_poll(struct file *file, struct poll_table_struct *wait)
 
        if (file->f_mode & FMODE_READ)
                if ((is->mapped && is->bytecount > 0) ||
-                   (!is->mapped && atomic_read(&is->sem.count) > 0))
+                   (!is->mapped && is->wfc.done > 0))
                        mask |= POLLIN | POLLRDNORM;
 
        if (file->f_mode & FMODE_WRITE)
                if ((os->mapped && os->bytecount > 0) ||
-                   (!os->mapped && atomic_read(&os->sem.count) > 0))
+                   (!os->mapped && os->wfc.done > 0))
                        mask |= POLLOUT | POLLWRNORM;
 
        DPRINTK("audio_poll() returned mask of %s%s\n",
@@ -897,7 +897,8 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                local_irq_save(flags);
                                if (os->mapped && !os->pending_frags) {
                                        os->pending_frags = os->nbfrags;
-                                       sema_init(&os->sem, 0);
+                                       init_completion(&os->wfc);
+                                       os->wfc.done = 0;
                                        os->active = 1;
                                }
                                os->stopped = 0;
@@ -958,7 +959,7 @@ audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                FN_OUT(19);
                                return -ENOMEM;
                        }
-                       inf.bytes = atomic_read(&s->sem.count) * s->fragsize;
+                       inf.bytes = s->wfc.done * s->fragsize;
 
                        inf.fragments = inf.bytes / s->fragsize;
                        inf.fragsize = s->fragsize;
index 42adef8bcf6f667facaa9341fb36b52130bc17ae..d3cc11b456fd5bef1f3cba44170d3770ff6a95e2 100644 (file)
@@ -67,7 +67,7 @@ typedef struct {
        int input_or_output;    /* Direction of this data stream */
        int bytecount;          /* nbr of processed bytes */
        int fragcount;          /* nbr of fragment transitions */
-       struct semaphore sem;   /* account for fragment usage */
+       struct completion wfc;  /* wait for "nbfrags" fragment completion */
        wait_queue_head_t wq;   /* for poll */
        int dma_spinref;        /* DMA is spinning */
        unsigned mapped:1;      /* mmap()'ed buffers */