aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/timer.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-06 13:56:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-06 13:56:51 -0400
commit920f2ecdf6c3b3526f60fbd38c68597953cad3ee (patch)
tree18188922ba38a5c53ee8d17032eb5c46dffc7fa2 /sound/core/timer.c
parent9ced560b82606b35adb33a27012a148d418a4c1f (diff)
parentfc18282cdcba984ab89c74d7e844c10114ae0795 (diff)
Merge tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This development cycle resulted in a fair amount of changes in both core and driver sides. The most significant change in ALSA core is about PCM. Also the support of of-graph card and the new DAPM widget for DSP are noteworthy changes in ASoC core. And there're lots of small changes splat over the tree, as you can see in diffstat. Below are a few highlights: ALSA core: - Removal of set_fs() hackery from PCM core stuff, and the code reorganization / optimization thereafter - Improved support of PCM ack ops, and a new ABI for improved control/status mmap handling - Lots of constifications in various codes ASoC core: - The support of of-graph card, which may work as a better generic device for a replacement of simple-card - New widget types intended mainly for use with DSPs ASoC drivers: - New drivers for Allwinner V3s SoCs - Ensonic ES8316 codec support - More Intel SKL and KBL works - More device support for Intel SST Atom (mostly for cheap tablets and 2-in-1 devices) - Support for Rockchip PDM controllers - Support for STM32 I2S and S/PDIF controllers - Support for ZTE AUD96P22 codecs HD-audio: - Support of new Realtek codecs (ALC215/ALC285/ALC289), more quirks for HP and Dell machines - A few more fixes for i915 component binding" * tag 'sound-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (418 commits) ALSA: hda - Fix unbalance of i915 module refcount ASoC: Intel: Skylake: Remove driver debugfs exit ASoC: Intel: Skylake: explicitly add the headers sst-dsp.h ALSA: hda/realtek - Remove GPIO_MASK ALSA: hda/realtek - Fix typo of pincfg for Dell quirk ALSA: pcm: add a documentation for tracepoints ALSA: atmel: ac97c: fix error return code in atmel_ac97c_probe() ALSA: x86: fix error return code in hdmi_lpe_audio_probe() ASoC: Intel: Skylake: Add support to read firmware registers ASoC: Intel: Skylake: Add sram address to sst_addr structure ASoC: Intel: Skylake: Debugfs facility to dump module config ASoC: Intel: Skylake: Add debugfs support ASoC: fix semicolon.cocci warnings ASoC: rt5645: Add quirk override by module option ASoC: rsnd: make arrays path and cmd_case static const ASoC: audio-graph-card: add widgets and routing for external amplifier support ASoC: audio-graph-card: update bindings for amplifier support ASoC: rt5665: calibration should be done before jack detection ASoC: rsnd: constify dev_pm_ops structures. ASoC: nau8825: change crosstalk-bypass property to bool type ...
Diffstat (limited to 'sound/core/timer.c')
-rw-r--r--sound/core/timer.c125
1 files changed, 60 insertions, 65 deletions
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 884c3066b028..a9b9a277e00c 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -319,6 +319,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
319 *ti = timeri; 319 *ti = timeri;
320 return 0; 320 return 0;
321} 321}
322EXPORT_SYMBOL(snd_timer_open);
322 323
323/* 324/*
324 * close a timer instance 325 * close a timer instance
@@ -384,6 +385,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
384 mutex_unlock(&register_mutex); 385 mutex_unlock(&register_mutex);
385 return 0; 386 return 0;
386} 387}
388EXPORT_SYMBOL(snd_timer_close);
387 389
388unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) 390unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
389{ 391{
@@ -398,6 +400,7 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
398 } 400 }
399 return 0; 401 return 0;
400} 402}
403EXPORT_SYMBOL(snd_timer_resolution);
401 404
402static void snd_timer_notify1(struct snd_timer_instance *ti, int event) 405static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
403{ 406{
@@ -589,6 +592,7 @@ int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
589 else 592 else
590 return snd_timer_start1(timeri, true, ticks); 593 return snd_timer_start1(timeri, true, ticks);
591} 594}
595EXPORT_SYMBOL(snd_timer_start);
592 596
593/* 597/*
594 * stop the timer instance. 598 * stop the timer instance.
@@ -602,6 +606,7 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
602 else 606 else
603 return snd_timer_stop1(timeri, true); 607 return snd_timer_stop1(timeri, true);
604} 608}
609EXPORT_SYMBOL(snd_timer_stop);
605 610
606/* 611/*
607 * start again.. the tick is kept. 612 * start again.. the tick is kept.
@@ -617,6 +622,7 @@ int snd_timer_continue(struct snd_timer_instance *timeri)
617 else 622 else
618 return snd_timer_start1(timeri, false, 0); 623 return snd_timer_start1(timeri, false, 0);
619} 624}
625EXPORT_SYMBOL(snd_timer_continue);
620 626
621/* 627/*
622 * pause.. remember the ticks left 628 * pause.. remember the ticks left
@@ -628,6 +634,7 @@ int snd_timer_pause(struct snd_timer_instance * timeri)
628 else 634 else
629 return snd_timer_stop1(timeri, false); 635 return snd_timer_stop1(timeri, false);
630} 636}
637EXPORT_SYMBOL(snd_timer_pause);
631 638
632/* 639/*
633 * reschedule the timer 640 * reschedule the timer
@@ -809,6 +816,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
809 if (use_tasklet) 816 if (use_tasklet)
810 tasklet_schedule(&timer->task_queue); 817 tasklet_schedule(&timer->task_queue);
811} 818}
819EXPORT_SYMBOL(snd_timer_interrupt);
812 820
813/* 821/*
814 822
@@ -859,6 +867,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
859 *rtimer = timer; 867 *rtimer = timer;
860 return 0; 868 return 0;
861} 869}
870EXPORT_SYMBOL(snd_timer_new);
862 871
863static int snd_timer_free(struct snd_timer *timer) 872static int snd_timer_free(struct snd_timer *timer)
864{ 873{
@@ -978,6 +987,7 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam
978 } 987 }
979 spin_unlock_irqrestore(&timer->lock, flags); 988 spin_unlock_irqrestore(&timer->lock, flags);
980} 989}
990EXPORT_SYMBOL(snd_timer_notify);
981 991
982/* 992/*
983 * exported functions for global timers 993 * exported functions for global timers
@@ -993,11 +1003,13 @@ int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer)
993 tid.subdevice = 0; 1003 tid.subdevice = 0;
994 return snd_timer_new(NULL, id, &tid, rtimer); 1004 return snd_timer_new(NULL, id, &tid, rtimer);
995} 1005}
1006EXPORT_SYMBOL(snd_timer_global_new);
996 1007
997int snd_timer_global_free(struct snd_timer *timer) 1008int snd_timer_global_free(struct snd_timer *timer)
998{ 1009{
999 return snd_timer_free(timer); 1010 return snd_timer_free(timer);
1000} 1011}
1012EXPORT_SYMBOL(snd_timer_global_free);
1001 1013
1002int snd_timer_global_register(struct snd_timer *timer) 1014int snd_timer_global_register(struct snd_timer *timer)
1003{ 1015{
@@ -1007,6 +1019,7 @@ int snd_timer_global_register(struct snd_timer *timer)
1007 dev.device_data = timer; 1019 dev.device_data = timer;
1008 return snd_timer_dev_register(&dev); 1020 return snd_timer_dev_register(&dev);
1009} 1021}
1022EXPORT_SYMBOL(snd_timer_global_register);
1010 1023
1011/* 1024/*
1012 * System timer 1025 * System timer
@@ -1327,6 +1340,33 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1327 wake_up(&tu->qchange_sleep); 1340 wake_up(&tu->qchange_sleep);
1328} 1341}
1329 1342
1343static int realloc_user_queue(struct snd_timer_user *tu, int size)
1344{
1345 struct snd_timer_read *queue = NULL;
1346 struct snd_timer_tread *tqueue = NULL;
1347
1348 if (tu->tread) {
1349 tqueue = kcalloc(size, sizeof(*tqueue), GFP_KERNEL);
1350 if (!tqueue)
1351 return -ENOMEM;
1352 } else {
1353 queue = kcalloc(size, sizeof(*queue), GFP_KERNEL);
1354 if (!queue)
1355 return -ENOMEM;
1356 }
1357
1358 spin_lock_irq(&tu->qlock);
1359 kfree(tu->queue);
1360 kfree(tu->tqueue);
1361 tu->queue_size = size;
1362 tu->queue = queue;
1363 tu->tqueue = tqueue;
1364 tu->qhead = tu->qtail = tu->qused = 0;
1365 spin_unlock_irq(&tu->qlock);
1366
1367 return 0;
1368}
1369
1330static int snd_timer_user_open(struct inode *inode, struct file *file) 1370static int snd_timer_user_open(struct inode *inode, struct file *file)
1331{ 1371{
1332 struct snd_timer_user *tu; 1372 struct snd_timer_user *tu;
@@ -1343,10 +1383,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
1343 init_waitqueue_head(&tu->qchange_sleep); 1383 init_waitqueue_head(&tu->qchange_sleep);
1344 mutex_init(&tu->ioctl_lock); 1384 mutex_init(&tu->ioctl_lock);
1345 tu->ticks = 1; 1385 tu->ticks = 1;
1346 tu->queue_size = 128; 1386 if (realloc_user_queue(tu, 128) < 0) {
1347 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
1348 GFP_KERNEL);
1349 if (tu->queue == NULL) {
1350 kfree(tu); 1387 kfree(tu);
1351 return -ENOMEM; 1388 return -ENOMEM;
1352 } 1389 }
@@ -1618,34 +1655,12 @@ static int snd_timer_user_tselect(struct file *file,
1618 if (err < 0) 1655 if (err < 0)
1619 goto __err; 1656 goto __err;
1620 1657
1621 tu->qhead = tu->qtail = tu->qused = 0; 1658 tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
1622 kfree(tu->queue); 1659 tu->timeri->callback = tu->tread
1623 tu->queue = NULL;
1624 kfree(tu->tqueue);
1625 tu->tqueue = NULL;
1626 if (tu->tread) {
1627 tu->tqueue = kmalloc(tu->queue_size * sizeof(struct snd_timer_tread),
1628 GFP_KERNEL);
1629 if (tu->tqueue == NULL)
1630 err = -ENOMEM;
1631 } else {
1632 tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
1633 GFP_KERNEL);
1634 if (tu->queue == NULL)
1635 err = -ENOMEM;
1636 }
1637
1638 if (err < 0) {
1639 snd_timer_close(tu->timeri);
1640 tu->timeri = NULL;
1641 } else {
1642 tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
1643 tu->timeri->callback = tu->tread
1644 ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; 1660 ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
1645 tu->timeri->ccallback = snd_timer_user_ccallback; 1661 tu->timeri->ccallback = snd_timer_user_ccallback;
1646 tu->timeri->callback_data = (void *)tu; 1662 tu->timeri->callback_data = (void *)tu;
1647 tu->timeri->disconnect = snd_timer_user_disconnect; 1663 tu->timeri->disconnect = snd_timer_user_disconnect;
1648 }
1649 1664
1650 __err: 1665 __err:
1651 return err; 1666 return err;
@@ -1687,8 +1702,6 @@ static int snd_timer_user_params(struct file *file,
1687 struct snd_timer_user *tu; 1702 struct snd_timer_user *tu;
1688 struct snd_timer_params params; 1703 struct snd_timer_params params;
1689 struct snd_timer *t; 1704 struct snd_timer *t;
1690 struct snd_timer_read *tr;
1691 struct snd_timer_tread *ttr;
1692 int err; 1705 int err;
1693 1706
1694 tu = file->private_data; 1707 tu = file->private_data;
@@ -1751,24 +1764,11 @@ static int snd_timer_user_params(struct file *file,
1751 spin_unlock_irq(&t->lock); 1764 spin_unlock_irq(&t->lock);
1752 if (params.queue_size > 0 && 1765 if (params.queue_size > 0 &&
1753 (unsigned int)tu->queue_size != params.queue_size) { 1766 (unsigned int)tu->queue_size != params.queue_size) {
1754 if (tu->tread) { 1767 err = realloc_user_queue(tu, params.queue_size);
1755 ttr = kmalloc(params.queue_size * sizeof(*ttr), 1768 if (err < 0)
1756 GFP_KERNEL); 1769 goto _end;
1757 if (ttr) {
1758 kfree(tu->tqueue);
1759 tu->queue_size = params.queue_size;
1760 tu->tqueue = ttr;
1761 }
1762 } else {
1763 tr = kmalloc(params.queue_size * sizeof(*tr),
1764 GFP_KERNEL);
1765 if (tr) {
1766 kfree(tu->queue);
1767 tu->queue_size = params.queue_size;
1768 tu->queue = tr;
1769 }
1770 }
1771 } 1770 }
1771 spin_lock_irq(&tu->qlock);
1772 tu->qhead = tu->qtail = tu->qused = 0; 1772 tu->qhead = tu->qtail = tu->qused = 0;
1773 if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { 1773 if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
1774 if (tu->tread) { 1774 if (tu->tread) {
@@ -1789,6 +1789,7 @@ static int snd_timer_user_params(struct file *file,
1789 } 1789 }
1790 tu->filter = params.filter; 1790 tu->filter = params.filter;
1791 tu->ticks = params.ticks; 1791 tu->ticks = params.ticks;
1792 spin_unlock_irq(&tu->qlock);
1792 err = 0; 1793 err = 0;
1793 _end: 1794 _end:
1794 if (copy_to_user(_params, &params, sizeof(params))) 1795 if (copy_to_user(_params, &params, sizeof(params)))
@@ -1891,13 +1892,19 @@ static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
1891 return snd_timer_user_next_device(argp); 1892 return snd_timer_user_next_device(argp);
1892 case SNDRV_TIMER_IOCTL_TREAD: 1893 case SNDRV_TIMER_IOCTL_TREAD:
1893 { 1894 {
1894 int xarg; 1895 int xarg, old_tread;
1895 1896
1896 if (tu->timeri) /* too late */ 1897 if (tu->timeri) /* too late */
1897 return -EBUSY; 1898 return -EBUSY;
1898 if (get_user(xarg, p)) 1899 if (get_user(xarg, p))
1899 return -EFAULT; 1900 return -EFAULT;
1901 old_tread = tu->tread;
1900 tu->tread = xarg ? 1 : 0; 1902 tu->tread = xarg ? 1 : 0;
1903 if (tu->tread != old_tread &&
1904 realloc_user_queue(tu, tu->queue_size) < 0) {
1905 tu->tread = old_tread;
1906 return -ENOMEM;
1907 }
1901 return 0; 1908 return 0;
1902 } 1909 }
1903 case SNDRV_TIMER_IOCTL_GINFO: 1910 case SNDRV_TIMER_IOCTL_GINFO:
@@ -2030,10 +2037,12 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
2030 poll_wait(file, &tu->qchange_sleep, wait); 2037 poll_wait(file, &tu->qchange_sleep, wait);
2031 2038
2032 mask = 0; 2039 mask = 0;
2040 spin_lock_irq(&tu->qlock);
2033 if (tu->qused) 2041 if (tu->qused)
2034 mask |= POLLIN | POLLRDNORM; 2042 mask |= POLLIN | POLLRDNORM;
2035 if (tu->disconnected) 2043 if (tu->disconnected)
2036 mask |= POLLERR; 2044 mask |= POLLERR;
2045 spin_unlock_irq(&tu->qlock);
2037 2046
2038 return mask; 2047 return mask;
2039} 2048}
@@ -2117,17 +2126,3 @@ static void __exit alsa_timer_exit(void)
2117 2126
2118module_init(alsa_timer_init) 2127module_init(alsa_timer_init)
2119module_exit(alsa_timer_exit) 2128module_exit(alsa_timer_exit)
2120
2121EXPORT_SYMBOL(snd_timer_open);
2122EXPORT_SYMBOL(snd_timer_close);
2123EXPORT_SYMBOL(snd_timer_resolution);
2124EXPORT_SYMBOL(snd_timer_start);
2125EXPORT_SYMBOL(snd_timer_stop);
2126EXPORT_SYMBOL(snd_timer_continue);
2127EXPORT_SYMBOL(snd_timer_pause);
2128EXPORT_SYMBOL(snd_timer_new);
2129EXPORT_SYMBOL(snd_timer_notify);
2130EXPORT_SYMBOL(snd_timer_global_new);
2131EXPORT_SYMBOL(snd_timer_global_free);
2132EXPORT_SYMBOL(snd_timer_global_register);
2133EXPORT_SYMBOL(snd_timer_interrupt);