import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / sound / core / timer.c
index 6ddcf06f52f9a0c710cfbd65157915e5d90b14a4..ee81c947c24bb9fb08e67b8c8db050a082a291ed 100644 (file)
@@ -73,7 +73,7 @@ struct snd_timer_user {
        struct timespec tstamp;         /* trigger tstamp */
        wait_queue_head_t qchange_sleep;
        struct fasync_struct *fasync;
-       struct mutex tread_sem;
+       struct mutex ioctl_lock;
 };
 
 /* list of timers */
@@ -1174,6 +1174,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
                tu->tstamp = *tstamp;
        if ((tu->filter & (1 << event)) == 0 || !tu->tread)
                return;
+       memset(&r1, 0, sizeof(r1));
        r1.event = event;
        r1.tstamp = *tstamp;
        r1.val = resolution;
@@ -1208,6 +1209,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
        }
        if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
            tu->last_resolution != resolution) {
+               memset(&r1, 0, sizeof(r1));
                r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
                r1.tstamp = tstamp;
                r1.val = resolution;
@@ -1256,7 +1258,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
                return -ENOMEM;
        spin_lock_init(&tu->qlock);
        init_waitqueue_head(&tu->qchange_sleep);
-       mutex_init(&tu->tread_sem);
+       mutex_init(&tu->ioctl_lock);
        tu->ticks = 1;
        tu->queue_size = 128;
        tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
@@ -1276,8 +1278,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
        if (file->private_data) {
                tu = file->private_data;
                file->private_data = NULL;
+               mutex_lock(&tu->ioctl_lock);
                if (tu->timeri)
                        snd_timer_close(tu->timeri);
+               mutex_unlock(&tu->ioctl_lock);
                kfree(tu->queue);
                kfree(tu->tqueue);
                kfree(tu);
@@ -1515,7 +1519,6 @@ static int snd_timer_user_tselect(struct file *file,
        int err = 0;
 
        tu = file->private_data;
-       mutex_lock(&tu->tread_sem);
        if (tu->timeri) {
                snd_timer_close(tu->timeri);
                tu->timeri = NULL;
@@ -1559,7 +1562,6 @@ static int snd_timer_user_tselect(struct file *file,
        }
 
       __err:
-       mutex_unlock(&tu->tread_sem);
        return err;
 }
 
@@ -1673,6 +1675,7 @@ static int snd_timer_user_params(struct file *file,
        if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
                if (tu->tread) {
                        struct snd_timer_tread tread;
+                       memset(&tread, 0, sizeof(tread));
                        tread.event = SNDRV_TIMER_EVENT_EARLY;
                        tread.tstamp.tv_sec = 0;
                        tread.tstamp.tv_nsec = 0;
@@ -1772,7 +1775,7 @@ enum {
        SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
 };
 
-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
                                 unsigned long arg)
 {
        struct snd_timer_user *tu;
@@ -1789,17 +1792,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
        {
                int xarg;
 
-               mutex_lock(&tu->tread_sem);
-               if (tu->timeri) {       /* too late */
-                       mutex_unlock(&tu->tread_sem);
+               if (tu->timeri) /* too late */
                        return -EBUSY;
-               }
-               if (get_user(xarg, p)) {
-                       mutex_unlock(&tu->tread_sem);
+               if (get_user(xarg, p))
                        return -EFAULT;
-               }
                tu->tread = xarg ? 1 : 0;
-               mutex_unlock(&tu->tread_sem);
                return 0;
        }
        case SNDRV_TIMER_IOCTL_GINFO:
@@ -1832,6 +1829,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
        return -ENOTTY;
 }
 
+static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+                                unsigned long arg)
+{
+       struct snd_timer_user *tu = file->private_data;
+       long ret;
+
+       mutex_lock(&tu->ioctl_lock);
+       ret = __snd_timer_user_ioctl(file, cmd, arg);
+       mutex_unlock(&tu->ioctl_lock);
+       return ret;
+}
+
 static int snd_timer_user_fasync(int fd, struct file * file, int on)
 {
        struct snd_timer_user *tu;