From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/sound/hda/hdac_component.c | 65 +++++++++++++++++++++-----------
1 files changed, 42 insertions(+), 23 deletions(-)
diff --git a/kernel/sound/hda/hdac_component.c b/kernel/sound/hda/hdac_component.c
index 6e46a9c..bb37e7e 100644
--- a/kernel/sound/hda/hdac_component.c
+++ b/kernel/sound/hda/hdac_component.c
@@ -54,41 +54,54 @@
/**
* snd_hdac_display_power - Power up / down the power refcount
* @bus: HDA core bus
+ * @idx: HDA codec address, pass HDA_CODEC_IDX_CONTROLLER for controller
* @enable: power up or down
*
- * This function is supposed to be used only by a HD-audio controller
- * driver that needs the interaction with graphics driver.
+ * This function is used by either HD-audio controller or codec driver that
+ * needs the interaction with graphics driver.
*
- * This function manages a refcount and calls the get_power() and
+ * This function updates the power status, and calls the get_power() and
* put_power() ops accordingly, toggling the codec wakeup, too.
- *
- * Returns zero for success or a negative error code.
*/
-int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
+void snd_hdac_display_power(struct hdac_bus *bus, unsigned int idx, bool enable)
{
struct drm_audio_component *acomp = bus->audio_component;
-
- if (!acomp || !acomp->ops)
- return -ENODEV;
dev_dbg(bus->dev, "display power %s\n",
enable ? "enable" : "disable");
- if (enable) {
- if (!bus->drm_power_refcount++) {
+ mutex_lock(&bus->lock);
+ if (enable)
+ set_bit(idx, &bus->display_power_status);
+ else
+ clear_bit(idx, &bus->display_power_status);
+
+ if (!acomp || !acomp->ops)
+ goto unlock;
+
+ if (bus->display_power_status) {
+ if (!bus->display_power_active) {
+ unsigned long cookie = -1;
+
if (acomp->ops->get_power)
- acomp->ops->get_power(acomp->dev);
+ cookie = acomp->ops->get_power(acomp->dev);
+
snd_hdac_set_codec_wakeup(bus, true);
snd_hdac_set_codec_wakeup(bus, false);
+ bus->display_power_active = cookie;
}
} else {
- WARN_ON(!bus->drm_power_refcount);
- if (!--bus->drm_power_refcount)
- if (acomp->ops->put_power)
- acomp->ops->put_power(acomp->dev);
- }
+ if (bus->display_power_active) {
+ unsigned long cookie = bus->display_power_active;
- return 0;
+ if (acomp->ops->put_power)
+ acomp->ops->put_power(acomp->dev, cookie);
+
+ bus->display_power_active = 0;
+ }
+ }
+ unlock:
+ mutex_unlock(&bus->lock);
}
EXPORT_SYMBOL_GPL(snd_hdac_display_power);
@@ -197,12 +210,14 @@
goto module_put;
}
+ complete_all(&acomp->master_bind_complete);
return 0;
module_put:
module_put(acomp->ops->owner);
out_unbind:
component_unbind_all(dev, acomp);
+ complete_all(&acomp->master_bind_complete);
return ret;
}
@@ -249,6 +264,7 @@
/**
* snd_hdac_acomp_init - Initialize audio component
* @bus: HDA core bus
+ * @aops: audio component ops
* @match_master: match function for finding components
* @extra_size: Extra bytes to allocate
*
@@ -266,7 +282,7 @@
*/
int snd_hdac_acomp_init(struct hdac_bus *bus,
const struct drm_audio_component_audio_ops *aops,
- int (*match_master)(struct device *, void *),
+ int (*match_master)(struct device *, int, void *),
size_t extra_size)
{
struct component_match *match = NULL;
@@ -282,10 +298,11 @@
if (!acomp)
return -ENOMEM;
acomp->audio_ops = aops;
+ init_completion(&acomp->master_bind_complete);
bus->audio_component = acomp;
devres_add(dev, acomp);
- component_match_add(dev, &match, match_master, bus);
+ component_match_add_typed(dev, &match, match_master, bus);
ret = component_master_add_with_match(dev, &hdac_component_master_ops,
match);
if (ret < 0)
@@ -321,9 +338,11 @@
if (!acomp)
return 0;
- WARN_ON(bus->drm_power_refcount);
- if (bus->drm_power_refcount > 0 && acomp->ops)
- acomp->ops->put_power(acomp->dev);
+ if (WARN_ON(bus->display_power_active) && acomp->ops)
+ acomp->ops->put_power(acomp->dev, bus->display_power_active);
+
+ bus->display_power_active = 0;
+ bus->display_power_status = 0;
component_master_del(dev, &hdac_component_master_ops);
--
Gitblit v1.6.2