From e31c194672c8e700483f4be6037e12d507a9e05b Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 7 Jan 2013 16:41:45 +0000 Subject: ASoC: arizona: Disable free-running mode on FLL1 The free running mode can cause problems when attempting to bring up the FLL running from a defined clock source. This patch disables free-running mode. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 1d8bb5917594..c3592db994a8 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -1082,6 +1082,9 @@ int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq, id, ret); } + regmap_update_bits(arizona->regmap, fll->base + 1, + ARIZONA_FLL1_FREERUN, 0); + return 0; } EXPORT_SYMBOL_GPL(arizona_init_fll); -- cgit v1.2.3 From 25b8d31488a3fb3611651991969526b2ea475764 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 10 Jan 2013 23:43:56 +0800 Subject: ASoC: fsl: fix multiple definition of init_module With commit f2818d0 (ASoC: fsl: fix miscompilation of snd-soc-imx-pcm), we will see the following build error when building modules with CONFIG_SND_IMX_SOC=m in imx_v6_v7_defconfig. CC [M] sound/soc/fsl/phycore-ac97.o LD [M] sound/soc/fsl/snd-soc-fsl-ssi.o LD [M] sound/soc/fsl/snd-soc-fsl-utils.o LD [M] sound/soc/fsl/snd-soc-imx-ssi.o LD [M] sound/soc/fsl/snd-soc-imx-audmux.o LD [M] sound/soc/fsl/snd-soc-imx-pcm.o sound/soc/fsl/imx-pcm-dma.o: In function `init_module': imx-pcm-dma.c:(.init.text+0x0): multiple definition of `init_module' sound/soc/fsl/imx-pcm-fiq.o:imx-pcm-fiq.c:(.init.text+0x0): first defined here sound/soc/fsl/imx-pcm-dma.o: In function `cleanup_module': imx-pcm-dma.c:(.exit.text+0x0): multiple definition of `cleanup_module' sound/soc/fsl/imx-pcm-fiq.o:imx-pcm-fiq.c:(.exit.text+0x0): first defined here make[4]: *** [sound/soc/fsl/snd-soc-imx-pcm.o] Error 1 Instead of using bool for SND_SOC_IMX_PCM_FIQ and SND_SOC_IMX_PCM_DMA to fix the original issue, we should completely remove SND_SOC_IMX_PCM and have imx-pcm.o statically linked with imx-pcm-fiq.o or imx-pcm-dma.o. Signed-off-by: Shawn Guo Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 9 ++------- sound/soc/fsl/Makefile | 5 ++++- sound/soc/fsl/imx-pcm.c | 3 --- 3 files changed, 6 insertions(+), 11 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 3b98159d9645..a210c8d7b4bc 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -108,18 +108,13 @@ if SND_IMX_SOC config SND_SOC_IMX_SSI tristate -config SND_SOC_IMX_PCM - tristate - config SND_SOC_IMX_PCM_FIQ - bool + tristate select FIQ - select SND_SOC_IMX_PCM config SND_SOC_IMX_PCM_DMA - bool + tristate select SND_SOC_DMAENGINE_PCM - select SND_SOC_IMX_PCM config SND_SOC_IMX_AUDMUX tristate diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index afd34794db53..ec1457915d7c 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -41,7 +41,10 @@ endif obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o -obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o +obj-$(CONFIG_SND_SOC_IMX_PCM_FIQ) += snd-soc-imx-pcm-fiq.o +snd-soc-imx-pcm-fiq-y := imx-pcm-fiq.o imx-pcm.o +obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += snd-soc-imx-pcm-dma.o +snd-soc-imx-pcm-dma-y := imx-pcm-dma.o imx-pcm.o # i.MX Machine Support snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o diff --git a/sound/soc/fsl/imx-pcm.c b/sound/soc/fsl/imx-pcm.c index d5cd9eff3b48..0c9f188ddc68 100644 --- a/sound/soc/fsl/imx-pcm.c +++ b/sound/soc/fsl/imx-pcm.c @@ -31,7 +31,6 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, runtime->dma_bytes); return ret; } -EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) { @@ -80,7 +79,6 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) out: return ret; } -EXPORT_SYMBOL_GPL(imx_pcm_new); void imx_pcm_free(struct snd_pcm *pcm) { @@ -102,7 +100,6 @@ void imx_pcm_free(struct snd_pcm *pcm) buf->area = NULL; } } -EXPORT_SYMBOL_GPL(imx_pcm_free); MODULE_DESCRIPTION("Freescale i.MX PCM driver"); MODULE_AUTHOR("Sascha Hauer "); -- cgit v1.2.3 From 8784c77a6cb8e0e9aaec3b3438d1016348342b7f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 10 Jan 2013 19:33:47 +0000 Subject: ASoC: dapm: Fix sense of regulator bypass mode Enable bypass when the regulator is idle, not when it is in use. This is consistent with what the few existing users actually want. Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1e36bc81e5af..258acadb9e7d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1023,7 +1023,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, if (SND_SOC_DAPM_EVENT_ON(event)) { if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { - ret = regulator_allow_bypass(w->regulator, true); + ret = regulator_allow_bypass(w->regulator, false); if (ret != 0) dev_warn(w->dapm->dev, "ASoC: Failed to bypass %s: %d\n", @@ -1033,7 +1033,7 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, return regulator_enable(w->regulator); } else { if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { - ret = regulator_allow_bypass(w->regulator, false); + ret = regulator_allow_bypass(w->regulator, true); if (ret != 0) dev_warn(w->dapm->dev, "ASoC: Failed to unbypass %s: %d\n", @@ -3039,6 +3039,14 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, w->name, ret); return NULL; } + + if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) { + ret = regulator_allow_bypass(w->regulator, true); + if (ret != 0) + dev_warn(w->dapm->dev, + "ASoC: Failed to unbypass %s: %d\n", + w->name, ret); + } break; case snd_soc_dapm_clock_supply: #ifdef CONFIG_CLKDEV_LOOKUP -- cgit v1.2.3 From 7f39bb9e9f076f7e3cba89c987892eb573475d9a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 11 Jan 2013 13:31:52 +0000 Subject: ASoC: wm5102: Correct AEC loopback mask The generated defines in the header are pre-shifted. Reported-by: Heather Lomond Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 7a9048dad1cd..1440b3f9b7bb 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -896,8 +896,7 @@ static const unsigned int wm5102_aec_loopback_values[] = { static const struct soc_enum wm5102_aec_loopback = SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, - ARIZONA_AEC_LOOPBACK_SRC_SHIFT, - ARIZONA_AEC_LOOPBACK_SRC_MASK, + ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf, ARRAY_SIZE(wm5102_aec_loopback_texts), wm5102_aec_loopback_texts, wm5102_aec_loopback_values); -- cgit v1.2.3 From 7d5cb4f7105e7cf12e58e6df5af0cbdb11060bca Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 11 Jan 2013 13:32:00 +0000 Subject: ASoC: wm5110: Correct AEC loopback mask The generated defines in the header are pre-shifted. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index ae80c8c28536..7a090968c4f7 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -344,8 +344,7 @@ static const unsigned int wm5110_aec_loopback_values[] = { static const struct soc_enum wm5110_aec_loopback = SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1, - ARIZONA_AEC_LOOPBACK_SRC_SHIFT, - ARIZONA_AEC_LOOPBACK_SRC_MASK, + ARIZONA_AEC_LOOPBACK_SRC_SHIFT, 0xf, ARRAY_SIZE(wm5110_aec_loopback_texts), wm5110_aec_loopback_texts, wm5110_aec_loopback_values); -- cgit v1.2.3 From a80cc734282805e15b5e023751a4d02f7ffbcc91 Mon Sep 17 00:00:00 2001 From: Chris Rattray Date: Tue, 15 Jan 2013 13:22:36 +0000 Subject: ASoC: wm2200: correct mixer values and text Signed-off-by: Chris Rattray Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/wm2200.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index e6cefe1ac677..d8c65f574658 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1019,8 +1019,6 @@ static const char *wm2200_mixer_texts[] = { "EQR", "LHPF1", "LHPF2", - "LHPF3", - "LHPF4", "DSP1.1", "DSP1.2", "DSP1.3", @@ -1053,7 +1051,6 @@ static int wm2200_mixer_values[] = { 0x25, 0x50, /* EQ */ 0x51, - 0x52, 0x60, /* LHPF1 */ 0x61, /* LHPF2 */ 0x68, /* DSP1 */ -- cgit v1.2.3 From b59e0f82aa350e380142353fbd30706092ba6312 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 17 Jan 2013 14:15:59 +0900 Subject: ASoC: arizona: Use actual rather than desired BCLK when calculating LRCLK Otherwise we'll get the wrong LRCLK if we need to pick a higher BCLK than is required. Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/arizona.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c3592db994a8..ef62c435848e 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -685,7 +685,7 @@ static int arizona_hw_params(struct snd_pcm_substream *substream, } sr_val = i; - lrclk = snd_soc_params_to_bclk(params) / params_rate(params); + lrclk = rates[bclk] / params_rate(params); arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n", rates[bclk], rates[bclk] / lrclk); -- cgit v1.2.3 From 7881fd0fb3ecc9e367ba998a4de533e7eecbdfeb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 20 Jan 2013 19:01:03 +0900 Subject: ASoC: wm_adsp: Use GFP_DMA for things that may be DMAed Normally kmalloc() returns things that are DMA safe so not visible on all platforms but we do need to explicitly request DMA safe memory. Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 7b198c38f3ef..4196f2d54967 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -324,7 +324,7 @@ static int wm_adsp_load(struct wm_adsp *dsp) if (reg) { buf = kmemdup(region->data, le32_to_cpu(region->len), - GFP_KERNEL); + GFP_KERNEL | GFP_DMA); if (!buf) { adsp_err(dsp, "Out of memory\n"); return -ENOMEM; @@ -439,7 +439,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) if (reg) { buf = kmemdup(blk->data, le32_to_cpu(blk->len), - GFP_KERNEL); + GFP_KERNEL | GFP_DMA); if (!buf) { adsp_err(dsp, "Out of memory\n"); return -ENOMEM; -- cgit v1.2.3 From a4cdbec758d2491a86ba94263b847768fa004fde Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 21 Jan 2013 09:02:31 +0000 Subject: ASoC: wm_adsp: Release firmware on error This patch correctly releases the firmware if the magic string in the firmware header does not match. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 4196f2d54967..b6b654837585 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -396,7 +396,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) hdr = (void*)&firmware->data[0]; if (memcmp(hdr->magic, "WMDR", 4) != 0) { adsp_err(dsp, "%s: invalid magic\n", file); - return -EINVAL; + goto out_fw; } adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, -- cgit v1.2.3 From 0712eea349d8e2b6d0e44b94a752d999319027fb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 23 Jan 2013 18:16:24 +0100 Subject: ALSA: hda - Add a fixup for Packard-Bell desktop with ALC880 A Packard-Bell desktop machine gives no proper pin configuration from BIOS. It's almost equivalent with the 6stack+fp standard config, just take the existing fixup. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=901846 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cf3886171109..a4b93647b397 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4694,6 +4694,7 @@ static const struct snd_pci_quirk alc880_fixup_tbl[] = { SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), + SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST), SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), -- cgit v1.2.3 From d56268fb108c7c21e19933588ca4d94652585183 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 29 Nov 2012 17:04:23 +0100 Subject: ALSA: usb-audio: fix invalid length check for RME and other UAC 2 devices Commit 23caaf19b11e (ALSA: usb-mixer: Add support for Audio Class v2.0) forgot to adjust the length check for UAC 2.0 feature unit descriptors. This would make the code abort on encountering a feature unit without per-channel controls, and thus prevented the driver to work with any device having such a unit, such as the RME Babyface or Fireface UCX. Reported-by: Florian Hanisch Tested-by: Matthew Robbetts Tested-by: Michael Beer Cc: Daniel Mack Cc: 2.6.35+ Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index ed4d89c8b52a..e90daf8cdaa8 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1331,16 +1331,23 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void } channels = (hdr->bLength - 7) / csize - 1; bmaControls = hdr->bmaControls; + if (hdr->bLength < 7 + csize) { + snd_printk(KERN_ERR "usbaudio: unit %u: " + "invalid UAC_FEATURE_UNIT descriptor\n", + unitid); + return -EINVAL; + } } else { struct uac2_feature_unit_descriptor *ftr = _ftr; csize = 4; channels = (hdr->bLength - 6) / 4 - 1; bmaControls = ftr->bmaControls; - } - - if (hdr->bLength < 7 || !csize || hdr->bLength < 7 + csize) { - snd_printk(KERN_ERR "usbaudio: unit %u: invalid UAC_FEATURE_UNIT descriptor\n", unitid); - return -EINVAL; + if (hdr->bLength < 6 + csize) { + snd_printk(KERN_ERR "usbaudio: unit %u: " + "invalid UAC_FEATURE_UNIT descriptor\n", + unitid); + return -EINVAL; + } } /* parse the source unit */ -- cgit v1.2.3 From fcd8f3b1d43c645e291638bc6c80a1c680722869 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 28 Jan 2013 05:45:47 +0100 Subject: ALSA: hda - fix inverted internal mic on Acer AOA150/ZG5 This patch enables internal mic input on the machine. Cc: stable@vger.kernel.org BugLink: https://bugs.launchpad.net/bugs/1107477 Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a4b93647b397..5faaad219a7f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5709,6 +5709,7 @@ static const struct alc_model_fixup alc268_fixup_models[] = { }; static const struct snd_pci_quirk alc268_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), /* below is codec SSID since multiple Toshiba laptops have the * same PCI SSID 1179:ff00 */ -- cgit v1.2.3 From f748abcc5bf62de007019d841f7caba81cc3d673 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Jan 2013 10:12:23 +0100 Subject: ALSA: hda - Enable LPIB delay count for Poulsbo / Oaktrail Currently we use LPIB forcibly for both playback and capture for Poulsbo and Oaktrail devices, and this seems rather problematic. The recent fix for LPIB delay count seems working well with these devices, so let's enable it instead. Reported-by: Martin Weishart Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 0b6aebacc56b..bf0a0046b130 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -3613,13 +3613,12 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* 5 Series/3400 */ { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, - /* SCH */ + /* Poulsbo */ { PCI_DEVICE(0x8086, 0x811b), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */ + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, + /* Oaktrail */ { PCI_DEVICE(0x8086, 0x080a), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Oaktrail */ + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, /* ICH */ { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | -- cgit v1.2.3 From 9ddf1aeb2134e72275c97a2c6ff2e3eb04f2f27a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Jan 2013 18:07:22 +0100 Subject: ALSA: hda - Fix non-snoop page handling For non-snoop mode, we fiddle with the page attributes of CORB/RIRB and the position buffer, but also the ring buffers. The problem is that the current code blindly assumes that the buffer is contiguous. However, the ring buffers may be SG-buffers, thus a wrong vmapped address is passed there, leading to Oops. This patch fixes the handling for SG-buffers. Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=800701 Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bf0a0046b130..c78286f6e5d8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -656,29 +656,43 @@ static char *driver_short_names[] = { #define get_azx_dev(substream) (substream->runtime->private_data) #ifdef CONFIG_X86 -static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on) +static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) { + int pages; + if (azx_snoop(chip)) return; - if (addr && size) { - int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (!dmab || !dmab->area || !dmab->bytes) + return; + +#ifdef CONFIG_SND_DMA_SGBUF + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) { + struct snd_sg_buf *sgbuf = dmab->private_data; if (on) - set_memory_wc((unsigned long)addr, pages); + set_pages_array_wc(sgbuf->page_table, sgbuf->pages); else - set_memory_wb((unsigned long)addr, pages); + set_pages_array_wb(sgbuf->page_table, sgbuf->pages); + return; } +#endif + + pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (on) + set_memory_wc((unsigned long)dmab->area, pages); + else + set_memory_wb((unsigned long)dmab->area, pages); } static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, bool on) { - __mark_pages_wc(chip, buf->area, buf->bytes, on); + __mark_pages_wc(chip, buf, on); } static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, - struct snd_pcm_runtime *runtime, bool on) + struct snd_pcm_substream *substream, bool on) { if (azx_dev->wc_marked != on) { - __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on); + __mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on); azx_dev->wc_marked = on; } } @@ -689,7 +703,7 @@ static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, { } static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, - struct snd_pcm_runtime *runtime, bool on) + struct snd_pcm_substream *substream, bool on) { } #endif @@ -1968,11 +1982,10 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, { struct azx_pcm *apcm = snd_pcm_substream_chip(substream); struct azx *chip = apcm->chip; - struct snd_pcm_runtime *runtime = substream->runtime; struct azx_dev *azx_dev = get_azx_dev(substream); int ret; - mark_runtime_wc(chip, azx_dev, runtime, false); + mark_runtime_wc(chip, azx_dev, substream, false); azx_dev->bufsize = 0; azx_dev->period_bytes = 0; azx_dev->format_val = 0; @@ -1980,7 +1993,7 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, params_buffer_bytes(hw_params)); if (ret < 0) return ret; - mark_runtime_wc(chip, azx_dev, runtime, true); + mark_runtime_wc(chip, azx_dev, substream, true); return ret; } @@ -1989,7 +2002,6 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) struct azx_pcm *apcm = snd_pcm_substream_chip(substream); struct azx_dev *azx_dev = get_azx_dev(substream); struct azx *chip = apcm->chip; - struct snd_pcm_runtime *runtime = substream->runtime; struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; /* reset BDL address */ @@ -2002,7 +2014,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) snd_hda_codec_cleanup(apcm->codec, hinfo, substream); - mark_runtime_wc(chip, azx_dev, runtime, false); + mark_runtime_wc(chip, azx_dev, substream, false); return snd_pcm_lib_free_pages(substream); } -- cgit v1.2.3