diff options
author | Takashi Iwai <tiwai@suse.de> | 2016-05-16 15:59:00 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2016-05-16 15:59:00 +0300 |
commit | a158f2b79ff1948c864a38296ea4249f7296362b (patch) | |
tree | e62d50376d29a63814cf9d26cbd4c522f6f9271a /sound/hda/ext | |
parent | 581abbaa03367f0b1327521f30bd2b69b8075b2f (diff) | |
parent | 515511a7920c69aebf7f5fef0cb8e1df6767f34c (diff) | |
download | linux-a158f2b79ff1948c864a38296ea4249f7296362b.tar.xz |
Merge tag 'asoc-v4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.7
The updates this time around are almost all driver code:
- Further slow progress on the topology code.
- Substantial updates and improvements for the da7219, es8328, fsl-ssi
Intel and rcar drivers.
Diffstat (limited to 'sound/hda/ext')
-rw-r--r-- | sound/hda/ext/hdac_ext_bus.c | 3 | ||||
-rw-r--r-- | sound/hda/ext/hdac_ext_controller.c | 66 |
2 files changed, 69 insertions, 0 deletions
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 64de0a3d6d93..31b510c5ca0b 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -105,6 +105,9 @@ int snd_hdac_ext_bus_init(struct hdac_ext_bus *ebus, struct device *dev, INIT_LIST_HEAD(&ebus->hlink_list); ebus->idx = idx++; + mutex_init(&ebus->lock); + ebus->cmd_dma_state = true; + return 0; } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init); diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index 548cc1e4114b..860f8cad6602 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -186,6 +186,9 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus) hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); + /* since link in On, update the ref */ + hlink->ref_count = 1; + list_add_tail(&hlink->list, &ebus->hlink_list); } @@ -327,3 +330,66 @@ int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus) return 0; } EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); + +int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus, + struct hdac_ext_link *link) +{ + int ret = 0; + + mutex_lock(&ebus->lock); + + /* + * if we move from 0 to 1, count will be 1 so power up this link + * as well, also check the dma status and trigger that + */ + if (++link->ref_count == 1) { + if (!ebus->cmd_dma_state) { + snd_hdac_bus_init_cmd_io(&ebus->bus); + ebus->cmd_dma_state = true; + } + + ret = snd_hdac_ext_bus_link_power_up(link); + } + + mutex_unlock(&ebus->lock); + return ret; +} +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_get); + +int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus, + struct hdac_ext_link *link) +{ + int ret = 0; + struct hdac_ext_link *hlink; + bool link_up = false; + + mutex_lock(&ebus->lock); + + /* + * if we move from 1 to 0, count will be 0 + * so power down this link as well + */ + if (--link->ref_count == 0) { + ret = snd_hdac_ext_bus_link_power_down(link); + + /* + * now check if all links are off, if so turn off + * cmd dma as well + */ + list_for_each_entry(hlink, &ebus->hlink_list, list) { + if (hlink->ref_count) { + link_up = true; + break; + } + } + + if (!link_up) { + snd_hdac_bus_stop_cmd_io(&ebus->bus); + ebus->cmd_dma_state = false; + } + } + + mutex_unlock(&ebus->lock); + return ret; +} +EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put); |