[RFC PATCH 1/2] ALSA: hda - keep track of HDA core bus instance in acomp
Kai Vehmanen
kai.vehmanen at linux.intel.com
Tue Oct 6 13:30:41 CEST 2020
In current HDA component implementation, HDA controller drivers
use snd_hdac_acomp_init() and pass it the HDA bus instance (hdac_bus).
When registration to component framework is done, the HDA controller
device instance 'hdac_bus->dev' is used.
In the component bind/unbind callbacks, only the device handle is passed
as context, and it is not possible to look up the HDA bus instance. Fix
this gap by adding a separate devres entry for the bus handle.
Signed-off-by: Kai Vehmanen <kai.vehmanen at linux.intel.com>
---
include/sound/hda_component.h | 5 +++++
sound/hda/hdac_component.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/include/sound/hda_component.h b/include/sound/hda_component.h
index d4804c72d959..476cc4e2083c 100644
--- a/include/sound/hda_component.h
+++ b/include/sound/hda_component.h
@@ -25,6 +25,7 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
int snd_hdac_acomp_exit(struct hdac_bus *bus);
int snd_hdac_acomp_register_notifier(struct hdac_bus *bus,
const struct drm_audio_component_audio_ops *ops);
+struct hdac_bus *snd_hdac_acomp_get_bus(struct device *dev);
#else
static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
{
@@ -62,6 +63,10 @@ static inline int snd_hdac_acomp_register_notifier(struct hdac_bus *bus,
{
return -ENODEV;
}
+static struct hdac_bus *snd_hdac_acomp_get_bus(struct device *dev)
+{
+ return NULL;
+}
#endif
#endif /* __SOUND_HDA_COMPONENT_H */
diff --git a/sound/hda/hdac_component.c b/sound/hda/hdac_component.c
index 89126c6fd216..d9d2675982f0 100644
--- a/sound/hda/hdac_component.c
+++ b/sound/hda/hdac_component.c
@@ -19,6 +19,29 @@ static struct drm_audio_component *hdac_get_acomp(struct device *dev)
return devres_find(dev, hdac_acomp_release, NULL, NULL);
}
+static void hdac_acomp_bus_release(struct device *dev, void *res)
+{
+}
+
+/**
+ * snd_hdac_acomp_get_bus - Get HDA core bus instance
+ * @dev: device
+ *
+ * If audio component registration has been done, this function
+ * will return the matching HDA core bus. Returns NULL otherwise.
+ */
+struct hdac_bus *snd_hdac_acomp_get_bus(struct device *dev)
+{
+ struct drm_audio_component *acomp = hdac_get_acomp(dev);
+ struct hdac_bus **bus =
+ devres_find(dev, hdac_acomp_bus_release, NULL, NULL);
+ if (!acomp || !*bus)
+ return NULL;
+
+ return *bus;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_bus);
+
/**
* snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup
* @bus: HDA core bus
@@ -286,6 +309,7 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
struct component_match *match = NULL;
struct device *dev = bus->dev;
struct drm_audio_component *acomp;
+ struct hdac_bus **bus_ptr;
int ret;
if (WARN_ON(hdac_get_acomp(dev)))
@@ -299,6 +323,14 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
bus->audio_component = acomp;
devres_add(dev, acomp);
+ bus_ptr = devres_alloc(hdac_acomp_bus_release, sizeof(*bus_ptr), GFP_KERNEL);
+ if (!bus_ptr) {
+ ret = -ENOMEM;
+ goto out_err_busptr;
+ }
+ *bus_ptr = bus;
+ devres_add(dev, bus_ptr);
+
component_match_add_typed(dev, &match, match_master, bus);
ret = component_master_add_with_match(dev, &hdac_component_master_ops,
match);
@@ -308,6 +340,8 @@ int snd_hdac_acomp_init(struct hdac_bus *bus,
return 0;
out_err:
+ devres_destroy(dev, hdac_acomp_bus_release, NULL, NULL);
+out_err_busptr:
bus->audio_component = NULL;
devres_destroy(dev, hdac_acomp_release, NULL, NULL);
dev_info(dev, "failed to add audio component master (%d)\n", ret);
--
2.28.0
More information about the Alsa-devel
mailing list