summaryrefslogtreecommitdiffstats
path: root/sound/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-07-11 15:48:18 +0200
committerTakashi Iwai <tiwai@suse.de>2018-07-17 22:25:47 +0200
commit82887c0beb1ee6b33eed8318d8e8d41c5b3eddae (patch)
tree884159632784699ff4360d09b32ac51847418edb /sound/hda
parentae891abe7c2ccf75b69ca8330225e37ecc06924e (diff)
downloadlinux-82887c0beb1ee6b33eed8318d8e8d41c5b3eddae.tar.bz2
ALSA: hda/i915: Associate audio component with devres
The HD-audio i915 binding code contains a single pointer, hdac_acomp, for allowing the access to audio component from the master bind/unbind callbacks. This was needed because the callbacks pass only the device pointer and we can't guarantee the object type assigned to the drvdata (which is free for each controller driver implementation). And this implementation will be a problem if we support multiple components for different DRM drivers, not only i915. As a solution, allocate the audio component object via devres and associate it with the given device, so that the component callbacks can refer to it via devres_find(). The removal of the object is still done half-manually via devres_destroy() to make the code consistent (although it may work without the explicit call). Also, the snd_hda_i915_register_notifier() had the reference to hdac_acomp as well. In this patch, the corresponding code is removed by passing hdac_bus object to the function, too. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/hda')
-rw-r--r--sound/hda/hdac_i915.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c
index 1a88c1aaf9bb..861b77bbc7df 100644
--- a/sound/hda/hdac_i915.c
+++ b/sound/hda/hdac_i915.c
@@ -22,7 +22,14 @@
#include <sound/hda_i915.h>
#include <sound/hda_register.h>
-static struct drm_audio_component *hdac_acomp;
+static void hdac_acomp_release(struct device *dev, void *res)
+{
+}
+
+static struct drm_audio_component *hdac_get_acomp(struct device *dev)
+{
+ return devres_find(dev, hdac_acomp_release, NULL, NULL);
+}
/**
* snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup
@@ -262,7 +269,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
static int hdac_component_master_bind(struct device *dev)
{
- struct drm_audio_component *acomp = hdac_acomp;
+ struct drm_audio_component *acomp = hdac_get_acomp(dev);
int ret;
ret = component_bind_all(dev, acomp);
@@ -294,7 +301,7 @@ out_unbind:
static void hdac_component_master_unbind(struct device *dev)
{
- struct drm_audio_component *acomp = hdac_acomp;
+ struct drm_audio_component *acomp = hdac_get_acomp(dev);
module_put(acomp->ops->owner);
component_unbind_all(dev, acomp);
@@ -314,6 +321,7 @@ static int hdac_component_master_match(struct device *dev, void *data)
/**
* snd_hdac_i915_register_notifier - Register i915 audio component ops
+ * @bus: HDA core bus
* @aops: i915 audio component ops
*
* This function is supposed to be used only by a HD-audio controller
@@ -323,12 +331,13 @@ static int hdac_component_master_match(struct device *dev, void *data)
*
* Returns zero for success or a negative error code.
*/
-int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *aops)
+int snd_hdac_i915_register_notifier(struct hdac_bus *bus,
+ const struct drm_audio_component_audio_ops *aops)
{
- if (!hdac_acomp)
+ if (!bus->audio_component)
return -ENODEV;
- hdac_acomp->audio_ops = aops;
+ bus->audio_component->audio_ops = aops;
return 0;
}
EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier);
@@ -365,18 +374,19 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
struct drm_audio_component *acomp;
int ret;
- if (WARN_ON(hdac_acomp))
+ if (WARN_ON(hdac_get_acomp(dev)))
return -EBUSY;
if (!i915_gfx_present())
return -ENODEV;
- i915_acomp = kzalloc(sizeof(*i915_acomp), GFP_KERNEL);
+ i915_acomp = devres_alloc(hdac_acomp_release, sizeof(*i915_acomp),
+ GFP_KERNEL);
if (!i915_acomp)
return -ENOMEM;
acomp = &i915_acomp->base;
bus->audio_component = acomp;
- hdac_acomp = acomp;
+ devres_add(dev, acomp);
component_match_add(dev, &match, hdac_component_master_match, bus);
ret = component_master_add_with_match(dev, &hdac_component_master_ops,
@@ -400,9 +410,8 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
out_master_del:
component_master_del(dev, &hdac_component_master_ops);
out_err:
- kfree(acomp);
bus->audio_component = NULL;
- hdac_acomp = NULL;
+ devres_destroy(dev, hdac_acomp_release, NULL, NULL);
dev_info(dev, "failed to add i915 component master (%d)\n", ret);
return ret;
@@ -434,9 +443,8 @@ int snd_hdac_i915_exit(struct hdac_bus *bus)
component_master_del(dev, &hdac_component_master_ops);
- kfree(acomp);
bus->audio_component = NULL;
- hdac_acomp = NULL;
+ devres_destroy(dev, hdac_acomp_release, NULL, NULL);
return 0;
}