summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-02-09 17:08:37 -0500
committerTakashi Iwai <tiwai@suse.de>2016-02-09 17:08:37 -0500
commit397da2d0ab0d1398242622d80a74df7245395c63 (patch)
tree51e01a67c653c67108f65d063b8b9cbfacf0b1a7 /sound
parentb8cb3750ce94d7610934465263850dcf40736bca (diff)
parent4dff5c7b7093b19c19d3a100f8a3ad87cb7cd9e7 (diff)
Merge branch 'topic/core-fixes' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/core/timer.c40
-rw-r--r--sound/drivers/dummy.c37
2 files changed, 39 insertions, 38 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 9b513a05765a..dca817fc7894 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -422,7 +422,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
422 spin_lock_irqsave(&timer->lock, flags); 422 spin_lock_irqsave(&timer->lock, flags);
423 list_for_each_entry(ts, &ti->slave_active_head, active_list) 423 list_for_each_entry(ts, &ti->slave_active_head, active_list)
424 if (ts->ccallback) 424 if (ts->ccallback)
425 ts->ccallback(ti, event + 100, &tstamp, resolution); 425 ts->ccallback(ts, event + 100, &tstamp, resolution);
426 spin_unlock_irqrestore(&timer->lock, flags); 426 spin_unlock_irqrestore(&timer->lock, flags);
427} 427}
428 428
@@ -518,9 +518,13 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
518 spin_unlock_irqrestore(&slave_active_lock, flags); 518 spin_unlock_irqrestore(&slave_active_lock, flags);
519 return -EBUSY; 519 return -EBUSY;
520 } 520 }
521 if (timeri->timer)
522 spin_lock(&timeri->timer->lock);
521 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; 523 timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
522 list_del_init(&timeri->ack_list); 524 list_del_init(&timeri->ack_list);
523 list_del_init(&timeri->active_list); 525 list_del_init(&timeri->active_list);
526 if (timeri->timer)
527 spin_unlock(&timeri->timer->lock);
524 spin_unlock_irqrestore(&slave_active_lock, flags); 528 spin_unlock_irqrestore(&slave_active_lock, flags);
525 goto __end; 529 goto __end;
526 } 530 }
@@ -1929,6 +1933,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1929{ 1933{
1930 struct snd_timer_user *tu; 1934 struct snd_timer_user *tu;
1931 long result = 0, unit; 1935 long result = 0, unit;
1936 int qhead;
1932 int err = 0; 1937 int err = 0;
1933 1938
1934 tu = file->private_data; 1939 tu = file->private_data;
@@ -1940,7 +1945,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1940 1945
1941 if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) { 1946 if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
1942 err = -EAGAIN; 1947 err = -EAGAIN;
1943 break; 1948 goto _error;
1944 } 1949 }
1945 1950
1946 set_current_state(TASK_INTERRUPTIBLE); 1951 set_current_state(TASK_INTERRUPTIBLE);
@@ -1955,42 +1960,37 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
1955 1960
1956 if (tu->disconnected) { 1961 if (tu->disconnected) {
1957 err = -ENODEV; 1962 err = -ENODEV;
1958 break; 1963 goto _error;
1959 } 1964 }
1960 if (signal_pending(current)) { 1965 if (signal_pending(current)) {
1961 err = -ERESTARTSYS; 1966 err = -ERESTARTSYS;
1962 break; 1967 goto _error;
1963 } 1968 }
1964 } 1969 }
1965 1970
1971 qhead = tu->qhead++;
1972 tu->qhead %= tu->queue_size;
1966 spin_unlock_irq(&tu->qlock); 1973 spin_unlock_irq(&tu->qlock);
1967 if (err < 0)
1968 goto _error;
1969 1974
1970 if (tu->tread) { 1975 if (tu->tread) {
1971 if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], 1976 if (copy_to_user(buffer, &tu->tqueue[qhead],
1972 sizeof(struct snd_timer_tread))) { 1977 sizeof(struct snd_timer_tread)))
1973 err = -EFAULT; 1978 err = -EFAULT;
1974 goto _error;
1975 }
1976 } else { 1979 } else {
1977 if (copy_to_user(buffer, &tu->queue[tu->qhead++], 1980 if (copy_to_user(buffer, &tu->queue[qhead],
1978 sizeof(struct snd_timer_read))) { 1981 sizeof(struct snd_timer_read)))
1979 err = -EFAULT; 1982 err = -EFAULT;
1980 goto _error;
1981 }
1982 } 1983 }
1983 1984
1984 tu->qhead %= tu->queue_size;
1985
1986 result += unit;
1987 buffer += unit;
1988
1989 spin_lock_irq(&tu->qlock); 1985 spin_lock_irq(&tu->qlock);
1990 tu->qused--; 1986 tu->qused--;
1987 if (err < 0)
1988 goto _error;
1989 result += unit;
1990 buffer += unit;
1991 } 1991 }
1992 spin_unlock_irq(&tu->qlock);
1993 _error: 1992 _error:
1993 spin_unlock_irq(&tu->qlock);
1994 return result > 0 ? result : err; 1994 return result > 0 ? result : err;
1995} 1995}
1996 1996
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index bde33308f0d6..c0f8f613f1f1 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -87,7 +87,7 @@ MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
87module_param(fake_buffer, bool, 0444); 87module_param(fake_buffer, bool, 0444);
88MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations."); 88MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
89#ifdef CONFIG_HIGH_RES_TIMERS 89#ifdef CONFIG_HIGH_RES_TIMERS
90module_param(hrtimer, bool, 0444); 90module_param(hrtimer, bool, 0644);
91MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source."); 91MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
92#endif 92#endif
93 93
@@ -109,6 +109,9 @@ struct dummy_timer_ops {
109 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); 109 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
110}; 110};
111 111
112#define get_dummy_ops(substream) \
113 (*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
114
112struct dummy_model { 115struct dummy_model {
113 const char *name; 116 const char *name;
114 int (*playback_constraints)(struct snd_pcm_runtime *runtime); 117 int (*playback_constraints)(struct snd_pcm_runtime *runtime);
@@ -137,7 +140,6 @@ struct snd_dummy {
137 int iobox; 140 int iobox;
138 struct snd_kcontrol *cd_volume_ctl; 141 struct snd_kcontrol *cd_volume_ctl;
139 struct snd_kcontrol *cd_switch_ctl; 142 struct snd_kcontrol *cd_switch_ctl;
140 const struct dummy_timer_ops *timer_ops;
141}; 143};
142 144
143/* 145/*
@@ -231,6 +233,8 @@ static struct dummy_model *dummy_models[] = {
231 */ 233 */
232 234
233struct dummy_systimer_pcm { 235struct dummy_systimer_pcm {
236 /* ops must be the first item */
237 const struct dummy_timer_ops *timer_ops;
234 spinlock_t lock; 238 spinlock_t lock;
235 struct timer_list timer; 239 struct timer_list timer;
236 unsigned long base_time; 240 unsigned long base_time;
@@ -366,6 +370,8 @@ static const struct dummy_timer_ops dummy_systimer_ops = {
366 */ 370 */
367 371
368struct dummy_hrtimer_pcm { 372struct dummy_hrtimer_pcm {
373 /* ops must be the first item */
374 const struct dummy_timer_ops *timer_ops;
369 ktime_t base_time; 375 ktime_t base_time;
370 ktime_t period_time; 376 ktime_t period_time;
371 atomic_t running; 377 atomic_t running;
@@ -492,31 +498,25 @@ static const struct dummy_timer_ops dummy_hrtimer_ops = {
492 498
493static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 499static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
494{ 500{
495 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
496
497 switch (cmd) { 501 switch (cmd) {
498 case SNDRV_PCM_TRIGGER_START: 502 case SNDRV_PCM_TRIGGER_START:
499 case SNDRV_PCM_TRIGGER_RESUME: 503 case SNDRV_PCM_TRIGGER_RESUME:
500 return dummy->timer_ops->start(substream); 504 return get_dummy_ops(substream)->start(substream);
501 case SNDRV_PCM_TRIGGER_STOP: 505 case SNDRV_PCM_TRIGGER_STOP:
502 case SNDRV_PCM_TRIGGER_SUSPEND: 506 case SNDRV_PCM_TRIGGER_SUSPEND:
503 return dummy->timer_ops->stop(substream); 507 return get_dummy_ops(substream)->stop(substream);
504 } 508 }
505 return -EINVAL; 509 return -EINVAL;
506} 510}
507 511
508static int dummy_pcm_prepare(struct snd_pcm_substream *substream) 512static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
509{ 513{
510 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 514 return get_dummy_ops(substream)->prepare(substream);
511
512 return dummy->timer_ops->prepare(substream);
513} 515}
514 516
515static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) 517static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
516{ 518{
517 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 519 return get_dummy_ops(substream)->pointer(substream);
518
519 return dummy->timer_ops->pointer(substream);
520} 520}
521 521
522static struct snd_pcm_hardware dummy_pcm_hardware = { 522static struct snd_pcm_hardware dummy_pcm_hardware = {
@@ -562,17 +562,19 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
562 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 562 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
563 struct dummy_model *model = dummy->model; 563 struct dummy_model *model = dummy->model;
564 struct snd_pcm_runtime *runtime = substream->runtime; 564 struct snd_pcm_runtime *runtime = substream->runtime;
565 const struct dummy_timer_ops *ops;
565 int err; 566 int err;
566 567
567 dummy->timer_ops = &dummy_systimer_ops; 568 ops = &dummy_systimer_ops;
568#ifdef CONFIG_HIGH_RES_TIMERS 569#ifdef CONFIG_HIGH_RES_TIMERS
569 if (hrtimer) 570 if (hrtimer)
570 dummy->timer_ops = &dummy_hrtimer_ops; 571 ops = &dummy_hrtimer_ops;
571#endif 572#endif
572 573
573 err = dummy->timer_ops->create(substream); 574 err = ops->create(substream);
574 if (err < 0) 575 if (err < 0)
575 return err; 576 return err;
577 get_dummy_ops(substream) = ops;
576 578
577 runtime->hw = dummy->pcm_hw; 579 runtime->hw = dummy->pcm_hw;
578 if (substream->pcm->device & 1) { 580 if (substream->pcm->device & 1) {
@@ -594,7 +596,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
594 err = model->capture_constraints(substream->runtime); 596 err = model->capture_constraints(substream->runtime);
595 } 597 }
596 if (err < 0) { 598 if (err < 0) {
597 dummy->timer_ops->free(substream); 599 get_dummy_ops(substream)->free(substream);
598 return err; 600 return err;
599 } 601 }
600 return 0; 602 return 0;
@@ -602,8 +604,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
602 604
603static int dummy_pcm_close(struct snd_pcm_substream *substream) 605static int dummy_pcm_close(struct snd_pcm_substream *substream)
604{ 606{
605 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 607 get_dummy_ops(substream)->free(substream);
606 dummy->timer_ops->free(substream);
607 return 0; 608 return 0;
608} 609}
609 610