diff mbox series

[RFC,1/2] ALSA: hda - keep track of HDA core bus instance in acomp

Message ID 20201006113042.471718-2-kai.vehmanen@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series ALSA: hda - acomp probe fix for i915 | expand

Commit Message

Kai Vehmanen Oct. 6, 2020, 11:30 a.m. UTC
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@linux.intel.com>
---
 include/sound/hda_component.h |  5 +++++
 sound/hda/hdac_component.c    | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)
diff mbox series

Patch

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);