summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/fb/efifb.txt (renamed from Documentation/fb/imacfb.txt)14
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt16
-rw-r--r--arch/frv/include/asm/segment.h6
-rw-r--r--arch/frv/include/asm/uaccess.h2
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/block/cciss.c1
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/mem.c10
-rw-r--r--drivers/char/mxser.c6
-rw-r--r--drivers/char/raw.c1
-rw-r--r--drivers/gpio/timbgpio.c12
-rw-r--r--drivers/macintosh/windfarm_core.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c8
-rw-r--r--drivers/mmc/host/omap_hsmmc.c9
-rw-r--r--drivers/platform/x86/intel_menlow.c1
-rw-r--r--drivers/rtc/rtc-mxc.c26
-rw-r--r--drivers/thermal/thermal_sys.c3
-rw-r--r--drivers/video/fsl-diu-fb.c1
-rw-r--r--drivers/video/mb862xx/mb862xxfb_accel.c5
-rw-r--r--drivers/video/vesafb.c26
-rw-r--r--fs/block_dev.c5
-rw-r--r--fs/fscache/stats.c4
-rw-r--r--fs/proc/task_mmu.c27
-rw-r--r--include/linux/bitops.h3
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/kernel.h2
-rw-r--r--include/linux/kfifo.h3
-rw-r--r--include/linux/mm.h4
-rw-r--r--include/linux/page_cgroup.h6
-rw-r--r--include/sound/ak4113.h2
-rw-r--r--include/sound/soc-dai.h18
-rw-r--r--include/sound/soc.h1
-rw-r--r--kernel/exit.c3
-rw-r--r--kernel/fork.c3
-rw-r--r--lib/ratelimit.c11
-rw-r--r--mm/memcontrol.c18
-rw-r--r--mm/memory.c3
-rw-r--r--mm/pagewalk.c47
-rw-r--r--mm/readahead.c2
-rw-r--r--mm/vmscan.c23
-rw-r--r--sound/i2c/other/ak4113.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c5
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_analog.c8
-rw-r--r--sound/pci/hda/patch_realtek.c164
-rw-r--r--sound/pci/mixart/mixart.c24
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c6
-rw-r--r--sound/soc/codecs/ac97.c15
-rw-r--r--sound/soc/codecs/wm8994.c58
-rw-r--r--sound/soc/codecs/wm_hubs.c83
-rw-r--r--sound/soc/codecs/wm_hubs.h1
-rw-r--r--sound/soc/davinci/davinci-i2s.c3
-rw-r--r--sound/soc/davinci/davinci-mcasp.c3
-rw-r--r--sound/soc/davinci/davinci-pcm.c4
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c8
-rw-r--r--sound/soc/imx/imx-ssi.c7
-rw-r--r--sound/soc/omap/omap-mcbsp.c4
-rw-r--r--sound/soc/omap/omap-mcpdm.c3
-rw-r--r--sound/soc/omap/omap-pcm.c21
-rw-r--r--sound/soc/pxa/pxa-ssp.c23
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c17
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c7
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c4
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c21
-rw-r--r--sound/soc/s3c24xx/s3c-dma.c4
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c13
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c7
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c19
-rw-r--r--sound/soc/s6000/s6000-i2s.c3
-rw-r--r--sound/soc/s6000/s6000-pcm.c40
-rw-r--r--sound/soc/soc-core.c3
72 files changed, 579 insertions, 344 deletions
diff --git a/Documentation/fb/imacfb.txt b/Documentation/fb/efifb.txt
index 316ec9b..a59916c 100644
--- a/Documentation/fb/imacfb.txt
+++ b/Documentation/fb/efifb.txt
@@ -1,9 +1,9 @@
-What is imacfb?
+What is efifb?
===============
This is a generic EFI platform driver for Intel based Apple computers.
-Imacfb is only for EFI booted Intel Macs.
+efifb is only for EFI booted Intel Macs.
Supported Hardware
==================
@@ -16,16 +16,16 @@ MacMini
How to use it?
==============
-Imacfb does not have any kind of autodetection of your machine.
+efifb does not have any kind of autodetection of your machine.
You have to add the following kernel parameters in your elilo.conf:
Macbook :
- video=imacfb:macbook
+ video=efifb:macbook
MacMini :
- video=imacfb:mini
+ video=efifb:mini
Macbook Pro 15", iMac 17" :
- video=imacfb:i17
+ video=efifb:i17
Macbook Pro 17", iMac 20" :
- video=imacfb:i20
+ video=efifb:i20
--
Edgar Hucek <gimli@dark-green.com>
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index f4dd3bf..98d14cb 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -119,10 +119,18 @@ the codec slots 0 and 1 no matter what the hardware reports.
Interrupt Handling
~~~~~~~~~~~~~~~~~~
-In rare but some cases, the interrupt isn't properly handled as
-default. You would notice this by the DMA transfer error reported by
-ALSA PCM core, for example. Using MSI might help in such a case.
-Pass `enable_msi=1` option for enabling MSI.
+HD-audio driver uses MSI as default (if available) since 2.6.33
+kernel as MSI works better on some machines, and in general, it's
+better for performance. However, Nvidia controllers showed bad
+regressions with MSI (especially in a combination with AMD chipset),
+thus we disabled MSI for them.
+
+There seem also still other devices that don't work with MSI. If you
+see a regression wrt the sound quality (stuttering, etc) or a lock-up
+in the recent kernel, try to pass `enable_msi=0` option to disable
+MSI. If it works, you can add the known bad device to the blacklist
+defined in hda_intel.c. In such a case, please report and give the
+patch back to the upstream developer.
HD-AUDIO CODEC
diff --git a/arch/frv/include/asm/segment.h b/arch/frv/include/asm/segment.h
index e3616a6..a2320a4 100644
--- a/arch/frv/include/asm/segment.h
+++ b/arch/frv/include/asm/segment.h
@@ -21,12 +21,12 @@ typedef struct {
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define KERNEL_DS MAKE_MM_SEG(0xdfffffffUL)
-
#ifdef CONFIG_MMU
#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
+#define KERNEL_DS MAKE_MM_SEG(0xdfffffffUL)
#else
-#define USER_DS KERNEL_DS
+#define USER_DS MAKE_MM_SEG(memory_end)
+#define KERNEL_DS MAKE_MM_SEG(0xe0000000UL)
#endif
#define get_ds() (KERNEL_DS)
diff --git a/arch/frv/include/asm/uaccess.h b/arch/frv/include/asm/uaccess.h
index 53650c9..0b67ec5 100644
--- a/arch/frv/include/asm/uaccess.h
+++ b/arch/frv/include/asm/uaccess.h
@@ -27,8 +27,6 @@
#define VERIFY_READ 0
#define VERIFY_WRITE 1
-#define __addr_ok(addr) ((unsigned long)(addr) < get_addr_limit())
-
/*
* check that a range of addresses falls within the current address limit
*/
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 985abd7..057979a 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -15,7 +15,7 @@
#include <linux/cpu.h>
#include <linux/device.h>
#include <linux/swap.h>
-#include <linux/gfp.h>
+#include <linux/slab.h>
static struct sysdev_class_attribute *node_state_attrs[];
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 9e3af30..eb5ff05 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3341,6 +3341,7 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
printk(KERN_WARNING
"cciss: controller cciss%d failed, stopping.\n",
h->ctlr);
+ spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
fail_all_cmds(h->ctlr);
return IRQ_HANDLED;
}
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 6c32fbf..56b2767 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -2021,8 +2021,6 @@ static int __init rs_init(void)
state->baud_base = amiga_colorclock;
state->xmit_fifo_size = 1;
- local_irq_save(flags);
-
/* set ISRs, and then disable the rx interrupts */
error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
if (error)
@@ -2033,6 +2031,8 @@ static int __init rs_init(void)
if (error)
goto fail_free_irq;
+ local_irq_save(flags);
+
/* turn off Rx and Tx interrupts */
custom.intena = IF_RBF | IF_TBE;
mb();
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 1f3215a..f54dab8 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -225,6 +225,7 @@ int __weak phys_mem_access_prot_allowed(struct file *file,
* outside of main memory.
*
*/
+#ifdef pgprot_noncached
static int uncached_access(struct file *file, unsigned long addr)
{
#if defined(CONFIG_IA64)
@@ -251,6 +252,7 @@ static int uncached_access(struct file *file, unsigned long addr)
return addr >= __pa(high_memory);
#endif
}
+#endif
static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
@@ -710,11 +712,6 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
switch (orig) {
case SEEK_CUR:
offset += file->f_pos;
- if ((unsigned long long)offset <
- (unsigned long long)file->f_pos) {
- ret = -EOVERFLOW;
- break;
- }
case SEEK_SET:
/* to avoid userland mistaking f_pos=-9 as -EBADF=-9 */
if ((unsigned long long)offset >= ~0xFFFULL) {
@@ -908,6 +905,9 @@ static int __init chr_dev_init(void)
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
mem_class = class_create(THIS_MODULE, "mem");
+ if (IS_ERR(mem_class))
+ return PTR_ERR(mem_class);
+
mem_class->devnode = mem_devnode;
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
if (!devlist[minor].name)
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 95c9f54..4702305 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -1768,7 +1768,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
int len, lsr;
len = mxser_chars_in_buffer(tty);
- spin_lock(&info->slock);
+ spin_lock_irq(&info->slock);
lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
spin_unlock_irq(&info->slock);
len += (lsr ? 0 : 1);
@@ -1778,12 +1778,12 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
case MOXA_ASPP_MON: {
int mcr, status;
- spin_lock(&info->slock);
+ spin_lock_irq(&info->slock);
status = mxser_get_msr(info->ioaddr, 1, tty->index);
mxser_check_modem_status(tty, info, status);
mcr = inb(info->ioaddr + UART_MCR);
- spin_unlock(&info->slock);
+ spin_unlock_irq(&info->slock);
if (mcr & MOXA_MUST_MCR_XON_FLAG)
info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index d331c59..8756ab0 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -248,6 +248,7 @@ static const struct file_operations raw_fops = {
.aio_read = generic_file_aio_read,
.write = do_sync_write,
.aio_write = blkdev_aio_write,
+ .fsync = blkdev_fsync,
.open = raw_open,
.release= raw_release,
.ioctl = raw_ioctl,
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index ac4d0f0..ddd0531 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -131,6 +131,7 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
unsigned long flags;
u32 lvr, flr, bflr = 0;
u32 ver;
+ int ret = 0;
if (offset < 0 || offset > tgpio->gpio.ngpio)
return -EINVAL;
@@ -154,8 +155,10 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
}
if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
- if (ver < 3)
- return -EINVAL;
+ if (ver < 3) {
+ ret = -EINVAL;
+ goto out;
+ }
else {
flr |= 1 << offset;
bflr |= 1 << offset;
@@ -175,9 +178,10 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
- spin_unlock_irqrestore(&tgpio->lock, flags);
- return 0;
+out:
+ spin_unlock_irqrestore(&tgpio->lock, flags);
+ return ret;
}
static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index c092354..ce88979 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -210,6 +210,7 @@ int wf_register_control(struct wf_control *new_ct)
kref_init(&new_ct->ref);
list_add(&new_ct->link, &wf_controls);
+ sysfs_attr_init(&new_ct->attr.attr);
new_ct->attr.attr.name = new_ct->name;
new_ct->attr.attr.mode = 0644;
new_ct->attr.show = wf_show_control;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 6c23456..71f5056 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -423,10 +423,12 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
dip = kzalloc(sizeof(*dip),GFP_KERNEL);
if (!dip) return;
+ sysfs_attr_init(&dip->attr_debugcmd.attr);
dip->attr_debugcmd.attr.name = "debugcmd";
dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
dip->attr_debugcmd.show = debugcmd_show;
dip->attr_debugcmd.store = debugcmd_store;
+ sysfs_attr_init(&dip->attr_debuginfo.attr);
dip->attr_debuginfo.attr.name = "debuginfo";
dip->attr_debuginfo.attr.mode = S_IRUGO;
dip->attr_debuginfo.show = debuginfo_show;
@@ -644,6 +646,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
return;
}
+ sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
@@ -658,6 +661,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_minor_number_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
@@ -672,6 +676,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->v4l_radio_minor_number_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_unit_number.attr);
sfp->attr_unit_number.attr.name = "unit_number";
sfp->attr_unit_number.attr.mode = S_IRUGO;
sfp->attr_unit_number.show = unit_number_show;
@@ -685,6 +690,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->unit_number_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_bus_info.attr);
sfp->attr_bus_info.attr.name = "bus_info_str";
sfp->attr_bus_info.attr.mode = S_IRUGO;
sfp->attr_bus_info.show = bus_info_show;
@@ -699,6 +705,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->bus_info_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_hdw_name.attr);
sfp->attr_hdw_name.attr.name = "device_hardware_type";
sfp->attr_hdw_name.attr.mode = S_IRUGO;
sfp->attr_hdw_name.show = hdw_name_show;
@@ -713,6 +720,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
sfp->hdw_name_created_ok = !0;
}
+ sysfs_attr_init(&sfp->attr_hdw_desc.attr);
sfp->attr_hdw_desc.attr.name = "device_hardware_description";
sfp->attr_hdw_desc.attr.mode = S_IRUGO;
sfp->attr_hdw_desc.show = hdw_desc_show;
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 83f0aff..e9caf69 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1179,15 +1179,10 @@ static void omap_hsmmc_detect(struct work_struct *work)
carddetect = -ENOSYS;
}
- if (carddetect) {
+ if (carddetect)
mmc_detect_change(host->mmc, (HZ * 200) / 1000);
- } else {
- mmc_host_enable(host->mmc);
- omap_hsmmc_reset_controller_fsm(host, SRD);
- mmc_host_lazy_disable(host->mmc);
-
+ else
mmc_detect_change(host->mmc, (HZ * 50) / 1000);
- }
}
/*
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 1190bad..2f795ce 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -397,6 +397,7 @@ static int intel_menlow_add_one_attribute(char *name, int mode, void *show,
if (!attr)
return -ENOMEM;
+ sysfs_attr_init(&attr->attr.attr); /* That is consistent naming :D */
attr->attr.attr.name = name;
attr->attr.attr.mode = mode;
attr->attr.show = show;
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index c77f6f7..d71fe61 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -384,21 +384,26 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
struct rtc_device *rtc;
struct rtc_plat_data *pdata = NULL;
u32 reg;
- int ret, rate;
+ unsigned long rate;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENODEV;
- pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- pdata->ioaddr = ioremap(res->start, resource_size(res));
+ if (!devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), pdev->name))
+ return -EBUSY;
+
+ pdata->ioaddr = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
clk = clk_get(&pdev->dev, "ckil");
if (IS_ERR(clk)) {
- iounmap(pdata->ioaddr);
ret = PTR_ERR(clk);
goto exit_free_pdata;
}
@@ -413,8 +418,7 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
else if (rate == 38400)
reg = RTC_INPUT_CLK_38400HZ;
else {
- dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n",
- clk_get_rate(clk));
+ dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate);
ret = -EINVAL;
goto exit_free_pdata;
}
@@ -450,8 +454,8 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
pdata->irq = platform_get_irq(pdev, 0);
if (pdata->irq >= 0 &&
- request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED,
- pdev->name, pdev) < 0) {
+ devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt,
+ IRQF_SHARED, pdev->name, pdev) < 0) {
dev_warn(&pdev->dev, "interrupt not available.\n");
pdata->irq = -1;
}
@@ -459,10 +463,10 @@ static int __init mxc_rtc_probe(struct platform_device *pdev)
return 0;
exit_put_clk:
+ clk_disable(pdata->clk);
clk_put(pdata->clk);
exit_free_pdata:
- kfree(pdata);
return ret;
}
@@ -473,12 +477,8 @@ static int __exit mxc_rtc_remove(struct platform_device *pdev)
rtc_device_unregister(pdata->rtc);
- if (pdata->irq >= 0)
- free_irq(pdata->irq, pdev);
-
clk_disable(pdata->clk);
clk_put(pdata->clk);
- kfree(pdata);
platform_set_drvdata(pdev, NULL);
return 0;
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 9b6297f..13c72c6 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -506,6 +506,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
tz->temp_input.attr.attr.name = tz->temp_input.name;
tz->temp_input.attr.attr.mode = 0444;
tz->temp_input.attr.show = temp_input_show;
+ sysfs_attr_init(&tz->temp_input.attr.attr);
result = device_create_file(hwmon->device, &tz->temp_input.attr);
if (result)
goto unregister_hwmon_device;
@@ -518,6 +519,7 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
tz->temp_crit.attr.attr.name = tz->temp_crit.name;
tz->temp_crit.attr.attr.mode = 0444;
tz->temp_crit.attr.show = temp_crit_show;
+ sysfs_attr_init(&tz->temp_crit.attr.attr);
result = device_create_file(hwmon->device,
&tz->temp_crit.attr);
if (result)
@@ -726,6 +728,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
goto release_idr;
sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
+ sysfs_attr_init(&dev->attr.attr);
dev->attr.attr.name = dev->attr_name;
dev->attr.attr.mode = 0444;
dev->attr.show = thermal_cooling_device_trip_point_show;
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 4637bcb..994358a 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1536,6 +1536,7 @@ static int __devinit fsl_diu_probe(struct of_device *ofdev,
goto error;
}
+ sysfs_attr_init(&machine_data->dev_attr.attr);
machine_data->dev_attr.attr.name = "monitor";
machine_data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
machine_data->dev_attr.show = show_monitor;
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/mb862xx/mb862xxfb_accel.c
index 8414249..fe92eed 100644
--- a/drivers/video/mb862xx/mb862xxfb_accel.c
+++ b/drivers/video/mb862xx/mb862xxfb_accel.c
@@ -4,7 +4,7 @@
* Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support
*
* (C) 2007 Alexander Shishkin <virtuoso@slind.org>
- * (C) 2009 Valentin Sitdikov <valentin.sitdikov@siemens.com>
+ * (C) 2009 Valentin Sitdikov <v.sitdikov@gmail.com>
* (C) 2009 Siemens AG
*
* This program is free software; you can redistribute it and/or modify
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#if defined(CONFIG_OF)
@@ -330,3 +331,5 @@ void mb862xxfb_init_accel(struct fb_info *info, int xres)
info->fix.accel = 0xff; /*FIXME: add right define */
}
EXPORT_SYMBOL(mb862xxfb_init_accel);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 54ac91d..0cadf7a 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -225,7 +225,7 @@ static int __init vesafb_setup(char *options)
return 0;
}
-static int __devinit vesafb_probe(struct platform_device *dev)
+static int __init vesafb_probe(struct platform_device *dev)
{
struct fb_info *info;
int i, err;
@@ -476,7 +476,6 @@ err:
}
static struct platform_driver vesafb_driver = {
- .probe = vesafb_probe,
.driver = {
.name = "vesafb",
},
@@ -492,20 +491,21 @@ static int __init vesafb_init(void)
/* ignore error return of fb_get_options */
fb_get_options("vesafb", &option);
vesafb_setup(option);
- ret = platform_driver_register(&vesafb_driver);
- if (!ret) {
- vesafb_device = platform_device_alloc("vesafb", 0);
+ vesafb_device = platform_device_alloc("vesafb", 0);
+ if (!vesafb_device)
+ return -ENOMEM;
- if (vesafb_device)
- ret = platform_device_add(vesafb_device);
- else
- ret = -ENOMEM;
+ ret = platform_device_add(vesafb_device);
+ if (!ret) {
+ ret = platform_driver_probe(&vesafb_driver, vesafb_probe);
+ if (ret)
+ platform_device_del(vesafb_device);
+ }
- if (ret) {
- platform_device_put(vesafb_device);
- platform_driver_unregister(&vesafb_driver);
- }
+ if (ret) {
+ platform_device_put(vesafb_device);
+ vesafb_device = NULL;
}
return ret;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d11d028..2a6d019 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -404,7 +404,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
* NULL first argument is nfsd_sync_dir() and that's not a directory.
*/
-static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
{
struct block_device *bdev = I_BDEV(filp->f_mapping->host);
int error;
@@ -418,6 +418,7 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync)
error = 0;
return error;
}
+EXPORT_SYMBOL(blkdev_fsync);
/*
* pseudo-fs
@@ -1481,7 +1482,7 @@ const struct file_operations def_blk_fops = {
.aio_read = generic_file_aio_read,
.aio_write = blkdev_aio_write,
.mmap = generic_file_mmap,
- .fsync = block_fsync,
+ .fsync = blkdev_fsync,
.unlocked_ioctl = block_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_blkdev_ioctl,
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
index 46435f3a..4765190 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -165,8 +165,8 @@ static int fscache_stats_show(struct seq_file *m, void *v)
atomic_read(&fscache_n_object_lookups),
atomic_read(&fscache_n_object_lookups_negative),
atomic_read(&fscache_n_object_lookups_positive),
- atomic_read(&fscache_n_object_lookups_timed_out),
- atomic_read(&fscache_n_object_created));
+ atomic_read(&fscache_n_object_created),
+ atomic_read(&fscache_n_object_lookups_timed_out));
seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
atomic_read(&fscache_n_updates),
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index a05a669..0705534 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -662,31 +662,18 @@ static u64 huge_pte_to_pagemap_entry(pte_t pte, int offset)
return pme;
}
-static int pagemap_hugetlb_range(pte_t *pte, unsigned long addr,
- unsigned long end, struct mm_walk *walk)
+/* This function walks within one hugetlb entry in the single call */
+static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
+ unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
{
- struct vm_area_struct *vma;
struct pagemapread *pm = walk->private;
- struct hstate *hs = NULL;
int err = 0;
+ u64 pfn;
- vma = find_vma(walk->mm, addr);
- if (vma)
- hs = hstate_vma(vma);
for (; addr != end; addr += PAGE_SIZE) {
- u64 pfn = PM_NOT_PRESENT;
-
- if (vma && (addr >= vma->vm_end)) {
- vma = find_vma(walk->mm, addr);
- if (vma)
- hs = hstate_vma(vma);
- }
-
- if (vma && (vma->vm_start <= addr) && is_vm_hugetlb_page(vma)) {
- /* calculate pfn of the "raw" page in the hugepage. */
- int offset = (addr & ~huge_page_mask(hs)) >> PAGE_SHIFT;
- pfn = huge_pte_to_pagemap_entry(*pte, offset);
- }
+ int offset = (addr & ~hmask) >> PAGE_SHIFT;
+ pfn = huge_pte_to_pagemap_entry(*pte, offset);
err = add_to_pagemap(addr, pfn, pm);
if (err)
return err;
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index b793898..b796eab 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -21,9 +21,6 @@
(bit) < (size); \
(bit) = find_next_bit((addr), (size), (bit) + 1))
-/* Temporary */
-#define for_each_bit(bit, addr, size) for_each_set_bit(bit, addr, size)
-
static __inline__ int get_bitmask_order(unsigned int count)
{
int order;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 10b8ded..39d57bc 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2212,6 +2212,7 @@ extern int generic_segment_checks(const struct iovec *iov,
/* fs/block_dev.c */
extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos);
+extern int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync);
/* fs/splice.c */
extern ssize_t generic_file_splice_read(struct file *, loff_t *,
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7f07074..9365227 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -426,7 +426,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
.burst = DEFAULT_RATELIMIT_BURST, \
}; \
\
- if (!__ratelimit(&_rs)) \
+ if (__ratelimit(&_rs)) \
printk(fmt, ##__VA_ARGS__); \
})
#else
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index ece0b1c..e117b1a 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -86,7 +86,8 @@ union { \
*/
#define INIT_KFIFO(name) \
name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \
- sizeof(struct kfifo), name##kfifo_buffer)
+ sizeof(struct kfifo), \
+ name##kfifo_buffer + sizeof(struct kfifo))
/**
* DEFINE_KFIFO - macro to define and initialize a kfifo
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e70f21b..462acaf 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -783,8 +783,8 @@ struct mm_walk {
int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *);
int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *);
int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *);
- int (*hugetlb_entry)(pte_t *, unsigned long, unsigned long,
- struct mm_walk *);
+ int (*hugetlb_entry)(pte_t *, unsigned long,
+ unsigned long, unsigned long, struct mm_walk *);
struct mm_struct *mm;
void *private;
};
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h
index 30b0813..aef22ae 100644
--- a/include/linux/page_cgroup.h
+++ b/include/linux/page_cgroup.h
@@ -39,6 +39,7 @@ enum {
PCG_CACHE, /* charged as cache */
PCG_USED, /* this object is in use. */
PCG_ACCT_LRU, /* page has been accounted for */
+ PCG_FILE_MAPPED, /* page is accounted as "mapped" */
};
#define TESTPCGFLAG(uname, lname) \
@@ -73,6 +74,11 @@ CLEARPCGFLAG(AcctLRU, ACCT_LRU)
TESTPCGFLAG(AcctLRU, ACCT_LRU)
TESTCLEARPCGFLAG(AcctLRU, ACCT_LRU)
+
+SETPCGFLAG(FileMapped, FILE_MAPPED)
+CLEARPCGFLAG(FileMapped, FILE_MAPPED)
+TESTPCGFLAG(FileMapped, FILE_MAPPED)
+
static inline int page_cgroup_nid(struct page_cgroup *pc)
{
return page_to_nid(pc->page);
diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h
index 8988eda..2609048 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);
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 061f16d..0a0b019 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -219,7 +219,6 @@ struct snd_soc_dai {
struct snd_soc_codec *codec;
unsigned int active;
unsigned char pop_wait:1;
- void *dma_data;
/* DAI private data */
void *private_data;
@@ -230,4 +229,21 @@ struct snd_soc_dai {
struct list_head list;
};
+static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
+ const struct snd_pcm_substream *ss)
+{
+ return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ dai->playback.dma_data : dai->capture.dma_data;
+}
+
+static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
+ const struct snd_pcm_substream *ss,
+ void *data)
+{
+ if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ dai->playback.dma_data = data;
+ else
+ dai->capture.dma_data = data;
+}
+
#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 5d234a8..a57fbfc 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -375,6 +375,7 @@ struct snd_soc_pcm_stream {
unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */
unsigned int active:1; /* stream is in use */
+ void *dma_data; /* used by platform code */
};
/* SoC audio ops */
diff --git a/kernel/exit.c b/kernel/exit.c
index cce59cb..7f2683a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -953,7 +953,8 @@ NORET_TYPE void do_exit(long code)
acct_update_integrals(tsk);
/* sync mm's RSS info before statistics gathering */
- sync_mm_rss(tsk, tsk->mm);
+ if (tsk->mm)
+ sync_mm_rss(tsk, tsk->mm);
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead) {
hrtimer_cancel(&tsk->signal->real_timer);
diff --git a/kernel/fork.c b/kernel/fork.c
index 4799c5f..44b0791 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1052,6 +1052,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->prev_utime = cputime_zero;
p->prev_stime = cputime_zero;
#endif
+#if defined(SPLIT_RSS_COUNTING)
+ memset(&p->rss_stat, 0, sizeof(p->rss_stat));
+#endif
p->default_timer_slack_ns = current->timer_slack_ns;
diff --git a/lib/ratelimit.c b/lib/ratelimit.c
index 09f5ce1..027a03f 100644
--- a/lib/ratelimit.c
+++ b/lib/ratelimit.c
@@ -16,9 +16,14 @@
/*
* __ratelimit - rate limiting
* @rs: ratelimit_state data
+ * @func: name of calling function
*
- * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
- * in every @rs->ratelimit_jiffies
+ * This enforces a rate limit: not more than @rs->burst callbacks
+ * in every @rs->interval
+ *
+ * RETURNS:
+ * 0 means callbacks will be suppressed.
+ * 1 means go ahead and do it.
*/
int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
@@ -35,7 +40,7 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
* the entity that is holding the lock already:
*/
if (!spin_trylock_irqsave(&rs->lock, flags))
- return 1;
+ return 0;
if (!rs->begin)
rs->begin = jiffies;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 9ed760d..f4ede99 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1359,16 +1359,19 @@ void mem_cgroup_update_file_mapped(struct page *page, int val)
lock_page_cgroup(pc);
mem = pc->mem_cgroup;
- if (!mem)
- goto done;
-
- if (!PageCgroupUsed(pc))
+ if (!mem || !PageCgroupUsed(pc))
goto done;
/*
* Preemption is already disabled. We can use __this_cpu_xxx
*/
- __this_cpu_add(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED], val);
+ if (val > 0) {
+ __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+ SetPageCgroupFileMapped(pc);
+ } else {
+ __this_cpu_dec(mem->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
+ ClearPageCgroupFileMapped(pc);
+ }
done:
unlock_page_cgroup(pc);
@@ -1801,16 +1804,13 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
static void __mem_cgroup_move_account(struct page_cgroup *pc,
struct mem_cgroup *from, struct mem_cgroup *to, bool uncharge)
{
- struct page *page;
-
VM_BUG_ON(from == to);
VM_BUG_ON(PageLRU(pc->page));
VM_BUG_ON(!PageCgroupLocked(pc));
VM_BUG_ON(!PageCgroupUsed(pc));
VM_BUG_ON(pc->mem_cgroup != from);
- page = pc->page;
- if (page_mapped(page) && !PageAnon(page)) {
+ if (PageCgroupFileMapped(pc)) {
/* Update mapped_file data for mem_cgroup */
preempt_disable();
__this_cpu_dec(from->stat->count[MEM_CGROUP_STAT_FILE_MAPPED]);
diff --git a/mm/memory.c b/mm/memory.c
index 1d2ea39..833952d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -125,13 +125,12 @@ core_initcall(init_zero_pfn);
#if defined(SPLIT_RSS_COUNTING)
-void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
+static void __sync_task_rss_stat(struct task_struct *task, struct mm_struct *mm)
{
int i;
for (i = 0; i < NR_MM_COUNTERS; i++) {
if (task->rss_stat.count[i]) {
- BUG_ON(!mm);
add_mm_counter(mm, i, task->rss_stat.count[i]);
task->rss_stat.count[i] = 0;
}
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 7b47a57..8b1a2ce 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -80,6 +80,37 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end,
return err;
}
+#ifdef CONFIG_HUGETLB_PAGE
+static unsigned long hugetlb_entry_end(struct hstate *h, unsigned long addr,
+ unsigned long end)
+{
+ unsigned long boundary = (addr & huge_page_mask(h)) + huge_page_size(h);
+ return boundary < end ? boundary : end;
+}
+
+static int walk_hugetlb_range(struct vm_area_struct *vma,
+ unsigned long addr, unsigned long end,
+ struct mm_walk *walk)
+{
+ struct hstate *h = hstate_vma(vma);
+ unsigned long next;
+ unsigned long hmask = huge_page_mask(h);
+ pte_t *pte;
+ int err = 0;
+
+ do {
+ next = hugetlb_entry_end(h, addr, end);
+ pte = huge_pte_offset(walk->mm, addr & hmask);
+ if (pte && walk->hugetlb_entry)
+ err = walk->hugetlb_entry(pte, hmask, addr, next, walk);
+ if (err)
+ return err;
+ } while (addr = next, addr != end);
+
+ return 0;
+}
+#endif
+
/**
* walk_page_range - walk a memory map's page tables with a callback
* @mm: memory map to walk
@@ -128,20 +159,16 @@ int walk_page_range(unsigned long addr, unsigned long end,
vma = find_vma(walk->mm, addr);
#ifdef CONFIG_HUGETLB_PAGE
if (vma && is_vm_hugetlb_page(vma)) {
- pte_t *pte;
- struct hstate *hs;
-
if (vma->vm_end < next)
next = vma->vm_end;
- hs = hstate_vma(vma);
- pte = huge_pte_offset(walk->mm,
- addr & huge_page_mask(hs));
- if (pte && !huge_pte_none(huge_ptep_get(pte))
- && walk->hugetlb_entry)
- err = walk->hugetlb_entry(pte, addr,
- next, walk);
+ /*
+ * Hugepage is very tightly coupled with vma, so
+ * walk through hugetlb entries within a given vma.
+ */
+ err = walk_hugetlb_range(vma, addr, next, walk);
if (err)
break;
+ pgd = pgd_offset(walk->mm, next);
continue;
}
#endif
diff --git a/mm/readahead.c b/mm/readahead.c
index 999b54b..dfa9a1a 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -503,7 +503,7 @@ void page_cache_sync_readahead(struct address_space *mapping,
return;
/* be dumb */
- if (filp->f_mode & FMODE_RANDOM) {
+ if (filp && (filp->f_mode & FMODE_RANDOM)) {
force_page_cache_readahead(mapping, filp, offset, req_size);
return;
}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index e0e5f15..3ff3311 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1535,13 +1535,6 @@ static void get_scan_ratio(struct zone *zone, struct scan_control *sc,
unsigned long ap, fp;
struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
- /* If we have no swap space, do not bother scanning anon pages. */
- if (!sc->may_swap || (nr_swap_pages <= 0)) {
- percent[0] = 0;
- percent[1] = 100;
- return;
- }
-
anon = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_ANON) +
zone_nr_lru_pages(zone, sc, LRU_INACTIVE_ANON);
file = zone_nr_lru_pages(zone, sc, LRU_ACTIVE_FILE) +
@@ -1639,20 +1632,22 @@ static void shrink_zone(int priority, struct zone *zone,
unsigned long nr_reclaimed = sc->nr_reclaimed;
unsigned long nr_to_reclaim = sc->nr_to_reclaim;
struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
+ int noswap = 0;
- get_scan_ratio(zone, sc, percent);
+ /* If we have no swap space, do not bother scanning anon pages. */
+ if (!sc->may_swap || (nr_swap_pages <= 0)) {
+ noswap = 1;
+ percent[0] = 0;
+ percent[1] = 100;
+ } else
+ get_scan_ratio(zone, sc, percent);
for_each_evictable_lru(l) {
int file = is_file_lru(l);
unsigned long scan;
- if (percent[file] == 0) {
- nr[l] = 0;
- continue;
- }
-
scan = zone_nr_lru_pages(zone, sc, l);
- if (priority) {
+ if (priority || noswap) {
scan >>= priority;
scan = (scan * percent[file]) / 100;
}
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index fff62cc..971a84a 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
}
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
- ak4113_write_t *write, const unsigned char pgm[5],
+ ak4113_write_t *write, const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113)
{
struct ak4113 *chip;
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 8dab82d..668a5ec 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
goto ctl_error;
#endif
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
+ err = snd_card_register(card);
+ if (err < 0)
goto ctl_error;
- }
snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
pci_set_drvdata(pci, chip);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 4bb9067..f8fd586 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2362,6 +2362,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = {
SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
+ SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
{}
};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index e6d1bdf..af34606 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1896,6 +1896,14 @@ static int patch_ad1981(struct hda_codec *codec)
case AD1981_THINKPAD:
spec->mixers[0] = ad1981_thinkpad_mixers;
spec->input_mux = &ad1981_thinkpad_capture_source;
+ /* set the upper-limit for mixer amp to 0dB for avoiding the
+ * possible damage by overloading
+ */
+ snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+ (1 << AC_AMPCAP_MUTE_SHIFT));
break;
case AD1981_TOSHIBA:
spec->mixers[0] = ad1981_hp_mixers;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9a23444..c7730db 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1621,6 +1621,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
*/
static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
+/* Route to built-in subwoofer as well as speakers */
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
/* Bias voltage on for external mic port */
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
/* Front Mic: set to PIN_IN (empty by default) */
@@ -1632,10 +1637,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
/* Enable speaker output */
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
/* Enable headphone output */
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
{ }
};
@@ -4984,6 +4991,70 @@ static void set_capture_mixer(struct hda_codec *codec)
}
}
+/* fill adc_nids (and capsrc_nids) containing all active input pins */
+static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
+ int num_nids)
+{
+ struct alc_spec *spec = codec->spec;
+ int n;
+ hda_nid_t fallback_adc = 0, fallback_cap = 0;
+
+ for (n = 0; n < num_nids; n++) {
+ hda_nid_t adc, cap;
+ hda_nid_t conn[HDA_MAX_NUM_INPUTS];
+ int nconns, i, j;
+
+ adc = nids[n];
+ if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
+ continue;
+ cap = adc;
+ nconns = snd_hda_get_connections(codec, cap, conn,
+ ARRAY_SIZE(conn));
+ if (nconns == 1) {
+ cap = conn[0];
+ nconns = snd_hda_get_connections(codec, cap, conn,
+ ARRAY_SIZE(conn));
+ }
+ if (nconns <= 0)
+ continue;
+ if (!fallback_adc) {
+ fallback_adc = adc;
+ fallback_cap = cap;
+ }
+ for (i = 0; i < AUTO_PIN_LAST; i++) {
+ hda_nid_t nid = spec->autocfg.input_pins[i];
+ if (!nid)
+ continue;
+ for (j = 0; j < nconns; j++) {
+ if (conn[j] == nid)
+ break;
+ }
+ if (j >= nconns)
+ break;
+ }
+ if (i >= AUTO_PIN_LAST) {
+ int num_adcs = spec->num_adc_nids;
+ spec->private_adc_nids[num_adcs] = adc;
+ spec->private_capsrc_nids[num_adcs] = cap;
+ spec->num_adc_nids++;
+ spec->adc_nids = spec->private_adc_nids;
+ if (adc != cap)
+ spec->capsrc_nids = spec->private_capsrc_nids;
+ }
+ }
+ if (!spec->num_adc_nids) {
+ printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
+ " using fallback 0x%x\n",
+ codec->chip_name, fallback_adc);
+ spec->private_adc_nids[0] = fallback_adc;
+ spec->adc_nids = spec->private_adc_nids;
+ if (fallback_adc != fallback_cap) {
+ spec->private_capsrc_nids[0] = fallback_cap;
+ spec->capsrc_nids = spec->private_adc_nids;
+ }
+ }
+}
+
#ifdef CONFIG_SND_HDA_INPUT_BEEP
#define set_beep_amp(spec, nid, idx, dir) \
((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -8398,9 +8469,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
- HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -10041,13 +10110,12 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
int idx;
alc_set_pin_output(codec, nid, pin_type);
+ if (dac_idx >= spec->multiout.num_dacs)
+ return;
if (spec->multiout.dac_nids[dac_idx] == 0x25)
idx = 4;
- else {
- if (spec->multiout.num_dacs >= dac_idx)
- return;
+ else
idx = spec->multiout.dac_nids[dac_idx] - 2;
- }
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
}
@@ -12459,11 +12527,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
unsigned char bits;
present = snd_hda_jack_detect(codec, 0x15);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
@@ -13333,9 +13401,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = {
0x22,
};
-/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
- * not a mux!
- */
+static hda_nid_t alc269_adc_candidates[] = {
+ 0x08, 0x09, 0x07,
+};
#define alc269_modes alc260_modes
#define alc269_capture_source alc880_lg_lw_capture_source
@@ -13482,11 +13550,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
unsigned char bits;
present = snd_hda_jack_detect(codec, 0x15);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13511,11 +13579,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
/* Check port replicator headphone socket */
present |= snd_hda_jack_detect(codec, 0x1a);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_write(codec, 0x20, 0,
AC_VERB_SET_COEF_INDEX, 0x0c);
@@ -13646,11 +13714,11 @@ static void alc269_speaker_automute(struct hda_codec *codec)
unsigned char bits;
present = snd_hda_jack_detect(codec, nid);
- bits = present ? AMP_IN_MUTE(0) : 0;
+ bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
/* unsolicited event for HP jack sensing */
@@ -13842,7 +13910,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
struct alc_spec *spec = codec->spec;
int err;
static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
- hda_nid_t real_capsrc_nids;
err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
alc269_ignore);
@@ -13866,18 +13933,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
add_verb(spec, alc269vb_init_verbs);
- real_capsrc_nids = alc269vb_capsrc_nids[0];
alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
} else {
add_verb(spec, alc269_init_verbs);
- real_capsrc_nids = alc269_capsrc_nids[0];
alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
}
spec->num_mux_defs = 1;
spec->input_mux = &spec->private_imux[0];
+ fillup_priv_adc_nids(codec, alc269_adc_candidates,
+ sizeof(alc269_adc_candidates));
+
/* set default input source */
- snd_hda_codec_write_cache(codec, real_capsrc_nids,
+ snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
0, AC_VERB_SET_CONNECT_SEL,
spec->input_mux->items[0].index);
@@ -14156,14 +14224,16 @@ static int patch_alc269(struct hda_codec *codec)
spec->stream_digital_playback = &alc269_pcm_digital_playback;
spec->stream_digital_capture = &alc269_pcm_digital_capture;
- if (!is_alc269vb) {
- spec->adc_nids = alc269_adc_nids;
- spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
- spec->capsrc_nids = alc269_capsrc_nids;
- } else {
- spec->adc_nids = alc269vb_adc_nids;
- spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
- spec->capsrc_nids = alc269vb_capsrc_nids;
+ if (!spec->adc_nids) { /* wasn't filled automatically? use default */
+ if (!is_alc269vb) {
+ spec->adc_nids = alc269_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
+ spec->capsrc_nids = alc269_capsrc_nids;
+ } else {
+ spec->adc_nids = alc269vb_adc_nids;
+ spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
+ spec->capsrc_nids = alc269vb_capsrc_nids;
+ }
}
if (!spec->cap_mixer)
@@ -17115,9 +17185,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)
present = snd_hda_jack_detect(codec, 0x21);
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
@@ -17128,13 +17198,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
present = snd_hda_jack_detect(codec, 0x21);
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
@@ -17145,13 +17215,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
present = snd_hda_jack_detect(codec, 0x15);
bits = present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
- AMP_IN_MUTE(0), bits);
+ HDA_AMP_MUTE, bits);
}
static void alc662_f5z_speaker_automute(struct hda_codec *codec)
@@ -17190,14 +17260,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
if (present1 || present2) {
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), AMP_IN_MUTE(0));
+ HDA_AMP_MUTE, HDA_AMP_MUTE);
} else {
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
- AMP_IN_MUTE(0), 0);
+ HDA_AMP_MUTE, 0);
snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
- AMP_IN_MUTE(0), 0);
+ HDA_AMP_MUTE, 0);
}
}
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 55e9315..3be8f97 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1162,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos)
{
struct mixart_mgr *mgr = entry->private_data;
+ unsigned long maxsize;
- count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
- if(count <= 0)
+ if (pos >= MIXART_BA0_SIZE)
return 0;
- if(pos + count > MIXART_BA0_SIZE)
- count = (long)(MIXART_BA0_SIZE - pos);
- if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
+ maxsize = MIXART_BA0_SIZE - pos;
+ if (count > maxsize)
+ count = maxsize;
+ count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+ if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
return -EFAULT;
return count;
}
@@ -1181,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos)
{
struct mixart_mgr *mgr = entry->private_data;
+ unsigned long maxsize;
- count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
- if(count <= 0)
+ if (pos > MIXART_BA1_SIZE)
return 0;
- if(pos + count > MIXART_BA1_SIZE)
- count = (long)(MIXART_BA1_SIZE - pos);
- if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
+ maxsize = MIXART_BA1_SIZE - pos;
+ if (count > maxsize)
+ count = maxsize;
+ count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+ if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
return -EFAULT;
return count;
}
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
index 9ef6b96..3e6628c8 100644
--- a/sound/soc/atmel/atmel-pcm.c
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params);
- prtd->params = rtd->dai->cpu_dai->dma_data;
+ prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
prtd->dma_buffer = runtime->dma_addr;
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
index e588e63..0b59806 100644
--- a/sound/soc/atmel/atmel_ssc_dai.c
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
ssc_p->dma_params[dir] = dma_params;
/*
- * The cpu_dai->dma_data field is only used to communicate the
- * appropriate DMA parameters to the pcm driver hw_params()
+ * The snd_soc_pcm_stream->dma_data field is only used to communicate
+ * the appropriate DMA parameters to the pcm driver hw_params()
* function. It should not be used for other purposes
* as it is common to all substreams.
*/
- rtd->dai->cpu_dai->dma_data = dma_params;
+ snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
channels = params_channels(params);
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index fd101d4..1f5e57a 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -81,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
static int ac97_soc_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+ struct snd_soc_card *card = socdev->card;
struct snd_soc_codec *codec;
struct snd_ac97_bus *ac97_bus;
struct snd_ac97_template ac97_template;
+ int i;
int ret = 0;
printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
@@ -103,12 +105,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
- ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
- if (ret < 0) {
- printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
- goto err;
- }
-
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0)
@@ -124,6 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
if (ret < 0)
goto bus_err;
+ for (i = 0; i < card->num_links; i++) {
+ if (card->dai_link[i].codec_dai->ac97_control) {
+ snd_ac97_dev_add_pdata(codec->ac97,
+ card->dai_link[i].cpu_dai->ac97_pdata);
+ }
+ }
+
return 0;
bus_err:
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 8d1c637..9da0724 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3008,34 +3008,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break;
case SND_SOC_BIAS_OFF:
- /* Switch over to startup biases */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK,
- WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- (1 << WM8994_VMID_RAMP_SHIFT));
-
- /* Disable main biases */
- snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
- WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
+ if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+ /* Switch over to startup biases */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ WM8994_VMID_RAMP_MASK,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ (1 << WM8994_VMID_RAMP_SHIFT));
- /* Discharge line */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH,
- WM8994_LINEOUT1_DISCH |
- WM8994_LINEOUT2_DISCH);
+ /* Disable main biases */
+ snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+ WM8994_BIAS_ENA |
+ WM8994_VMID_SEL_MASK, 0);
- msleep(5);
+ /* Discharge line */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+ WM8994_LINEOUT1_DISCH |
+ WM8994_LINEOUT2_DISCH,
+ WM8994_LINEOUT1_DISCH |
+ WM8994_LINEOUT2_DISCH);
- /* Switch off startup biases */
- snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
- WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
- WM8994_VMID_BUF_ENA |
- WM8994_VMID_RAMP_MASK, 0);
+ msleep(5);
+ /* Switch off startup biases */
+ snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+ WM8994_BIAS_SRC |
+ WM8994_STARTUP_BIAS_ENA |
+ WM8994_VMID_BUF_ENA |
+ WM8994_VMID_RAMP_MASK, 0);
+ }
break;
}
codec->bias_level = level;
@@ -3402,7 +3407,7 @@ struct snd_soc_dai wm8994_dai[] = {
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
- .playback = {
+ .capture = {
.stream_name = "AIF3 Capture",
.channels_min = 2,
.channels_max = 2,
@@ -3731,11 +3736,12 @@ static int wm8994_codec_probe(struct platform_device *pdev)
case 3:
wm8994->hubs.dcs_codes = -5;
wm8994->hubs.hp_startup_mode = 1;
+ wm8994->hubs.dcs_readback_mode = 1;
break;
default:
+ wm8994->hubs.dcs_readback_mode = 1;
break;
}
-
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 486bdd2..e1f225a 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = {
static const struct soc_enum speaker_mode =
SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
-static void wait_for_dc_servo(struct snd_soc_codec *codec)
+static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
{
unsigned int reg;
int count = 0;
+ unsigned int val;
+
+ val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
+
+ /* Trigger the command */
+ snd_soc_write(codec, WM8993_DC_SERVO_0, val);
dev_dbg(codec->dev, "Waiting for DC servo...\n");
do {
count++;
msleep(1);
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
+ reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
dev_dbg(codec->dev, "DC servo: %x\n", reg);
- } while (reg & WM8993_DCS_DATAPATH_BUSY && count < 400);
+ } while (reg & op && count < 400);
- if (reg & WM8993_DCS_DATAPATH_BUSY)
+ if (reg & op)
dev_err(codec->dev, "Timed out waiting for DC Servo\n");
}
@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
static void calibrate_dc_servo(struct snd_soc_codec *codec)
{
struct wm_hubs_data *hubs = codec->private_data;
- u16 reg, dcs_cfg;
+ u16 reg, reg_l, reg_r, dcs_cfg;
/* Set for 32 series updates */
snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
WM8993_DCS_SERIES_NO_01_MASK,
32 << WM8993_DCS_SERIES_NO_01_SHIFT);
-
- /* Enable the DC servo. Write all bits to avoid triggering startup
- * or write calibration.
- */
- snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
- 0xFFFF,
- WM8993_DCS_ENA_CHAN_0 |
- WM8993_DCS_ENA_CHAN_1 |
- WM8993_DCS_TRIG_SERIES_1 |
- WM8993_DCS_TRIG_SERIES_0);
-
- wait_for_dc_servo(codec);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
/* Apply correction to DC servo result */
if (hubs->dcs_codes) {
dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
hubs->dcs_codes);
+ /* Different chips in the family support different
+ * readback methods.
+ */
+ switch (hubs->dcs_readback_mode) {
+ case 0:
+ reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+ & WM8993_DCS_INTEG_CHAN_0_MASK;;
+ reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+ & WM8993_DCS_INTEG_CHAN_1_MASK;
+ break;
+ case 1:
+ reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+ reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+ >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+ break;
+ default:
+ WARN(1, "Unknown DCS readback method");
+ break;
+ }
+
/* HPOUT1L */
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
- WM8993_DCS_INTEG_CHAN_0_MASK;;
- reg += hubs->dcs_codes;
- dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+ if (reg_l + hubs->dcs_codes > 0 &&
+ reg_l + hubs->dcs_codes < 0xff)
+ reg_l += hubs->dcs_codes;
+ dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
/* HPOUT1R */
- reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
- WM8993_DCS_INTEG_CHAN_1_MASK;
- reg += hubs->dcs_codes;
- dcs_cfg |= reg;
+ if (reg_r + hubs->dcs_codes > 0 &&
+ reg_r + hubs->dcs_codes < 0xff)
+ reg_r += hubs->dcs_codes;
+ dcs_cfg |= reg_r;
/* Do it */
snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
- snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
- WM8993_DCS_TRIG_DAC_WR_0 |
- WM8993_DCS_TRIG_DAC_WR_1,
- WM8993_DCS_TRIG_DAC_WR_0 |
- WM8993_DCS_TRIG_DAC_WR_1);
-
- wait_for_dc_servo(codec);
+ wait_for_dc_servo(codec,
+ WM8993_DCS_TRIG_DAC_WR_0 |
+ WM8993_DCS_TRIG_DAC_WR_1);
}
}
@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+ struct wm_hubs_data *hubs = codec->private_data;
int ret;
ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+ /* If we're applying an offset correction then updating the
+ * callibration would be likely to introduce further offsets. */
+ if (hubs->dcs_codes)
+ return ret;
+
/* Only need to do this if the outputs are active */
if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
& (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 420104f..e51c166 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
/* This *must* be the first element of the codec->private_data struct */
struct wm_hubs_data {
int dcs_codes;
+ int dcs_readback_mode;
int hp_startup_mode;
};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 62af7e0..adadcd3 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -586,7 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev;
- davinci_i2s_dai.dma_data = dev->dma_params;
+ davinci_i2s_dai.capture.dma_data = dev->dma_params;
+ davinci_i2s_dai.playback.dma_data = dev->dma_params;
ret = snd_soc_register_dai(&davinci_i2s_dai);
if (ret != 0)
goto err_free_mem;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 6c80cc3..79f0f4a 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -918,7 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev;
- davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params;
+ davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
+ davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 80c7fdf..2dc406f 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_hardware *ppcm;
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data;
+ struct davinci_pcm_dma_params *pa;
struct davinci_pcm_dma_params *params;
+
+ pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
if (!pa)
return -ENODEV;
params = &pa[substream->stream];
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index 86668ab..2e79d71 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -84,11 +84,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+ struct imx_pcm_dma_params *dma_params;
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int ret;
+ dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
if (iprtd->dma < 0) {
pr_err("Failed to claim the audio DMA\n");
@@ -193,10 +195,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+ struct imx_pcm_dma_params *dma_params;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int err;
+ dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
+
iprtd->substream = substream;
iprtd->buf = (unsigned int *)substream->dma_buffer.area;
iprtd->period_cnt = 0;
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 6546b06..0bcc6d7 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -235,17 +235,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct imx_ssi *ssi = cpu_dai->private_data;
+ struct imx_pcm_dma_params *dma_data;
u32 reg, sccr;
/* Tx/Rx config */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
reg = SSI_STCCR;
- cpu_dai->dma_data = &ssi->dma_params_tx;
+ dma_data = &ssi->dma_params_tx;
} else {
reg = SSI_SRCCR;
- cpu_dai->dma_data = &ssi->dma_params_rx;
+ dma_data = &ssi->dma_params_rx;
}
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
+
sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
/* DAI data (word) size */
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index e814a95..8ad9dc9 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
OMAP_DMA_DATA_TYPE_S16;
- cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &omap_mcbsp_dai_dma_params[id][substream->stream]);
if (mcbsp_data->configured) {
/* McBSP already configured by another stream */
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 25f19e4..b7f4f7e 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
int stream = substream->stream;
int channels, err, link_mask = 0;
- cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream];
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &omap_mcpdm_dai_dma_params[stream]);
channels = params_channels(params);
switch (channels) {
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index ba8acbb..1e52190 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -61,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
struct omap_runtime_data *prtd = runtime->private_data;
unsigned long flags;
- if ((cpu_is_omap1510()) &&
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
+ if ((cpu_is_omap1510())) {
/*
* OMAP1510 doesn't fully support DMA progress counter
* and there is no software emulation implemented yet,
- * so have to maintain our own playback progress counter
+ * so have to maintain our own progress counters
* that can be used by omap_pcm_pointer() instead.
*/
spin_lock_irqsave(&prtd->lock, flags);
@@ -101,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct omap_runtime_data *prtd = runtime->private_data;
- struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
+ struct omap_pcm_dma_data *dma_data;
int err = 0;
+ dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
/* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma_data)
@@ -190,8 +191,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
dma_params.frame_count = runtime->periods;
omap_set_dma_params(prtd->dma_ch, &dma_params);
- if ((cpu_is_omap1510()) &&
- (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
+ if ((cpu_is_omap1510()))
omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
else
@@ -249,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
dma_addr_t ptr;
snd_pcm_uframes_t offset;
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ if (cpu_is_omap1510()) {
+ offset = prtd->period_index * runtime->period_size;
+ } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
ptr = omap_get_dma_dst_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- } else if (!(cpu_is_omap1510())) {
+ } else {
ptr = omap_get_dma_src_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
- } else
- offset = prtd->period_index * runtime->period_size;
+ }
if (offset >= runtime->buffer_size)
offset = 0;
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d5fc52d..544fd95 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -122,10 +122,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
ssp_disable(ssp);
}
- if (cpu_dai->dma_data) {
- kfree(cpu_dai->dma_data);
- cpu_dai->dma_data = NULL;
- }
+ kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+ snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
+
return ret;
}
@@ -142,10 +141,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
clk_disable(ssp->clk);
}
- if (cpu_dai->dma_data) {
- kfree(cpu_dai->dma_data);
- cpu_dai->dma_data = NULL;
- }
+ kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+ snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
}
#ifdef CONFIG_PM
@@ -570,19 +567,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params));
int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+ struct pxa2xx_pcm_dma_params *dma_data;
+
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
/* generate correct DMA params */
- if (cpu_dai->dma_data)
- kfree(cpu_dai->dma_data);
+ kfree(dma_data);
/* Network mode with one active slot (ttsa == 1) can be used
* to force 16-bit frame width on the wire (for S16_LE), even
* with two channels. Use 16-bit DMA transfers for this case.
*/
- cpu_dai->dma_data = ssp_get_dma_params(ssp,
+ dma_data = ssp_get_dma_params(ssp,
((chn == 2) && (ttsa != 1)) || (width == 32),
substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ snd_soc_dai_set_dma_data(dai, substream, dma_data);
+
/* we can only change the settings if the port is not in use */
if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
return 0;
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index e9ae7b3..d314115 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct pxa2xx_pcm_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out;
+ dma_data = &pxa2xx_ac97_pcm_stereo_out;
else
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in;
+ dma_data = &pxa2xx_ac97_pcm_stereo_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0;
}
@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct pxa2xx_pcm_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
+ dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
else
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+ dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0;
}
@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -ENODEV;
else
- cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in;
+ snd_soc_dai_set_dma_data(cpu_dai, substream,
+ &pxa2xx_ac97_pcm_mic_mono_in);
return 0;
}
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 6b8f655..c1a52757 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct pxa2xx_pcm_dma_params *dma_data;
BUG_ON(IS_ERR(clk_i2s));
clk_enable(clk_i2s);
@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
pxa_i2s_wait();
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out;
+ dma_data = &pxa2xx_i2s_pcm_stereo_out;
else
- cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in;
+ dma_data = &pxa2xx_i2s_pcm_stereo_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
/* is port used by another stream */
if (!(SACR0 & SACR0_ENB)) {
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index d38e395..adc7e6f 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct pxa2xx_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
+ struct pxa2xx_pcm_dma_params *dma;
int ret;
+ dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
+
/* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma)
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
index ee8ed9d7..ecf4fd0 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ struct s3c_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- cpu_dai->dma_data = &s3c_ac97_pcm_out;
+ dma_data = &s3c_ac97_pcm_out;
else
- cpu_dai->dma_data = &s3c_ac97_pcm_in;
+ dma_data = &s3c_ac97_pcm_in;
+
+ snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0;
}
@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
{
u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
return 0;
}
@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -ENODEV;
else
- cpu_dai->dma_data = &s3c_ac97_mic_in;
+ snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
return 0;
}
@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
{
u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
return 0;
}
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c
index 7725e26..1b61c23 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/s3c24xx/s3c-dma.c
@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
struct s3c24xx_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
unsigned long totbytes = params_buffer_bytes(params);
+ struct s3c_dma_params *dma =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
int ret = 0;
+
pr_debug("Entered %s\n", __func__);
/* return if this is a bufferless transfer e.g.
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index e994d83..8851594 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
+ struct s3c_dma_params *dma_data;
u32 iismod;
pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dai->cpu_dai->dma_data = i2s->dma_playback;
+ dma_data = i2s->dma_playback;
else
- dai->cpu_dai->dma_data = i2s->dma_capture;
+ dma_data = i2s->dma_capture;
+
+ snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Working copies of register */
iismod = readl(i2s->regs + S3C2412_IISMOD);
@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
unsigned long irqs;
int ret = 0;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
pr_debug("Entered %s\n", __func__);
@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
* of the auto reload mechanism of S3C24XX.
* This call won't bother S3C64XX.
*/
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break;
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
index a98f40c..326f0a9 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
+ struct s3c_dma_params *dma_data;
void __iomem *regs = pcm->regs;
struct clk *clk;
int sclk_div, sync_div;
@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
dev_dbg(pcm->dev, "Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- dai->cpu_dai->dma_data = pcm->dma_playback;
+ dma_data = pcm->dma_playback;
else
- dai->cpu_dai->dma_data = pcm->dma_capture;
+ dma_data = pcm->dma_capture;
+
+ snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Strictly check for sample size */
switch (params_format(params)) {
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 0bc5950..c3ac890 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct s3c_dma_params *dma_data;
u32 iismod;
pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
+ dma_data = &s3c24xx_i2s_pcm_stereo_out;
else
- rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
+ dma_data = &s3c24xx_i2s_pcm_stereo_in;
+
+ snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data);
/* Working copies of register */
iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8:
iismod &= ~S3C2410_IISMOD_16BIT;
- ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->dma_size = 1;
+ dma_data->dma_size = 1;
break;
case SNDRV_PCM_FORMAT_S16_LE:
iismod |= S3C2410_IISMOD_16BIT;
- ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->dma_size = 2;
+ dma_data->dma_size = 2;
break;
default:
return -EINVAL;
@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int channel = ((struct s3c_dma_params *)
- rtd->dai->cpu_dai->dma_data)->channel;
+ struct s3c_dma_params *dma_data =
+ snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
pr_debug("Entered %s\n", __func__);
@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
else
s3c24xx_snd_txctrl(1);
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+ s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c
index 0664fac..5b9ac17 100644
--- a/sound/soc/s6000/s6000-i2s.c
+++ b/sound/soc/s6000/s6000-i2s.c
@@ -519,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
s6000_i2s_dai.dev = &pdev->dev;
s6000_i2s_dai.private_data = dev;
- s6000_i2s_dai.dma_data = &dev->dma_params;
+ s6000_i2s_dai.capture.dma_data = &dev->dma_params;
+ s6000_i2s_dai.playback.dma_data = &dev->dma_params;
dev->sifbase = sifmem->start;
dev->scbbase = mmio;
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 1d61109..9c7f7f0 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
int channel;
unsigned int period_size;
unsigned int dma_offset;
dma_addr_t dma_pos;
dma_addr_t src, dst;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
period_size = snd_pcm_lib_period_bytes(substream);
dma_offset = prtd->period * period_size;
dma_pos = runtime->dma_addr + dma_offset;
@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
{
struct snd_pcm *pcm = data;
struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *params =
+ snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
struct s6000_runtime_data *prtd;
unsigned int has_xrun;
int i, ret = IRQ_NONE;
@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
{
struct s6000_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
unsigned long flags;
int srcinc;
u32 dma;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
spin_lock_irqsave(&prtd->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
{
struct s6000_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
unsigned long flags;
u32 channel;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
channel = par->dma_out;
else
@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
int ret;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
ret = par->trigger(substream, cmd, 0);
if (ret < 0)
return ret;
@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd = runtime->private_data;
unsigned long flags;
unsigned int offset;
dma_addr_t count;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
spin_lock_irqsave(&prtd->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
static int s6000_pcm_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd;
int ret;
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
ret = snd_pcm_hw_constraint_step(runtime, 0,
@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par;
int ret;
ret = snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params));
@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
return ret;
}
+ par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
if (par->same_rate) {
spin_lock(&par->lock);
if (par->rate == -1 ||
@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
- struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *par =
+ snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
spin_lock(&par->lock);
par->in_use &= ~(1 << substream->stream);
@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = {
static void s6000_pcm_free(struct snd_pcm *pcm)
{
struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *params =
+ snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
free_irq(params->irq, pcm);
snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm)
{
struct snd_soc_pcm_runtime *runtime = pcm->private_data;
- struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
+ struct s6000_pcm_dma_params *params;
int res;
+ params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
+
if (!card->dev->dma_mask)
card->dev->dma_mask = &s6000_pcm_dmamask;
if (!card->dev->coherent_dma_mask)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 2320153..ad7f952 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1549,7 +1549,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
mutex_unlock(&codec->mutex);
return ret;
}
- if (card->dai_link[i].codec_dai->ac97_control) {
+ /* Check for codec->ac97 to handle the ac97.c fun */
+ if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
snd_ac97_dev_add_pdata(codec->ac97,
card->dai_link[i].cpu_dai->ac97_pdata);
}
OpenPOWER on IntegriCloud