diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 5eeb0fe..7490219 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -133,6 +133,12 @@ struct hdac_hdmi_drv_data {
 	int port_num;
 };
 
+/* each supplier - consumer pair has one instance of this structure */
+struct hdac_hdmi_dev_link {
+	struct list_head head;
+	struct device_link *link;
+};
+
 struct hdac_hdmi_priv {
 	struct hdac_device *hdev;
 	struct snd_soc_component *component;
@@ -141,10 +147,12 @@ struct hdac_hdmi_priv {
 	struct list_head pin_list;
 	struct list_head cvt_list;
 	struct list_head pcm_list;
+	struct list_head link_list;	/* supplier - consumer pairs */
 	int num_pin;
 	int num_cvt;
 	int num_ports;
 	struct mutex pin_mutex;
+	struct mutex link_mutex;
 	struct hdac_chmap chmap;
 	struct hdac_hdmi_drv_data *drv_data;
 	struct snd_soc_dai_driver *dai_drv;
@@ -1792,6 +1800,72 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
 }
 EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
 
+/**
+ * hdac_hdmi_device_link_add - add a link between consumer and hdev device
+ * @consumer: Consumer end of the link.
+ * @component: The hdmi codec component.
+ * @flags: Link flags.
+ *
+ * If there is a consumer of the hdev device, which means a consumer device
+ * operation depends on the hdev device power status, the consumer device
+ * driver should call this function. It supports several consumers depending
+ * on the same hdmi codec hdev device.
+ *
+ * Return: pointer of device_link, or NULL if fails to create device_link
+ */
+struct device_link *
+hdac_hdmi_device_link_add(struct device *consumer,
+			  struct snd_soc_component *component,
+			  u32 flags)
+{
+	struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);
+	struct hdac_device *hdev = hdmi->hdev;
+	struct hdac_hdmi_dev_link *dev_link;
+
+	dev_link = devm_kzalloc(&hdev->dev, sizeof(*dev_link), GFP_KERNEL);
+	if (!dev_link)
+		return NULL;
+
+	dev_link->link = device_link_add(consumer, &hdev->dev, flags);
+
+	mutex_lock(&hdmi->link_mutex);
+	if (dev_link->link)
+		list_add(&dev_link->head, &hdmi->link_list);
+	mutex_unlock(&hdmi->link_mutex);
+
+	return dev_link->link;
+}
+EXPORT_SYMBOL_GPL(hdac_hdmi_device_link_add);
+
+/**
+ * hdac_hdmi_device_link_del - del the link between consumer and hdev device
+ * @consumer: Consumer end of the link.
+ * @component: The hdmi codec component.
+ *
+ * If the consumer doesn't need the dependency any longer, the consumer device
+ * driver should call this function to release the device_link
+ */
+void hdac_hdmi_device_link_del(struct device *consumer,
+			       struct snd_soc_component *component)
+{
+	struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);
+	struct hdac_device *hdev = hdmi->hdev;
+	struct hdac_hdmi_dev_link *dev_link, *tmp;
+
+	mutex_lock(&hdmi->link_mutex);
+	list_for_each_entry_safe(dev_link, tmp, &hdmi->link_list, head) {
+		if (dev_link->link->consumer == consumer &&
+		    dev_link->link->supplier == &hdev->dev) {
+			device_link_del(dev_link->link);
+			list_del(&dev_link->head);
+			devm_kfree(&hdev->dev, dev_link);
+			return;
+		}
+	}
+	mutex_unlock(&hdmi->link_mutex);
+}
+EXPORT_SYMBOL_GPL(hdac_hdmi_device_link_del);
+
 static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
 			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
 {
@@ -2031,7 +2105,9 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
 	INIT_LIST_HEAD(&hdmi_priv->pin_list);
 	INIT_LIST_HEAD(&hdmi_priv->cvt_list);
 	INIT_LIST_HEAD(&hdmi_priv->pcm_list);
+	INIT_LIST_HEAD(&hdmi_priv->link_list);
 	mutex_init(&hdmi_priv->pin_mutex);
+	mutex_init(&hdmi_priv->link_mutex);
 
 	/*
 	 * Turned off in the runtime_suspend during the first explicit
@@ -2058,8 +2134,18 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
 
 static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
 {
+	struct hdac_hdmi_dev_link *dev_link, *tmp;
+	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
+
 	snd_hdac_display_power(hdev->bus, hdev->addr, false);
 
+	mutex_unlock(&hdmi->link_mutex);
+	list_for_each_entry_safe(dev_link, tmp, &hdmi->link_list, head) {
+		device_link_del(dev_link->link);
+		list_del(&dev_link->head);
+	}
+	mutex_unlock(&hdmi->link_mutex);
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/hdac_hdmi.h b/sound/soc/codecs/hdac_hdmi.h
index 4fa2fc9..e877167 100644
--- a/sound/soc/codecs/hdac_hdmi.h
+++ b/sound/soc/codecs/hdac_hdmi.h
@@ -7,4 +7,11 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
 
 int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 			struct snd_soc_dapm_context *dapm);
+
+struct device_link *
+hdac_hdmi_device_link_add(struct device *consumer,
+			  struct snd_soc_component *component,
+			  u32 flags);
+void hdac_hdmi_device_link_del(struct device *consumer,
+			       struct snd_soc_component *component);
 #endif /* __HDAC_HDMI_H__ */
