summaryrefslogtreecommitdiffstats
path: root/sound/hda
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-05-13 09:26:22 -0400
committerMark Brown <broonie@kernel.org>2016-05-13 09:26:22 -0400
commitc988e26130132813e3550a7b97ab2ed2ae0455eb (patch)
tree9259bd3e05c9a3f607051501ece7c252785f2e22 /sound/hda
parent35302156ea791f96bdc7e0ca3c44cb25341fbcb1 (diff)
parentb2047e996cd88d36eb0f4e84fe6aedab831a4b31 (diff)
Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
Diffstat (limited to 'sound/hda')
-rw-r--r--sound/hda/ext/hdac_ext_bus.c3
-rw-r--r--sound/hda/ext/hdac_ext_controller.c66
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 2433f7c81472..3b7ae24900fd 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,
105 INIT_LIST_HEAD(&ebus->hlink_list); 105 INIT_LIST_HEAD(&ebus->hlink_list);
106 ebus->idx = idx++; 106 ebus->idx = idx++;
107 107
108 mutex_init(&ebus->lock);
109 ebus->cmd_dma_state = true;
110
108 return 0; 111 return 0;
109} 112}
110EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_init); 113EXPORT_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)
186 hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP); 186 hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
187 hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID); 187 hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
188 188
189 /* since link in On, update the ref */
190 hlink->ref_count = 1;
191
189 list_add_tail(&hlink->list, &ebus->hlink_list); 192 list_add_tail(&hlink->list, &ebus->hlink_list);
190 } 193 }
191 194
@@ -327,3 +330,66 @@ int snd_hdac_ext_bus_link_power_down_all(struct hdac_ext_bus *ebus)
327 return 0; 330 return 0;
328} 331}
329EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); 332EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all);
333
334int snd_hdac_ext_bus_link_get(struct hdac_ext_bus *ebus,
335 struct hdac_ext_link *link)
336{
337 int ret = 0;
338
339 mutex_lock(&ebus->lock);
340
341 /*
342 * if we move from 0 to 1, count will be 1 so power up this link
343 * as well, also check the dma status and trigger that
344 */
345 if (++link->ref_count == 1) {
346 if (!ebus->cmd_dma_state) {
347 snd_hdac_bus_init_cmd_io(&ebus->bus);
348 ebus->cmd_dma_state = true;
349 }
350
351 ret = snd_hdac_ext_bus_link_power_up(link);
352 }
353
354 mutex_unlock(&ebus->lock);
355 return ret;
356}
357EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_get);
358
359int snd_hdac_ext_bus_link_put(struct hdac_ext_bus *ebus,
360 struct hdac_ext_link *link)
361{
362 int ret = 0;
363 struct hdac_ext_link *hlink;
364 bool link_up = false;
365
366 mutex_lock(&ebus->lock);
367
368 /*
369 * if we move from 1 to 0, count will be 0
370 * so power down this link as well
371 */
372 if (--link->ref_count == 0) {
373 ret = snd_hdac_ext_bus_link_power_down(link);
374
375 /*
376 * now check if all links are off, if so turn off
377 * cmd dma as well
378 */
379 list_for_each_entry(hlink, &ebus->hlink_list, list) {
380 if (hlink->ref_count) {
381 link_up = true;
382 break;
383 }
384 }
385
386 if (!link_up) {
387 snd_hdac_bus_stop_cmd_io(&ebus->bus);
388 ebus->cmd_dma_state = false;
389 }
390 }
391
392 mutex_unlock(&ebus->lock);
393 return ret;
394}
395EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_put);