bool *audio_enabled, char *buffer, int max_bytes);
int snd_hdac_i915_init(struct hdac_bus *bus);
int snd_hdac_i915_exit(struct hdac_bus *bus);
-int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *);
+int snd_hdac_i915_register_notifier(struct hdac_bus *bus,
+ const struct drm_audio_component_audio_ops *ops);
#else
static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable)
{
{
return 0;
}
-static inline int snd_hdac_i915_register_notifier(const struct drm_audio_component_audio_ops *ops)
+static inline int snd_hdac_i915_register_notifier(struct hdac_bus *bus,
+ const struct drm_audio_component_audio_ops *ops)
{
return -ENODEV;
}
#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
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);
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);
/**
* 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
*
* 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);
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,
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;
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;
}
int pin_idx, pcm_idx;
if (codec_has_acomp(codec))
- snd_hdac_i915_register_notifier(NULL);
+ snd_hdac_i915_register_notifier(&codec->bus->core, NULL);
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
*/
wmb();
spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify;
- snd_hdac_i915_register_notifier(&spec->drm_audio_ops);
+ snd_hdac_i915_register_notifier(&codec->bus->core,
+ &spec->drm_audio_ops);
}
/* setup_stream ops override for HSW+ */