Merge branch 'for-linus-2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[deliverable/linux.git] / sound / hda / ext / hdac_ext_controller.c
index 548cc1e4114bb81af0136cf77d517b4e751c6736..860f8cad6602d59332f1990b2e3ee216da0b72f6 100644 (file)
@@ -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);
This page took 0.028656 seconds and 5 git commands to generate.