summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-07-11 09:48:18 -0400
committerTakashi Iwai <tiwai@suse.de>2018-07-17 16:25:47 -0400
commit82887c0beb1ee6b33eed8318d8e8d41c5b3eddae (patch)
tree884159632784699ff4360d09b32ac51847418edb
parentae891abe7c2ccf75b69ca8330225e37ecc06924e (diff)
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>
-rw-r--r--include/sound/hda_i915.h6
-rw-r--r--sound/hda/hdac_i915.c34
-rw-r--r--sound/pci/hda/patch_hdmi.c5
-rw-r--r--sound/soc/codecs/hdac_hdmi.c2
4 files changed, 29 insertions, 18 deletions
diff --git a/include/sound/hda_i915.h b/include/sound/hda_i915.h
index f69ea84e7b65..648263791559 100644
--- a/include/sound/hda_i915.h
+++ b/include/sound/hda_i915.h
@@ -17,7 +17,8 @@ int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id,
17 bool *audio_enabled, char *buffer, int max_bytes); 17 bool *audio_enabled, char *buffer, int max_bytes);
18int snd_hdac_i915_init(struct hdac_bus *bus); 18int snd_hdac_i915_init(struct hdac_bus *bus);
19int snd_hdac_i915_exit(struct hdac_bus *bus); 19int snd_hdac_i915_exit(struct hdac_bus *bus);
20int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *); 20int snd_hdac_i915_register_notifier(struct hdac_bus *bus,
21 const struct drm_audio_component_audio_ops *ops);
21#else 22#else
22static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) 23static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
23{ 24{
@@ -49,7 +50,8 @@ static inline int snd_hdac_i915_exit(struct hdac_bus *bus)
49{ 50{
50 return 0; 51 return 0;
51} 52}
52static inline int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *ops) 53static inline int snd_hdac_i915_register_notifier(struct hdac_bus *bus,
54 const struct drm_audio_component_audio_ops *ops)
53{ 55{
54 return -ENODEV; 56 return -ENODEV;
55} 57}
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 @@
22#include <sound/hda_i915.h> 22#include <sound/hda_i915.h>
23#include <sound/hda_register.h> 23#include <sound/hda_register.h>
24 24
25static struct drm_audio_component *hdac_acomp; 25static void hdac_acomp_release(struct device *dev, void *res)
26{
27}
28
29static struct drm_audio_component *hdac_get_acomp(struct device *dev)
30{
31 return devres_find(dev, hdac_acomp_release, NULL, NULL);
32}
26 33
27/** 34/**
28 * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup 35 * snd_hdac_set_codec_wakeup - Enable / disable HDMI/DP codec wakeup
@@ -262,7 +269,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_acomp_get_eld);
262 269
263static int hdac_component_master_bind(struct device *dev) 270static int hdac_component_master_bind(struct device *dev)
264{ 271{
265 struct drm_audio_component *acomp = hdac_acomp; 272 struct drm_audio_component *acomp = hdac_get_acomp(dev);
266 int ret; 273 int ret;
267 274
268 ret = component_bind_all(dev, acomp); 275 ret = component_bind_all(dev, acomp);
@@ -294,7 +301,7 @@ out_unbind:
294 301
295static void hdac_component_master_unbind(struct device *dev) 302static void hdac_component_master_unbind(struct device *dev)
296{ 303{
297 struct drm_audio_component *acomp = hdac_acomp; 304 struct drm_audio_component *acomp = hdac_get_acomp(dev);
298 305
299 module_put(acomp->ops->owner); 306 module_put(acomp->ops->owner);
300 component_unbind_all(dev, acomp); 307 component_unbind_all(dev, acomp);
@@ -314,6 +321,7 @@ static int hdac_component_master_match(struct device *dev, void *data)
314 321
315/** 322/**
316 * snd_hdac_i915_register_notifier - Register i915 audio component ops 323 * snd_hdac_i915_register_notifier - Register i915 audio component ops
324 * @bus: HDA core bus
317 * @aops: i915 audio component ops 325 * @aops: i915 audio component ops
318 * 326 *
319 * This function is supposed to be used only by a HD-audio controller 327 * 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)
323 * 331 *
324 * Returns zero for success or a negative error code. 332 * Returns zero for success or a negative error code.
325 */ 333 */
326int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *aops) 334int snd_hdac_i915_register_notifier(struct hdac_bus *bus,
335 const struct drm_audio_component_audio_ops *aops)
327{ 336{
328 if (!hdac_acomp) 337 if (!bus->audio_component)
329 return -ENODEV; 338 return -ENODEV;
330 339
331 hdac_acomp->audio_ops = aops; 340 bus->audio_component->audio_ops = aops;
332 return 0; 341 return 0;
333} 342}
334EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); 343EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier);
@@ -365,18 +374,19 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
365 struct drm_audio_component *acomp; 374 struct drm_audio_component *acomp;
366 int ret; 375 int ret;
367 376
368 if (WARN_ON(hdac_acomp)) 377 if (WARN_ON(hdac_get_acomp(dev)))
369 return -EBUSY; 378 return -EBUSY;
370 379
371 if (!i915_gfx_present()) 380 if (!i915_gfx_present())
372 return -ENODEV; 381 return -ENODEV;
373 382
374 i915_acomp = kzalloc(sizeof(*i915_acomp), GFP_KERNEL); 383 i915_acomp = devres_alloc(hdac_acomp_release, sizeof(*i915_acomp),
384 GFP_KERNEL);
375 if (!i915_acomp) 385 if (!i915_acomp)
376 return -ENOMEM; 386 return -ENOMEM;
377 acomp = &i915_acomp->base; 387 acomp = &i915_acomp->base;
378 bus->audio_component = acomp; 388 bus->audio_component = acomp;
379 hdac_acomp = acomp; 389 devres_add(dev, acomp);
380 390
381 component_match_add(dev, &match, hdac_component_master_match, bus); 391 component_match_add(dev, &match, hdac_component_master_match, bus);
382 ret = component_master_add_with_match(dev, &hdac_component_master_ops, 392 ret = component_master_add_with_match(dev, &hdac_component_master_ops,
@@ -400,9 +410,8 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
400out_master_del: 410out_master_del:
401 component_master_del(dev, &hdac_component_master_ops); 411 component_master_del(dev, &hdac_component_master_ops);
402out_err: 412out_err:
403 kfree(acomp);
404 bus->audio_component = NULL; 413 bus->audio_component = NULL;
405 hdac_acomp = NULL; 414 devres_destroy(dev, hdac_acomp_release, NULL, NULL);
406 dev_info(dev, "failed to add i915 component master (%d)\n", ret); 415 dev_info(dev, "failed to add i915 component master (%d)\n", ret);
407 416
408 return ret; 417 return ret;
@@ -434,9 +443,8 @@ int snd_hdac_i915_exit(struct hdac_bus *bus)
434 443
435 component_master_del(dev, &hdac_component_master_ops); 444 component_master_del(dev, &hdac_component_master_ops);
436 445
437 kfree(acomp);
438 bus->audio_component = NULL; 446 bus->audio_component = NULL;
439 hdac_acomp = NULL; 447 devres_destroy(dev, hdac_acomp_release, NULL, NULL);
440 448
441 return 0; 449 return 0;
442} 450}
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index c0847017114c..bf174a013f2d 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2288,7 +2288,7 @@ static void generic_hdmi_free(struct hda_codec *codec)
2288 int pin_idx, pcm_idx; 2288 int pin_idx, pcm_idx;
2289 2289
2290 if (codec_has_acomp(codec)) 2290 if (codec_has_acomp(codec))
2291 snd_hdac_i915_register_notifier(NULL); 2291 snd_hdac_i915_register_notifier(&codec->bus->core, NULL);
2292 2292
2293 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 2293 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2294 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 2294 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
@@ -2518,7 +2518,8 @@ static void register_i915_notifier(struct hda_codec *codec)
2518 */ 2518 */
2519 wmb(); 2519 wmb();
2520 spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify; 2520 spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify;
2521 snd_hdac_i915_register_notifier(&spec->drm_audio_ops); 2521 snd_hdac_i915_register_notifier(&codec->bus->core,
2522 &spec->drm_audio_ops);
2522} 2523}
2523 2524
2524/* setup_stream ops override for HSW+ */ 2525/* setup_stream ops override for HSW+ */
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 460075475f20..2b7c33db4ded 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -1812,7 +1812,7 @@ static int hdmi_codec_probe(struct snd_soc_component *component)
1812 return ret; 1812 return ret;
1813 1813
1814 aops.audio_ptr = hdev; 1814 aops.audio_ptr = hdev;
1815 ret = snd_hdac_i915_register_notifier(&aops); 1815 ret = snd_hdac_i915_register_notifier(hdev->bus, &aops);
1816 if (ret < 0) { 1816 if (ret < 0) {
1817 dev_err(&hdev->dev, "notifier register failed: err: %d\n", ret); 1817 dev_err(&hdev->dev, "notifier register failed: err: %d\n", ret);
1818 return ret; 1818 return ret;