diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/core/seq/seq_clientmgr.c | 1 | ||||
-rw-r--r-- | sound/core/seq/seq_fifo.c | 10 | ||||
-rw-r--r-- | sound/core/seq/seq_lock.c | 9 | ||||
-rw-r--r-- | sound/core/seq/seq_memory.c | 17 | ||||
-rw-r--r-- | sound/core/seq/seq_memory.h | 1 | ||||
-rw-r--r-- | sound/core/timer.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 17 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 2 | ||||
-rw-r--r-- | sound/ppc/awacs.c | 1 | ||||
-rw-r--r-- | sound/soc/codecs/wm8960.c | 19 | ||||
-rw-r--r-- | sound/soc/fsl/imx-hdmi-dma.c | 4 | ||||
-rw-r--r-- | sound/soc/fsl/imx-wm8958.c | 16 | ||||
-rw-r--r-- | sound/soc/fsl/imx-wm8960.c | 16 | ||||
-rw-r--r-- | sound/soc/intel/boards/bytcr_rt5640.c | 3 |
15 files changed, 110 insertions, 38 deletions
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index ce6703ecfcef..8158ba354b48 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -1921,6 +1921,7 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client, info.output_pool != client->pool->size)) { if (snd_seq_write_pool_allocated(client)) { /* remove all existing cells */ + snd_seq_pool_mark_closing(client->pool); snd_seq_queue_client_leave_cells(client->number); snd_seq_pool_done(client->pool); } diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index 1d5acbe0c08b..3490d21ab9e7 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -70,6 +70,9 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo) return; *fifo = NULL; + if (f->pool) + snd_seq_pool_mark_closing(f->pool); + snd_seq_fifo_clear(f); /* wake up clients if any */ @@ -135,6 +138,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, f->tail = cell; if (f->head == NULL) f->head = cell; + cell->next = NULL; f->cells++; spin_unlock_irqrestore(&f->lock, flags); @@ -214,6 +218,8 @@ void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f, spin_lock_irqsave(&f->lock, flags); cell->next = f->head; f->head = cell; + if (!f->tail) + f->tail = cell; f->cells++; spin_unlock_irqrestore(&f->lock, flags); } @@ -259,6 +265,10 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) /* NOTE: overflow flag is not cleared */ spin_unlock_irqrestore(&f->lock, flags); + /* close the old pool and wait until all users are gone */ + snd_seq_pool_mark_closing(oldpool); + snd_use_lock_sync(&f->use_lock); + /* release cells in old pool */ for (cell = oldhead; cell; cell = next) { next = cell->next; diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c index 3b693e924db7..12ba83367b1b 100644 --- a/sound/core/seq/seq_lock.c +++ b/sound/core/seq/seq_lock.c @@ -28,19 +28,16 @@ /* wait until all locks are released */ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) { - int max_count = 5 * HZ; + int warn_count = 5 * HZ; if (atomic_read(lockp) < 0) { pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line); return; } while (atomic_read(lockp) > 0) { - if (max_count == 0) { - pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); - break; - } + if (warn_count-- == 0) + pr_warn("ALSA: seq_lock: waiting [%d left] in %s:%d\n", atomic_read(lockp), file, line); schedule_timeout_uninterruptible(1); - max_count--; } } diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index dfa5156f3585..5847c4475bf3 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -414,6 +414,18 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) return 0; } +/* refuse the further insertion to the pool */ +void snd_seq_pool_mark_closing(struct snd_seq_pool *pool) +{ + unsigned long flags; + + if (snd_BUG_ON(!pool)) + return; + spin_lock_irqsave(&pool->lock, flags); + pool->closing = 1; + spin_unlock_irqrestore(&pool->lock, flags); +} + /* remove events */ int snd_seq_pool_done(struct snd_seq_pool *pool) { @@ -424,10 +436,6 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) return -EINVAL; /* wait for closing all threads */ - spin_lock_irqsave(&pool->lock, flags); - pool->closing = 1; - spin_unlock_irqrestore(&pool->lock, flags); - if (waitqueue_active(&pool->output_sleep)) wake_up(&pool->output_sleep); @@ -484,6 +492,7 @@ int snd_seq_pool_delete(struct snd_seq_pool **ppool) *ppool = NULL; if (pool == NULL) return 0; + snd_seq_pool_mark_closing(pool); snd_seq_pool_done(pool); kfree(pool); return 0; diff --git a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h index 4a2ec779b8a7..32f959c17786 100644 --- a/sound/core/seq/seq_memory.h +++ b/sound/core/seq/seq_memory.h @@ -84,6 +84,7 @@ static inline int snd_seq_total_cells(struct snd_seq_pool *pool) int snd_seq_pool_init(struct snd_seq_pool *pool); /* done pool - free events */ +void snd_seq_pool_mark_closing(struct snd_seq_pool *pool); int snd_seq_pool_done(struct snd_seq_pool *pool); /* create pool */ diff --git a/sound/core/timer.c b/sound/core/timer.c index 8800d237369a..b024ef0ec32b 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1695,9 +1695,21 @@ static int snd_timer_user_params(struct file *file, return -EBADFD; if (copy_from_user(¶ms, _params, sizeof(params))) return -EFAULT; - if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) { - err = -EINVAL; - goto _end; + if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { + u64 resolution; + + if (params.ticks < 1) { + err = -EINVAL; + goto _end; + } + + /* Don't allow resolution less than 1ms */ + resolution = snd_timer_resolution(tu->timeri); + resolution *= params.ticks; + if (resolution < 1000000) { + err = -EINVAL; + goto _end; + } } if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 16d09825a995..68bd0ba8bab8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1985,7 +1985,20 @@ static void azx_remove(struct pci_dev *pci) /* cancel the pending probing work */ chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); + /* FIXME: below is an ugly workaround. + * Both device_release_driver() and driver_probe_device() + * take *both* the device's and its parent's lock before + * calling the remove() and probe() callbacks. The codec + * probe takes the locks of both the codec itself and its + * parent, i.e. the PCI controller dev. Meanwhile, when + * the PCI controller is unbound, it takes its lock, too + * ==> ouch, a deadlock! + * As a workaround, we unlock temporarily here the controller + * device during cancel_work_sync() call. + */ + device_unlock(&pci->dev); cancel_work_sync(&hda->probe_work); + device_lock(&pci->dev); snd_card_free(card); } @@ -2027,9 +2040,9 @@ static const struct pci_device_id azx_ids[] = { .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lewisburg */ { PCI_DEVICE(0x8086, 0xa1f0), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, { PCI_DEVICE(0x8086, 0xa270), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c20), .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3adf376092dd..9b5dd2ac60b6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4741,6 +4741,7 @@ enum { ALC292_FIXUP_DISABLE_AAMIX, ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK, ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, ALC275_FIXUP_DELL_XPS, ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE, ALC293_FIXUP_LENOVO_SPK_NOISE, @@ -5339,6 +5340,15 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC269_FIXUP_HEADSET_MODE }, + [ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE + }, [ALC275_FIXUP_DELL_XPS] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -5411,7 +5421,7 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc298_fixup_speaker_volume, .chained = true, - .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, + .chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE, }, [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { .type = HDA_FIXUP_PINS, @@ -5470,6 +5480,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), + SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), @@ -5583,6 +5594,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460), SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), + SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI), SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC), SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 840178a26a6b..9f74f1514590 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1537,6 +1537,8 @@ static const struct snd_pci_quirk stac9200_fixup_tbl[] = { "Dell Inspiron 1501", STAC_9200_DELL_M26), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, "unknown Dell", STAC_9200_DELL_M26), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201, + "Dell Latitude D430", STAC_9200_DELL_M22), /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), /* Gateway machines needs EAPD to be set on resume */ diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 09da7b52bc2e..1468e4b7bf93 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c @@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) if (err < 0) return err; } + master_vol = NULL; if (pm7500) err = build_mixers(chip, ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500), diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 28eb426a8356..6cd20fdd93c0 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -814,6 +814,10 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, } } + ret = wm8960_configure_clocking(codec); + if (ret) + return ret; + /* Set VMID to 2x50k */ snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80); break; @@ -1020,11 +1024,6 @@ static bool is_pll_freq_available(unsigned int source, unsigned int target) target *= 4; Ndiv = target / source; - if (Ndiv < 6) { - source >>= 1; - Ndiv = target / source; - } - if ((Ndiv < 6) || (Ndiv > 12)) return false; @@ -1135,6 +1134,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, if (pll_id == WM8960_SYSCLK_AUTO) return 0; + if (is_pll_freq_available(freq_in, freq_out)) + return -EINVAL; + return wm8960_set_pll(codec, freq_in, freq_out); } @@ -1294,6 +1296,7 @@ static int wm8960_i2c_probe(struct i2c_client *i2c, struct wm8960_data *pdata = dev_get_platdata(&i2c->dev); struct wm8960_priv *wm8960; int ret; + int repeat_reset = 10; wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv), GFP_KERNEL); @@ -1315,7 +1318,11 @@ static int wm8960_i2c_probe(struct i2c_client *i2c, else if (i2c->dev.of_node) wm8960_set_pdata_from_of(i2c, &wm8960->pdata); - ret = wm8960_reset(wm8960->regmap); + do { + ret = wm8960_reset(wm8960->regmap); + repeat_reset--; + } while (repeat_reset > 0 && ret != 0); + if (ret != 0) { dev_err(&i2c->dev, "Failed to issue reset\n"); return ret; diff --git a/sound/soc/fsl/imx-hdmi-dma.c b/sound/soc/fsl/imx-hdmi-dma.c index 0df685159e9c..411906f9ab70 100644 --- a/sound/soc/fsl/imx-hdmi-dma.c +++ b/sound/soc/fsl/imx-hdmi-dma.c @@ -1,7 +1,7 @@ /* * imx-hdmi-dma.c -- HDMI DMA driver for ALSA Soc Audio Layer * - * Copyright (C) 2011-2014 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2016 Freescale Semiconductor, Inc. * * based on imx-pcm-dma-mx2.c * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> @@ -455,7 +455,7 @@ static void hdmi_dma_data_copy(struct snd_pcm_substream *substream, if (runtime->access != SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) return; - appl_bytes = runtime->status->hw_ptr * (runtime->frame_bits / 8); + appl_bytes = (runtime->status->hw_ptr % (priv->buffer_bytes/(runtime->frame_bits/8))) * (runtime->frame_bits/8); if (type == 'p') appl_bytes += 2 * priv->period_bytes; offset = appl_bytes % priv->buffer_bytes; diff --git a/sound/soc/fsl/imx-wm8958.c b/sound/soc/fsl/imx-wm8958.c index a2adfb7a3fcf..0db3e6a4ef11 100644 --- a/sound/soc/fsl/imx-wm8958.c +++ b/sound/soc/fsl/imx-wm8958.c @@ -397,12 +397,13 @@ static int imx_wm8958_set_bias_level_post(struct snd_soc_card *card, static int imx_wm8958_probe(struct platform_device *pdev) { - struct device_node *cpu_np, *codec_np = NULL, *gpr_np; + struct device_node *cpu_np, *codec_np = NULL; struct device_node *np = pdev->dev.of_node; struct platform_device *cpu_pdev; struct imx_priv *priv = &card_priv; struct i2c_client *codec_dev; struct imx_wm8958_data *data; + struct of_phandle_args args; int ret; priv->pdev = pdev; @@ -441,16 +442,19 @@ static int imx_wm8958_probe(struct platform_device *pdev) goto fail; } - gpr_np = of_parse_phandle(pdev->dev.of_node, "gpr", 0); - if (gpr_np) { - data->gpr = syscon_node_to_regmap(gpr_np); + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, "gpr", 3, + 0, &args); + if (ret) { + dev_err(&pdev->dev, "failed to get gpr property\n"); + goto fail; + } else { + data->gpr = syscon_node_to_regmap(args.np); if (IS_ERR(data->gpr)) { ret = PTR_ERR(data->gpr); dev_err(&pdev->dev, "failed to get gpr regmap\n"); goto fail; } - if (data->gpr) - regmap_update_bits(data->gpr, 4, 1<<20, 1<<20); + regmap_update_bits(data->gpr, args.args[0], args.args[1], args.args[2]); } if (of_property_read_bool(np, "codec-master")) { diff --git a/sound/soc/fsl/imx-wm8960.c b/sound/soc/fsl/imx-wm8960.c index d65e7765f077..cef6d0066af3 100644 --- a/sound/soc/fsl/imx-wm8960.c +++ b/sound/soc/fsl/imx-wm8960.c @@ -420,13 +420,13 @@ static struct snd_soc_dai_link imx_wm8960_dai[] = { static int imx_wm8960_probe(struct platform_device *pdev) { struct device_node *cpu_np, *codec_np = NULL; - struct device_node *gpr_np; struct platform_device *cpu_pdev; struct imx_priv *priv = &card_priv; struct i2c_client *codec_dev; struct imx_wm8960_data *data; struct platform_device *asrc_pdev = NULL; struct device_node *asrc_np; + struct of_phandle_args args; u32 width; int ret; @@ -476,17 +476,19 @@ static int imx_wm8960_probe(struct platform_device *pdev) goto fail; } - gpr_np = of_parse_phandle(pdev->dev.of_node, "gpr", 0); - if (gpr_np) { - data->gpr = syscon_node_to_regmap(gpr_np); + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, "gpr", 3, + 0, &args); + if (ret) { + dev_err(&pdev->dev, "failed to get gpr property\n"); + goto fail; + } else { + data->gpr = syscon_node_to_regmap(args.np); if (IS_ERR(data->gpr)) { ret = PTR_ERR(data->gpr); dev_err(&pdev->dev, "failed to get gpr regmap\n"); goto fail; } - - /* set SAI2_MCLK_DIR to enable codec MCLK for imx7d */ - regmap_update_bits(data->gpr, 4, 1<<20, 1<<20); + regmap_update_bits(data->gpr, args.args[0], args.args[1], args.args[2]); } of_property_read_u32_array(pdev->dev.of_node, "hp-det", data->hp_det, 2); diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 7f55d59024a8..64ca3fef3c10 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -149,7 +149,7 @@ static struct snd_soc_dai_link byt_dailink[] = { .codec_dai_name = "snd-soc-dummy-dai", .codec_name = "snd-soc-dummy", .platform_name = "sst-mfld-platform", - .ignore_suspend = 1, + .nonatomic = true, .dynamic = 1, .dpcm_playback = 1, .dpcm_capture = 1, @@ -176,6 +176,7 @@ static struct snd_soc_dai_link byt_dailink[] = { | SND_SOC_DAIFMT_CBS_CFS, .be_hw_params_fixup = byt_codec_fixup, .ignore_suspend = 1, + .nonatomic = true, .dpcm_playback = 1, .dpcm_capture = 1, .ops = &byt_be_ssp2_ops, |