Skip to content

Commit

Permalink
Merge branch 'for-linus' into for-next
Browse files Browse the repository at this point in the history
  • Loading branch information
tiwai committed Feb 26, 2016
2 parents 30ff595 + 473f414 commit d61b04f
Show file tree
Hide file tree
Showing 38 changed files with 331 additions and 192 deletions.
2 changes: 2 additions & 0 deletions Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-sgtl5000"
(compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt)

"fsl,imx-audio-wm8960"

Required properties:

- compatible : Contains one of entries in the compatible list.
Expand Down
2 changes: 1 addition & 1 deletion include/sound/hdaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);

void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
void snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
void (*ack)(struct hdac_bus *,
struct hdac_stream *));

Expand Down
16 changes: 14 additions & 2 deletions sound/core/pcm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
static DEFINE_RWLOCK(snd_pcm_link_rwlock);
static DECLARE_RWSEM(snd_pcm_link_rwsem);

/* Writer in rwsem may block readers even during its waiting in queue,
* and this may lead to a deadlock when the code path takes read sem
* twice (e.g. one in snd_pcm_action_nonatomic() and another in
* snd_pcm_stream_lock()). As a (suboptimal) workaround, let writer to
* spin until it gets the lock.
*/
static inline void down_write_nonblock(struct rw_semaphore *lock)
{
while (!down_write_trylock(lock))
cond_resched();
}

/**
* snd_pcm_stream_lock - Lock the PCM stream
* @substream: PCM substream
Expand Down Expand Up @@ -1813,7 +1825,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
res = -ENOMEM;
goto _nolock;
}
down_write(&snd_pcm_link_rwsem);
down_write_nonblock(&snd_pcm_link_rwsem);
write_lock_irq(&snd_pcm_link_rwlock);
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
substream->runtime->status->state != substream1->runtime->status->state ||
Expand Down Expand Up @@ -1860,7 +1872,7 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
struct snd_pcm_substream *s;
int res = 0;

down_write(&snd_pcm_link_rwsem);
down_write_nonblock(&snd_pcm_link_rwsem);
write_lock_irq(&snd_pcm_link_rwlock);
if (!snd_pcm_stream_linked(substream)) {
res = -EALREADY;
Expand Down
13 changes: 9 additions & 4 deletions sound/core/seq/seq_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,15 +383,20 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)

if (snd_BUG_ON(!pool))
return -EINVAL;
if (pool->ptr) /* should be atomic? */
return 0;

pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
if (!pool->ptr)
cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
if (!cellptr)
return -ENOMEM;

/* add new cells to the free cell list */
spin_lock_irqsave(&pool->lock, flags);
if (pool->ptr) {
spin_unlock_irqrestore(&pool->lock, flags);
vfree(cellptr);
return 0;
}

pool->ptr = cellptr;
pool->free = NULL;

for (cell = 0; cell < pool->size; cell++) {
Expand Down
13 changes: 8 additions & 5 deletions sound/core/seq/seq_ports.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,19 +535,22 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
bool is_src, bool ack)
{
struct snd_seq_port_subs_info *grp;
struct list_head *list;
bool empty;

grp = is_src ? &port->c_src : &port->c_dest;
list = is_src ? &subs->src_list : &subs->dest_list;
down_write(&grp->list_mutex);
write_lock_irq(&grp->list_lock);
if (is_src)
list_del(&subs->src_list);
else
list_del(&subs->dest_list);
empty = list_empty(list);
if (!empty)
list_del_init(list);
grp->exclusive = 0;
write_unlock_irq(&grp->list_lock);
up_write(&grp->list_mutex);

unsubscribe_port(client, port, grp, &subs->info, ack);
if (!empty)
unsubscribe_port(client, port, grp, &subs->info, ack);
}

/* connect two ports */
Expand Down
7 changes: 6 additions & 1 deletion sound/hda/hdac_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,25 +426,30 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_stop_chip);
* @bus: HD-audio core bus
* @status: INTSTS register value
* @ask: callback to be called for woken streams
*
* Returns the bits of handled streams, or zero if no stream is handled.
*/
void snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
void (*ack)(struct hdac_bus *,
struct hdac_stream *))
{
struct hdac_stream *azx_dev;
u8 sd_status;
int handled = 0;

list_for_each_entry(azx_dev, &bus->stream_list, list) {
if (status & azx_dev->sd_int_sta_mask) {
sd_status = snd_hdac_stream_readb(azx_dev, SD_STS);
snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK);
handled |= 1 << azx_dev->index;
if (!azx_dev->substream || !azx_dev->running ||
!(sd_status & SD_INT_COMPLETE))
continue;
if (ack)
ack(bus, azx_dev);
}
}
return handled;
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_handle_stream_irq);

Expand Down
47 changes: 26 additions & 21 deletions sound/pci/hda/hda_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,8 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
struct azx *chip = dev_id;
struct hdac_bus *bus = azx_bus(chip);
u32 status;
bool active, handled = false;
int repeat = 0; /* count for avoiding endless loop */

#ifdef CONFIG_PM
if (azx_has_pm_runtime(chip))
Expand All @@ -939,33 +941,36 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)

spin_lock(&bus->reg_lock);

if (chip->disabled) {
spin_unlock(&bus->reg_lock);
return IRQ_NONE;
}

status = azx_readl(chip, INTSTS);
if (status == 0 || status == 0xffffffff) {
spin_unlock(&bus->reg_lock);
return IRQ_NONE;
}
if (chip->disabled)
goto unlock;

snd_hdac_bus_handle_stream_irq(bus, status, stream_update);
do {
status = azx_readl(chip, INTSTS);
if (status == 0 || status == 0xffffffff)
break;

/* clear rirb int */
status = azx_readb(chip, RIRBSTS);
if (status & RIRB_INT_MASK) {
if (status & RIRB_INT_RESPONSE) {
if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
udelay(80);
snd_hdac_bus_update_rirb(bus);
handled = true;
active = false;
if (snd_hdac_bus_handle_stream_irq(bus, status, stream_update))
active = true;

/* clear rirb int */
status = azx_readb(chip, RIRBSTS);
if (status & RIRB_INT_MASK) {
active = true;
if (status & RIRB_INT_RESPONSE) {
if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
udelay(80);
snd_hdac_bus_update_rirb(bus);
}
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
}
azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
}
} while (active && ++repeat < 10);

unlock:
spin_unlock(&bus->reg_lock);

return IRQ_HANDLED;
return IRQ_RETVAL(handled);
}
EXPORT_SYMBOL_GPL(azx_interrupt);

Expand Down
20 changes: 9 additions & 11 deletions sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,10 @@ enum {
((pci)->device == 0x0d0c) || \
((pci)->device == 0x160c))

#define IS_BROXTON(pci) ((pci)->device == 0x5a98)
#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))

static char *driver_short_names[] = {
[AZX_DRIVER_ICH] = "HDA Intel",
Expand Down Expand Up @@ -540,13 +543,13 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)

if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
snd_hdac_set_codec_wakeup(bus, true);
if (IS_BROXTON(pci)) {
if (IS_SKL_PLUS(pci)) {
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
}
azx_init_chip(chip, full_reset);
if (IS_BROXTON(pci)) {
if (IS_SKL_PLUS(pci)) {
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
val = val | INTEL_HDA_CGCTL_MISCBDCGE;
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
Expand All @@ -555,7 +558,7 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
snd_hdac_set_codec_wakeup(bus, false);

/* reduce dma latency to avoid noise */
if (IS_BROXTON(pci))
if (IS_BXT(pci))
bxt_reduce_dma_latency(chip);
}

Expand Down Expand Up @@ -977,11 +980,6 @@ static int azx_resume(struct device *dev)
/* put codec down to D3 at hibernation for Intel SKL+;
* otherwise BIOS may still access the codec and screw up the driver
*/
#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))

static int azx_freeze_noirq(struct device *dev)
{
struct pci_dev *pci = to_pci_dev(dev);
Expand Down Expand Up @@ -2168,10 +2166,10 @@ static void azx_remove(struct pci_dev *pci)
struct hda_intel *hda;

if (card) {
/* flush the pending probing work */
/* cancel the pending probing work */
chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
flush_work(&hda->probe_work);
cancel_work_sync(&hda->probe_work);

snd_card_free(card);
}
Expand Down
39 changes: 37 additions & 2 deletions sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -3801,6 +3801,10 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,

static void alc_headset_mode_default(struct hda_codec *codec)
{
static struct coef_fw coef0225[] = {
UPDATE_COEF(0x45, 0x3f<<10, 0x34<<10),
{}
};
static struct coef_fw coef0255[] = {
WRITE_COEF(0x45, 0xc089),
WRITE_COEF(0x45, 0xc489),
Expand Down Expand Up @@ -3842,6 +3846,9 @@ static void alc_headset_mode_default(struct hda_codec *codec)
};

switch (codec->core.vendor_id) {
case 0x10ec0225:
alc_process_coef_fw(codec, coef0225);
break;
case 0x10ec0255:
case 0x10ec0256:
alc_process_coef_fw(codec, coef0255);
Expand Down Expand Up @@ -4749,6 +4756,9 @@ enum {
ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
ALC293_FIXUP_LENOVO_SPK_NOISE,
ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
ALC255_FIXUP_DELL_SPK_NOISE,
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC280_FIXUP_HP_HEADSET_MIC,
};

static const struct hda_fixup alc269_fixups[] = {
Expand Down Expand Up @@ -5368,6 +5378,29 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc233_fixup_lenovo_line2_mic_hotkey,
},
[ALC255_FIXUP_DELL_SPK_NOISE] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_disable_aamix,
.chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
},
[ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) {
/* Disable pass-through path for FRONT 14h */
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x36 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x57d7 },
{}
},
.chained = true,
.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
},
[ALC280_FIXUP_HP_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_disable_aamix,
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MIC,
},
};

static const struct snd_pci_quirk alc269_fixup_tbl[] = {
Expand Down Expand Up @@ -5410,6 +5443,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
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),
Expand Down Expand Up @@ -5470,6 +5504,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
SND_PCI_QUIRK(0x103c, 0x221c, "HP EliteBook 755 G2", ALC280_FIXUP_HP_HEADSET_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
Expand Down Expand Up @@ -5638,10 +5673,10 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{0x21, 0x03211020}

static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC225_STANDARD_PINS,
{0x14, 0x901701a0}),
SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC225_STANDARD_PINS,
{0x14, 0x901701b0}),
SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
Expand Down
1 change: 1 addition & 0 deletions sound/soc/amd/acp-pcm-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ static int acp_dma_open(struct snd_pcm_substream *substream)
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0) {
dev_err(prtd->platform->dev, "set integer constraint failed\n");
kfree(adata);
return ret;
}

Expand Down
Loading

0 comments on commit d61b04f

Please sign in to comment.