diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-12-20 23:39:47 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-12-20 23:39:47 +0100 |
commit | 55fa518867978e1f5fd8353098f80d125ac734d7 (patch) | |
tree | 3502b331c1f9ec4cac25dc8ba30b6a0a324e350c /sound | |
parent | bb1f24bf00a85f666b56a09b7cdbfd221af16c2c (diff) | |
parent | eea0579fc85e64e9f05361d5aacf496fe7a151aa (diff) |
Merge branch 'topic/pcsp-fix' into topic/misc
Diffstat (limited to 'sound')
60 files changed, 855 insertions, 546 deletions
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h index 622cd37a011..a0f223c13f6 100644 --- a/sound/aoa/soundbus/soundbus.h +++ b/sound/aoa/soundbus/soundbus.h @@ -8,7 +8,7 @@ #ifndef __SOUNDBUS_H #define __SOUNDBUS_H -#include <asm/of_device.h> +#include <linux/of_device.h> #include <sound/pcm.h> #include <linux/list.h> diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index cba71d86754..c2635beb4c8 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -44,7 +44,7 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { .name = "AC97 PCM out", .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRTXPCDR, + .drcmr = &DRCMR(12), .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST32 | DCMD_WIDTH4, }; @@ -52,7 +52,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = { .name = "AC97 PCM in", .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRRXPCDR, + .drcmr = &DRCMR(11), .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_WIDTH4, }; diff --git a/sound/core/control.c b/sound/core/control.c index b0bf4269104..636b3b52ef8 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -113,7 +113,6 @@ static int snd_ctl_release(struct inode *inode, struct file *file) unsigned int idx; ctl = file->private_data; - fasync_helper(-1, file, 0, &ctl->fasync); file->private_data = NULL; card = ctl->card; write_lock_irqsave(&card->ctl_files_rwlock, flags); diff --git a/sound/core/init.c b/sound/core/init.c index 8af467df924..b47ff8b44be 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -264,8 +264,11 @@ static int snd_disconnect_release(struct inode *inode, struct file *file) } spin_unlock(&shutdown_lock); - if (likely(df)) + if (likely(df)) { + if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync) + df->disconnected_f_op->fasync(-1, file, 0); return df->disconnected_f_op->release(inode, file); + } panic("%s(%p, %p) failed!", __func__, inode, file); } @@ -549,9 +552,9 @@ int snd_card_register(struct snd_card *card) return -EINVAL; #ifndef CONFIG_SYSFS_DEPRECATED if (!card->card_dev) { - card->card_dev = device_create_drvdata(sound_class, card->dev, - MKDEV(0, 0), NULL, - "card%i", card->number); + card->card_dev = device_create(sound_class, card->dev, + MKDEV(0, 0), NULL, + "card%i", card->number); if (IS_ERR(card->card_dev)) card->card_dev = NULL; } diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index a7b46ec72f3..1b3534d6768 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -33,9 +33,6 @@ #include <linux/moduleparam.h> #include <linux/mutex.h> #include <sound/memalloc.h> -#ifdef CONFIG_SBUS -#include <asm/sbus.h> -#endif MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>"); @@ -162,39 +159,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, } #endif /* CONFIG_HAS_DMA */ -#ifdef CONFIG_SBUS - -static void *snd_malloc_sbus_pages(struct device *dev, size_t size, - dma_addr_t *dma_addr) -{ - struct sbus_dev *sdev = (struct sbus_dev *)dev; - int pg; - void *res; - - if (WARN_ON(!dma_addr)) - return NULL; - pg = get_order(size); - res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr); - if (res != NULL) - inc_snd_pages(pg); - return res; -} - -static void snd_free_sbus_pages(struct device *dev, size_t size, - void *ptr, dma_addr_t dma_addr) -{ - struct sbus_dev *sdev = (struct sbus_dev *)dev; - int pg; - - if (ptr == NULL) - return; - pg = get_order(size); - dec_snd_pages(pg); - sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr); -} - -#endif /* CONFIG_SBUS */ - /* * * ALSA generic memory management @@ -231,11 +195,6 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size, dmab->area = snd_malloc_pages(size, (unsigned long)device); dmab->addr = 0; break; -#ifdef CONFIG_SBUS - case SNDRV_DMA_TYPE_SBUS: - dmab->area = snd_malloc_sbus_pages(device, size, &dmab->addr); - break; -#endif #ifdef CONFIG_HAS_DMA case SNDRV_DMA_TYPE_DEV: dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); @@ -306,11 +265,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) case SNDRV_DMA_TYPE_CONTINUOUS: snd_free_pages(dmab->area, dmab->bytes); break; -#ifdef CONFIG_SBUS - case SNDRV_DMA_TYPE_SBUS: - snd_free_sbus_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); - break; -#endif #ifdef CONFIG_HAS_DMA case SNDRV_DMA_TYPE_DEV: snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); @@ -419,7 +373,7 @@ static int snd_mem_proc_read(struct seq_file *seq, void *offset) long pages = snd_allocated_pages >> (PAGE_SHIFT-12); struct snd_mem_list *mem; int devno; - static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; + static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" }; mutex_lock(&list_mutex); seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n", diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 1af62b8b86c..e17836680f4 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -2283,7 +2283,7 @@ static int snd_pcm_oss_open_file(struct file *file, int idx, err; struct snd_pcm_oss_file *pcm_oss_file; struct snd_pcm_substream *substream; - unsigned int f_mode = file->f_mode; + fmode_t f_mode = file->f_mode; if (rpcm_oss_file) *rpcm_oss_file = NULL; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index aef18682c03..a789efc9df3 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -2169,7 +2169,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file) if (snd_BUG_ON(!substream)) return -ENXIO; pcm = substream->pcm; - fasync_helper(-1, file, 0, &substream->runtime->fasync); mutex_lock(&pcm->open_mutex); snd_pcm_release_substream(substream); kfree(pcm_file); diff --git a/sound/core/sound.c b/sound/core/sound.c index c0685e2f0af..44a69bb8d4f 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -274,9 +274,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, return minor; } snd_minors[minor] = preg; - preg->dev = device_create_drvdata(sound_class, device, - MKDEV(major, minor), - private_data, "%s", name); + preg->dev = device_create(sound_class, device, MKDEV(major, minor), + private_data, "%s", name); if (IS_ERR(preg->dev)) { snd_minors[minor] = NULL; mutex_unlock(&sound_mutex); diff --git a/sound/core/timer.c b/sound/core/timer.c index e582face89d..c584408c9f1 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1263,7 +1263,6 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) if (file->private_data) { tu = file->private_data; file->private_data = NULL; - fasync_helper(-1, file, 0, &tu->fasync); if (tu->timeri) snd_timer_close(tu->timeri); kfree(tu->queue); diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index 70533a333b5..cdef2664218 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h @@ -62,6 +62,8 @@ struct snd_pcsp { unsigned short port, irq, dma; spinlock_t substream_lock; struct snd_pcm_substream *playback_substream; + unsigned int fmt_size; + unsigned int is_signed; size_t playback_ptr; size_t period_ptr; atomic_t timer_active; diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index 40f95f549d2..84cc2658c05 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -36,12 +36,13 @@ static void pcsp_call_pcm_elapsed(unsigned long priv) static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0); -enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) +/* write the port and returns the next expire time in ns; + * called at the trigger-start and in hrtimer callback + */ +static unsigned long pcsp_timer_update(struct hrtimer *handle) { unsigned char timer_cnt, val; - int fmt_size, periods_elapsed; u64 ns; - size_t period_bytes, buffer_bytes; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); @@ -51,28 +52,25 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) outb(chip->val61, 0x61); chip->thalf = 0; if (!atomic_read(&chip->timer_active)) - goto stop; - hrtimer_forward(&chip->timer, chip->timer.expires, - ktime_set(0, chip->ns_rem)); - return HRTIMER_RESTART; + return 0; + return chip->ns_rem; } if (!atomic_read(&chip->timer_active)) - goto stop; + return 0; substream = chip->playback_substream; if (!substream) - goto stop; + return 0; runtime = substream->runtime; - fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3; /* assume it is mono! */ - val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; - if (snd_pcm_format_signed(runtime->format)) + val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1]; + if (chip->is_signed) val ^= 0x80; timer_cnt = val * CUR_DIV() / 256; if (timer_cnt && chip->enable) { - spin_lock(&i8253_lock); + spin_lock_irqsave(&i8253_lock, flags); if (!nforce_wa) { outb_p(chip->val61, 0x61); outb_p(timer_cnt, 0x42); @@ -81,14 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) outb(chip->val61 ^ 2, 0x61); chip->thalf = 1; } - spin_unlock(&i8253_lock); + spin_unlock_irqrestore(&i8253_lock, flags); } + chip->ns_rem = PCSP_PERIOD_NS(); + ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem); + chip->ns_rem -= ns; + return ns; +} + +enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) +{ + struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); + struct snd_pcm_substream *substream; + int periods_elapsed, pointer_update; + size_t period_bytes, buffer_bytes; + unsigned long ns; + unsigned long flags; + + pointer_update = !chip->thalf; + ns = pcsp_timer_update(handle); + if (!ns) + return HRTIMER_NORESTART; + + /* update the playback position */ + substream = chip->playback_substream; + if (!substream) + return HRTIMER_NORESTART; + period_bytes = snd_pcm_lib_period_bytes(substream); buffer_bytes = snd_pcm_lib_buffer_bytes(substream); spin_lock_irqsave(&chip->substream_lock, flags); - chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; + chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size; periods_elapsed = chip->playback_ptr - chip->period_ptr; if (periods_elapsed < 0) { #if PCSP_DEBUG @@ -106,31 +129,27 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) if (periods_elapsed) { chip->period_ptr += periods_elapsed * period_bytes; chip->period_ptr %= buffer_bytes; - tasklet_schedule(&pcsp_pcm_tasklet); } spin_unlock_irqrestore(&chip->substream_lock, flags); - if (!atomic_read(&chip->timer_active)) - goto stop; + if (periods_elapsed) + tasklet_schedule(&pcsp_pcm_tasklet); - chip->ns_rem = PCSP_PERIOD_NS(); - ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem); - chip->ns_rem -= ns; - hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns)); - return HRTIMER_RESTART; + hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); - stop: - return HRTIMER_NORESTART; + return HRTIMER_RESTART; } -static void pcsp_start_playing(struct snd_pcsp *chip) +static int pcsp_start_playing(struct snd_pcsp *chip) { + unsigned long ns; + #if PCSP_DEBUG printk(KERN_INFO "PCSP: start_playing called\n"); #endif if (atomic_read(&chip->timer_active)) { printk(KERN_ERR "PCSP: Timer already active\n"); - return; + return -EIO; } spin_lock(&i8253_lock); @@ -140,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip) atomic_set(&chip->timer_active, 1); chip->thalf = 0; - hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); + ns = pcsp_timer_update(&pcsp_chip.timer); + if (!ns) + return -EIO; + + hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL); + return 0; } static void pcsp_stop_playing(struct snd_pcsp *chip) @@ -220,6 +244,9 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream) pcsp_sync_stop(chip); chip->playback_ptr = 0; chip->period_ptr = 0; + chip->fmt_size = + snd_pcm_format_physical_width(substream->runtime->format) >> 3; + chip->is_signed = snd_pcm_format_signed(substream->runtime->format); return 0; } @@ -232,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - pcsp_start_playing(chip); - break; + return pcsp_start_playing(chip); case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: pcsp_stop_playing(chip); diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 83e90057270..c13a178383b 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -87,8 +87,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea) static int snd_tea575x_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data) { - struct video_device *dev = video_devdata(file); - struct snd_tea575x *tea = video_get_drvdata(dev); + struct snd_tea575x *tea = video_drvdata(file); void __user *arg = (void __user *)data; switch(cmd) { @@ -175,6 +174,21 @@ static void snd_tea575x_release(struct video_device *vfd) { } +static int snd_tea575x_exclusive_open(struct inode *inode, struct file *file) +{ + struct snd_tea575x *tea = video_drvdata(file); + + return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0; +} + +static int snd_tea575x_exclusive_release(struct inode *inode, struct file *file) +{ + struct snd_tea575x *tea = video_drvdata(file); + + clear_bit(0, &tea->in_use); + return 0; +} + /* * initialize all the tea575x chips */ @@ -193,9 +207,10 @@ void snd_tea575x_init(struct snd_tea575x *tea) tea->vd.release = snd_tea575x_release; video_set_drvdata(&tea->vd, tea); tea->vd.fops = &tea->fops; + tea->in_use = 0; tea->fops.owner = tea->card->module; - tea->fops.open = video_exclusive_open; - tea->fops.release = video_exclusive_release; + tea->fops.open = snd_tea575x_exclusive_open; + tea->fops.release = snd_tea575x_exclusive_release; tea->fops.ioctl = snd_tea575x_ioctl; if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) { snd_printk(KERN_ERR "unable to register tea575x tuner\n"); diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 660beb41f76..ce0aa044e27 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -211,7 +211,7 @@ config SND_GUSCLASSIC config SND_GUSEXTREME tristate "Gravis UltraSound Extreme" - select SND_HWDEP + select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM help diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index 23018a7c063..81e1f443d09 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -93,7 +93,7 @@ static struct au1550_state { spinlock_t lock; struct mutex open_mutex; struct mutex sem; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; struct dmabuf { diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index d978b009656..1308d8d3418 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -129,7 +129,7 @@ typedef struct { int (*mixer_ioctl)(u_int, u_long); /* optional */ int (*write_sq_setup)(void); /* optional */ int (*read_sq_setup)(void); /* optional */ - int (*sq_open)(mode_t); /* optional */ + int (*sq_open)(fmode_t); /* optional */ int (*state_info)(char *, size_t); /* optional */ void (*abort_read)(void); /* optional */ int min_dsp_speed; @@ -235,7 +235,7 @@ struct sound_queue { */ int active; wait_queue_head_t action_queue, open_queue, sync_queue; - int open_mode; + int non_blocking; int busy, syncing, xruns, died; }; diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 285239d64b8..4d45bd63718 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c @@ -143,7 +143,7 @@ static int AtaMixerIoctl(u_int cmd, u_long arg); static int TTMixerIoctl(u_int cmd, u_long arg); static int FalconMixerIoctl(u_int cmd, u_long arg); static int AtaWriteSqSetup(void); -static int AtaSqOpen(mode_t mode); +static int AtaSqOpen(fmode_t mode); static int TTStateInfo(char *buffer, size_t space); static int FalconStateInfo(char *buffer, size_t space); @@ -1461,7 +1461,7 @@ static int AtaWriteSqSetup(void) return 0 ; } -static int AtaSqOpen(mode_t mode) +static int AtaSqOpen(fmode_t mode) { write_sq_ignore_int = 1; return 0 ; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 95fc5c68175..793b7f47843 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -212,7 +212,7 @@ static int irq_installed; #endif /* MODULE */ /* control over who can modify resources shared between play/record */ -static mode_t shared_resource_owner; +static fmode_t shared_resource_owner; static int shared_resources_initialised; /* @@ -603,7 +603,7 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft, while (uLeft) { while (write_sq.count >= write_sq.max_active) { sq_play(); - if (write_sq.open_mode & O_NONBLOCK) + if (write_sq.non_blocking) return uWritten > 0 ? uWritten : -EAGAIN; SLEEP(write_sq.action_queue); if (signal_pending(current)) @@ -668,7 +668,7 @@ static inline void sq_init_waitqueue(struct sound_queue *sq) #if 0 /* blocking open() */ static inline void sq_wake_up(struct sound_queue *sq, struct file *file, - mode_t mode) + fmode_t mode) { if (file->f_mode & mode) { sq->busy = 0; /* CHECK: IS THIS OK??? */ @@ -677,7 +677,7 @@ static inline void sq_wake_up(struct sound_queue *sq, struct file *file, } #endif -static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode, +static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode, int numbufs, int bufsize) |