]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
UBUNTU: SAUCE: sound/hda: Load i915_bpo from the hda driver on SKL/KBL/BXT
authorTimo Aaltonen <timo.aaltonen@canonical.com>
Mon, 22 Feb 2016 17:01:54 +0000 (19:01 +0200)
committerTim Gardner <tim.gardner@canonical.com>
Wed, 6 Apr 2016 09:21:14 +0000 (10:21 +0100)
BugLink: http://bugs.launchpad.net/bugs/1540390
Signed-off-by: Timo Aaltonen <timo.aaltonen@canonical.com>
Signed-off-by: Andy Whitcroft <apw@canonical.com>
include/sound/hda_i915.h
sound/hda/hdac_i915.c
sound/pci/hda/hda_intel.c

index 930b41e5acf4cb9a9008cfc7394dad61d87895a9..c65a22ef2ccbb240def3a664c69a78767a0918c3 100644 (file)
@@ -11,6 +11,7 @@ int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable);
 int snd_hdac_display_power(struct hdac_bus *bus, bool enable);
 int snd_hdac_get_display_clk(struct hdac_bus *bus);
 int snd_hdac_i915_init(struct hdac_bus *bus);
+int snd_hdac_i915_init_bpo(struct hdac_bus *bus);
 int snd_hdac_i915_exit(struct hdac_bus *bus);
 int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *);
 #else
@@ -30,6 +31,10 @@ static inline int snd_hdac_i915_init(struct hdac_bus *bus)
 {
        return -ENODEV;
 }
+static inline int snd_hdac_i915_init_bpo(struct hdac_bus *bus)
+{
+       return -ENODEV;
+}
 static inline int snd_hdac_i915_exit(struct hdac_bus *bus)
 {
        return 0;
index 8fef1b8d1fd8acc443bc86a2aedd66763d9b84fd..581d84adf30383e5c1996bdc129f50155e45a176 100644 (file)
@@ -170,6 +170,11 @@ static int hdac_component_master_match(struct device *dev, void *data)
        return !strcmp(dev->driver->name, "i915");
 }
 
+static int hdac_component_master_match_bpo(struct device *dev, void *data)
+{
+       return !strcmp(dev->driver->name, "i915_bpo");
+}
+
 /**
  * snd_hdac_i915_register_notifier - Register i915 audio component ops
  * @aops: i915 audio component ops
@@ -246,6 +251,49 @@ out_err:
 }
 EXPORT_SYMBOL_GPL(snd_hdac_i915_init);
 
+int snd_hdac_i915_init_bpo(struct hdac_bus *bus)
+{
+       struct component_match *match = NULL;
+       struct device *dev = bus->dev;
+       struct i915_audio_component *acomp;
+       int ret;
+
+       acomp = kzalloc(sizeof(*acomp), GFP_KERNEL);
+       if (!acomp)
+               return -ENOMEM;
+       bus->audio_component = acomp;
+       hdac_acomp = acomp;
+
+       component_match_add(dev, &match, hdac_component_master_match_bpo, bus);
+       ret = component_master_add_with_match(dev, &hdac_component_master_ops,
+                                             match);
+       if (ret < 0)
+               goto out_err;
+
+       /*
+        * Atm, we don't support deferring the component binding, so make sure
+        * i915_bpo is loaded and that the binding successfully completes.
+        */
+       request_module("i915_bpo");
+
+       if (!acomp->ops) {
+               ret = -ENODEV;
+               goto out_master_del;
+       }
+       dev_dbg(dev, "bound to i915_bpo component master\n");
+
+       return 0;
+out_master_del:
+       component_master_del(dev, &hdac_component_master_ops);
+out_err:
+       kfree(acomp);
+       bus->audio_component = NULL;
+       dev_err(dev, "failed to add i915_bpo component master (%d)\n", ret);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(snd_hdac_i915_init_bpo);
+
 /**
  * snd_hdac_i915_exit - Finalize i915 audio component
  * @bus: HDA core bus
index 2c13298e80b7477a4bef0646319af55f118831e2..ca73121bbf1d59b8c8b18517aa2a434482afb113 100644 (file)
@@ -2061,7 +2061,12 @@ static int azx_probe_continue(struct azx *chip)
                if (CONTROLLER_IN_GPU(pci))
                        hda->need_i915_power = 1;
 
-               err = snd_hdac_i915_init(bus);
+               if (((chip->driver_caps & AZX_DCAPS_INTEL_SKYLAKE) == AZX_DCAPS_INTEL_SKYLAKE) || \
+                       ((chip->driver_caps & AZX_DCAPS_INTEL_BROXTON) == AZX_DCAPS_INTEL_BROXTON))
+                       err = snd_hdac_i915_init_bpo(bus);
+               else
+                       err = snd_hdac_i915_init(bus);
+
                if (err < 0) {
                        /* if the controller is bound only with HDMI/DP
                         * (for HSW and BDW), we need to abort the probe;