]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - sound/oss/omap-audio.c
[PATCH] ARM: OMAP: OSS: sem2mutex conversion
[linux-2.6-omap-h63xx.git] / sound / oss / omap-audio.c
index bd10ae6a3d4542cebb7fd1f84c1973b2c888b879..cc1f14a2d29bc5fa12100e154cb980d8102fafaa 100644 (file)
 #include <linux/soundcard.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/hardware.h>
-#include <asm/semaphore.h>
 
 #include "omap-audio-dma-intfc.h"
 #include "omap-audio.h"
@@ -105,15 +106,15 @@ static int audio_open(struct inode *inode, struct file *file);
 
 static int audio_release(struct inode *inode, struct file *file);
 
-static int audio_probe(struct device *dev);
+static int audio_probe(struct platform_device *pdev);
 
-static int audio_remove(struct device *dev);
+static int audio_remove(struct platform_device *pdev);
 
-static void audio_shutdown(struct device *dev);
+static void audio_shutdown(struct platform_device *pdev);
 
-static int audio_suspend(struct device *dev, pm_message_t mesg, u32 level);
+static int audio_suspend(struct platform_device *pdev, pm_message_t mesg);
 
-static int audio_resume(struct device *dev, u32 level);
+static int audio_resume(struct platform_device *pdev);
 
 static void audio_free(struct device *dev);
 
@@ -141,14 +142,15 @@ static struct file_operations omap_audio_fops = {
 };
 
 /* Driver information */
-static struct device_driver omap_audio_driver = {
-       .name           = OMAP_AUDIO_NAME,
-       .bus            = &platform_bus_type,
+static struct platform_driver omap_audio_driver = {
        .probe          = audio_probe,
        .remove         = audio_remove,
        .suspend        = audio_suspend,
-       .resume         = audio_resume,
        .shutdown       = audio_shutdown,
+       .resume         = audio_resume,
+       .driver         = {
+               .name   = OMAP_AUDIO_NAME,
+       },
 };
 
 /* Device Information */
@@ -282,7 +284,7 @@ static void audio_free(struct device *dev)
  * WARNING!!!!  : It is expected that the codec would have registered with us by now
  *
  *********************************************************************************/
-static int audio_probe(struct device *dev)
+static int audio_probe(struct platform_device *pdev)
 {
        int ret;
        FN_IN;
@@ -300,7 +302,7 @@ static int audio_probe(struct device *dev)
  * audio_remove() Function to handle removal operations
  *
  *********************************************************************************/
-static int audio_remove(struct device *dev)
+static int audio_remove(struct platform_device *pdev)
 {
        FN_IN;
        if (audio_state.hw_remove) {
@@ -315,7 +317,7 @@ static int audio_remove(struct device *dev)
  * audio_shutdown(): Function to handle shutdown operations
  *
  *********************************************************************************/
-static void audio_shutdown(struct device *dev)
+static void audio_shutdown(struct platform_device *pdev)
 {
        FN_IN;
        if (audio_state.hw_cleanup) {
@@ -330,16 +332,13 @@ static void audio_shutdown(struct device *dev)
  * audio_suspend(): Function to handle suspend operations 
  *
  *********************************************************************************/
-static int audio_suspend(struct device *dev, pm_message_t mesg, u32 level)
+static int audio_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
        int ret = 0;
 
 #ifdef CONFIG_PM
-       void *data = dev->driver_data;
+       void *data = pdev->dev.driver_data;
        FN_IN;
-       if (level != SUSPEND_POWER_DOWN) {
-               return 0;
-       }
        if (audio_state.hw_suspend) {
                ret = audio_ldm_suspend(data);
                if (ret == 0)
@@ -361,16 +360,13 @@ static int audio_suspend(struct device *dev, pm_message_t mesg, u32 level)
  * audio_resume(): Function to handle resume operations
  *
  *********************************************************************************/
-static int audio_resume(struct device *dev, u32 level)
+static int audio_resume(struct platform_device *pdev)
 {
        int ret = 0;
 
 #ifdef CONFIG_PM
-       void *data = dev->driver_data;
+       void *data = pdev->dev.driver_data;
        FN_IN;
-       if (level != RESUME_POWER_ON) {
-               return 0;
-       }
        if (audio_state.hw_resume) {
                ret = audio_ldm_resume(data);
                if (ret == 0)
@@ -442,6 +438,7 @@ int audio_register_codec(audio_state_t * codec_state)
        }
 
        memcpy(&audio_state, codec_state, sizeof(audio_state_t));
+       mutex_init(&audio_state.mutex);
 
        ret = platform_device_register(&omap_audio_device);
        if (ret != 0) {
@@ -450,7 +447,7 @@ int audio_register_codec(audio_state_t * codec_state)
                goto register_out;
        }
 
-       ret = driver_register(&omap_audio_driver);
+       ret = platform_driver_register(&omap_audio_driver);
        if (ret != 0) {
                printk(KERN_ERR "Device Register failed =%d\n", ret);
                ret = -ENODEV;
@@ -485,7 +482,7 @@ int audio_unregister_codec(audio_state_t * codec_state)
                return -EPERM;
        }
 
-       driver_unregister(&omap_audio_driver);
+       platform_driver_unregister(&omap_audio_driver);
        platform_device_unregister(&omap_audio_device);
 
        memset(&audio_state, 0, sizeof(audio_state_t));
@@ -531,13 +528,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 +542,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 +551,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 +613,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 +626,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 +743,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 +892,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 +954,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;
@@ -1028,7 +1024,7 @@ static int audio_open(struct inode *inode, struct file *file)
                return -ESTALE;
        }
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        /* access control */
        err = -ENODEV;
@@ -1096,7 +1092,7 @@ static int audio_open(struct inode *inode, struct file *file)
        err = 0;
 
       out:
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
        if (err) {
                module_put(state->owner);
                module_put(THIS_MODULE);
@@ -1118,7 +1114,7 @@ static int audio_release(struct inode *inode, struct file *file)
 
        FN_IN;
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        if (file->f_mode & FMODE_READ) {
                audio_discard_buf(is);
@@ -1149,7 +1145,7 @@ static int audio_release(struct inode *inode, struct file *file)
                        state->hw_shutdown(state->data);
        }
 
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 
        module_put(state->owner);
        module_put(THIS_MODULE);