From f11947c7c5b8abffd328739996dfdffef2b3e03f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 2 Apr 2010 14:29:23 +0300 Subject: ALSA: i2c: cleanup: change parameter to pointer We actually pass an array of 7 chars not 5. This silences a smatch warning. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- include/sound/ak4113.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/sound') diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h index 8988edae1609..2609048c1d44 100644 --- a/include/sound/ak4113.h +++ b/include/sound/ak4113.h @@ -307,7 +307,7 @@ struct ak4113 { int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, ak4113_write_t *write, - const unsigned char pgm[AK4113_WRITABLE_REGS], + const unsigned char *pgm, void *private_data, struct ak4113 **r_ak4113); void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg, unsigned char mask, unsigned char val); -- cgit v1.2.3 From 24e4a1211f691fc671de44685430dbad757d8487 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Apr 2010 11:22:01 +0200 Subject: ALSA: info - Use standard types for info callbacks Use loff_t, size_t and ssize_t for arguments of info callbacks to follow the standard procfs. Signed-off-by: Takashi Iwai --- include/sound/info.h | 24 ++++++++++++------------ sound/drivers/opl4/opl4_proc.c | 21 +++++++++++++-------- sound/isa/gus/gus_mem_proc.c | 16 ++++++++-------- sound/pci/cs4281.c | 16 ++++++++-------- sound/pci/cs46xx/cs46xx_lib.c | 7 ++++--- sound/pci/emu10k1/emuproc.c | 8 ++++---- sound/pci/mixart/mixart.c | 32 ++++++++++++++++---------------- 7 files changed, 65 insertions(+), 59 deletions(-) (limited to 'include/sound') diff --git a/include/sound/info.h b/include/sound/info.h index 112e8949e1a7..4e94cf1ff762 100644 --- a/include/sound/info.h +++ b/include/sound/info.h @@ -51,18 +51,18 @@ struct snd_info_entry_ops { unsigned short mode, void **file_private_data); int (*release)(struct snd_info_entry *entry, unsigned short mode, void *file_private_data); - long (*read)(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos); - long (*write)(struct snd_info_entry *entry, void *file_private_data, - struct file *file, const char __user *buf, - unsigned long count, unsigned long pos); - long long (*llseek)(struct snd_info_entry *entry, - void *file_private_data, struct file *file, - long long offset, int orig); - unsigned int(*poll)(struct snd_info_entry *entry, - void *file_private_data, struct file *file, - poll_table *wait); + ssize_t (*read)(struct snd_info_entry *entry, void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos); + ssize_t (*write)(struct snd_info_entry *entry, void *file_private_data, + struct file *file, const char __user *buf, + size_t count, loff_t pos); + loff_t (*llseek)(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + loff_t offset, int orig); + unsigned int (*poll)(struct snd_info_entry *entry, + void *file_private_data, struct file *file, + poll_table *wait); int (*ioctl)(struct snd_info_entry *entry, void *file_private_data, struct file *file, unsigned int cmd, unsigned long arg); int (*mmap)(struct snd_info_entry *entry, void *file_private_data, diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index 1679300b7583..eb72814dfd5f 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c @@ -49,9 +49,10 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry, return 0; } -static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *_buf, - unsigned long count, unsigned long pos) +static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *_buf, + size_t count, loff_t pos) { struct snd_opl4 *opl4 = entry->private_data; long size; @@ -75,9 +76,11 @@ static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_priv return 0; } -static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_private_data, - struct file *file, const char __user *_buf, - unsigned long count, unsigned long pos) +static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + const char __user *_buf, + size_t count, size_t pos) { struct snd_opl4 *opl4 = entry->private_data; long size; @@ -101,8 +104,10 @@ static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_pri return 0; } -static long long snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, void *file_private_data, - struct file *file, long long offset, int orig) +static loff_t snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + loff_t offset, int orig) { switch (orig) { case SEEK_SET: diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index 2803e227aec9..b2d2dba6c860 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -31,9 +31,10 @@ struct gus_proc_private { struct snd_gus_card * gus; }; -static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { long size; struct gus_proc_private *priv = entry->private_data; @@ -51,11 +52,10 @@ static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_priva return 0; } -static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) +static loff_t snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, + void *private_file_data, + struct file *file, + loff_t offset, int orig) { struct gus_proc_private *priv = entry->private_data; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 9edc65059e3e..b0bba2e86b12 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1139,10 +1139,10 @@ static void snd_cs4281_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq); } -static long snd_cs4281_BA0_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { long size; struct cs4281 *chip = entry->private_data; @@ -1157,10 +1157,10 @@ static long snd_cs4281_BA0_read(struct snd_info_entry *entry, return size; } -static long snd_cs4281_BA1_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { long size; struct cs4281 *chip = entry->private_data; diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 3f99a5e8528c..08117b142381 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -2657,9 +2657,10 @@ static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { } * proc interface */ -static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { long size; struct snd_cs46xx_region *region = entry->private_data; diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index baa7cd508cd8..347b2415db59 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -341,10 +341,10 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry, #define TOTAL_SIZE_CODE (0x200*8) #define A_TOTAL_SIZE_CODE (0x400*8) -static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { long size; struct snd_emu10k1 *emu = entry->private_data; diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 3be8f97c8bc0..b5df78bcc25b 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1102,11 +1102,10 @@ static int snd_mixart_free(struct mixart_mgr *mgr) /* * proc interface */ -static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) +static loff_t snd_mixart_BA0_llseek(struct snd_info_entry *entry, + void *private_file_data, + struct file *file, + loff_t offset, int orig) { offset = offset & ~3; /* 4 bytes aligned */ @@ -1128,11 +1127,10 @@ static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry, return file->f_pos; } -static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) +static loff_t snd_mixart_BA1_llseek(struct snd_info_entry *entry, + void *private_file_data, + struct file *file, + loff_t offset, int orig) { offset = offset & ~3; /* 4 bytes aligned */ @@ -1157,9 +1155,10 @@ static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry, /* mixart_BA0 proc interface for BAR 0 - read callback */ -static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { struct mixart_mgr *mgr = entry->private_data; unsigned long maxsize; @@ -1178,9 +1177,10 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private /* mixart_BA1 proc interface for BAR 1 - read callback */ -static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { struct mixart_mgr *mgr = entry->private_data; unsigned long maxsize; -- cgit v1.2.3 From 0340c7dccd80d8706c636e030a6ebbddbddca690 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 16 Apr 2010 13:10:10 +0200 Subject: ALSA: Release v1.0.23 Signed-off-by: Jaroslav Kysela --- include/sound/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/sound') diff --git a/include/sound/version.h b/include/sound/version.h index 7fed23442db8..bf69a5b7e65f 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h */ -#define CONFIG_SND_VERSION "1.0.22.1" +#define CONFIG_SND_VERSION "1.0.23" #define CONFIG_SND_DATE "" -- cgit v1.2.3 From 396fa8272601c3d488cb8391c3962a7ee552afd0 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sun, 9 May 2010 20:35:44 +0200 Subject: ALSA: es1688: allocate snd_es1688 structure as a part of snd_card structure Allocate the snd_es1688 during the snd_card allocation. This allows to remove the card pointer from the snd_es1688 structure. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- include/sound/es1688.h | 10 +++++----- sound/isa/es1688/es1688.c | 23 ++++++++++++---------- sound/isa/es1688/es1688_lib.c | 44 ++++++++++++++----------------------------- sound/isa/gus/gusextreme.c | 26 +++++++++++++------------ 4 files changed, 46 insertions(+), 57 deletions(-) (limited to 'include/sound') diff --git a/include/sound/es1688.h b/include/sound/es1688.h index 10fcf1465810..4c29572effb2 100644 --- a/include/sound/es1688.h +++ b/include/sound/es1688.h @@ -44,7 +44,6 @@ struct snd_es1688 { unsigned char pad; unsigned int dma_size; - struct snd_card *card; struct snd_pcm *pcm; struct snd_pcm_substream *playback_substream; struct snd_pcm_substream *capture_substream; @@ -108,14 +107,15 @@ struct snd_es1688 { void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data); int snd_es1688_create(struct snd_card *card, + struct snd_es1688 *chip, unsigned long port, unsigned long mpu_port, int irq, int mpu_irq, int dma8, - unsigned short hardware, - struct snd_es1688 ** rchip); -int snd_es1688_pcm(struct snd_es1688 *chip, int device, struct snd_pcm ** rpcm); -int snd_es1688_mixer(struct snd_es1688 *chip); + unsigned short hardware); +int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device, + struct snd_pcm **rpcm); +int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip); #endif /* __SOUND_ES1688_H */ diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 07df201ed8fa..281679493fb4 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -79,8 +79,8 @@ static int __devinit snd_es1688_match(struct device *dev, unsigned int n) return enable[n]; } -static int __devinit snd_es1688_legacy_create(struct snd_card *card, - struct device *dev, unsigned int n, struct snd_es1688 **rchip) +static int __devinit snd_es1688_legacy_create(struct snd_card *card, + struct snd_es1688 *chip, struct device *dev, unsigned int n) { static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; @@ -104,14 +104,14 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card, } if (port[n] != SNDRV_AUTO_PORT) - return snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + return snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO); i = 0; do { port[n] = possible_ports[i]; - error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + error = snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO); } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); return error; @@ -125,19 +125,22 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); + error = snd_card_create(index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); if (error < 0) return error; - error = snd_es1688_legacy_create(card, dev, n, &chip); + chip = card->private_data; + + error = snd_es1688_legacy_create(card, chip, dev, n); if (error < 0) goto out; - error = snd_es1688_pcm(chip, 0, &pcm); + error = snd_es1688_pcm(card, chip, 0, &pcm); if (error < 0) goto out; - error = snd_es1688_mixer(chip); + error = snd_es1688_mixer(card, chip); if (error < 0) goto out; diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index c76bb00c9d15..fdd440417bf0 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -620,7 +620,6 @@ static int snd_es1688_free(struct snd_es1688 *chip) disable_dma(chip->dma8); free_dma(chip->dma8); } - kfree(chip); return 0; } @@ -638,23 +637,20 @@ static const char *snd_es1688_chip_id(struct snd_es1688 *chip) } int snd_es1688_create(struct snd_card *card, + struct snd_es1688 *chip, unsigned long port, unsigned long mpu_port, int irq, int mpu_irq, int dma8, - unsigned short hardware, - struct snd_es1688 **rchip) + unsigned short hardware) { static struct snd_device_ops ops = { .dev_free = snd_es1688_dev_free, }; - struct snd_es1688 *chip; int err; - *rchip = NULL; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->irq = -1; @@ -662,25 +658,21 @@ int snd_es1688_create(struct snd_card *card, if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) { snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); - snd_es1688_free(chip); return -EBUSY; } if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); - snd_es1688_free(chip); return -EBUSY; } chip->irq = irq; if (request_dma(dma8, "ES1688")) { snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8); - snd_es1688_free(chip); return -EBUSY; } chip->dma8 = dma8; spin_lock_init(&chip->reg_lock); spin_lock_init(&chip->mixer_lock); - chip->card = card; chip->port = port; mpu_port &= ~0x000f; if (mpu_port < 0x300 || mpu_port > 0x330) @@ -689,23 +681,16 @@ int snd_es1688_create(struct snd_card *card, chip->mpu_irq = mpu_irq; chip->hardware = hardware; - if ((err = snd_es1688_probe(chip)) < 0) { - snd_es1688_free(chip); + err = snd_es1688_probe(chip); + if (err < 0) return err; - } - if ((err = snd_es1688_init(chip, 1)) < 0) { - snd_es1688_free(chip); - return err; - } - /* Register device */ - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_es1688_free(chip); + err = snd_es1688_init(chip, 1); + if (err < 0) return err; - } - *rchip = chip; - return 0; + /* Register device */ + return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); } static struct snd_pcm_ops snd_es1688_playback_ops = { @@ -730,12 +715,14 @@ static struct snd_pcm_ops snd_es1688_capture_ops = { .pointer = snd_es1688_capture_pointer, }; -int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm) +int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, + int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0) + err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm); + if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops); @@ -1009,18 +996,15 @@ static unsigned char snd_es1688_init_table[][2] = { { ES1688_REC_DEV, 0x17 } }; -int snd_es1688_mixer(struct snd_es1688 *chip) +int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip) { - struct snd_card *card; unsigned int idx; int err; unsigned char reg, val; - if (snd_BUG_ON(!chip || !chip->card)) + if (snd_BUG_ON(!chip || !card)) return -EINVAL; - card = chip->card; - strcpy(card->mixername, snd_es1688_chip_id(chip)); for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) { diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 65e4b18581a6..008e8e5bfa37 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -95,7 +95,7 @@ static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n) } static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, - struct device *dev, unsigned int n, struct snd_es1688 **rchip) + struct snd_es1688 *chip, struct device *dev, unsigned int n) { static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; @@ -119,14 +119,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, } if (port[n] != SNDRV_AUTO_PORT) - return snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + return snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688); i = 0; do { port[n] = possible_ports[i]; - error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], - mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + error = snd_es1688_create(card, chip, port[n], mpu_port[n], + irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688); } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); return error; @@ -206,9 +206,8 @@ static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus, return 0; } -static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) +static int __devinit snd_gusextreme_mixer(struct snd_card *card) { - struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; int error; @@ -241,17 +240,20 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) struct snd_opl3 *opl3; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card); + error = snd_card_create(index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); if (error < 0) return error; + es1688 = card->private_data; + if (mpu_port[n] == SNDRV_AUTO_PORT) mpu_port[n] = 0; if (mpu_irq[n] > 15) mpu_irq[n] = -1; - error = snd_gusextreme_es1688_create(card, dev, n, &es1688); + error = snd_gusextreme_es1688_create(card, es1688, dev, n); if (error < 0) goto out; @@ -280,11 +282,11 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) } gus->codec_flag = 1; - error = snd_es1688_pcm(es1688, 0, NULL); + error = snd_es1688_pcm(card, es1688, 0, NULL); if (error < 0) goto out; - error = snd_es1688_mixer(es1688); + error = snd_es1688_mixer(card, es1688); if (error < 0) goto out; @@ -300,7 +302,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - error = snd_gusextreme_mixer(es1688); + error = snd_gusextreme_mixer(card); if (error < 0) goto out; -- cgit v1.2.3 From a20971b201ac1fcd236400942c98b0106c42c70a Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Mon, 10 May 2010 09:47:32 +0200 Subject: ALSA: Merge es1688 and es968 drivers The ESS ES968 chip is nothing more then a PnP companion for a non-PnP audio chip. It was paired with non-PnP ESS' chips: ES688 and ES1688. The ESS' audio chips are handled by the es1688 driver in native mode. The PnP cards are handled by the ES968 driver in SB compatible mode. Move the ES968 chip handling to the es1688 driver so the driver can handle both PnP and non-PnP cards. The es968 is removed. Also, a new PnP id is added for the card I acquired (the change was tested on this card). Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 21 +- include/sound/es1688.h | 1 + sound/isa/Kconfig | 16 +- sound/isa/es1688/es1688.c | 205 +++++++++++++++++--- sound/isa/es1688/es1688_lib.c | 3 +- sound/isa/sb/Makefile | 2 - sound/isa/sb/es968.c | 248 ------------------------ 7 files changed, 190 insertions(+), 306 deletions(-) delete mode 100644 sound/isa/sb/es968.c (limited to 'include/sound') diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index dc681badca67..2075bbb8b3e2 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -632,28 +632,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. The power-management is supported. - Module snd-es968 - ---------------- - - Module for sound cards based on ESS ES968 chip (PnP only). - - This module supports multiple cards, PnP and autoprobe. - - The power-management is supported. - Module snd-es1688 ----------------- Module for ESS AudioDrive ES-1688 and ES-688 sound cards. - port - port # for ES-1688 chip (0x220,0x240,0x260) - fm_port - port # for OPL3 (option; share the same port as default) + isapnp - ISA PnP detection - 0 = disable, 1 = enable (default) mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default) - irq - IRQ # for ES-1688 chip (5,7,9,10) mpu_irq - IRQ # for MPU-401 port (5,7,9,10) + fm_port - port # for OPL3 (option; share the same port as default) + + with isapnp=0, the following additional options are available: + port - port # for ES-1688 chip (0x220,0x240,0x260) + irq - IRQ # for ES-1688 chip (5,7,9,10) dma8 - DMA # for ES-1688 chip (0,1,3) - This module supports multiple cards and autoprobe (without MPU-401 port). + This module supports multiple cards and autoprobe (without MPU-401 port) + and PnP with the ES968 chip. Module snd-es18xx ----------------- diff --git a/include/sound/es1688.h b/include/sound/es1688.h index 4c29572effb2..3ec7ecbe2502 100644 --- a/include/sound/es1688.h +++ b/include/sound/es1688.h @@ -117,5 +117,6 @@ int snd_es1688_create(struct snd_card *card, int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device, struct snd_pcm **rpcm); int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip); +int snd_es1688_reset(struct snd_es1688 *chip); #endif /* __SOUND_ES1688_H */ diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 755a0a5f0e3f..c6990c680796 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -128,26 +128,14 @@ config SND_CS4236 To compile this driver as a module, choose M here: the module will be called snd-cs4236. -config SND_ES968 - tristate "Generic ESS ES968 driver" - depends on PNP - select ISAPNP - select SND_MPU401_UART - select SND_SB8_DSP - help - Say Y here to include support for ESS AudioDrive ES968 chips. - - To compile this driver as a module, choose M here: the module - will be called snd-es968. - config SND_ES1688 - tristate "Generic ESS ES688/ES1688 driver" + tristate "Generic ESS ES688/ES1688 and ES968 PnP driver" select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM help Say Y here to include support for ESS AudioDrive ES688 or - ES1688 chips. + ES1688 chips. Also, this module support cards with ES968 PnP chip. To compile this driver as a module, choose M here: the module will be called snd-es1688. diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 281679493fb4..fdcce311f80a 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100}," "{ESS,ES688 AudioDrive,pnp:ESS6881}," "{ESS,ES1688 AudioDrive,pnp:ESS1681}}"); +MODULE_ALIAS("snd_es968"); + static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ +#ifdef CONFIG_PNP +static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; +#endif static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ @@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); +#ifdef CONFIG_PNP +module_param_array(isapnp, bool, NULL, 0444); +MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard."); +#endif MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); @@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); +#ifdef CONFIG_PNP +#define is_isapnp_selected(dev) isapnp[dev] +#else +#define is_isapnp_selected(dev) 0 +#endif + static int __devinit snd_es1688_match(struct device *dev, unsigned int n) { - return enable[n]; + return enable[n] && !is_isapnp_selected(n); } static int __devinit snd_es1688_legacy_create(struct snd_card *card, - struct snd_es1688 *chip, struct device *dev, unsigned int n) + struct device *dev, unsigned int n) { + struct snd_es1688 *chip = card->private_data; static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas[] = {1, 3, 0, -1}; @@ -117,32 +134,20 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card, return error; } -static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) +static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n) { - struct snd_card *card; - struct snd_es1688 *chip; + struct snd_es1688 *chip = card->private_data; struct snd_opl3 *opl3; struct snd_pcm *pcm; int error; - error = snd_card_create(index[n], id[n], THIS_MODULE, - sizeof(struct snd_es1688), &card); - if (error < 0) - return error; - - chip = card->private_data; - - error = snd_es1688_legacy_create(card, chip, dev, n); - if (error < 0) - goto out; - error = snd_es1688_pcm(card, chip, 0, &pcm); if (error < 0) - goto out; + return error; error = snd_es1688_mixer(card, chip); if (error < 0) - goto out; + return error; strcpy(card->driver, "ES1688"); strcpy(card->shortname, pcm->name); @@ -155,12 +160,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) if (fm_port[n] > 0) { if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2, OPL3_HW_OPL3, 0, &opl3) < 0) - dev_warn(dev, + dev_warn(card->dev, "opl3 not detected at 0x%lx\n", fm_port[n]); else { error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); if (error < 0) - goto out; + return error; } } @@ -170,23 +175,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) chip->mpu_port, 0, mpu_irq[n], IRQF_DISABLED, NULL); if (error < 0) - goto out; + return error; } + return snd_card_register(card); +} + +static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n) +{ + struct snd_card *card; + int error; + + error = snd_card_create(index[n], id[n], THIS_MODULE, + sizeof(struct snd_es1688), &card); + if (error < 0) + return error; + + error = snd_es1688_legacy_create(card, dev, n); + if (error < 0) + goto out; + snd_card_set_dev(card, dev); - error = snd_card_register(card); + error = snd_es1688_probe(card, n); if (error < 0) goto out; dev_set_drvdata(dev, card); - return 0; -out: snd_card_free(card); + return 0; +out: + snd_card_free(card); return error; } -static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) +static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n) { snd_card_free(dev_get_drvdata(dev)); dev_set_drvdata(dev, NULL); @@ -195,8 +218,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) static struct isa_driver snd_es1688_driver = { .match = snd_es1688_match, - .probe = snd_es1688_probe, - .remove = __devexit_p(snd_es1688_remove), + .probe = snd_es1688_isa_probe, + .remove = __devexit_p(snd_es1688_isa_remove), #if 0 /* FIXME */ .suspend = snd_es1688_suspend, .resume = snd_es1688_resume, @@ -206,14 +229,140 @@ static struct isa_driver snd_es1688_driver = { } }; +static int snd_es968_pnp_is_probed; + +#ifdef CONFIG_PNP +static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n, + struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) +{ + struct snd_es1688 *chip = card->private_data; + struct pnp_dev *pdev; + int error; + + pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL); + if (pdev == NULL) + return -ENODEV; + + error = pnp_activate_dev(pdev); + if (error < 0) { + snd_printk(KERN_ERR "ES968 pnp configure failure\n"); + return error; + } + port[n] = pnp_port_start(pdev, 0); + dma8[n] = pnp_dma(pdev, 0); + irq[n] = pnp_irq(pdev, 0); + + return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_AUTO); +} + +static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) +{ + struct snd_card *card; + static unsigned int dev; + int error; + struct snd_es1688 *chip; + + if (snd_es968_pnp_is_probed) + return -EBUSY; + for ( ; dev < SNDRV_CARDS; dev++) { + if (enable[dev] && isapnp[dev]) + break; + } + + error = snd_card_create(index[dev], id[dev], THIS_MODULE, + sizeof(struct snd_es1688), &card); + if (error < 0) + return error; + chip = card->private_data; + + error = snd_card_es968_pnp(card, dev, pcard, pid); + if (error < 0) { + snd_card_free(card); + return error; + } + snd_card_set_dev(card, &pcard->card->dev); + error = snd_es1688_probe(card, dev); + if (error < 0) + return error; + pnp_set_card_drvdata(pcard, card); + snd_es968_pnp_is_probed = 1; + return 0; +} + +static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) +{ + snd_card_free(pnp_get_card_drvdata(pcard)); + pnp_set_card_drvdata(pcard, NULL); + snd_es968_pnp_is_probed = 0; +} + +#ifdef CONFIG_PM +static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, + pm_message_t state) +{ + struct snd_card *card = pnp_get_card_drvdata(pcard); + struct snd_es1688 *chip = card->private_data; + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + snd_pcm_suspend_all(chip->pcm); + return 0; +} + +static int snd_es968_pnp_resume(struct pnp_card_link *pcard) +{ + struct snd_card *card = pnp_get_card_drvdata(pcard); + struct snd_es1688 *chip = card->private_data; + + snd_es1688_reset(chip); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); + return 0; +} +#endif + +static struct pnp_card_device_id snd_es968_pnpids[] = { + { .id = "ESS0968", .devs = { { "@@@0968" }, } }, + { .id = "ESS0968", .devs = { { "ESS0968" }, } }, + { .id = "", } /* end */ +}; + +MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); + +static struct pnp_card_driver es968_pnpc_driver = { + .flags = PNP_DRIVER_RES_DISABLE, + .name = DEV_NAME " PnP", + .id_table = snd_es968_pnpids, + .probe = snd_es968_pnp_detect, + .remove = __devexit_p(snd_es968_pnp_remove), +#ifdef CONFIG_PM + .suspend = snd_es968_pnp_suspend, + .resume = snd_es968_pnp_resume, +#endif +}; +#endif + static int __init alsa_card_es1688_init(void) { +#ifdef CONFIG_PNP + pnp_register_card_driver(&es968_pnpc_driver); + if (snd_es968_pnp_is_probed) + return 0; + pnp_unregister_card_driver(&es968_pnpc_driver); +#endif return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); } static void __exit alsa_card_es1688_exit(void) { - isa_unregister_driver(&snd_es1688_driver); + if (!snd_es968_pnp_is_probed) { + isa_unregister_driver(&snd_es1688_driver); + return; + } +#ifdef CONFIG_PNP + pnp_unregister_card_driver(&es968_pnpc_driver); +#endif } module_init(alsa_card_es1688_init); diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index fdd440417bf0..07676200496a 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -99,7 +99,7 @@ static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned cha return result; } -static int snd_es1688_reset(struct snd_es1688 *chip) +int snd_es1688_reset(struct snd_es1688 *chip) { int i; @@ -115,6 +115,7 @@ static int snd_es1688_reset(struct snd_es1688 *chip) snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */ return 0; } +EXPORT_SYMBOL(snd_es1688_reset); static int snd_es1688_probe(struct snd_es1688 *chip) { diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index af3669681788..08b9fb974658 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -11,7 +11,6 @@ snd-sb8-objs := sb8.o snd-sb16-objs := sb16.o snd-sbawe-objs := sbawe.o emu8000.o snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o -snd-es968-objs := es968.o snd-jazz16-objs := jazz16.o # Toplevel Module Dependency @@ -21,7 +20,6 @@ obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o obj-$(CONFIG_SND_SB8) += snd-sb8.o obj-$(CONFIG_SND_SB16) += snd-sb16.o obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o -obj-$(CONFIG_SND_ES968) += snd-es968.o obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o ifeq ($(CONFIG_SND_SB16_CSP),y) obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c deleted file mode 100644 index ff18286fef9d..000000000000 --- a/sound/isa/sb/es968.c +++ /dev/null @@ -1,248 +0,0 @@ - -/* - card-es968.c - driver for ESS AudioDrive ES968 based soundcards. - Copyright (C) 1999 by Massimo Piccioni - - Thanks to Pierfrancesco 'qM2' Passerini. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include -#include -#include - -#define PFX "es968: " - -MODULE_AUTHOR("Massimo Piccioni "); -MODULE_DESCRIPTION("ESS AudioDrive ES968"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ -static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ -static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */ -static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */ - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for es968 based soundcard."); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for es968 based soundcard."); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable es968 based soundcard."); - -struct snd_card_es968 { - struct pnp_dev *dev; - struct snd_sb *chip; -}; - -static struct pnp_card_device_id snd_es968_pnpids[] = { - { .id = "ESS0968", .devs = { { "@@@0968" }, } }, - { .id = "", } /* end */ -}; - -MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids); - -#define DRIVER_NAME "snd-card-es968" - -static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id) -{ - struct snd_sb *chip = dev_id; - - if (chip->open & SB_OPEN_PCM) { - return snd_sb8dsp_interrupt(chip); - } else { - return snd_sb8dsp_midi_interrupt(chip); - } -} - -static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, - struct pnp_card_link *card, - const struct pnp_card_device_id *id) -{ - struct pnp_dev *pdev; - int err; - - acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL); - if (acard->dev == NULL) - return -ENODEV; - - pdev = acard->dev; - - err = pnp_activate_dev(pdev); - if (err < 0) { - snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n"); - return err; - } - port[dev] = pnp_port_start(pdev, 0); - dma8[dev] = pnp_dma(pdev, 0); - irq[dev] = pnp_irq(pdev, 0); - - return 0; -} - -static int __devinit snd_card_es968_probe(int dev, - struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) -{ - int error; - struct snd_sb *chip; - struct snd_card *card; - struct snd_card_es968 *acard; - - error = snd_card_create(index[dev], id[dev], THIS_MODULE, - sizeof(struct snd_card_es968), &card); - if (error < 0) - return error; - acard = card->private_data; - if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) { - snd_card_free(card); - return error; - } - snd_card_set_dev(card, &pcard->card->dev); - - if ((error = snd_sbdsp_create(card, port[dev], - irq[dev], - snd_card_es968_interrupt, - dma8[dev], - -1, - SB_HW_AUTO, &chip)) < 0) { - snd_card_free(card); - return error; - } - acard->chip = chip; - - if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sbmixer_new(chip)) < 0) { - snd_card_free(card); - return error; - } - - if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) { - snd_card_free(card); - return error; - } - - strcpy(card->driver, "ES968"); - strcpy(card->shortname, "ESS ES968"); - sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d", - card->shortname, chip->name, chip->port, irq[dev], dma8[dev]); - - if ((error = snd_card_register(card)) < 0) { - snd_card_free(card); - return error; - } - pnp_set_card_drvdata(pcard, card); - return 0; -} - -static unsigned int __devinitdata es968_devices; - -static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card, - const struct pnp_card_device_id *id) -{ - static int dev; - int res; - - for ( ; dev < SNDRV_CARDS; dev++) { - if (!enable[dev]) - continue; - res = snd_card_es968_probe(dev, card, id); - if (res < 0) - return res; - dev++; - es968_devices++; - return 0; - } - return -ENODEV; -} - -static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard) -{ - snd_card_free(pnp_get_card_drvdata(pcard)); - pnp_set_card_drvdata(pcard, NULL); -} - -#ifdef CONFIG_PM -static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state) -{ - struct snd_card *card = pnp_get_card_drvdata(pcard); - struct snd_card_es968 *acard = card->private_data; - struct snd_sb *chip = acard->chip; - - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend_all(chip->pcm); - snd_sbmixer_suspend(chip); - return 0; -} - -static int snd_es968_pnp_resume(struct pnp_card_link *pcard) -{ - struct snd_card *card = pnp_get_card_drvdata(pcard); - struct snd_card_es968 *acard = card->private_data; - struct snd_sb *chip = acard->chip; - - snd_sbdsp_reset(chip); - snd_sbmixer_resume(chip); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} -#endif - -static struct pnp_card_driver es968_pnpc_driver = { - .flags = PNP_DRIVER_RES_DISABLE, - .name = "es968", - .id_table = snd_es968_pnpids, - .probe = snd_es968_pnp_detect, - .remove = __devexit_p(snd_es968_pnp_remove), -#ifdef CONFIG_PM - .suspend = snd_es968_pnp_suspend, - .resume = snd_es968_pnp_resume, -#endif -}; - -static int __init alsa_card_es968_init(void) -{ - int err = pnp_register_card_driver(&es968_pnpc_driver); - if (err) - return err; - - if (!es968_devices) { - pnp_unregister_card_driver(&es968_pnpc_driver); -#ifdef MODULE - snd_printk(KERN_ERR "no ES968 based soundcards found\n"); -#endif - return -ENODEV; - } - return 0; -} - -static void __exit alsa_card_es968_exit(void) -{ - pnp_unregister_card_driver(&es968_pnpc_driver); -} - -module_init(alsa_card_es968_init) -module_exit(alsa_card_es968_exit) -- cgit v1.2.3 From ed77134bfccf5e75b6cbadab268e559dbe6a4ebb Mon Sep 17 00:00:00 2001 From: Mark Gross Date: Thu, 6 May 2010 01:59:26 +0200 Subject: PM QOS update This patch changes the string based list management to a handle base implementation to help with the hot path use of pm-qos, it also renames much of the API to use "request" as opposed to "requirement" that was used in the initial implementation. I did this because request more accurately represents what it actually does. Also, I added a string based ABI for users wanting to use a string interface. So if the user writes 0xDDDDDDDD formatted hex it will be accepted by the interface. (someone asked me for it and I don't think it hurts anything.) This patch updates some documentation input I got from Randy. Signed-off-by: markgross Signed-off-by: Rafael J. Wysocki --- Documentation/power/pm_qos_interface.txt | 48 +++---- drivers/acpi/processor_idle.c | 2 +- drivers/cpuidle/governors/ladder.c | 2 +- drivers/cpuidle/governors/menu.c | 2 +- drivers/net/e1000e/netdev.c | 22 ++-- drivers/net/igbvf/netdev.c | 6 +- drivers/net/wireless/ipw2x00/ipw2100.c | 11 +- include/linux/netdevice.h | 4 + include/linux/pm_qos_params.h | 14 +- include/sound/pcm.h | 3 +- kernel/pm_qos_params.c | 214 +++++++++++++++---------------- net/mac80211/mlme.c | 2 +- sound/core/pcm.c | 3 - sound/core/pcm_native.c | 14 +- 14 files changed, 176 insertions(+), 171 deletions(-) (limited to 'include/sound') diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index c40866e8b957..bfed898a03fc 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -18,44 +18,46 @@ and pm_qos_params.h. This is done because having the available parameters being runtime configurable or changeable from a driver was seen as too easy to abuse. -For each parameter a list of performance requirements is maintained along with +For each parameter a list of performance requests is maintained along with an aggregated target value. The aggregated target value is updated with -changes to the requirement list or elements of the list. Typically the -aggregated target value is simply the max or min of the requirement values held +changes to the request list or elements of the list. Typically the +aggregated target value is simply the max or min of the request values held in the parameter list elements. From kernel mode the use of this interface is simple: -pm_qos_add_requirement(param_id, name, target_value): -Will insert a named element in the list for that identified PM_QOS parameter -with the target value. Upon change to this list the new target is recomputed -and any registered notifiers are called only if the target value is now -different. -pm_qos_update_requirement(param_id, name, new_target_value): -Will search the list identified by the param_id for the named list element and -then update its target value, calling the notification tree if the aggregated -target is changed. with that name is already registered. +handle = pm_qos_add_request(param_class, target_value): +Will insert an element into the list for that identified PM_QOS class with the +target value. Upon change to this list the new target is recomputed and any +registered notifiers are called only if the target value is now different. +Clients of pm_qos need to save the returned handle. -pm_qos_remove_requirement(param_id, name): -Will search the identified list for the named element and remove it, after -removal it will update the aggregate target and call the notification tree if -the target was changed as a result of removing the named requirement. +void pm_qos_update_request(handle, new_target_value): +Will update the list element pointed to by the handle with the new target value +and recompute the new aggregated target, calling the notification tree if the +target is changed. + +void pm_qos_remove_request(handle): +Will remove the element. After removal it will update the aggregate target and +call the notification tree if the target was changed as a result of removing +the request. From user mode: -Only processes can register a pm_qos requirement. To provide for automatic -cleanup for process the interface requires the process to register its -parameter requirements in the following way: +Only processes can register a pm_qos request. To provide for automatic +cleanup of a process, the interface requires the process to register its +parameter requests in the following way: To register the default pm_qos target for the specific parameter, the process must open one of /dev/[cpu_dma_latency, network_latency, network_throughput] As long as the device node is held open that process has a registered -requirement on the parameter. The name of the requirement is "process_" -derived from the current->pid from within the open system call. +request on the parameter. -To change the requested target value the process needs to write a s32 value to -the open device node. This translates to a pm_qos_update_requirement call. +To change the requested target value the process needs to write an s32 value to +the open device node. Alternatively the user mode program could write a hex +string for the value using 10 char long format e.g. "0x12345678". This +translates to a pm_qos_update_request call. To remove the user mode request for a target value simply close the device node. diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5939e7f7d8e9..c3817e1f32c7 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -698,7 +698,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) "max_cstate: C%d\n" "maximum allowed latency: %d usec\n", pr->power.state ? pr->power.state - pr->power.states : 0, - max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)); + max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY)); seq_puts(seq, "states:\n"); diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 1c1ceb4f218f..12c98900dcf8 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c @@ -67,7 +67,7 @@ static int ladder_select_state(struct cpuidle_device *dev) struct ladder_device *ldev = &__get_cpu_var(ladder_devices); struct ladder_device_state *last_state; int last_residency, last_idx = ldev->last_state_idx; - int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY); + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); /* Special case when user has set very strict latency requirement */ if (unlikely(latency_req == 0)) { diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index f8e57c6303f2..b81ad9c731ae 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -182,7 +182,7 @@ static u64 div_round64(u64 dividend, u32 divisor) static int menu_select(struct cpuidle_device *dev) { struct menu_device *data = &__get_cpu_var(menu_devices); - int latency_req = pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY); + int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); int i; int multiplier; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index dbf81788bb40..d5d55c6a373f 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2524,12 +2524,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) * excessive C-state transition latencies result in * dropped transactions. */ - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, - adapter->netdev->name, 55); + pm_qos_update_request( + adapter->netdev->pm_qos_req, 55); } else { - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, - adapter->netdev->name, - PM_QOS_DEFAULT_VALUE); + pm_qos_update_request( + adapter->netdev->pm_qos_req, + PM_QOS_DEFAULT_VALUE); } } @@ -2824,8 +2824,8 @@ int e1000e_up(struct e1000_adapter *adapter) /* DMA latency requirement to workaround early-receive/jumbo issue */ if (adapter->flags & FLAG_HAS_ERT) - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, - adapter->netdev->name, + adapter->netdev->pm_qos_req = + pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); /* hardware has been reset, we need to reload some things */ @@ -2887,9 +2887,11 @@ void e1000e_down(struct e1000_adapter *adapter) e1000_clean_tx_ring(adapter); e1000_clean_rx_ring(adapter); - if (adapter->flags & FLAG_HAS_ERT) - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, - adapter->netdev->name); + if (adapter->flags & FLAG_HAS_ERT) { + pm_qos_remove_request( + adapter->netdev->pm_qos_req); + adapter->netdev->pm_qos_req = NULL; + } /* * TODO: for power management, we could drop the link and diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index 1b1edad1eb5e..f16e981812a9 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -48,6 +48,7 @@ #define DRV_VERSION "1.0.0-k0" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; +struct pm_qos_request_list *igbvf_driver_pm_qos_req; static const char igbvf_driver_string[] = "Intel(R) Virtual Function Network Driver"; static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; @@ -2899,7 +2900,7 @@ static int __init igbvf_init_module(void) printk(KERN_INFO "%s\n", igbvf_copyright); ret = pci_register_driver(&igbvf_driver); - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name, + igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); return ret; @@ -2915,7 +2916,8 @@ module_init(igbvf_init_module); static void __exit igbvf_exit_module(void) { pci_unregister_driver(&igbvf_driver); - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, igbvf_driver_name); + pm_qos_remove_request(igbvf_driver_pm_qos_req); + igbvf_driver_pm_qos_req = NULL; } module_exit(igbvf_exit_module); diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 9b72c45a7748..2b05fe5e994c 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -174,6 +174,8 @@ that only one external action is invoked at a time. #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" +struct pm_qos_request_list *ipw2100_pm_qos_req; + /* Debugging stuff */ #ifdef CONFIG_IPW2100_DEBUG #define IPW2100_RX_DEBUG /* Reception debugging */ @@ -1739,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) /* the ipw2100 hardware really doesn't want power management delays * longer than 175usec */ - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", 175); + pm_qos_update_request(ipw2100_pm_qos_req, 175); /* If the interrupt is enabled, turn it off... */ spin_lock_irqsave(&priv->low_lock, flags); @@ -1887,8 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv) ipw2100_disable_interrupts(priv); spin_unlock_irqrestore(&priv->low_lock, flags); - pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", - PM_QOS_DEFAULT_VALUE); + pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); /* We have to signal any supplicant if we are disassociating */ if (associated) @@ -6669,7 +6670,7 @@ static int __init ipw2100_init(void) if (ret) goto out; - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100", + ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); #ifdef CONFIG_IPW2100_DEBUG ipw2100_debug_level = debug; @@ -6692,7 +6693,7 @@ static void __exit ipw2100_exit(void) &driver_attr_debug_level); #endif pci_unregister_driver(&ipw2100_pci_driver); - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, "ipw2100"); + pm_qos_remove_request(ipw2100_pm_qos_req); } module_init(ipw2100_init); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index fa8b47637997..3857517f1ca5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -31,6 +31,7 @@ #include #ifdef __KERNEL__ +#include #include #include #include @@ -711,6 +712,9 @@ struct net_device { * the interface. */ char name[IFNAMSIZ]; + + struct pm_qos_request_list *pm_qos_req; + /* device name hash chain */ struct hlist_node name_hlist; /* snmp alias */ diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h index d74f75ed1e47..8ba440e5eb7f 100644 --- a/include/linux/pm_qos_params.h +++ b/include/linux/pm_qos_params.h @@ -14,12 +14,14 @@ #define PM_QOS_NUM_CLASSES 4 #define PM_QOS_DEFAULT_VALUE -1 -int pm_qos_add_requirement(int qos, char *name, s32 value); -int pm_qos_update_requirement(int qos, char *name, s32 new_value); -void pm_qos_remove_requirement(int qos, char *name); +struct pm_qos_request_list; -int pm_qos_requirement(int qos); +struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value); +void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, + s32 new_value); +void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req); -int pm_qos_add_notifier(int qos, struct notifier_block *notifier); -int pm_qos_remove_notifier(int qos, struct notifier_block *notifier); +int pm_qos_request(int pm_qos_class); +int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); +int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 8b611a561985..dd76cdede64d 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -29,6 +29,7 @@ #include #include #include +#include #define snd_pcm_substream_chip(substream) ((substream)->private_data) #define snd_pcm_chip(pcm) ((pcm)->private_data) @@ -365,7 +366,7 @@ struct snd_pcm_substream { int number; char name[32]; /* substream name */ int stream; /* stream (direction) */ - char latency_id[20]; /* latency identifier */ + struct pm_qos_request_list *latency_pm_qos_req; /* pm_qos request */ size_t buffer_bytes_max; /* limit ring buffer size */ struct snd_dma_buffer dma_buffer; unsigned int dma_buf_id; diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 3db49b9ca374..a1aea040eb57 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c @@ -2,7 +2,7 @@ * This module exposes the interface to kernel space for specifying * QoS dependencies. It provides infrastructure for registration of: * - * Dependents on a QoS value : register requirements + * Dependents on a QoS value : register requests * Watchers of QoS value : get notified when target QoS value changes * * This QoS design is best effort based. Dependents register their QoS needs. @@ -14,19 +14,21 @@ * timeout: usec <-- currently not used. * throughput: kbs (kilo byte / sec) * - * There are lists of pm_qos_objects each one wrapping requirements, notifiers + * There are lists of pm_qos_objects each one wrapping requests, notifiers * - * User mode requirements on a QOS parameter register themselves to the + * User mode requests on a QOS parameter register themselves to the * subsystem by opening the device node /dev/... and writing there request to * the node. As long as the process holds a file handle open to the node the * client continues to be accounted for. Upon file release the usermode - * requirement is removed and a new qos target is computed. This way when the - * requirement that the application has is cleaned up when closes the file + * request is removed and a new qos target is computed. This way when the + * request that the application has is cleaned up when closes the file * pointer or exits the pm_qos_object will get an opportunity to clean up. * * Mark Gross */ +/*#define DEBUG*/ + #include #include #include @@ -42,25 +44,25 @@ #include /* - * locking rule: all changes to requirements or notifiers lists + * locking rule: all changes to requests or notifiers lists * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock * held, taken with _irqsave. One lock to rule them all */ -struct requirement_list { +struct pm_qos_request_list { struct list_head list; union { s32 value; s32 usec; s32 kbps; }; - char *name; + int pm_qos_class; }; static s32 max_compare(s32 v1, s32 v2); static s32 min_compare(s32 v1, s32 v2); struct pm_qos_object { - struct requirement_list requirements; + struct pm_qos_request_list requests; struct blocking_notifier_head *notifiers; struct miscdevice pm_qos_power_miscdev; char *name; @@ -72,7 +74,7 @@ struct pm_qos_object { static struct pm_qos_object null_pm_qos; static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); static struct pm_qos_object cpu_dma_pm_qos = { - .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)}, + .requests = {LIST_HEAD_INIT(cpu_dma_pm_qos.requests.list)}, .notifiers = &cpu_dma_lat_notifier, .name = "cpu_dma_latency", .default_value = 2000 * USEC_PER_SEC, @@ -82,7 +84,7 @@ static struct pm_qos_object cpu_dma_pm_qos = { static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); static struct pm_qos_object network_lat_pm_qos = { - .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)}, + .requests = {LIST_HEAD_INIT(network_lat_pm_qos.requests.list)}, .notifiers = &network_lat_notifier, .name = "network_latency", .default_value = 2000 * USEC_PER_SEC, @@ -93,8 +95,7 @@ static struct pm_qos_object network_lat_pm_qos = { static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); static struct pm_qos_object network_throughput_pm_qos = { - .requirements = - {LIST_HEAD_INIT(network_throughput_pm_qos.requirements.list)}, + .requests = {LIST_HEAD_INIT(network_throughput_pm_qos.requests.list)}, .notifiers = &network_throughput_notifier, .name = "network_throughput", .default_value = 0, @@ -135,31 +136,34 @@ static s32 min_compare(s32 v1, s32 v2) } -static void update_target(int target) +static void update_target(int pm_qos_class) { s32 extreme_value; - struct requirement_list *node; + struct pm_qos_request_list *node; unsigned long flags; int call_notifier = 0; spin_lock_irqsave(&pm_qos_lock, flags); - extreme_value = pm_qos_array[target]->default_value; + extreme_value = pm_qos_array[pm_qos_class]->default_value; list_for_each_entry(node, - &pm_qos_array[target]->requirements.list, list) { - extreme_value = pm_qos_array[target]->comparitor( + &pm_qos_array[pm_qos_class]->requests.list, list) { + extreme_value = pm_qos_array[pm_qos_class]->comparitor( extreme_value, node->value); } - if (atomic_read(&pm_qos_array[target]->target_value) != extreme_value) { + if (atomic_read(&pm_qos_array[pm_qos_class]->target_value) != + extreme_value) { call_notifier = 1; - atomic_set(&pm_qos_array[target]->target_value, extreme_value); - pr_debug(KERN_ERR "new target for qos %d is %d\n", target, - atomic_read(&pm_qos_array[target]->target_value)); + atomic_set(&pm_qos_array[pm_qos_class]->target_value, + extreme_value); + pr_debug(KERN_ERR "new target for qos %d is %d\n", pm_qos_class, + atomic_read(&pm_qos_array[pm_qos_class]->target_value)); } spin_unlock_irqrestore(&pm_qos_lock, flags); if (call_notifier) - blocking_notifier_call_chain(pm_qos_array[target]->notifiers, - (unsigned long) extreme_value, NULL); + blocking_notifier_call_chain( + pm_qos_array[pm_qos_class]->notifiers, + (unsigned long) extreme_value, NULL); } static int register_pm_qos_misc(struct pm_qos_object *qos) @@ -185,125 +189,110 @@ static int find_pm_qos_object_by_minor(int minor) } /** - * pm_qos_requirement - returns current system wide qos expectation + * pm_qos_request - returns current system wide qos expectation * @pm_qos_class: identification of which qos value is requested * * This function returns the current target value in an atomic manner. */ -int pm_qos_requirement(int pm_qos_class) +int pm_qos_request(int pm_qos_class) { return atomic_read(&pm_qos_array[pm_qos_class]->target_value); } -EXPORT_SYMBOL_GPL(pm_qos_requirement); +EXPORT_SYMBOL_GPL(pm_qos_request); /** - * pm_qos_add_requirement - inserts new qos request into the list + * pm_qos_add_request - inserts new qos request into the list * @pm_qos_class: identifies which list of qos request to us - * @name: identifies the request * @value: defines the qos request * * This function inserts a new entry in the pm_qos_class list of requested qos * performance characteristics. It recomputes the aggregate QoS expectations - * for the pm_qos_class of parameters. + * for the pm_qos_class of parameters, and returns the pm_qos_request list + * element as a handle for use in updating and removal. Call needs to save + * this handle for later use. */ -int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value) +struct pm_qos_request_list *pm_qos_add_request(int pm_qos_class, s32 value) { - struct requirement_list *dep; + struct pm_qos_request_list *dep; unsigned long flags; - dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL); + dep = kzalloc(sizeof(struct pm_qos_request_list), GFP_KERNEL); if (dep) { if (value == PM_QOS_DEFAULT_VALUE) dep->value = pm_qos_array[pm_qos_class]->default_value; else dep->value = value; - dep->name = kstrdup(name, GFP_KERNEL); - if (!dep->name) - goto cleanup; + dep->pm_qos_class = pm_qos_class; spin_lock_irqsave(&pm_qos_lock, flags); list_add(&dep->list, - &pm_qos_array[pm_qos_class]->requirements.list); + &pm_qos_array[pm_qos_class]->requests.list); spin_unlock_irqrestore(&pm_qos_lock, flags); update_target(pm_qos_class); - - return 0; } -cleanup: - kfree(dep); - return -ENOMEM; + return dep; } -EXPORT_SYMBOL_GPL(pm_qos_add_requirement); +EXPORT_SYMBOL_GPL(pm_qos_add_request); /** - * pm_qos_update_requirement - modifies an existing qos request - * @pm_qos_class: identifies which list of qos request to us - * @name: identifies the request + * pm_qos_update_request - modifies an existing qos request + * @pm_qos_req : handle to list element holding a pm_qos request to use * @value: defines the qos request * - * Updates an existing qos requirement for the pm_qos_class of parameters along + * Updates an existing qos request for the pm_qos_class of parameters along * with updating the target pm_qos_class value. * - * If the named request isn't in the list then no change is made. + * Attempts are made to make this code callable on hot code paths. */ -int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value) +void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, + s32 new_value) { unsigned long flags; - struct requirement_list *node; int pending_update = 0; + s32 temp; spin_lock_irqsave(&pm_qos_lock, flags); - list_for_each_entry(node, - &pm_qos_array[pm_qos_class]->requirements.list, list) { - if (strcmp(node->name, name) == 0) { - if (new_value == PM_QOS_DEFAULT_VALUE) - node->value = - pm_qos_array[pm_qos_class]->default_value; - else - node->value = new_value; - pending_update = 1; - break; - } + if (new_value == PM_QOS_DEFAULT_VALUE) + temp = pm_qos_array[pm_qos_req->pm_qos_class]->default_value; + else + temp = new_value; + + if (temp != pm_qos_req->value) { + pending_update = 1; + pm_qos_req->value = temp; } spin_unlock_irqrestore(&pm_qos_lock, flags); if (pending_update) - update_target(pm_qos_class); - - return 0; + update_target(pm_qos_req->pm_qos_class); } -EXPORT_SYMBOL_GPL(pm_qos_update_requirement); +EXPORT_SYMBOL_GPL(pm_qos_update_request); /** - * pm_qos_remove_requirement - modifies an existing qos request - * @pm_qos_class: identifies which list of qos request to us - * @name: identifies the request + * pm_qos_remove_request - modifies an existing qos request + * @pm_qos_req: handle to request list element * - * Will remove named qos request from pm_qos_class list of parameters and - * recompute the current target value for the pm_qos_class. + * Will remove pm qos request from the list of requests and + * recompute the current target value for the pm_qos_class. Call this + * on slow code paths. */ -void pm_qos_remove_requirement(int pm_qos_class, char *name) +void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req) { unsigned long flags; - struct requirement_list *node; - int pending_update = 0; + int qos_class; + + if (pm_qos_req == NULL) + return; + /* silent return to keep pcm code cleaner */ + qos_class = pm_qos_req->pm_qos_class; spin_lock_irqsave(&pm_qos_lock, flags); - list_for_each_entry(node, - &pm_qos_array[pm_qos_class]->requirements.list, list) { - if (strcmp(node->name, name) == 0) { - kfree(node->name); - list_del(&node->list); - kfree(node); - pending_update = 1; - break; - } - } + list_del(&pm_qos_req->list); + kfree(pm_qos_req); spin_unlock_irqrestore(&pm_qos_lock, flags); - if (pending_update) - update_target(pm_qos_class); + update_target(qos_class); } -EXPORT_SYMBOL_GPL(pm_qos_remove_requirement); +EXPORT_SYMBOL_GPL(pm_qos_remove_request); /** * pm_qos_add_notifier - sets notification entry for changes to target value @@ -313,7 +302,7 @@ EXPORT_SYMBOL_GPL(pm_qos_remove_requirement); * will register the notifier into a notification chain that gets called * upon changes to the pm_qos_class target value. */ - int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) +int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) { int retval; @@ -343,21 +332,16 @@ int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) } EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); -#define PID_NAME_LEN 32 - static int pm_qos_power_open(struct inode *inode, struct file *filp) { - int ret; long pm_qos_class; - char name[PID_NAME_LEN]; pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); if (pm_qos_class >= 0) { - filp->private_data = (void *)pm_qos_class; - snprintf(name, PID_NAME_LEN, "process_%d", current->pid); - ret = pm_qos_add_requirement(pm_qos_class, name, - PM_QOS_DEFAULT_VALUE); - if (ret >= 0) + filp->private_data = (void *) pm_qos_add_request(pm_qos_class, + PM_QOS_DEFAULT_VALUE); + + if (filp->private_data) return 0; } return -EPERM; @@ -365,32 +349,40 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp) static int pm_qos_power_release(struct inode *inode, struct file *filp) { - int pm_qos_class; - char name[PID_NAME_LEN]; + struct pm_qos_request_list *req; - pm_qos_class = (long)filp->private_data; - snprintf(name, PID_NAME_LEN, "process_%d", current->pid); - pm_qos_remove_requirement(pm_qos_class, name); + req = (struct pm_qos_request_list *)filp->private_data; + pm_qos_remove_request(req); return 0; } + static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { s32 value; - int pm_qos_class; - char name[PID_NAME_LEN]; - - pm_qos_class = (long)filp->private_data; - if (count != sizeof(s32)) + int x; + char ascii_value[11]; + struct pm_qos_request_list *pm_qos_req; + + if (count == sizeof(s32)) { + if (copy_from_user(&value, buf, sizeof(s32))) + return -EFAULT; + } else if (count == 11) { /* len('0x12345678/0') */ + if (copy_from_user(ascii_value, buf, 11)) + return -EFAULT; + x = sscanf(ascii_value, "%x", &value); + if (x != 1) + return -EINVAL; + pr_debug(KERN_ERR "%s, %d, 0x%x\n", ascii_value, x, value); + } else return -EINVAL; - if (copy_from_user(&value, buf, sizeof(s32))) - return -EFAULT; - snprintf(name, PID_NAME_LEN, "process_%d", current->pid); - pm_qos_update_requirement(pm_qos_class, name, value); - return sizeof(s32); + pm_qos_req = (struct pm_qos_request_list *)filp->private_data; + pm_qos_update_request(pm_qos_req, value); + + return count; } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4aefa6dc3091..29de1965ff74 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -495,7 +495,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) s32 beaconint_us; if (latency < 0) - latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY); + latency = pm_qos_request(PM_QOS_NETWORK_LATENCY); beaconint_us = ieee80211_tu_to_usec( found->vif.bss_conf.beacon_int); diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 0d428d0896db..cbe815dfbdc8 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -648,9 +648,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) substream->number = idx; substream->stream = stream; sprintf(substream->name, "subdevice #%i", idx); - snprintf(substream->latency_id, sizeof(substream->latency_id), - "ALSA-PCM%d-%d%c%d", pcm->card->number, pcm->device, - (stream ? 'c' : 'p'), idx); substream->buffer_bytes_max = UINT_MAX; if (prev == NULL) pstr->substream = substream; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 872887624030..605c86df71c5 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -481,11 +481,13 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, snd_pcm_timer_resolution_change(substream); runtime->status->state = SNDRV_PCM_STATE_SETUP; - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, - substream->latency_id); + if (substream->latency_pm_qos_req) { + pm_qos_remove_request(substream->latency_pm_qos_req); + substream->latency_pm_qos_req = NULL; + } if ((usecs = period_to_usecs(runtime)) >= 0) - pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, - substream->latency_id, usecs); + substream->latency_pm_qos_req = pm_qos_add_request( + PM_QOS_CPU_DMA_LATENCY, usecs); return 0; _error: /* hardware might be unuseable from this time, @@ -540,8 +542,8 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) if (substream->ops->hw_free) result = substream->ops->hw_free(substream); runtime->status->state = SNDRV_PCM_STATE_OPEN; - pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, - substream->latency_id); + pm_qos_remove_request(substream->latency_pm_qos_req); + substream->latency_pm_qos_req = NULL; return result; } -- cgit v1.2.3 From 89485d4931769d40353ea49bff1596accff8f06e Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 11 May 2010 18:57:37 +0200 Subject: ALSA: include/sound/asound.h whitespace fixups This fixes some whitespace/indentation flaws I stumbled over. Signed-off-by: Daniel Mack Signed-off-by: Takashi Iwai --- include/sound/asound.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'include/sound') diff --git a/include/sound/asound.h b/include/sound/asound.h index 098595500632..9f1eecf99e6b 100644 --- a/include/sound/asound.h +++ b/include/sound/asound.h @@ -574,7 +574,7 @@ enum { #define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */ struct snd_timer_id { - int dev_class; + int dev_class; int dev_sclass; int card; int device; @@ -762,7 +762,7 @@ struct snd_ctl_elem_id { snd_ctl_elem_iface_t iface; /* interface identifier */ unsigned int device; /* device/client number */ unsigned int subdevice; /* subdevice (substream) number */ - unsigned char name[44]; /* ASCII name of item */ + unsigned char name[44]; /* ASCII name of item */ unsigned int index; /* index of item */ }; @@ -809,7 +809,7 @@ struct snd_ctl_elem_info { struct snd_ctl_elem_value { struct snd_ctl_elem_id id; /* W: element ID */ unsigned int indirect: 1; /* W: indirect access - obsoleted */ - union { + union { union { long value[128]; long *value_ptr; /* obsoleted */ @@ -827,15 +827,15 @@ struct snd_ctl_elem_value { unsigned char *data_ptr; /* obsoleted */ } bytes; struct snd_aes_iec958 iec958; - } value; /* RO */ + } value; /* RO */ struct timespec tstamp; - unsigned char reserved[128-sizeof(struct timespec)]; + unsigned char reserved[128-sizeof(struct timespec)]; }; struct snd_ctl_tlv { - unsigned int numid; /* control element numeric identification */ - unsigned int length; /* in bytes aligned to 4 */ - unsigned int tlv[0]; /* first TLV */ + unsigned int numid; /* control element numeric identification */ + unsigned int length; /* in bytes aligned to 4 */ + unsigned int tlv[0]; /* first TLV */ }; #define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) @@ -886,8 +886,8 @@ struct snd_ctl_event { unsigned int mask; struct snd_ctl_elem_id id; } elem; - unsigned char data8[60]; - } data; + unsigned char data8[60]; + } data; }; /* -- cgit v1.2.3