Merge branch 'topic/hda-ca0132-dsp' into for-next
authorTakashi Iwai <tiwai@suse.de>
Thu, 7 Feb 2013 11:34:36 +0000 (12:34 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 7 Feb 2013 11:34:36 +0000 (12:34 +0100)
1  2 
sound/pci/hda/Kconfig
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_intel.c

diff --combined sound/pci/hda/Kconfig
index 4466bf63d6bf56fd7e80a69691c4e72c15912d69,11b4b77a821515f85933032eef4689710edbdb4b..80a7d44bcf81f38780776fa5abb0eb2f8f35087b
@@@ -15,6 -15,9 +15,9 @@@ menuconfig SND_HDA_INTE
  
  if SND_HDA_INTEL
  
+ config SND_HDA_DSP_LOADER
+       bool
  config SND_HDA_PREALLOC_SIZE
        int "Pre-allocated buffer size for HD-audio driver"
        range 0 32768
@@@ -37,8 -40,8 +40,8 @@@ config SND_HDA_HWDE
          with codecs for debugging purposes.
  
  config SND_HDA_RECONFIG
 -      bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)"
 -      depends on SND_HDA_HWDEP && EXPERIMENTAL
 +      bool "Allow dynamic codec reconfiguration"
 +      depends on SND_HDA_HWDEP
        help
          Say Y here to enable the HD-audio codec re-configuration feature.
          This adds the sysfs interfaces to allow user to clear the whole
@@@ -72,6 -75,7 +75,6 @@@ config SND_HDA_INPUT_JAC
  
  config SND_HDA_PATCH_LOADER
        bool "Support initialization patch loading for HD-audio"
 -      depends on EXPERIMENTAL
        select FW_LOADER
        select SND_HDA_HWDEP
        select SND_HDA_RECONFIG
@@@ -86,7 -90,6 +89,7 @@@
  config SND_HDA_CODEC_REALTEK
        bool "Build Realtek HD-audio codec support"
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include Realtek HD-audio codec support in
          snd-hda-intel driver, such as ALC880.
  config SND_HDA_CODEC_ANALOG
        bool "Build Analog Device HD-audio codec support"
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include Analog Device HD-audio codec support in
          snd-hda-intel driver, such as AD1986A.
  config SND_HDA_CODEC_SIGMATEL
        bool "Build IDT/Sigmatel HD-audio codec support"
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include IDT (Sigmatel) HD-audio codec support in
          snd-hda-intel driver, such as STAC9200.
  config SND_HDA_CODEC_VIA
        bool "Build VIA HD-audio codec support"
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include VIA HD-audio codec support in
          snd-hda-intel driver, such as VT1708.
@@@ -151,8 -151,8 +154,8 @@@ config SND_HDA_CODEC_HDM
  
  config SND_HDA_CODEC_CIRRUS
        bool "Build Cirrus Logic codec support"
 -      depends on SND_HDA_INTEL
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include Cirrus Logic codec support in
          snd-hda-intel driver, such as CS4206.
  config SND_HDA_CODEC_CONEXANT
        bool "Build Conexant HD-audio codec support"
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include Conexant HD-audio codec support in
          snd-hda-intel driver, such as CX20549.
  
  config SND_HDA_CODEC_CA0110
        bool "Build Creative CA0110-IBG codec support"
 -      depends on SND_HDA_INTEL
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include Creative CA0110-IBG codec support in
          snd-hda-intel driver, found on some Creative X-Fi cards.
  
  config SND_HDA_CODEC_CA0132
        bool "Build Creative CA0132 codec support"
 -      depends on SND_HDA_INTEL
        default y
        help
          Say Y here to include Creative CA0132 codec support in
          snd-hda-codec-ca0132.
          This module is automatically loaded at probing.
  
+ config SND_HDA_CODEC_CA0132_DSP
+       bool "Support new DSP code for CA0132 codec"
+       depends on SND_HDA_CODEC_CA0132 && FW_LOADER
+       select SND_HDA_DSP_LOADER
+       help
+         Say Y here to enable the DSP for Creative CA0132 for extended
+         features like equalizer or echo cancellation.
+         Note that this option requires the external firmware file
+         (ctefx.bin).
  config SND_HDA_CODEC_CMEDIA
        bool "Build C-Media HD-audio codec support"
        default y
 +      select SND_HDA_GENERIC
        help
          Say Y here to include C-Media HD-audio codec support in
          snd-hda-intel driver, such as CMI9880.
index fbedcf3c9d0b2aae8bc5c65b2d72f32330f44e86,c9f53bd587b05e7122f6be89dee4151969cedb73..6c592722efcd8a9f284cdc36d69e3b418907980e
@@@ -618,6 -618,17 +618,17 @@@ struct hda_bus_ops 
        /* notify power-up/down from codec to controller */
        void (*pm_notify)(struct hda_bus *bus, bool power_up);
  #endif
+ #ifdef CONFIG_SND_HDA_DSP_LOADER
+       /* prepare DSP transfer */
+       int (*load_dsp_prepare)(struct hda_bus *bus, unsigned int format,
+                               unsigned int byte_size,
+                               struct snd_dma_buffer *bufp);
+       /* start/stop DSP transfer */
+       void (*load_dsp_trigger)(struct hda_bus *bus, bool start);
+       /* clean up DSP transfer */
+       void (*load_dsp_cleanup)(struct hda_bus *bus,
+                                struct snd_dma_buffer *dmab);
+ #endif
  };
  
  /* template to pass to the bus constructor */
@@@ -719,10 -730,9 +730,10 @@@ struct hda_codec_ops 
  
  /* record for amp information cache */
  struct hda_cache_head {
 -      u32 key;                /* hash key */
 +      u32 key:31;             /* hash key */
 +      u32 dirty:1;
        u16 val;                /* assigned value */
 -      u16 next;               /* next link; -1 = terminal */
 +      u16 next;
  };
  
  struct hda_amp_info {
@@@ -758,7 -768,6 +769,7 @@@ struct hda_pcm_stream 
        u32 rates;      /* supported rates */
        u64 formats;    /* supported formats (SNDRV_PCM_FMTBIT_) */
        unsigned int maxbps;    /* supported max. bit per sample */
 +      const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
        struct hda_pcm_ops ops;
  };
  
@@@ -831,21 -840,19 +842,21 @@@ struct hda_codec 
        struct hda_cache_rec amp_cache; /* cache for amp access */
        struct hda_cache_rec cmd_cache; /* cache for other commands */
  
 -      struct snd_array conn_lists;    /* connection-list array */
 +      struct list_head conn_list;     /* linked-list of connection-list */
  
        struct mutex spdif_mutex;
        struct mutex control_mutex;
        struct mutex hash_mutex;
        struct snd_array spdif_out;
        unsigned int spdif_in_enable;   /* SPDIF input enable? */
 +      int primary_dig_out_type;       /* primary digital out PCM type */
        const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
        struct snd_array init_pins;     /* initial (BIOS) pin configurations */
        struct snd_array driver_pins;   /* pin configs set by codec parser */
        struct snd_array cvt_setups;    /* audio convert setups */
  
  #ifdef CONFIG_SND_HDA_HWDEP
 +      struct mutex user_mutex;
        struct snd_hwdep *hwdep;        /* assigned hwdep device */
        struct snd_array init_verbs;    /* additional init verbs */
        struct snd_array hints;         /* additional hints */
        unsigned int pins_shutup:1;     /* pins are shut up */
        unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
        unsigned int no_jack_detect:1;  /* Machine has no jack-detection */
 +      unsigned int inv_eapd:1; /* broken h/w: inverted EAPD control */
 +      unsigned int inv_jack_detect:1; /* broken h/w: inverted detection bit */
        unsigned int pcm_format_first:1; /* PCM format must be set first */
        unsigned int epss:1;            /* supporting EPSS? */
 +      unsigned int cached_write:1;    /* write only to caches */
  #ifdef CONFIG_PM
        unsigned int power_on :1;       /* current (global) power-state */
        unsigned int d3_stop_clk:1;     /* support D3 operation without BCLK */
        unsigned int pm_down_notified:1; /* PM notified to controller */
 +      unsigned int in_pm:1;           /* suspend/resume being performed */
        int power_transition;   /* power-state in transition */
        int power_count;        /* current (global) power refcount */
        struct delayed_work power_work; /* delayed task for powerdown */
        spinlock_t power_lock;
  #endif
  
 +      /* filter the requested power state per nid */
 +      unsigned int (*power_filter)(struct hda_codec *codec, hda_nid_t nid,
 +                                   unsigned int power_state);
 +
        /* codec-specific additional proc output */
        void (*proc_widget_hook)(struct snd_info_buffer *buffer,
                                 struct hda_codec *codec, hda_nid_t nid);
  
        /* jack detection */
        struct snd_array jacktbl;
 +      unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */
 +      struct delayed_work jackpoll_work;
  
  #ifdef CONFIG_SND_HDA_INPUT_JACK
        /* jack detection */
        struct snd_array jacks;
  #endif
 +
 +      /* fix-up list */
 +      int fixup_id;
 +      const struct hda_fixup *fixup_list;
 +      const char *fixup_name;
 +
 +      /* additional init verbs */
 +      struct snd_array verbs;
  };
  
  /* direction */
@@@ -949,8 -938,6 +960,8 @@@ snd_hda_get_num_conns(struct hda_codec 
  }
  int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
                            hda_nid_t *conn_list, int max_conns);
 +int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
 +                        const hda_nid_t **listp);
  int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
                          const hda_nid_t *list);
  int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
@@@ -971,6 -958,7 +982,6 @@@ void snd_hda_sequence_write(struct hda_
  int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
  
  /* cached write */
 -#ifdef CONFIG_PM
  int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
                              int direct, unsigned int verb, unsigned int parm);
  void snd_hda_sequence_write_cache(struct hda_codec *codec,
  int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
                              int direct, unsigned int verb, unsigned int parm);
  void snd_hda_codec_resume_cache(struct hda_codec *codec);
 -#else
 -#define snd_hda_codec_write_cache     snd_hda_codec_write
 -#define snd_hda_codec_update_cache    snd_hda_codec_write
 -#define snd_hda_sequence_write_cache  snd_hda_sequence_write
 -#endif
 +/* both for cmd & amp caches */
 +void snd_hda_codec_flush_cache(struct hda_codec *codec);
  
  /* the struct for codec->pin_configs */
  struct hda_pincfg {
        hda_nid_t nid;
 -      unsigned char ctrl;     /* current pin control value */
 -      unsigned char pad;      /* reserved */
 +      unsigned char ctrl;     /* original pin control value */
 +      unsigned char target;   /* target pin control value */
        unsigned int cfg;       /* default configuration */
  };
  
@@@ -1043,15 -1034,14 +1054,15 @@@ unsigned int snd_hda_calc_stream_format
  int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
                                unsigned int format);
  
 +extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
 +
  /*
   * Misc
   */
  void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
  void snd_hda_bus_reboot_notify(struct hda_bus *bus);
  void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
 -                                  unsigned int power_state,
 -                                  bool eapd_workaround);
 +                                  unsigned int power_state);
  
  int snd_hda_lock_devices(struct hda_bus *bus);
  void snd_hda_unlock_devices(struct hda_bus *bus);
@@@ -1150,6 -1140,40 +1161,40 @@@ static inline void snd_hda_power_sync(s
  int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf);
  #endif
  
+ #ifdef CONFIG_SND_HDA_DSP_LOADER
+ static inline int
+ snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
+                               unsigned int size,
+                               struct snd_dma_buffer *bufp)
+ {
+       return codec->bus->ops.load_dsp_prepare(codec->bus, format, size, bufp);
+ }
+ static inline void
+ snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start)
+ {
+       return codec->bus->ops.load_dsp_trigger(codec->bus, start);
+ }
+ static inline void
+ snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
+                               struct snd_dma_buffer *dmab)
+ {
+       return codec->bus->ops.load_dsp_cleanup(codec->bus, dmab);
+ }
+ #else
+ static inline int
+ snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
+                               unsigned int size,
+                               struct snd_dma_buffer *bufp)
+ {
+       return -ENOSYS;
+ }
+ static inline void
+ snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) {}
+ static inline void
+ snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
+                               struct snd_dma_buffer *dmab) {}
+ #endif
  /*
   * Codec modularization
   */
index d9e37ffdb0486eb87164a787578ef5a927f063cd,99e61b985d29ab79e4d68db414d08ed3f5f610f2..4b099c603fe116d6416cc056f5bf0f243ef152fd
  #include <linux/reboot.h>
  #include <linux/io.h>
  #include <linux/pm_runtime.h>
 +#include <linux/clocksource.h>
 +#include <linux/time.h>
 +#include <linux/completion.h>
 +
  #ifdef CONFIG_X86
  /* for snoop control */
  #include <asm/pgtable.h>
@@@ -72,7 -68,6 +72,7 @@@ static int position_fix[SNDRV_CARDS] = 
  static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
  static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
  static int probe_only[SNDRV_CARDS];
 +static int jackpoll_ms[SNDRV_CARDS];
  static bool single_cmd;
  static int enable_msi = -1;
  #ifdef CONFIG_SND_HDA_PATCH_LOADER
@@@ -100,8 -95,6 +100,8 @@@ module_param_array(probe_mask, int, NUL
  MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
  module_param_array(probe_only, int, NULL, 0444);
  MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
 +module_param_array(jackpoll_ms, int, NULL, 0444);
 +MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)");
  module_param(single_cmd, bool, 0444);
  MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
                 "(for debugging only).");
@@@ -134,8 -127,8 +134,8 @@@ MODULE_PARM_DESC(power_save, "Automati
   * this may give more power-saving, but will take longer time to
   * wake up.
   */
 -static bool power_save_controller = 1;
 -module_param(power_save_controller, bool, 0644);
 +static int power_save_controller = -1;
 +module_param(power_save_controller, bint, 0644);
  MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
  #endif /* CONFIG_PM */
  
@@@ -192,7 -185,7 +192,7 @@@ MODULE_DESCRIPTION("Intel HDA driver")
  #ifdef CONFIG_SND_VERBOSE_PRINTK
  #define SFX   /* nop */
  #else
 -#define SFX   "hda-intel: "
 +#define SFX   "hda-intel "
  #endif
  
  #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
@@@ -423,9 -416,6 +423,9 @@@ struct azx_dev 
        unsigned int insufficient :1;
        unsigned int wc_marked:1;
        unsigned int no_period_wakeup:1;
 +
 +      struct timecounter  azx_tc;
 +      struct cyclecounter azx_cc;
  };
  
  /* CORB/RIRB */
@@@ -470,7 -460,6 +470,7 @@@ struct azx 
        /* locks */
        spinlock_t reg_lock;
        struct mutex open_mutex;
 +      struct completion probe_wait;
  
        /* streams (x num_streams) */
        struct azx_dev *azx_dev;
        struct list_head list;
  };
  
 +#define CREATE_TRACE_POINTS
 +#include "hda_intel_trace.h"
 +
  /* driver types */
  enum {
        AZX_DRIVER_ICH,
  #define AZX_DCAPS_ALIGN_BUFSIZE       (1 << 22)       /* buffer size alignment */
  #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23)  /* BDLE in 4k boundary */
  #define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25) /* Take LPIB as delay */
 +#define AZX_DCAPS_PM_RUNTIME  (1 << 26)       /* runtime PM support */
 +
 +/* quirks for Intel PCH */
 +#define AZX_DCAPS_INTEL_PCH_NOPM \
 +      (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
 +       AZX_DCAPS_COUNT_LPIB_DELAY)
 +
 +#define AZX_DCAPS_INTEL_PCH \
 +      (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME)
  
  /* quirks for ATI SB / AMD Hudson */
  #define AZX_DCAPS_PRESET_ATI_SB \
  #define use_vga_switcheroo(chip)      0
  #endif
  
 -#if defined(SUPPORT_VGA_SWITCHEROO) || defined(CONFIG_SND_HDA_PATCH_LOADER)
 -#define DELAYED_INIT_MARK
 -#define DELAYED_INITDATA_MARK
 -#else
 -#define DELAYED_INIT_MARK     __devinit
 -#define DELAYED_INITDATA_MARK __devinitdata
 -#endif
 -
 -static char *driver_short_names[] DELAYED_INITDATA_MARK = {
 +static char *driver_short_names[] = {
        [AZX_DRIVER_ICH] = "HDA Intel",
        [AZX_DRIVER_PCH] = "HDA Intel PCH",
        [AZX_DRIVER_SCH] = "HDA Intel MID",
  #define get_azx_dev(substream) (substream->runtime->private_data)
  
  #ifdef CONFIG_X86
 -static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on)
 +static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
  {
 +      int pages;
 +
        if (azx_snoop(chip))
                return;
 -      if (addr && size) {
 -              int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 +      if (!dmab || !dmab->area || !dmab->bytes)
 +              return;
 +
 +#ifdef CONFIG_SND_DMA_SGBUF
 +      if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
 +              struct snd_sg_buf *sgbuf = dmab->private_data;
                if (on)
 -                      set_memory_wc((unsigned long)addr, pages);
 +                      set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
                else
 -                      set_memory_wb((unsigned long)addr, pages);
 +                      set_pages_array_wb(sgbuf->page_table, sgbuf->pages);
 +              return;
        }
 +#endif
 +
 +      pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
 +      if (on)
 +              set_memory_wc((unsigned long)dmab->area, pages);
 +      else
 +              set_memory_wb((unsigned long)dmab->area, pages);
  }
  
  static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
                                 bool on)
  {
 -      __mark_pages_wc(chip, buf->area, buf->bytes, on);
 +      __mark_pages_wc(chip, buf, on);
  }
  static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
 -                                 struct snd_pcm_runtime *runtime, bool on)
 +                                 struct snd_pcm_substream *substream, bool on)
  {
        if (azx_dev->wc_marked != on) {
 -              __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on);
 +              __mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on);
                azx_dev->wc_marked = on;
        }
  }
@@@ -703,7 -674,7 +703,7 @@@ static inline void mark_pages_wc(struc
  {
  }
  static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
 -                                 struct snd_pcm_runtime *runtime, bool on)
 +                                 struct snd_pcm_substream *substream, bool on)
  {
  }
  #endif
@@@ -726,7 -697,7 +726,7 @@@ static int azx_alloc_cmd_io(struct azx 
                                  snd_dma_pci_data(chip->pci),
                                  PAGE_SIZE, &chip->rb);
        if (err < 0) {
 -              snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
 +              snd_printk(KERN_ERR SFX "%s: cannot allocate CORB/RIRB\n", pci_name(chip->pci));
                return err;
        }
        mark_pages_wc(chip, &chip->rb, true);
@@@ -811,27 -782,15 +811,27 @@@ static int azx_corb_send_cmd(struct hda
  {
        struct azx *chip = bus->private_data;
        unsigned int addr = azx_command_addr(val);
 -      unsigned int wp;
 +      unsigned int wp, rp;
  
        spin_lock_irq(&chip->reg_lock);
  
        /* add command to corb */
 -      wp = azx_readb(chip, CORBWP);
 +      wp = azx_readw(chip, CORBWP);
 +      if (wp == 0xffff) {
 +              /* something wrong, controller likely turned to D3 */
 +              spin_unlock_irq(&chip->reg_lock);
 +              return -EIO;
 +      }
        wp++;
        wp %= ICH6_MAX_CORB_ENTRIES;
  
 +      rp = azx_readw(chip, CORBRP);
 +      if (wp == rp) {
 +              /* oops, it's full */
 +              spin_unlock_irq(&chip->reg_lock);
 +              return -EAGAIN;
 +      }
 +
        chip->rirb.cmds[addr]++;
        chip->corb.buf[wp] = cpu_to_le32(val);
        azx_writel(chip, CORBWP, wp);
@@@ -850,12 -809,7 +850,12 @@@ static void azx_update_rirb(struct azx 
        unsigned int addr;
        u32 res, res_ex;
  
 -      wp = azx_readb(chip, RIRBWP);
 +      wp = azx_readw(chip, RIRBWP);
 +      if (wp == 0xffff) {
 +              /* something wrong, controller likely turned to D3 */
 +              return;
 +      }
 +
        if (wp == chip->rirb.wp)
                return;
        chip->rirb.wp = wp;
                        smp_wmb();
                        chip->rirb.cmds[addr]--;
                } else
 -                      snd_printk(KERN_ERR SFX "spurious response %#x:%#x, "
 +                      snd_printk(KERN_ERR SFX "%s: spurious response %#x:%#x, "
                                   "last cmd=%#08x\n",
 +                                 pci_name(chip->pci),
                                   res, res_ex,
                                   chip->last_cmd[addr]);
        }
@@@ -920,9 -873,9 +920,9 @@@ static unsigned int azx_rirb_get_respon
        }
  
        if (!chip->polling_mode && chip->poll_count < 2) {
 -              snd_printdd(SFX "azx_get_response timeout, "
 +              snd_printdd(SFX "%s: azx_get_response timeout, "
                           "polling the codec once: last cmd=0x%08x\n",
 -                         chip->last_cmd[addr]);
 +                         pci_name(chip->pci), chip->last_cmd[addr]);
                do_poll = 1;
                chip->poll_count++;
                goto again;
  
  
        if (!chip->polling_mode) {
 -              snd_printk(KERN_WARNING SFX "azx_get_response timeout, "
 +              snd_printk(KERN_WARNING SFX "%s: azx_get_response timeout, "
                           "switching to polling mode: last cmd=0x%08x\n",
 -                         chip->last_cmd[addr]);
 +                         pci_name(chip->pci), chip->last_cmd[addr]);
                chip->polling_mode = 1;
                goto again;
        }
  
        if (chip->msi) {
 -              snd_printk(KERN_WARNING SFX "No response from codec, "
 +              snd_printk(KERN_WARNING SFX "%s: No response from codec, "
                           "disabling MSI: last cmd=0x%08x\n",
 -                         chip->last_cmd[addr]);
 +                         pci_name(chip->pci), chip->last_cmd[addr]);
                free_irq(chip->irq, chip);
                chip->irq = -1;
                pci_disable_msi(chip->pci);
@@@ -1006,8 -959,8 +1006,8 @@@ static int azx_single_wait_for_response
                udelay(1);
        }
        if (printk_ratelimit())
 -              snd_printd(SFX "get_response timeout: IRS=0x%x\n",
 -                         azx_readw(chip, IRS));
 +              snd_printd(SFX "%s: get_response timeout: IRS=0x%x\n",
 +                         pci_name(chip->pci), azx_readw(chip, IRS));
        chip->rirb.res[addr] = -1;
        return -EIO;
  }
@@@ -1034,8 -987,8 +1034,8 @@@ static int azx_single_send_cmd(struct h
                udelay(1);
        }
        if (printk_ratelimit())
 -              snd_printd(SFX "send_cmd timeout: IRS=0x%x, val=0x%x\n",
 -                         azx_readw(chip, IRS), val);
 +              snd_printd(SFX "%s: send_cmd timeout: IRS=0x%x, val=0x%x\n",
 +                         pci_name(chip->pci), azx_readw(chip, IRS), val);
        return -EIO;
  }
  
@@@ -1085,10 -1038,19 +1085,19 @@@ static unsigned int azx_get_response(st
  static void azx_power_notify(struct hda_bus *bus, bool power_up);
  #endif
  
+ #ifdef CONFIG_SND_HDA_DSP_LOADER
+ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
+                               unsigned int byte_size,
+                               struct snd_dma_buffer *bufp);
+ static void azx_load_dsp_trigger(struct hda_bus *bus, bool start);
+ static void azx_load_dsp_cleanup(struct hda_bus *bus,
+                                struct snd_dma_buffer *dmab);
+ #endif
  /* reset codec link */
  static int azx_reset(struct azx *chip, int full_reset)
  {
 -      int count;
 +      unsigned long timeout;
  
        if (!full_reset)
                goto __skip;
        /* reset controller */
        azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_RESET);
  
 -      count = 50;
 -      while (azx_readb(chip, GCTL) && --count)
 -              msleep(1);
 +      timeout = jiffies + msecs_to_jiffies(100);
 +      while (azx_readb(chip, GCTL) &&
 +                      time_before(jiffies, timeout))
 +              usleep_range(500, 1000);
  
        /* delay for >= 100us for codec PLL to settle per spec
         * Rev 0.9 section 5.5.1
         */
 -      msleep(1);
 +      usleep_range(500, 1000);
  
        /* Bring controller out of reset */
        azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
  
 -      count = 50;
 -      while (!azx_readb(chip, GCTL) && --count)
 -              msleep(1);
 +      timeout = jiffies + msecs_to_jiffies(100);
 +      while (!azx_readb(chip, GCTL) &&
 +                      time_before(jiffies, timeout))
 +              usleep_range(500, 1000);
  
        /* Brent Chartrand said to wait >= 540us for codecs to initialize */
 -      msleep(1);
 +      usleep_range(1000, 1200);
  
        __skip:
        /* check to see if controller is ready */
        if (!azx_readb(chip, GCTL)) {
 -              snd_printd(SFX "azx_reset: controller not ready!\n");
 +              snd_printd(SFX "%s: azx_reset: controller not ready!\n", pci_name(chip->pci));
                return -EBUSY;
        }
  
        /* detect codecs */
        if (!chip->codec_mask) {
                chip->codec_mask = azx_readw(chip, STATESTS);
 -              snd_printdd(SFX "codec_mask = 0x%x\n", chip->codec_mask);
 +              snd_printdd(SFX "%s: codec_mask = 0x%x\n", pci_name(chip->pci), chip->codec_mask);
        }
  
        return 0;
@@@ -1279,7 -1239,7 +1288,7 @@@ static void azx_init_pci(struct azx *ch
         * The PCI register TCSEL is defined in the Intel manuals.
         */
        if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
 -              snd_printdd(SFX "Clearing TCSEL\n");
 +              snd_printdd(SFX "%s: Clearing TCSEL\n", pci_name(chip->pci));
                update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0);
        }
  
         * we need to enable snoop.
         */
        if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) {
 -              snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip));
 +              snd_printdd(SFX "%s: Setting ATI snoop: %d\n", pci_name(chip->pci), azx_snoop(chip));
                update_pci_byte(chip->pci,
                                ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
                                azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
  
        /* For NVIDIA HDA, enable snoop */
        if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) {
 -              snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip));
 +              snd_printdd(SFX "%s: Setting Nvidia snoop: %d\n", pci_name(chip->pci), azx_snoop(chip));
                update_pci_byte(chip->pci,
                                NVIDIA_HDA_TRANSREG_ADDR,
                                0x0f, NVIDIA_HDA_ENABLE_COHBITS);
                        pci_read_config_word(chip->pci,
                                INTEL_SCH_HDA_DEVC, &snoop);
                }
 -              snd_printdd(SFX "SCH snoop: %s\n",
 -                              (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
 +              snd_printdd(SFX "%s: SCH snoop: %s\n",
 +                              pci_name(chip->pci), (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)
                                ? "Disabled" : "Enabled");
          }
  }
@@@ -1408,7 -1368,7 +1417,7 @@@ static irqreturn_t azx_interrupt(int ir
   * set up a BDL entry
   */
  static int setup_bdle(struct azx *chip,
-                     struct snd_pcm_substream *substream,
+                     struct snd_dma_buffer *dmab,
                      struct azx_dev *azx_dev, u32 **bdlp,
                      int ofs, int size, int with_ioc)
  {
                if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES)
                        return -EINVAL;
  
-               addr = snd_pcm_sgbuf_get_addr(substream, ofs);
+               addr = snd_sgbuf_get_addr(dmab, ofs);
                /* program the address field of the BDL entry */
                bdl[0] = cpu_to_le32((u32)addr);
                bdl[1] = cpu_to_le32(upper_32_bits(addr));
                /* program the size field of the BDL entry */
-               chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size);
+               chunk = snd_sgbuf_get_chunk_size(dmab, ofs, size);
                /* one BDLE cannot cross 4K boundary on CTHDA chips */
                if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY) {
                        u32 remain = 0x1000 - (ofs & 0xfff);
@@@ -1481,11 -1441,12 +1490,12 @@@ static int azx_setup_periods(struct az
                                pos_align;
                pos_adj = frames_to_bytes(runtime, pos_adj);
                if (pos_adj >= period_bytes) {
 -                      snd_printk(KERN_WARNING SFX "Too big adjustment %d\n",
 -                                 bdl_pos_adj[chip->dev_index]);
 +                      snd_printk(KERN_WARNING SFX "%s: Too big adjustment %d\n",
 +                                 pci_name(chip->pci), bdl_pos_adj[chip->dev_index]);
                        pos_adj = 0;
                } else {
-                       ofs = setup_bdle(chip, substream, azx_dev,
+                       ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream),
+                                        azx_dev,
                                         &bdl, ofs, pos_adj, true);
                        if (ofs < 0)
                                goto error;
                pos_adj = 0;
        for (i = 0; i < periods; i++) {
                if (i == periods - 1 && pos_adj)
-                       ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
+                       ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream),
+                                        azx_dev, &bdl, ofs,
                                         period_bytes - pos_adj, 0);
                else
-                       ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
+                       ofs = setup_bdle(chip, snd_pcm_get_dma_buf(substream),
+                                        azx_dev, &bdl, ofs,
                                         period_bytes,
                                         !azx_dev->no_period_wakeup);
                if (ofs < 0)
        return 0;
  
   error:
 -      snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n",
 -                 azx_dev->bufsize, period_bytes);
 +      snd_printk(KERN_ERR SFX "%s: Too many BDL entries: buffer=%d, period=%d\n",
 +                 pci_name(chip->pci), azx_dev->bufsize, period_bytes);
        return -EINVAL;
  }
  
@@@ -1604,7 -1567,7 +1616,7 @@@ static int probe_codec(struct azx *chip
        mutex_unlock(&chip->bus->cmd_mutex);
        if (res == -1)
                return -EIO;
 -      snd_printdd(SFX "codec #%d probed OK\n", addr);
 +      snd_printdd(SFX "%s: codec #%d probed OK\n", pci_name(chip->pci), addr);
        return 0;
  }
  
@@@ -1631,33 -1594,17 +1643,33 @@@ static void azx_bus_reset(struct hda_bu
        bus->in_reset = 0;
  }
  
 +static int get_jackpoll_interval(struct azx *chip)
 +{
 +      int i = jackpoll_ms[chip->dev_index];
 +      unsigned int j;
 +      if (i == 0)
 +              return 0;
 +      if (i < 50 || i > 60000)
 +              j = 0;
 +      else
 +              j = msecs_to_jiffies(i);
 +      if (j == 0)
 +              snd_printk(KERN_WARNING SFX
 +                         "jackpoll_ms value out of range: %d\n", i);
 +      return j;
 +}
 +
  /*
   * Codec initialization
   */
  
  /* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
 -static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] DELAYED_INITDATA_MARK = {
 +static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
        [AZX_DRIVER_NVIDIA] = 8,
        [AZX_DRIVER_TERA] = 1,
  };
  
 -static int DELAYED_INIT_MARK azx_codec_create(struct azx *chip, const char *model)
 +static int azx_codec_create(struct azx *chip, const char *model)
  {
        struct hda_bus_template bus_temp;
        int c, codecs, err;
        bus_temp.power_save = &power_save;
        bus_temp.ops.pm_notify = azx_power_notify;
  #endif
+ #ifdef CONFIG_SND_HDA_DSP_LOADER
+       bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare;
+       bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger;
+       bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup;
+ #endif
  
        err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus);
        if (err < 0)
                return err;
  
        if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) {
 -              snd_printd(SFX "Enable delay in RIRB handling\n");
 +              snd_printd(SFX "%s: Enable delay in RIRB handling\n", pci_name(chip->pci));
                chip->bus->needs_damn_long_delay = 1;
        }
  
                                 * that don't exist
                                 */
                                snd_printk(KERN_WARNING SFX
 -                                         "Codec #%d probe error; "
 -                                         "disabling it...\n", c);
 +                                         "%s: Codec #%d probe error; "
 +                                         "disabling it...\n", pci_name(chip->pci), c);
                                chip->codec_mask &= ~(1 << c);
                                /* More badly, accessing to a non-existing
                                 * codec often screws up the controller chip,
         * access works around the stall.  Grrr...
         */
        if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) {
 -              snd_printd(SFX "Enable sync_write for stable communication\n");
 +              snd_printd(SFX "%s: Enable sync_write for stable communication\n",
 +                      pci_name(chip->pci));
                chip->bus->sync_write = 1;
                chip->bus->allow_bus_reset = 1;
        }
                        err = snd_hda_codec_new(chip->bus, c, &codec);
                        if (err < 0)
                                continue;
 +                      codec->jackpoll_interval = get_jackpoll_interval(chip);
                        codec->beep_mode = chip->beep_mode;
                        codecs++;
                }
        }
        if (!codecs) {
 -              snd_printk(KERN_ERR SFX "no codecs initialized\n");
 +              snd_printk(KERN_ERR SFX "%s: no codecs initialized\n", pci_name(chip->pci));
                return -ENXIO;
        }
        return 0;
  }
  
  /* configure each codec instance */
 -static int __devinit azx_codec_configure(struct azx *chip)
 +static int azx_codec_configure(struct azx *chip)
  {
        struct hda_codec *codec;
        list_for_each_entry(codec, &chip->bus->codec_list, list) {
@@@ -1795,64 -1745,6 +1812,64 @@@ static inline void azx_release_device(s
        azx_dev->opened = 0;
  }
  
 +static cycle_t azx_cc_read(const struct cyclecounter *cc)
 +{
 +      struct azx_dev *azx_dev = container_of(cc, struct azx_dev, azx_cc);
 +      struct snd_pcm_substream *substream = azx_dev->substream;
 +      struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 +      struct azx *chip = apcm->chip;
 +
 +      return azx_readl(chip, WALLCLK);
 +}
 +
 +static void azx_timecounter_init(struct snd_pcm_substream *substream,
 +                              bool force, cycle_t last)
 +{
 +      struct azx_dev *azx_dev = get_azx_dev(substream);
 +      struct timecounter *tc = &azx_dev->azx_tc;
 +      struct cyclecounter *cc = &azx_dev->azx_cc;
 +      u64 nsec;
 +
 +      cc->read = azx_cc_read;
 +      cc->mask = CLOCKSOURCE_MASK(32);
 +
 +      /*
 +       * Converting from 24 MHz to ns means applying a 125/3 factor.
 +       * To avoid any saturation issues in intermediate operations,
 +       * the 125 factor is applied first. The division is applied
 +       * last after reading the timecounter value.
 +       * Applying the 1/3 factor as part of the multiplication
 +       * requires at least 20 bits for a decent precision, however
 +       * overflows occur after about 4 hours or less, not a option.
 +       */
 +
 +      cc->mult = 125; /* saturation after 195 years */
 +      cc->shift = 0;
 +
 +      nsec = 0; /* audio time is elapsed time since trigger */
 +      timecounter_init(tc, cc, nsec);
 +      if (force)
 +              /*
 +               * force timecounter to use predefined value,
 +               * used for synchronized starts
 +               */
 +              tc->cycle_last = last;
 +}
 +
 +static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
 +                              struct timespec *ts)
 +{
 +      struct azx_dev *azx_dev = get_azx_dev(substream);
 +      u64 nsec;
 +
 +      nsec = timecounter_read(&azx_dev->azx_tc);
 +      nsec = div_u64(nsec, 3); /* can be optimized */
 +
 +      *ts = ns_to_timespec(nsec);
 +
 +      return 0;
 +}
 +
  static struct snd_pcm_hardware azx_pcm_hw = {
        .info =                 (SNDRV_PCM_INFO_MMAP |
                                 SNDRV_PCM_INFO_INTERLEAVED |
                                 /* SNDRV_PCM_INFO_RESUME |*/
                                 SNDRV_PCM_INFO_PAUSE |
                                 SNDRV_PCM_INFO_SYNC_START |
 +                               SNDRV_PCM_INFO_HAS_WALL_CLOCK |
                                 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
        .formats =              SNDRV_PCM_FMTBIT_S16_LE,
        .rates =                SNDRV_PCM_RATE_48000,
@@@ -1902,12 -1793,6 +1919,12 @@@ static int azx_pcm_open(struct snd_pcm_
        runtime->hw.rates = hinfo->rates;
        snd_pcm_limit_hw_rates(runtime);
        snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
 +
 +      /* avoid wrap-around with wall-clock */
 +      snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
 +                              20,
 +                              178000000);
 +
        if (chip->align_buffer_size)
                /* constrain buffer sizes to be multiple of 128
                   bytes. This is more efficient in terms of memory
                mutex_unlock(&chip->open_mutex);
                return -EINVAL;
        }
 +
 +      /* disable WALLCLOCK timestamps for capture streams
 +         until we figure out how to handle digital inputs */
 +      if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 +              runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK;
 +
        spin_lock_irqsave(&chip->reg_lock, flags);
        azx_dev->substream = substream;
        azx_dev->running = 0;
@@@ -1989,10 -1868,11 +2006,10 @@@ static int azx_pcm_hw_params(struct snd
  {
        struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
        struct azx *chip = apcm->chip;
 -      struct snd_pcm_runtime *runtime = substream->runtime;
        struct azx_dev *azx_dev = get_azx_dev(substream);
        int ret;
  
 -      mark_runtime_wc(chip, azx_dev, runtime, false);
 +      mark_runtime_wc(chip, azx_dev, substream, false);
        azx_dev->bufsize = 0;
        azx_dev->period_bytes = 0;
        azx_dev->format_val = 0;
                                        params_buffer_bytes(hw_params));
        if (ret < 0)
                return ret;
 -      mark_runtime_wc(chip, azx_dev, runtime, true);
 +      mark_runtime_wc(chip, azx_dev, substream, true);
        return ret;
  }
  
@@@ -2009,6 -1889,7 +2026,6 @@@ static int azx_pcm_hw_free(struct snd_p
        struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
        struct azx_dev *azx_dev = get_azx_dev(substream);
        struct azx *chip = apcm->chip;
 -      struct snd_pcm_runtime *runtime = substream->runtime;
        struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
  
        /* reset BDL address */
  
        snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
  
 -      mark_runtime_wc(chip, azx_dev, runtime, false);
 +      mark_runtime_wc(chip, azx_dev, substream, false);
        return snd_pcm_lib_free_pages(substream);
  }
  
@@@ -2046,16 -1927,16 +2063,16 @@@ static int azx_pcm_prepare(struct snd_p
                                                ctls);
        if (!format_val) {
                snd_printk(KERN_ERR SFX
 -                         "invalid format_val, rate=%d, ch=%d, format=%d\n",
 -                         runtime->rate, runtime->channels, runtime->format);
 +                         "%s: invalid format_val, rate=%d, ch=%d, format=%d\n",
 +                         pci_name(chip->pci), runtime->rate, runtime->channels, runtime->format);
                return -EINVAL;
        }
  
        bufsize = snd_pcm_lib_buffer_bytes(substream);
        period_bytes = snd_pcm_lib_period_bytes(substream);
  
 -      snd_printdd(SFX "azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
 -                  bufsize, format_val);
 +      snd_printdd(SFX "%s: azx_pcm_prepare: bufsize=0x%x, format=0x%x\n",
 +                  pci_name(chip->pci), bufsize, format_val);
  
        if (bufsize != azx_dev->bufsize ||
            period_bytes != azx_dev->period_bytes ||
@@@ -2097,9 -1978,6 +2114,9 @@@ static int azx_pcm_trigger(struct snd_p
        int rstart = 0, start, nsync = 0, sbits = 0;
        int nwait, timeout;
  
 +      azx_dev = get_azx_dev(substream);
 +      trace_azx_pcm_trigger(chip, azx_dev, cmd);
 +
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                rstart = 1;
                        azx_readl(chip, OLD_SSYNC) & ~sbits);
        else
                azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
 +      if (start) {
 +              azx_timecounter_init(substream, 0, 0);
 +              if (nsync > 1) {
 +                      cycle_t cycle_last;
 +
 +                      /* same start cycle for master and group */
 +                      azx_dev = get_azx_dev(substream);
 +                      cycle_last = azx_dev->azx_tc.cycle_last;
 +
 +                      snd_pcm_group_for_each_entry(s, substream) {
 +                              if (s->pcm->card != substream->pcm->card)
 +                                      continue;
 +                              azx_timecounter_init(s, 1, cycle_last);
 +                      }
 +              }
 +      }
        spin_unlock(&chip->reg_lock);
        return 0;
  }
@@@ -2272,7 -2134,6 +2289,7 @@@ static unsigned int azx_get_position(st
  {
        unsigned int pos;
        int stream = azx_dev->substream->stream;
 +      int delay = 0;
  
        switch (chip->position_fix[stream]) {
        case POS_FIX_LPIB:
            chip->position_fix[stream] == POS_FIX_POSBUF &&
            (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
                unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
 -              int delay;
                if (stream == SNDRV_PCM_STREAM_PLAYBACK)
                        delay = pos - lpib_pos;
                else
                        delay += azx_dev->bufsize;
                if (delay >= azx_dev->period_bytes) {
                        snd_printk(KERN_WARNING SFX
 -                                 "Unstable LPIB (%d >= %d); "
 +                                 "%s: Unstable LPIB (%d >= %d); "
                                   "disabling LPIB delay counting\n",
 -                                 delay, azx_dev->period_bytes);
 +                                 pci_name(chip->pci), delay, azx_dev->period_bytes);
                        delay = 0;
                        chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
                }
                azx_dev->substream->runtime->delay =
                        bytes_to_frames(azx_dev->substream->runtime, delay);
        }
 +      trace_azx_get_position(chip, azx_dev, pos, delay);
        return pos;
  }
  
@@@ -2349,11 -2210,13 +2366,11 @@@ static int azx_position_ok(struct azx *
  {
        u32 wallclk;
        unsigned int pos;
 -      int stream;
  
        wallclk = azx_readl(chip, WALLCLK) - azx_dev->start_wallclk;
        if (wallclk < (azx_dev->period_wallclk * 2) / 3)
                return -1;      /* bogus (too early) interrupt */
  
 -      stream = azx_dev->substream->stream;
        pos = azx_get_position(chip, azx_dev, true);
  
        if (WARN_ONCE(!azx_dev->period_bytes,
@@@ -2444,7 -2307,6 +2461,7 @@@ static struct snd_pcm_ops azx_pcm_ops 
        .prepare = azx_pcm_prepare,
        .trigger = azx_pcm_trigger,
        .pointer = azx_pcm_pointer,
 +      .wall_clock =  azx_get_wallclock_tstamp,
        .mmap = azx_pcm_mmap,
        .page = snd_pcm_sgbuf_ops_page,
  };
@@@ -2473,8 -2335,7 +2490,8 @@@ azx_attach_pcm_stream(struct hda_bus *b
  
        list_for_each_entry(apcm, &chip->pcm_list, list) {
                if (apcm->pcm->device == pcm_dev) {
 -                      snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
 +                      snd_printk(KERN_ERR SFX "%s: PCM %d already exists\n",
 +                                 pci_name(chip->pci), pcm_dev);
                        return -EBUSY;
                }
        }
  /*
   * mixer creation - all stuff is implemented in hda module
   */
 -static int __devinit azx_mixer_create(struct azx *chip)
 +static int azx_mixer_create(struct azx *chip)
  {
        return snd_hda_build_controls(chip->bus);
  }
  /*
   * initialize SD streams
   */
 -static int __devinit azx_init_stream(struct azx *chip)
 +static int azx_init_stream(struct azx *chip)
  {
        int i;
  
@@@ -2583,15 -2444,99 +2600,102 @@@ static void azx_stop_chip(struct azx *c
        chip->initialized = 0;
  }
  
+ #ifdef CONFIG_SND_HDA_DSP_LOADER
+ /*
+  * DSP loading code (e.g. for CA0132)
+  */
+ /* use the first stream for loading DSP */
+ static struct azx_dev *
+ azx_get_dsp_loader_dev(struct azx *chip)
+ {
+       return &chip->azx_dev[chip->playback_index_offset];
+ }
+ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
+                               unsigned int byte_size,
+                               struct snd_dma_buffer *bufp)
+ {
+       u32 *bdl;
+       struct azx *chip = bus->private_data;
+       struct azx_dev *azx_dev;
+       int err;
+       if (snd_hda_lock_devices(bus))
+               return -EBUSY;
+       err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG,
+                                 snd_dma_pci_data(chip->pci),
+                                 byte_size, bufp);
+       if (err < 0)
+               goto error;
+       azx_dev = azx_get_dsp_loader_dev(chip);
+       azx_dev->bufsize = byte_size;
+       azx_dev->period_bytes = byte_size;
+       azx_dev->format_val = format;
+       azx_stream_reset(chip, azx_dev);
+       /* reset BDL address */
+       azx_sd_writel(azx_dev, SD_BDLPL, 0);
+       azx_sd_writel(azx_dev, SD_BDLPU, 0);
+       azx_dev->frags = 0;
+       bdl = (u32 *)azx_dev->bdl.area;
+       err = setup_bdle(chip, bufp, azx_dev, &bdl, 0, byte_size, 0);
+       if (err < 0)
+               goto error;
+       azx_setup_controller(chip, azx_dev);
+       return azx_dev->stream_tag;
+  error:
+       snd_hda_unlock_devices(bus);
+       return err;
+ }
+ static void azx_load_dsp_trigger(struct hda_bus *bus, bool start)
+ {
+       struct azx *chip = bus->private_data;
+       struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
+       if (start)
+               azx_stream_start(chip, azx_dev);
+       else
+               azx_stream_stop(chip, azx_dev);
+       azx_dev->running = start;
+ }
+ static void azx_load_dsp_cleanup(struct hda_bus *bus,
+                                struct snd_dma_buffer *dmab)
+ {
+       struct azx *chip = bus->private_data;
+       struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
+       /* reset BDL address */
+       azx_sd_writel(azx_dev, SD_BDLPL, 0);
+       azx_sd_writel(azx_dev, SD_BDLPU, 0);
+       azx_sd_writel(azx_dev, SD_CTL, 0);
+       azx_dev->bufsize = 0;
+       azx_dev->period_bytes = 0;
+       azx_dev->format_val = 0;
+       snd_dma_free_pages(dmab);
+       snd_hda_unlock_devices(bus);
+ }
+ #endif /* CONFIG_SND_HDA_DSP_LOADER */
  #ifdef CONFIG_PM
  /* power-up/down the controller */
  static void azx_power_notify(struct hda_bus *bus, bool power_up)
  {
        struct azx *chip = bus->private_data;
  
 +      if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
 +              return;
 +
        if (power_up)
                pm_runtime_get_sync(&chip->pci->dev);
        else
@@@ -2652,9 -2597,6 +2756,9 @@@ static int azx_suspend(struct device *d
        struct azx *chip = card->private_data;
        struct azx_pcm *p;
  
 +      if (chip->disabled)
 +              return 0;
 +
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        azx_clear_irq_pending(chip);
        list_for_each_entry(p, &chip->pcm_list, list)
@@@ -2680,9 -2622,6 +2784,9 @@@ static int azx_resume(struct device *de
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip = card->private_data;
  
 +      if (chip->disabled)
 +              return 0;
 +
        pci_set_power_state(pci, PCI_D0);
        pci_restore_state(pci);
        if (pci_enable_device(pci) < 0) {
@@@ -2713,6 -2652,9 +2817,6 @@@ static int azx_runtime_suspend(struct d
        struct snd_card *card = dev_get_drvdata(dev);
        struct azx *chip = card->private_data;
  
 -      if (!power_save_controller)
 -              return -EAGAIN;
 -
        azx_stop_chip(chip);
        azx_clear_irq_pending(chip);
        return 0;
@@@ -2727,27 -2669,12 +2831,27 @@@ static int azx_runtime_resume(struct de
        azx_init_chip(chip, 1);
        return 0;
  }
 +
 +static int azx_runtime_idle(struct device *dev)
 +{
 +      struct snd_card *card = dev_get_drvdata(dev);
 +      struct azx *chip = card->private_data;
 +
 +      if (power_save_controller > 0)
 +              return 0;
 +      if (!power_save_controller ||
 +          !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME))
 +              return -EBUSY;
 +
 +      return 0;
 +}
 +
  #endif /* CONFIG_PM_RUNTIME */
  
  #ifdef CONFIG_PM
  static const struct dev_pm_ops azx_pm = {
        SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
 -      SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, NULL)
 +      SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
  };
  
  #define AZX_PM_OPS    &azx_pm
@@@ -2779,11 -2706,11 +2883,11 @@@ static void azx_notifier_unregister(str
                unregister_reboot_notifier(&chip->reboot_notifier);
  }
  
 -static int DELAYED_INIT_MARK azx_first_init(struct azx *chip);
 -static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip);
 +static int azx_first_init(struct azx *chip);
 +static int azx_probe_continue(struct azx *chip);
  
  #ifdef SUPPORT_VGA_SWITCHEROO
 -static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci);
 +static struct pci_dev *get_bound_vga(struct pci_dev *pci);
  
  static void azx_vs_set_state(struct pci_dev *pci,
                             enum vga_switcheroo_state state)
        struct azx *chip = card->private_data;
        bool disabled;
  
 +      wait_for_completion(&chip->probe_wait);
        if (chip->init_failed)
                return;
  
                }
        } else {
                snd_printk(KERN_INFO SFX
 -                         "%s %s via VGA-switcheroo\n",
 -                         disabled ? "Disabling" : "Enabling",
 -                         pci_name(chip->pci));
 +                         "%s: %s via VGA-switcheroo\n", pci_name(chip->pci),
 +                         disabled ? "Disabling" : "Enabling");
                if (disabled) {
                        azx_suspend(&pci->dev);
                        chip->disabled = true;
                        if (snd_hda_lock_devices(chip->bus))
 -                              snd_printk(KERN_WARNING SFX
 -                                         "Cannot lock devices!\n");
 +                              snd_printk(KERN_WARNING SFX "%s: Cannot lock devices!\n",
 +                                         pci_name(chip->pci));
                } else {
                        snd_hda_unlock_devices(chip->bus);
                        chip->disabled = false;
@@@ -2837,7 -2764,6 +2941,7 @@@ static bool azx_vs_can_switch(struct pc
        struct snd_card *card = pci_get_drvdata(pci);
        struct azx *chip = card->private_data;
  
 +      wait_for_completion(&chip->probe_wait);
        if (chip->init_failed)
                return false;
        if (chip->disabled || !chip->bus)
        return true;
  }
  
 -static void __devinit init_vga_switcheroo(struct azx *chip)
 +static void init_vga_switcheroo(struct azx *chip)
  {
        struct pci_dev *p = get_bound_vga(chip->pci);
        if (p) {
@@@ -2865,7 -2791,7 +2969,7 @@@ static const struct vga_switcheroo_clie
        .can_switch = azx_vs_can_switch,
  };
  
 -static int __devinit register_vga_switcheroo(struct azx *chip)
 +static int register_vga_switcheroo(struct azx *chip)
  {
        int err;
  
@@@ -2899,9 -2825,6 +3003,9 @@@ static int azx_free(struct azx *chip
  
        azx_notifier_unregister(chip);
  
 +      chip->init_failed = 1; /* to be sure */
 +      complete_all(&chip->probe_wait);
 +
        if (use_vga_switcheroo(chip)) {
                if (chip->disabled && chip->bus)
                        snd_hda_unlock_devices(chip->bus);
@@@ -2960,7 -2883,7 +3064,7 @@@ static int azx_dev_free(struct snd_devi
  /*
   * Check of disabled HDMI controller by vga-switcheroo
   */
 -static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci)
 +static struct pci_dev *get_bound_vga(struct pci_dev *pci)
  {
        struct pci_dev *p;
  
        return NULL;
  }
  
 -static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
 +static bool check_hdmi_disabled(struct pci_dev *pci)
  {
        bool vga_inactive = false;
        struct pci_dev *p = get_bound_vga(pci);
  /*
   * white/black-listing for position_fix
   */
 -static struct snd_pci_quirk position_fix_list[] __devinitdata = {
 +static struct snd_pci_quirk position_fix_list[] = {
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
        {}
  };
  
 -static int __devinit check_position_fix(struct azx *chip, int fix)
 +static int check_position_fix(struct azx *chip, int fix)
  {
        const struct snd_pci_quirk *q;
  
  
        /* Check VIA/ATI HD Audio Controller exist */
        if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) {
 -              snd_printd(SFX "Using VIACOMBO position fix\n");
 +              snd_printd(SFX "%s: Using VIACOMBO position fix\n", pci_name(chip->pci));
                return POS_FIX_VIACOMBO;
        }
        if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
 -              snd_printd(SFX "Using LPIB position fix\n");
 +              snd_printd(SFX "%s: Using LPIB position fix\n", pci_name(chip->pci));
                return POS_FIX_LPIB;
        }
        return POS_FIX_AUTO;
  /*
   * black-lists for probe_mask
   */
 -static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
 +static struct snd_pci_quirk probe_mask_list[] = {
        /* Thinkpad often breaks the controller communication when accessing
         * to the non-working (or non-existing) modem codec slot.
         */
  
  #define AZX_FORCE_CODEC_MASK  0x100
  
 -static void __devinit check_probe_mask(struct azx *chip, int dev)
 +static void check_probe_mask(struct azx *chip, int dev)
  {
        const struct snd_pci_quirk *q;
  
  /*
   * white/black-list for enable_msi
   */
 -static struct snd_pci_quirk msi_black_list[] __devinitdata = {
 +static struct snd_pci_quirk msi_black_list[] = {
        SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
        SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
        SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
        {}
  };
  
 -static void __devinit check_msi(struct azx *chip)
 +static void check_msi(struct azx *chip)
  {
        const struct snd_pci_quirk *q;
  
  }
  
  /* check the snoop mode availability */
 -static void __devinit azx_check_snoop_available(struct azx *chip)
 +static void azx_check_snoop_available(struct azx *chip)
  {
        bool snoop = chip->snoop;
  
        }
  
        if (snoop != chip->snoop) {
 -              snd_printk(KERN_INFO SFX "Force to %s mode\n",
 -                         snoop ? "snoop" : "non-snoop");
 +              snd_printk(KERN_INFO SFX "%s: Force to %s mode\n",
 +                         pci_name(chip->pci), snoop ? "snoop" : "non-snoop");
                chip->snoop = snoop;
        }
  }
  /*
   * constructor
   */
 -static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
 -                              int dev, unsigned int driver_caps,
 -                              struct azx **rchip)
 +static int azx_create(struct snd_card *card, struct pci_dev *pci,
 +                    int dev, unsigned int driver_caps,
 +                    struct azx **rchip)
  {
        static struct snd_device_ops ops = {
                .dev_free = azx_dev_free,
  
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (!chip) {
 -              snd_printk(KERN_ERR SFX "cannot allocate chip\n");
 +              snd_printk(KERN_ERR SFX "%s: Cannot allocate chip\n", pci_name(pci));
                pci_disable_device(pci);
                return -ENOMEM;
        }
        INIT_LIST_HEAD(&chip->pcm_list);
        INIT_LIST_HEAD(&chip->list);
        init_vga_switcheroo(chip);
 +      init_completion(&chip->probe_wait);
  
        chip->position_fix[0] = chip->position_fix[1] =
                check_position_fix(chip, position_fix[dev]);
                }
        }
  
 -      if (check_hdmi_disabled(pci)) {
 -              snd_printk(KERN_INFO SFX "VGA controller for %s is disabled\n",
 -                         pci_name(pci));
 -              if (use_vga_switcheroo(chip)) {
 -                      snd_printk(KERN_INFO SFX "Delaying initialization\n");
 -                      chip->disabled = true;
 -                      goto ok;
 -              }
 -              kfree(chip);
 -              pci_disable_device(pci);
 -              return -ENXIO;
 -      }
 -
 -      err = azx_first_init(chip);
 -      if (err < 0) {
 -              azx_free(chip);
 -              return err;
 -      }
 -
 - ok:
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
        if (err < 0) {
 -              snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
 +              snd_printk(KERN_ERR SFX "%s: Error creating device [card]!\n",
 +                 pci_name(chip->pci));
                azx_free(chip);
                return err;
        }
        return 0;
  }
  
 -static int DELAYED_INIT_MARK azx_first_init(struct azx *chip)
 +static int azx_first_init(struct azx *chip)
  {
        int dev = chip->dev_index;
        struct pci_dev *pci = chip->pci;
        chip->addr = pci_resource_start(pci, 0);
        chip->remap_addr = pci_ioremap_bar(pci, 0);
        if (chip->remap_addr == NULL) {
 -              snd_printk(KERN_ERR SFX "ioremap error\n");
 +              snd_printk(KERN_ERR SFX "%s: ioremap error\n", pci_name(chip->pci));
                return -ENXIO;
        }
  
        synchronize_irq(chip->irq);
  
        gcap = azx_readw(chip, GCAP);
 -      snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
 +      snd_printdd(SFX "%s: chipset global capabilities = 0x%x\n", pci_name(chip->pci), gcap);
  
        /* disable SB600 64bit support for safety */
        if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
  
        /* disable 64bit DMA address on some devices */
        if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
 -              snd_printd(SFX "Disabling 64bit DMA\n");
 +              snd_printd(SFX "%s: Disabling 64bit DMA\n", pci_name(chip->pci));
                gcap &= ~ICH6_GCAP_64OK;
        }
  
        chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
                                GFP_KERNEL);
        if (!chip->azx_dev) {
 -              snd_printk(KERN_ERR SFX "cannot malloc azx_dev\n");
 +              snd_printk(KERN_ERR SFX "%s: cannot malloc azx_dev\n", pci_name(chip->pci));
                return -ENOMEM;
        }
  
                                          snd_dma_pci_data(chip->pci),
                                          BDL_SIZE, &chip->azx_dev[i].bdl);
                if (err < 0) {
 -                      snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
 +                      snd_printk(KERN_ERR SFX "%s: cannot allocate BDL\n", pci_name(chip->pci));
                        return -ENOMEM;
                }
                mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
                                  snd_dma_pci_data(chip->pci),
                                  chip->num_streams * 8, &chip->posbuf);
        if (err < 0) {
 -              snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
 +              snd_printk(KERN_ERR SFX "%s: cannot allocate posbuf\n", pci_name(chip->pci));
                return -ENOMEM;
        }
        mark_pages_wc(chip, &chip->posbuf, true);
  
        /* codec detection */
        if (!chip->codec_mask) {
 -              snd_printk(KERN_ERR SFX "no codecs found!\n");
 +              snd_printk(KERN_ERR SFX "%s: no codecs found!\n", pci_name(chip->pci));
                return -ENODEV;
        }
  
@@@ -3434,8 -3375,7 +3538,8 @@@ static void azx_firmware_cb(const struc
        struct pci_dev *pci = chip->pci;
  
        if (!fw) {
 -              snd_printk(KERN_ERR SFX "Cannot load firmware, aborting\n");
 +              snd_printk(KERN_ERR SFX "%s: Cannot load firmware, aborting\n",
 +                         pci_name(chip->pci));
                goto error;
        }
  
  }
  #endif
  
 -static int __devinit azx_probe(struct pci_dev *pci,
 -                             const struct pci_device_id *pci_id)
 +static int azx_probe(struct pci_dev *pci,
 +                   const struct pci_device_id *pci_id)
  {
        static int dev;
        struct snd_card *card;
  
        err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
        if (err < 0) {
 -              snd_printk(KERN_ERR SFX "Error creating card!\n");
 +              snd_printk(KERN_ERR "hda-intel: Error creating card!\n");
                return err;
        }
  
        if (err < 0)
                goto out_free;
        card->private_data = chip;
 +
 +      pci_set_drvdata(pci, card);
 +
 +      err = register_vga_switcheroo(chip);
 +      if (err < 0) {
 +              snd_printk(KERN_ERR SFX
 +                         "%s: Error registering VGA-switcheroo client\n", pci_name(pci));
 +              goto out_free;
 +      }
 +
 +      if (check_hdmi_disabled(pci)) {
 +              snd_printk(KERN_INFO SFX "%s: VGA controller is disabled\n",
 +                         pci_name(pci));
 +              snd_printk(KERN_INFO SFX "%s: Delaying initialization\n", pci_name(pci));
 +              chip->disabled = true;
 +      }
 +
        probe_now = !chip->disabled;
 +      if (probe_now) {
 +              err = azx_first_init(chip);
 +              if (err < 0)
 +                      goto out_free;
 +      }
  
  #ifdef CONFIG_SND_HDA_PATCH_LOADER
        if (patch[dev] && *patch[dev]) {
 -              snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
 -                         patch[dev]);
 +              snd_printk(KERN_ERR SFX "%s: Applying patch firmware '%s'\n",
 +                         pci_name(pci), patch[dev]);
                err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
                                              &pci->dev, GFP_KERNEL, card,
                                              azx_firmware_cb);
                        goto out_free;
        }
  
 -      pci_set_drvdata(pci, card);
 -
        if (pci_dev_run_wake(pci))
                pm_runtime_put_noidle(&pci->dev);
  
 -      err = register_vga_switcheroo(chip);
 -      if (err < 0) {
 -              snd_printk(KERN_ERR SFX
 -                         "Error registering VGA-switcheroo client\n");
 -              goto out_free;
 -      }
 -
        dev++;
 +      complete_all(&chip->probe_wait);
        return 0;
  
  out_free:
        snd_card_free(card);
 +      pci_set_drvdata(pci, NULL);
        return err;
  }
  
 -static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
 +static int azx_probe_continue(struct azx *chip)
  {
        int dev = chip->dev_index;
        int err;
                                         chip->fw->data);
                if (err < 0)
                        goto out_free;
 +#ifndef CONFIG_PM
                release_firmware(chip->fw); /* no longer needed */
                chip->fw = NULL;
 +#endif
        }
  #endif
        if ((probe_only[dev] & 1) == 0) {
@@@ -3594,7 -3517,7 +3698,7 @@@ out_free
        return err;
  }
  
 -static void __devexit azx_remove(struct pci_dev *pci)
 +static void azx_remove(struct pci_dev *pci)
  {
        struct snd_card *card = pci_get_drvdata(pci);
  
  static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
        /* CPT */
        { PCI_DEVICE(0x8086, 0x1c20),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* PBG */
        { PCI_DEVICE(0x8086, 0x1d20),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE},
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Panther Point */
        { PCI_DEVICE(0x8086, 0x1e20),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Lynx Point */
        { PCI_DEVICE(0x8086, 0x8c20),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Lynx Point-LP */
        { PCI_DEVICE(0x8086, 0x9c20),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Lynx Point-LP */
        { PCI_DEVICE(0x8086, 0x9c21),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
        /* Haswell */
 +      { PCI_DEVICE(0x8086, 0x0a0c),
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
        { PCI_DEVICE(0x8086, 0x0c0c),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
        { PCI_DEVICE(0x8086, 0x0d0c),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
        /* 5 Series/3400 */
        { PCI_DEVICE(0x8086, 0x3b56),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 -      /* SCH */
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH },
 +      /* Poulsbo */
        { PCI_DEVICE(0x8086, 0x811b),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
 +      /* Oaktrail */
        { PCI_DEVICE(0x8086, 0x080a),
 -        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
 -        AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Oaktrail */
 +        .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* ICH */
        { PCI_DEVICE(0x8086, 0x2668),
          .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC |
@@@ -3782,7 -3713,7 +3886,7 @@@ static struct pci_driver azx_driver = 
        .name = KBUILD_MODNAME,
        .id_table = azx_ids,
        .probe = azx_probe,
 -      .remove = __devexit_p(azx_remove),
 +      .remove = azx_remove,
        .driver = {
                .pm = AZX_PM_OPS,
        },