aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r--sound/core/timer.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 9a6157ea6881..fc144f43faa6 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -35,6 +35,9 @@
35#include <sound/initval.h> 35#include <sound/initval.h>
36#include <linux/kmod.h> 36#include <linux/kmod.h>
37 37
38/* internal flags */
39#define SNDRV_TIMER_IFLG_PAUSED 0x00010000
40
38#if IS_ENABLED(CONFIG_SND_HRTIMER) 41#if IS_ENABLED(CONFIG_SND_HRTIMER)
39#define DEFAULT_TIMER_LIMIT 4 42#define DEFAULT_TIMER_LIMIT 4
40#else 43#else
@@ -294,8 +297,21 @@ int snd_timer_open(struct snd_timer_instance **ti,
294 get_device(&timer->card->card_dev); 297 get_device(&timer->card->card_dev);
295 timeri->slave_class = tid->dev_sclass; 298 timeri->slave_class = tid->dev_sclass;
296 timeri->slave_id = slave_id; 299 timeri->slave_id = slave_id;
297 if (list_empty(&timer->open_list_head) && timer->hw.open) 300
298 timer->hw.open(timer); 301 if (list_empty(&timer->open_list_head) && timer->hw.open) {
302 int err = timer->hw.open(timer);
303 if (err) {
304 kfree(timeri->owner);
305 kfree(timeri);
306
307 if (timer->card)
308 put_device(&timer->card->card_dev);
309 module_put(timer->module);
310 mutex_unlock(&register_mutex);
311 return err;
312 }
313 }
314
299 list_add_tail(&timeri->open_list, &timer->open_list_head); 315 list_add_tail(&timeri->open_list, &timer->open_list_head);
300 snd_timer_check_master(timeri); 316 snd_timer_check_master(timeri);
301 mutex_unlock(&register_mutex); 317 mutex_unlock(&register_mutex);
@@ -526,6 +542,10 @@ static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop)
526 } 542 }
527 } 543 }
528 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); 544 timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
545 if (stop)
546 timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED;
547 else
548 timeri->flags |= SNDRV_TIMER_IFLG_PAUSED;
529 snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : 549 snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
530 SNDRV_TIMER_EVENT_CONTINUE); 550 SNDRV_TIMER_EVENT_CONTINUE);
531 unlock: 551 unlock:
@@ -587,6 +607,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
587 */ 607 */
588int snd_timer_continue(struct snd_timer_instance *timeri) 608int snd_timer_continue(struct snd_timer_instance *timeri)
589{ 609{
610 /* timer can continue only after pause */
611 if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
612 return -EINVAL;
613
590 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) 614 if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
591 return snd_timer_start_slave(timeri, false); 615 return snd_timer_start_slave(timeri, false);
592 else 616 else
@@ -813,6 +837,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
813 timer->tmr_subdevice = tid->subdevice; 837 timer->tmr_subdevice = tid->subdevice;
814 if (id) 838 if (id)
815 strlcpy(timer->id, id, sizeof(timer->id)); 839 strlcpy(timer->id, id, sizeof(timer->id));
840 timer->sticks = 1;
816 INIT_LIST_HEAD(&timer->device_list); 841 INIT_LIST_HEAD(&timer->device_list);
817 INIT_LIST_HEAD(&timer->open_list_head); 842 INIT_LIST_HEAD(&timer->open_list_head);
818 INIT_LIST_HEAD(&timer->active_list_head); 843 INIT_LIST_HEAD(&timer->active_list_head);
@@ -1817,6 +1842,9 @@ static int snd_timer_user_continue(struct file *file)
1817 tu = file->private_data; 1842 tu = file->private_data;
1818 if (!tu->timeri) 1843 if (!tu->timeri)
1819 return -EBADFD; 1844 return -EBADFD;
1845 /* start timer instead of continue if it's not used before */
1846 if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
1847 return snd_timer_user_start(file);
1820 tu->timeri->lost = 0; 1848 tu->timeri->lost = 0;
1821 return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; 1849 return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
1822} 1850}
@@ -1958,6 +1986,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1958 tu->qused--; 1986 tu->qused--;
1959 spin_unlock_irq(&tu->qlock); 1987 spin_unlock_irq(&tu->qlock);
1960 1988
1989 mutex_lock(&tu->ioctl_lock);
1961 if (tu->tread) { 1990 if (tu->tread) {
1962 if (copy_to_user(buffer, &tu->tqueue[qhead], 1991 if (copy_to_user(buffer, &tu->tqueue[qhead],
1963 sizeof(struct snd_timer_tread))) 1992 sizeof(struct snd_timer_tread)))
@@ -1967,6 +1996,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1967 sizeof(struct snd_timer_read))) 1996 sizeof(struct snd_timer_read)))
1968 err = -EFAULT; 1997 err = -EFAULT;
1969 } 1998 }
1999 mutex_unlock(&tu->ioctl_lock);
1970 2000
1971 spin_lock_irq(&tu->qlock); 2001 spin_lock_irq(&tu->qlock);
1972 if (err < 0) 2002 if (err < 0)