aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/au1550_ac97.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-08-16 00:32:24 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-08-16 00:32:24 -0400
commitbbcf6e8b66ab2fb5ddab4d0fe40c2e6a5ebe5301 (patch)
tree071fa9f86dc04a16570be367d04cff3b00c694ad /sound/oss/au1550_ac97.c
parent57682827b9a5edb52e33af0be9082b51bffcd5c7 (diff)
parentda5cabf80e2433131bf0ed8993abc0f7ea618c73 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: arch/sh/include/asm/Kbuild drivers/Makefile Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'sound/oss/au1550_ac97.c')
-rw-r--r--sound/oss/au1550_ac97.c92
1 files changed, 52 insertions, 40 deletions
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index c1070e33b32f..c6f2621221ba 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -43,13 +43,13 @@
43#include <linux/sound.h> 43#include <linux/sound.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/soundcard.h> 45#include <linux/soundcard.h>
46#include <linux/smp_lock.h>
46#include <linux/init.h> 47#include <linux/init.h>
47#include <linux/interrupt.h> 48#include <linux/interrupt.h>
48#include <linux/kernel.h> 49#include <linux/kernel.h>
49#include <linux/poll.h> 50#include <linux/poll.h>
50#include <linux/bitops.h> 51#include <linux/bitops.h>
51#include <linux/spinlock.h> 52#include <linux/spinlock.h>
52#include <linux/smp_lock.h>
53#include <linux/ac97_codec.h> 53#include <linux/ac97_codec.h>
54#include <linux/mutex.h> 54#include <linux/mutex.h>
55 55
@@ -162,19 +162,10 @@ ld2(unsigned int x)
162static void 162static void
163au1550_delay(int msec) 163au1550_delay(int msec)
164{ 164{
165 unsigned long tmo;
166 signed long tmo2;
167
168 if (in_interrupt()) 165 if (in_interrupt())
169 return; 166 return;
170 167
171 tmo = jiffies + (msec * HZ) / 1000; 168 schedule_timeout_uninterruptible(msecs_to_jiffies(msec));
172 for (;;) {
173 tmo2 = tmo - jiffies;
174 if (tmo2 <= 0)
175 break;
176 schedule_timeout(tmo2);
177 }
178} 169}
179 170
180static u16 171static u16
@@ -807,7 +798,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin)
807static int 798static int
808au1550_open_mixdev(struct inode *inode, struct file *file) 799au1550_open_mixdev(struct inode *inode, struct file *file)
809{ 800{
801 lock_kernel();
810 file->private_data = &au1550_state; 802 file->private_data = &au1550_state;
803 unlock_kernel();
811 return 0; 804 return 0;
812} 805}
813 806
@@ -824,22 +817,26 @@ mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
824 return codec->mixer_ioctl(codec, cmd, arg); 817 return codec->mixer_ioctl(codec, cmd, arg);
825} 818}
826 819
827static int 820static long
828au1550_ioctl_mixdev(struct inode *inode, struct file *file, 821au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
829 unsigned int cmd, unsigned long arg)
830{ 822{
831 struct au1550_state *s = (struct au1550_state *)file->private_data; 823 struct au1550_state *s = (struct au1550_state *)file->private_data;
832 struct ac97_codec *codec = s->codec; 824 struct ac97_codec *codec = s->codec;
825 int ret;
833 826
834 return mixdev_ioctl(codec, cmd, arg); 827 lock_kernel();
828 ret = mixdev_ioctl(codec, cmd, arg);
829 unlock_kernel();
830
831 return ret;
835} 832}
836 833
837static /*const */ struct file_operations au1550_mixer_fops = { 834static /*const */ struct file_operations au1550_mixer_fops = {
838 owner:THIS_MODULE, 835 .owner = THIS_MODULE,
839 llseek:au1550_llseek, 836 .llseek = au1550_llseek,
840 ioctl:au1550_ioctl_mixdev, 837 .unlocked_ioctl = au1550_ioctl_mixdev,
841 open:au1550_open_mixdev, 838 .open = au1550_open_mixdev,
842 release:au1550_release_mixdev, 839 .release = au1550_release_mixdev,
843}; 840};
844 841
845static int 842static int
@@ -1343,8 +1340,7 @@ dma_count_done(struct dmabuf *db)
1343 1340
1344 1341
1345static int 1342static int
1346au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 1343au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1347 unsigned long arg)
1348{ 1344{
1349 struct au1550_state *s = (struct au1550_state *)file->private_data; 1345 struct au1550_state *s = (struct au1550_state *)file->private_data;
1350 unsigned long flags; 1346 unsigned long flags;
@@ -1780,6 +1776,17 @@ au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1780 return mixdev_ioctl(s->codec, cmd, arg); 1776 return mixdev_ioctl(s->codec, cmd, arg);
1781} 1777}
1782 1778
1779static long
1780au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1781{
1782 int ret;
1783
1784 lock_kernel();
1785 ret = au1550_ioctl(file, cmd, arg);
1786 unlock_kernel();
1787
1788 return ret;
1789}
1783 1790
1784static int 1791static int
1785au1550_open(struct inode *inode, struct file *file) 1792au1550_open(struct inode *inode, struct file *file)
@@ -1797,21 +1804,22 @@ au1550_open(struct inode *inode, struct file *file)
1797#endif 1804#endif
1798 1805
1799 file->private_data = s; 1806 file->private_data = s;
1807 lock_kernel();
1800 /* wait for device to become free */ 1808 /* wait for device to become free */
1801 mutex_lock(&s->open_mutex); 1809 mutex_lock(&s->open_mutex);
1802 while (s->open_mode & file->f_mode) { 1810 while (s->open_mode & file->f_mode) {
1803 if (file->f_flags & O_NONBLOCK) { 1811 ret = -EBUSY;
1804 mutex_unlock(&s->open_mutex); 1812 if (file->f_flags & O_NONBLOCK)
1805 return -EBUSY; 1813 goto out;
1806 }
1807 add_wait_queue(&s->open_wait, &wait); 1814 add_wait_queue(&s->open_wait, &wait);
1808 __set_current_state(TASK_INTERRUPTIBLE); 1815 __set_current_state(TASK_INTERRUPTIBLE);
1809 mutex_unlock(&s->open_mutex); 1816 mutex_unlock(&s->open_mutex);
1810 schedule(); 1817 schedule();
1811 remove_wait_queue(&s->open_wait, &wait); 1818 remove_wait_queue(&s->open_wait, &wait);
1812 set_current_state(TASK_RUNNING); 1819 set_current_state(TASK_RUNNING);
1820 ret = -ERESTARTSYS;
1813 if (signal_pending(current)) 1821 if (signal_pending(current))
1814 return -ERESTARTSYS; 1822 goto out2;
1815 mutex_lock(&s->open_mutex); 1823 mutex_lock(&s->open_mutex);
1816 } 1824 }
1817 1825
@@ -1840,17 +1848,21 @@ au1550_open(struct inode *inode, struct file *file)
1840 1848
1841 if (file->f_mode & FMODE_READ) { 1849 if (file->f_mode & FMODE_READ) {
1842 if ((ret = prog_dmabuf_adc(s))) 1850 if ((ret = prog_dmabuf_adc(s)))
1843 return ret; 1851 goto out;
1844 } 1852 }
1845 if (file->f_mode & FMODE_WRITE) { 1853 if (file->f_mode & FMODE_WRITE) {
1846 if ((ret = prog_dmabuf_dac(s))) 1854 if ((ret = prog_dmabuf_dac(s)))
1847 return ret; 1855 goto out;
1848 } 1856 }
1849 1857
1850 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 1858 s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
1851 mutex_unlock(&s->open_mutex);
1852 mutex_init(&s->sem); 1859 mutex_init(&s->sem);
1853 return 0; 1860 ret = 0;
1861out:
1862 mutex_unlock(&s->open_mutex);
1863out2:
1864 unlock_kernel();
1865 return ret;
1854} 1866}
1855 1867
1856static int 1868static int
@@ -1885,15 +1897,15 @@ au1550_release(struct inode *inode, struct file *file)
1885} 1897}
1886 1898
1887static /*const */ struct file_operations au1550_audio_fops = { 1899static /*const */ struct file_operations au1550_audio_fops = {
1888 owner: THIS_MODULE, 1900 .owner = THIS_MODULE,
1889 llseek: au1550_llseek, 1901 .llseek = au1550_llseek,
1890 read: au1550_read, 1902 .read = au1550_read,
1891 write: au1550_write, 1903 .write = au1550_write,
1892 poll: au1550_poll, 1904 .poll = au1550_poll,
1893 ioctl: au1550_ioctl, 1905 .unlocked_ioctl = au1550_unlocked_ioctl,
1894 mmap: au1550_mmap, 1906 .mmap = au1550_mmap,
1895 open: au1550_open, 1907 .open = au1550_open,
1896 release: au1550_release, 1908 .release = au1550_release,
1897}; 1909};
1898 1910
1899MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com"); 1911MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");