| From b662fdd0a681eb56d0adc72545a9385309786b1e Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 6 Feb 2020 22:02:21 +0200 |
| Subject: ALSA: hda: do not override bus codec_mask in link_get() |
| |
| From: Kai Vehmanen <kai.vehmanen@linux.intel.com> |
| |
| [ Upstream commit 43bcb1c0507858cdc95e425017dcc33f8105df39 ] |
| |
| snd_hdac_ext_bus_link_get() does not work correctly in case |
| there are multiple codecs on the bus. It unconditionally |
| resets the bus->codec_mask value. As per documentation in |
| hdaudio.h and existing use in client code, this field should |
| be used to store bit flag of detected codecs on the bus. |
| |
| By overwriting value of the codec_mask, information on all |
| detected codecs is lost. No current user of hdac is impacted, |
| but use of bus->codec_mask is planned in future patches |
| for SOF. |
| |
| Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> |
| Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> |
| Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> |
| Reviewed-by: Takashi Iwai <tiwai@suse.de> |
| Link: https://lore.kernel.org/r/20200206200223.7715-1-kai.vehmanen@linux.intel.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/hda/ext/hdac_ext_controller.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c |
| index cfab60d88c921..09ff209df4a30 100644 |
| --- a/sound/hda/ext/hdac_ext_controller.c |
| +++ b/sound/hda/ext/hdac_ext_controller.c |
| @@ -254,6 +254,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); |
| int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, |
| struct hdac_ext_link *link) |
| { |
| + unsigned long codec_mask; |
| int ret = 0; |
| |
| mutex_lock(&bus->lock); |
| @@ -280,9 +281,11 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, |
| * HDA spec section 4.3 - Codec Discovery |
| */ |
| udelay(521); |
| - bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS); |
| - dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask); |
| - snd_hdac_chip_writew(bus, STATESTS, bus->codec_mask); |
| + codec_mask = snd_hdac_chip_readw(bus, STATESTS); |
| + dev_dbg(bus->dev, "codec_mask = 0x%lx\n", codec_mask); |
| + snd_hdac_chip_writew(bus, STATESTS, codec_mask); |
| + if (!bus->codec_mask) |
| + bus->codec_mask = codec_mask; |
| } |
| |
| mutex_unlock(&bus->lock); |
| -- |
| 2.20.1 |
| |