ALSA: hda - Pass bus io_ops directly from the top-level driver
[firefly-linux-kernel-4.4.55.git] / sound / pci / hda / hda_intel.c
index a8a1e14272a1e574302da56ad0ad7540bf8fd60d..7492d11fd8ff0d3549da3ceec7d2b63ce1f03b9b 100644 (file)
@@ -62,7 +62,6 @@
 #include <linux/firmware.h>
 #include "hda_codec.h"
 #include "hda_controller.h"
-#include "hda_priv.h"
 #include "hda_intel.h"
 
 /* position fix mode */
@@ -174,7 +173,6 @@ static struct kernel_param_ops param_ops_xint = {
 #define param_check_xint param_check_int
 
 static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
-static int *power_save_addr = &power_save;
 module_param(power_save, xint, 0644);
 MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
                 "(in second, 0 = disable).");
@@ -187,7 +185,7 @@ static bool power_save_controller = 1;
 module_param(power_save_controller, bool, 0644);
 MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
 #else
-static int *power_save_addr;
+#define power_save     0
 #endif /* CONFIG_PM */
 
 static int align_buffer_size = -1;
@@ -299,8 +297,12 @@ enum {
         AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_POWERWELL |\
         AZX_DCAPS_SNOOP_TYPE(SCH))
 
+#define AZX_DCAPS_INTEL_BRASWELL \
+       (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_I915_POWERWELL)
+
 #define AZX_DCAPS_INTEL_SKYLAKE \
-       (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG)
+       (AZX_DCAPS_INTEL_PCH | AZX_DCAPS_SEPARATE_STREAM_TAG |\
+        AZX_DCAPS_I915_POWERWELL)
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -530,10 +532,10 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
        if (ok == 1) {
                azx_dev->irq_pending = 0;
                return ok;
-       } else if (ok == 0 && chip->bus && chip->bus->workq) {
+       } else if (ok == 0) {
                /* bogus IRQ, process it later */
                azx_dev->irq_pending = 1;
-               queue_work(chip->bus->workq, &hda->irq_pending_work);
+               schedule_work(&hda->irq_pending_work);
        }
        return 0;
 }
@@ -741,7 +743,6 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
 {
        struct hda_intel *hda;
        struct azx *chip;
-       struct hda_codec *c;
        int prev = power_save;
        int ret = param_set_int(val, kp);
 
@@ -753,8 +754,7 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
                chip = &hda->chip;
                if (!chip->bus || chip->disabled)
                        continue;
-               list_for_each_entry(c, &chip->bus->codec_list, list)
-                       snd_hda_power_sync(c);
+               snd_hda_set_power_save(chip->bus, power_save * 1000);
        }
        mutex_unlock(&card_list_lock);
        return 0;
@@ -773,7 +773,6 @@ static int azx_suspend(struct device *dev)
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip;
        struct hda_intel *hda;
-       struct azx_pcm *p;
 
        if (!card)
                return 0;
@@ -785,10 +784,6 @@ static int azx_suspend(struct device *dev)
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        azx_clear_irq_pending(chip);
-       list_for_each_entry(p, &chip->pcm_list, list)
-               snd_pcm_suspend_all(p->pcm);
-       if (chip->initialized)
-               snd_hda_suspend(chip->bus);
        azx_stop_chip(chip);
        azx_enter_link_reset(chip);
        if (chip->irq >= 0) {
@@ -831,7 +826,6 @@ static int azx_resume(struct device *dev)
 
        azx_init_chip(chip, true);
 
-       snd_hda_resume(chip->bus);
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
 }
@@ -852,7 +846,7 @@ static int azx_runtime_suspend(struct device *dev)
        if (chip->disabled || hda->init_failed)
                return 0;
 
-       if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+       if (!azx_has_pm_runtime(chip))
                return 0;
 
        /* enable controller wake up event */
@@ -885,7 +879,7 @@ static int azx_runtime_resume(struct device *dev)
        if (chip->disabled || hda->init_failed)
                return 0;
 
-       if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+       if (!azx_has_pm_runtime(chip))
                return 0;
 
        if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
@@ -901,10 +895,10 @@ static int azx_runtime_resume(struct device *dev)
 
        bus = chip->bus;
        if (status && bus) {
-               list_for_each_entry(codec, &bus->codec_list, list)
+               list_for_each_codec(codec, bus)
                        if (status & (1 << codec->addr))
-                               queue_delayed_work(codec->bus->workq,
-                                                  &codec->jackpoll_work, codec->jackpoll_interval);
+                               schedule_delayed_work(&codec->jackpoll_work,
+                                                     codec->jackpoll_interval);
        }
 
        /* disable controller Wake Up event*/
@@ -928,8 +922,8 @@ static int azx_runtime_idle(struct device *dev)
        if (chip->disabled || hda->init_failed)
                return 0;
 
-       if (!power_save_controller ||
-           !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
+       if (!power_save_controller || !azx_has_pm_runtime(chip) ||
+           chip->bus->core.codec_powered)
                return -EBUSY;
 
        return 0;
@@ -1071,14 +1065,11 @@ static int azx_free(struct azx *chip)
        struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
        int i;
 
-       if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
-                       && chip->running)
+       if (azx_has_pm_runtime(chip) && chip->running)
                pm_runtime_get_noresume(&pci->dev);
 
        azx_del_card_list(chip);
 
-       azx_notifier_unregister(chip);
-
        hda->init_failed = 1; /* to be sure */
        complete_all(&hda->probe_wait);
 
@@ -1374,9 +1365,11 @@ static void azx_probe_work(struct work_struct *work)
 /*
  * constructor
  */
+static const struct hdac_io_ops pci_hda_io_ops;
+static const struct hda_controller_ops pci_hda_ops;
+
 static int azx_create(struct snd_card *card, struct pci_dev *pci,
                      int dev, unsigned int driver_caps,
-                     const struct hda_controller_ops *hda_ops,
                      struct azx **rchip)
 {
        static struct snd_device_ops ops = {
@@ -1394,7 +1387,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
 
        hda = kzalloc(sizeof(*hda), GFP_KERNEL);
        if (!hda) {
-               dev_err(card->dev, "Cannot allocate hda\n");
                pci_disable_device(pci);
                return -ENOMEM;
        }
@@ -1404,7 +1396,8 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
        mutex_init(&chip->open_mutex);
        chip->card = card;
        chip->pci = pci;
-       chip->ops = hda_ops;
+       chip->ops = &pci_hda_ops;
+       chip->io_ops = &pci_hda_io_ops;
        chip->irq = -1;
        chip->driver_caps = driver_caps;
        chip->driver_type = driver_caps & 0xff;
@@ -1575,10 +1568,8 @@ static int azx_first_init(struct azx *chip)
        chip->num_streams = chip->playback_streams + chip->capture_streams;
        chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
                                GFP_KERNEL);
-       if (!chip->azx_dev) {
-               dev_err(card->dev, "cannot malloc azx_dev\n");
+       if (!chip->azx_dev)
                return -ENOMEM;
-       }
 
        err = azx_alloc_stream_pages(chip);
        if (err < 0)
@@ -1615,19 +1606,6 @@ static int azx_first_init(struct azx *chip)
        return 0;
 }
 
-static void power_down_all_codecs(struct azx *chip)
-{
-#ifdef CONFIG_PM
-       /* The codecs were powered up in snd_hda_codec_new().
-        * Now all initialization done, so turn them down if possible
-        */
-       struct hda_codec *codec;
-       list_for_each_entry(codec, &chip->bus->codec_list, list) {
-               snd_hda_power_down(codec);
-       }
-#endif
-}
-
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 /* callback from request_firmware_nowait() */
 static void azx_firmware_cb(const struct firmware *fw, void *context)
@@ -1706,15 +1684,16 @@ static int disable_msi_reset_irq(struct azx *chip)
 }
 
 /* DMA page allocation helpers.  */
-static int dma_alloc_pages(struct azx *chip,
+static int dma_alloc_pages(struct hdac_bus *bus,
                           int type,
                           size_t size,
                           struct snd_dma_buffer *buf)
 {
+       struct azx *chip = to_hda_bus(bus)->private_data;
        int err;
 
        err = snd_dma_alloc_pages(type,
-                                 chip->card->dev,
+                                 bus->dev,
                                  size, buf);
        if (err < 0)
                return err;
@@ -1722,8 +1701,10 @@ static int dma_alloc_pages(struct azx *chip,
        return 0;
 }
 
-static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
+static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
 {
+       struct azx *chip = to_hda_bus(bus)->private_data;
+
        mark_pages_wc(chip, buf, false);
        snd_dma_free_pages(buf);
 }
@@ -1765,16 +1746,19 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
 #endif
 }
 
-static const struct hda_controller_ops pci_hda_ops = {
+static const struct hdac_io_ops pci_hda_io_ops = {
        .reg_writel = pci_azx_writel,
        .reg_readl = pci_azx_readl,
        .reg_writew = pci_azx_writew,
        .reg_readw = pci_azx_readw,
        .reg_writeb = pci_azx_writeb,
        .reg_readb = pci_azx_readb,
-       .disable_msi_reset_irq = disable_msi_reset_irq,
        .dma_alloc_pages = dma_alloc_pages,
        .dma_free_pages = dma_free_pages,
+};
+
+static const struct hda_controller_ops pci_hda_ops = {
+       .disable_msi_reset_irq = disable_msi_reset_irq,
        .substream_alloc_pages = substream_alloc_pages,
        .substream_free_pages = substream_free_pages,
        .pcm_mmap_prepare = pcm_mmap_prepare,
@@ -1805,8 +1789,7 @@ static int azx_probe(struct pci_dev *pci,
                return err;
        }
 
-       err = azx_create(card, pci, dev, pci_id->driver_data,
-                        &pci_hda_ops, &chip);
+       err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
        if (err < 0)
                goto out_free;
        card->private_data = chip;
@@ -1887,6 +1870,10 @@ static int azx_probe_continue(struct azx *chip)
 #endif
        }
 
+       err = azx_bus_create(chip, model[dev]);
+       if (err < 0)
+               goto out_free;
+
        err = azx_first_init(chip);
        if (err < 0)
                goto out_free;
@@ -1896,12 +1883,10 @@ static int azx_probe_continue(struct azx *chip)
 #endif
 
        /* create codec instances */
-       err = azx_codec_create(chip, model[dev],
-                              azx_max_codecs[chip->driver_type],
-                              power_save_addr);
-
+       err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
        if (err < 0)
                goto out_free;
+
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
        if (chip->fw) {
                err = snd_hda_load_patch(chip->bus, chip->fw->size,
@@ -1920,25 +1905,14 @@ static int azx_probe_continue(struct azx *chip)
                        goto out_free;
        }
 
-       /* create PCM streams */
-       err = snd_hda_build_pcms(chip->bus);
-       if (err < 0)
-               goto out_free;
-
-       /* create mixer controls */
-       err = azx_mixer_create(chip);
-       if (err < 0)
-               goto out_free;
-
        err = snd_card_register(chip->card);
        if (err < 0)
                goto out_free;
 
        chip->running = 1;
-       power_down_all_codecs(chip);
-       azx_notifier_register(chip);
        azx_add_card_list(chip);
-       if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) || hda->use_vga_switcheroo)
+       snd_hda_set_power_save(chip->bus, power_save * 1000);
+       if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
                pm_runtime_put_noidle(&pci->dev);
 
 out_free:
@@ -1956,6 +1930,18 @@ static void azx_remove(struct pci_dev *pci)
                snd_card_free(card);
 }
 
+static void azx_shutdown(struct pci_dev *pci)
+{
+       struct snd_card *card = pci_get_drvdata(pci);
+       struct azx *chip;
+
+       if (!card)
+               return;
+       chip = card->private_data;
+       if (chip && chip->running)
+               azx_stop_chip(chip);
+}
+
 /* PCI IDs */
 static const struct pci_device_id azx_ids[] = {
        /* CPT */
@@ -2017,7 +2003,7 @@ static const struct pci_device_id azx_ids[] = {
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Braswell */
        { PCI_DEVICE(0x8086, 0x2284),
-         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+         .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL },
        /* ICH6 */
        { PCI_DEVICE(0x8086, 0x2668),
          .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH },
@@ -2178,6 +2164,7 @@ static struct pci_driver azx_driver = {
        .id_table = azx_ids,
        .probe = azx_probe,
        .remove = azx_remove,
+       .shutdown = azx_shutdown,
        .driver = {
                .pm = AZX_PM_OPS,
        },