Merge branch 'for-linus' into for-next
authorTakashi Iwai <tiwai@suse.de>
Tue, 11 Sep 2012 14:46:36 +0000 (16:46 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 11 Sep 2012 14:46:36 +0000 (16:46 +0200)
To merge HD-audio fixes back to 3.7 development line

1  2 
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_sigmatel.c
sound/usb/endpoint.c

index ff97cf3e8bade9f68594340dc7a5beafd330539a,1c65cc5e3a31101d098d6cdb48a2772d1adc38f9..d71d101e92935721daeea42a26965262aaf997dd
@@@ -94,19 -94,13 +94,19 @@@ int snd_hda_delete_codec_preset(struct 
  }
  EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
  static void hda_power_work(struct work_struct *work);
  static void hda_keep_power_on(struct hda_codec *codec);
  #define hda_codec_is_power_on(codec)  ((codec)->power_on)
 +static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
 +{
 +      if (bus->ops.pm_notify)
 +              bus->ops.pm_notify(bus, power_up);
 +}
  #else
  static inline void hda_keep_power_on(struct hda_codec *codec) {}
  #define hda_codec_is_power_on(codec)  1
 +#define hda_call_pm_notify(bus, state) {}
  #endif
  
  /**
@@@ -814,7 -808,7 +814,7 @@@ find_codec_preset(struct hda_codec *cod
  {
        struct hda_codec_preset_list *tbl;
        const struct hda_codec_preset *preset;
 -      int mod_requested = 0;
 +      unsigned int mod_requested = 0;
  
        if (is_generic_config(codec))
                return NULL; /* use the generic parser */
@@@ -1192,7 -1186,7 +1192,7 @@@ static void snd_hda_codec_free(struct h
                return;
        snd_hda_jack_tbl_clear(codec);
        restore_init_pincfgs(codec);
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
        cancel_delayed_work(&codec->power_work);
        flush_workqueue(codec->bus->workq);
  #endif
        codec->bus->caddr_tbl[codec->addr] = NULL;
        if (codec->patch_ops.free)
                codec->patch_ops.free(codec);
 +#ifdef CONFIG_PM
 +      if (!codec->pm_down_notified) /* cancel leftover refcounts */
 +              hda_call_pm_notify(codec->bus, false);
 +#endif
        module_put(codec->owner);
        free_hda_cache(&codec->amp_cache);
        free_hda_cache(&codec->cmd_cache);
  static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
                                hda_nid_t fg, unsigned int power_state);
  
 -static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
 +static unsigned int hda_set_power_state(struct hda_codec *codec,
                                unsigned int power_state);
  
  /**
@@@ -1239,7 -1229,6 +1239,7 @@@ int /*__devinit*/ snd_hda_codec_new(str
  {
        struct hda_codec *codec;
        char component[31];
 +      hda_nid_t fg;
        int err;
  
        if (snd_BUG_ON(!bus))
        snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
        snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
        spin_lock_init(&codec->power_lock);
        INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
        /* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
         * phase.
         */
        hda_keep_power_on(codec);
 +      hda_call_pm_notify(bus, true);
  #endif
  
        if (codec->bus->modelname) {
                goto error;
        }
  
 -      err = read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg);
 +      fg = codec->afg ? codec->afg : codec->mfg;
 +      err = read_widget_caps(codec, fg);
        if (err < 0) {
                snd_printk(KERN_ERR "hda_codec: cannot malloc\n");
                goto error;
                goto error;
  
        if (!codec->subsystem_id) {
 -              hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
                codec->subsystem_id =
 -                      snd_hda_codec_read(codec, nid, 0,
 +                      snd_hda_codec_read(codec, fg, 0,
                                           AC_VERB_GET_SUBSYSTEM_ID, 0);
        }
  
 -      codec->epss = snd_hda_codec_get_supported_ps(codec,
 -                                      codec->afg ? codec->afg : codec->mfg,
 +#ifdef CONFIG_PM
 +      codec->d3_stop_clk = snd_hda_codec_get_supported_ps(codec, fg,
 +                                      AC_PWRST_CLKSTOP);
 +      if (!codec->d3_stop_clk)
 +              bus->power_keep_link_on = 1;
 +#endif
 +      codec->epss = snd_hda_codec_get_supported_ps(codec, fg,
                                        AC_PWRST_EPSS);
  
        /* power-up all before initialization */
 -      hda_set_power_state(codec,
 -                          codec->afg ? codec->afg : codec->mfg,
 -                          AC_PWRST_D0);
 +      hda_set_power_state(codec, AC_PWRST_D0);
  
        snd_hda_codec_proc_new(codec);
  
@@@ -2350,7 -2335,7 +2350,7 @@@ int snd_hda_codec_reset(struct hda_code
  
        /* OK, let it free */
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
        cancel_delayed_work_sync(&codec->power_work);
        codec->power_on = 0;
        codec->power_transition = 0;
        }
        if (codec->patch_ops.free)
                codec->patch_ops.free(codec);
+       memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
        snd_hda_jack_tbl_clear(codec);
        codec->proc_widget_hook = NULL;
        codec->spec = NULL;
        codec->num_pcms = 0;
        codec->pcm_info = NULL;
        codec->preset = NULL;
-       memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
        codec->slave_dig_outs = NULL;
        codec->spdif_status_reset = 0;
        module_put(codec->owner);
@@@ -3515,6 -3500,20 +3515,6 @@@ void snd_hda_codec_set_power_to_all(str
                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
                                    power_state);
        }
 -
 -      if (power_state == AC_PWRST_D0) {
 -              unsigned long end_time;
 -              int state;
 -              /* wait until the codec reachs to D0 */
 -              end_time = jiffies + msecs_to_jiffies(500);
 -              do {
 -                      state = snd_hda_codec_read(codec, fg, 0,
 -                                                 AC_VERB_GET_POWER_STATE, 0);
 -                      if (state == power_state)
 -                              break;
 -                      msleep(1);
 -              } while (time_after_eq(end_time, jiffies));
 -      }
  }
  EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
  
@@@ -3535,40 -3534,18 +3535,40 @@@ static bool snd_hda_codec_get_supported
  }
  
  /*
 - * set power state of the codec
 + * wait until the state is reached, returns the current state
   */
 -static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
 -                              unsigned int power_state)
 +static unsigned int hda_sync_power_state(struct hda_codec *codec,
 +                                       hda_nid_t fg,
 +                                       unsigned int power_state)
  {
 -      int count;
 -      unsigned int state;
 +      unsigned long end_time = jiffies + msecs_to_jiffies(500);
 +      unsigned int state, actual_state;
  
 -      if (codec->patch_ops.set_power_state) {
 -              codec->patch_ops.set_power_state(codec, fg, power_state);
 -              return;
 +      for (;;) {
 +              state = snd_hda_codec_read(codec, fg, 0,
 +                                         AC_VERB_GET_POWER_STATE, 0);
 +              if (state & AC_PWRST_ERROR)
 +                      break;
 +              actual_state = (state >> 4) & 0x0f;
 +              if (actual_state == power_state)
 +                      break;
 +              if (time_after_eq(jiffies, end_time))
 +                      break;
 +              /* wait until the codec reachs to the target state */
 +              msleep(1);
        }
 +      return state;
 +}
 +
 +/*
 + * set power state of the codec, and return the power state
 + */
 +static unsigned int hda_set_power_state(struct hda_codec *codec,
 +                                      unsigned int power_state)
 +{
 +      hda_nid_t fg = codec->afg ? codec->afg : codec->mfg;
 +      int count;
 +      unsigned int state;
  
        /* this delay seems necessary to avoid click noise at power-down */
        if (power_state == AC_PWRST_D3) {
  
        /* repeat power states setting at most 10 times*/
        for (count = 0; count < 10; count++) {
 -              snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
 -                                  power_state);
 -              snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
 -              state = snd_hda_codec_read(codec, fg, 0,
 -                                         AC_VERB_GET_POWER_STATE, 0);
 +              if (codec->patch_ops.set_power_state)
 +                      codec->patch_ops.set_power_state(codec, fg,
 +                                                       power_state);
 +              else {
 +                      snd_hda_codec_read(codec, fg, 0,
 +                                         AC_VERB_SET_POWER_STATE,
 +                                         power_state);
 +                      snd_hda_codec_set_power_to_all(codec, fg, power_state,
 +                                                     true);
 +              }
 +              state = hda_sync_power_state(codec, fg, power_state);
                if (!(state & AC_PWRST_ERROR))
                        break;
        }
 +
 +      return state;
  }
  
  #ifdef CONFIG_SND_HDA_HWDEP
@@@ -3610,16 -3579,16 +3610,16 @@@ static inline void hda_exec_init_verbs(
  #ifdef CONFIG_PM
  /*
   * call suspend and power-down; used both from PM and power-save
 + * this function returns the power state in the end
   */
 -static void hda_call_codec_suspend(struct hda_codec *codec)
 +static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
  {
 +      unsigned int state;
 +
        if (codec->patch_ops.suspend)
                codec->patch_ops.suspend(codec);
        hda_cleanup_all_streams(codec);
 -      hda_set_power_state(codec,
 -                          codec->afg ? codec->afg : codec->mfg,
 -                          AC_PWRST_D3);
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +      state = hda_set_power_state(codec, AC_PWRST_D3);
        cancel_delayed_work(&codec->power_work);
        spin_lock(&codec->power_lock);
        snd_hda_update_power_acct(codec);
        codec->power_transition = 0;
        codec->power_jiffies = jiffies;
        spin_unlock(&codec->power_lock);
 -#endif
 +      return state;
  }
  
  /*
@@@ -3640,7 -3609,9 +3640,7 @@@ static void hda_call_codec_resume(struc
         * in the resume / power-save sequence
         */
        hda_keep_power_on(codec);
 -      hda_set_power_state(codec,
 -                          codec->afg ? codec->afg : codec->mfg,
 -                          AC_PWRST_D0);
 +      hda_set_power_state(codec, AC_PWRST_D0);
        restore_pincfgs(codec); /* restore all current pin configs */
        restore_shutup_pins(codec);
        hda_exec_init_verbs(codec);
                snd_hda_codec_resume_amp(codec);
                snd_hda_codec_resume_cache(codec);
        }
 +      snd_hda_jack_report_sync(codec);
        snd_hda_power_down(codec); /* flag down before returning */
  }
  #endif /* CONFIG_PM */
@@@ -3699,7 -3669,6 +3699,7 @@@ int snd_hda_codec_build_controls(struc
                err = codec->patch_ops.build_controls(codec);
        if (err < 0)
                return err;
 +      snd_hda_jack_report_sync(codec); /* call at the last init point */
        return 0;
  }
  
@@@ -4242,7 -4211,7 +4242,7 @@@ int snd_hda_codec_build_pcms(struct hda
   *
   * This function returns 0 if successful, or a negative error code.
   */
 -int __devinit snd_hda_build_pcms(struct hda_bus *bus)
 +int snd_hda_build_pcms(struct hda_bus *bus)
  {
        struct hda_codec *codec;
  
@@@ -4422,13 -4391,12 +4422,13 @@@ int snd_hda_add_new_ctls(struct hda_cod
  }
  EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
  static void hda_power_work(struct work_struct *work)
  {
        struct hda_codec *codec =
                container_of(work, struct hda_codec, power_work.work);
        struct hda_bus *bus = codec->bus;
 +      unsigned int state;
  
        spin_lock(&codec->power_lock);
        if (codec->power_transition > 0) { /* during power-up sequence? */
        }
        spin_unlock(&codec->power_lock);
  
 -      hda_call_codec_suspend(codec);
 -      if (bus->ops.pm_notify)
 -              bus->ops.pm_notify(bus);
 +      state = hda_call_codec_suspend(codec);
 +      codec->pm_down_notified = 0;
 +      if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) {
 +              codec->pm_down_notified = 1;
 +              hda_call_pm_notify(bus, false);
 +      }
  }
  
  static void hda_keep_power_on(struct hda_codec *codec)
@@@ -4473,16 -4438,19 +4473,16 @@@ void snd_hda_update_power_acct(struct h
  /* Transition to powered up, if wait_power_down then wait for a pending
   * transition to D3 to complete. A pending D3 transition is indicated
   * with power_transition == -1. */
 +/* call this with codec->power_lock held! */
  static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
  {
        struct hda_bus *bus = codec->bus;
  
 -      spin_lock(&codec->power_lock);
 -      codec->power_count++;
        /* Return if power_on or transitioning to power_on, unless currently
         * powering down. */
        if ((codec->power_on || codec->power_transition > 0) &&
 -          !(wait_power_down && codec->power_transition < 0)) {
 -              spin_unlock(&codec->power_lock);
 +          !(wait_power_down && codec->power_transition < 0))
                return;
 -      }
        spin_unlock(&codec->power_lock);
  
        cancel_delayed_work_sync(&codec->power_work);
        if (codec->power_on) {
                if (codec->power_transition < 0)
                        codec->power_transition = 0;
 -              spin_unlock(&codec->power_lock);
                return;
        }
 +
        trace_hda_power_up(codec);
        snd_hda_update_power_acct(codec);
        codec->power_on = 1;
        codec->power_transition = 1; /* avoid reentrance */
        spin_unlock(&codec->power_lock);
  
 -      if (bus->ops.pm_notify)
 -              bus->ops.pm_notify(bus);
 +      if (codec->pm_down_notified) {
 +              codec->pm_down_notified = 0;
 +              hda_call_pm_notify(bus, true);
 +      }
 +
        hda_call_codec_resume(codec);
  
        spin_lock(&codec->power_lock);
        codec->power_transition = 0;
 -      spin_unlock(&codec->power_lock);
 -}
 -
 -/**
 - * snd_hda_power_up - Power-up the codec
 - * @codec: HD-audio codec
 - *
 - * Increment the power-up counter and power up the hardware really when
 - * not turned on yet.
 - */
 -void snd_hda_power_up(struct hda_codec *codec)
 -{
 -      __snd_hda_power_up(codec, false);
 -}
 -EXPORT_SYMBOL_HDA(snd_hda_power_up);
 -
 -/**
 - * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
 - *   D3 transition to complete.  This differs from snd_hda_power_up() when
 - *   power_transition == -1.  snd_hda_power_up sees this case as a nop,
 - *   snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
 - *   back up.
 - * @codec: HD-audio codec
 - *
 - * Cancel any power down operation hapenning on the work queue, then power up.
 - */
 -void snd_hda_power_up_d3wait(struct hda_codec *codec)
 -{
 -      /* This will cancel and wait for pending power_work to complete. */
 -      __snd_hda_power_up(codec, true);
  }
 -EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait);
  
  #define power_save(codec)     \
        ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
  
 -/**
 - * snd_hda_power_down - Power-down the codec
 - * @codec: HD-audio codec
 - *
 - * Decrement the power-up counter and schedules the power-off work if
 - * the counter rearches to zero.
 - */
 -void snd_hda_power_down(struct hda_codec *codec)
 +/* Transition to powered down */
 +static void __snd_hda_power_down(struct hda_codec *codec)
  {
 -      spin_lock(&codec->power_lock);
 -      --codec->power_count;
 -      if (!codec->power_on || codec->power_count || codec->power_transition) {
 -              spin_unlock(&codec->power_lock);
 +      if (!codec->power_on || codec->power_count || codec->power_transition)
                return;
 -      }
 +
        if (power_save(codec)) {
                codec->power_transition = -1; /* avoid reentrance */
                queue_delayed_work(codec->bus->workq, &codec->power_work,
                                msecs_to_jiffies(power_save(codec) * 1000));
        }
 +}
 +
 +/**
 + * snd_hda_power_save - Power-up/down/sync the codec
 + * @codec: HD-audio codec
 + * @delta: the counter delta to change
 + *
 + * Change the power-up counter via @delta, and power up or down the hardware
 + * appropriately.  For the power-down, queue to the delayed action.
 + * Passing zero to @delta means to synchronize the power state.
 + */
 +void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait)
 +{
 +      spin_lock(&codec->power_lock);
 +      codec->power_count += delta;
 +      trace_hda_power_count(codec);
 +      if (delta > 0)
 +              __snd_hda_power_up(codec, d3wait);
 +      else
 +              __snd_hda_power_down(codec);
        spin_unlock(&codec->power_lock);
  }
 -EXPORT_SYMBOL_HDA(snd_hda_power_down);
 +EXPORT_SYMBOL_HDA(snd_hda_power_save);
  
  /**
   * snd_hda_check_amp_list_power - Check the amp list and update the power
@@@ -5102,6 -5087,9 +5102,6 @@@ EXPORT_SYMBOL_HDA(snd_hda_suspend)
   * @bus: the HDA bus
   *
   * Returns 0 if successful.
 - *
 - * This function is defined only when POWER_SAVE isn't set.
 - * In the power-save mode, the codec is resumed dynamically.
   */
  int snd_hda_resume(struct hda_bus *bus)
  {
index 76ec2421fae19655a4558870f93617a0d480b759,228cdf93fa29692685107ff88fb0b3ddc6be0106..e1a12c754de98b63d0b4cd1f85494e3a6ee1fd64
@@@ -46,7 -46,6 +46,7 @@@
  #include <linux/mutex.h>
  #include <linux/reboot.h>
  #include <linux/io.h>
 +#include <linux/pm_runtime.h>
  #ifdef CONFIG_X86
  /* for snoop control */
  #include <asm/pgtable.h>
@@@ -56,7 -55,6 +56,7 @@@
  #include <sound/initval.h>
  #include <linux/vgaarb.h>
  #include <linux/vga_switcheroo.h>
 +#include <linux/firmware.h>
  #include "hda_codec.h"
  
  
@@@ -110,16 -108,9 +110,16 @@@ MODULE_PARM_DESC(beep_mode, "Select HD
                            "(0=off, 1=on) (default=1).");
  #endif
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
 +static int param_set_xint(const char *val, const struct kernel_param *kp);
 +static struct kernel_param_ops param_ops_xint = {
 +      .set = param_set_xint,
 +      .get = param_get_int,
 +};
 +#define param_check_xint param_check_int
 +
  static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
 -module_param(power_save, int, 0644);
 +module_param(power_save, xint, 0644);
  MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
                 "(in second, 0 = disable).");
  
  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.");
 -#endif
 +#endif /* CONFIG_PM */
  
  static int align_buffer_size = -1;
  module_param(align_buffer_size, bint, 0644);
@@@ -415,7 -406,6 +415,7 @@@ struct azx_dev 
         */
        unsigned int insufficient :1;
        unsigned int wc_marked:1;
 +      unsigned int no_period_wakeup:1;
  };
  
  /* CORB/RIRB */
@@@ -481,10 -471,6 +481,10 @@@ struct azx 
        struct snd_dma_buffer rb;
        struct snd_dma_buffer posbuf;
  
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +      const struct firmware *fw;
 +#endif
 +
        /* flags */
        int position_fix[2]; /* for both playback/capture streams */
        int poll_count;
  
        /* reboot notifier (for mysterious hangup problem at power-down) */
        struct notifier_block reboot_notifier;
 +
 +      /* card list (for power_save trigger) */
 +      struct list_head list;
  };
  
  /* driver types */
@@@ -577,17 -560,13 +577,17 @@@ enum 
   * VGA-switcher support
   */
  #ifdef SUPPORT_VGA_SWITCHEROO
 +#define use_vga_switcheroo(chip)      ((chip)->use_vga_switcheroo)
 +#else
 +#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
 -#define use_vga_switcheroo(chip)      ((chip)->use_vga_switcheroo)
  #else
  #define DELAYED_INIT_MARK     __devinit
  #define DELAYED_INITDATA_MARK __devinitdata
 -#define use_vga_switcheroo(chip)      0
  #endif
  
  static char *driver_short_names[] DELAYED_INITDATA_MARK = {
@@@ -1033,8 -1012,8 +1033,8 @@@ static unsigned int azx_get_response(st
                return azx_rirb_get_response(bus, addr);
  }
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 -static void azx_power_notify(struct hda_bus *bus);
 +#ifdef CONFIG_PM
 +static void azx_power_notify(struct hda_bus *bus, bool power_up);
  #endif
  
  /* reset codec link */
@@@ -1290,11 -1269,6 +1290,11 @@@ static irqreturn_t azx_interrupt(int ir
        u8 sd_status;
        int i, ok;
  
 +#ifdef CONFIG_PM_RUNTIME
 +      if (chip->pci->dev.power.runtime_status != RPM_ACTIVE)
 +              return IRQ_NONE;
 +#endif
 +
        spin_lock(&chip->reg_lock);
  
        if (chip->disabled) {
@@@ -1420,7 -1394,7 +1420,7 @@@ static int azx_setup_periods(struct az
        ofs = 0;
        azx_dev->frags = 0;
        pos_adj = bdl_pos_adj[chip->dev_index];
 -      if (pos_adj > 0) {
 +      if (!azx_dev->no_period_wakeup && pos_adj > 0) {
                struct snd_pcm_runtime *runtime = substream->runtime;
                int pos_align = pos_adj;
                pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
                        pos_adj = 0;
                } else {
                        ofs = setup_bdle(chip, substream, azx_dev,
 -                                       &bdl, ofs, pos_adj,
 -                                       !substream->runtime->no_period_wakeup);
 +                                       &bdl, ofs, pos_adj, true);
                        if (ofs < 0)
                                goto error;
                }
                else
                        ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
                                         period_bytes,
 -                                       !substream->runtime->no_period_wakeup);
 +                                       !azx_dev->no_period_wakeup);
                if (ofs < 0)
                        goto error;
        }
@@@ -1605,7 -1580,7 +1605,7 @@@ static int DELAYED_INIT_MARK azx_codec_
        bus_temp.ops.get_response = azx_get_response;
        bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
        bus_temp.ops.bus_reset = azx_bus_reset;
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
        bus_temp.power_save = &power_save;
        bus_temp.ops.pm_notify = azx_power_notify;
  #endif
@@@ -1922,12 -1897,10 +1922,12 @@@ static int azx_pcm_prepare(struct snd_p
  
        if (bufsize != azx_dev->bufsize ||
            period_bytes != azx_dev->period_bytes ||
 -          format_val != azx_dev->format_val) {
 +          format_val != azx_dev->format_val ||
 +          runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
                azx_dev->bufsize = bufsize;
                azx_dev->period_bytes = period_bytes;
                azx_dev->format_val = format_val;
 +              azx_dev->no_period_wakeup = runtime->no_period_wakeup;
                err = azx_setup_periods(chip, substream, azx_dev);
                if (err < 0)
                        return err;
@@@ -2406,65 -2379,33 +2406,65 @@@ static void azx_stop_chip(struct azx *c
        chip->initialized = 0;
  }
  
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
  /* power-up/down the controller */
 -static void azx_power_notify(struct hda_bus *bus)
 +static void azx_power_notify(struct hda_bus *bus, bool power_up)
  {
        struct azx *chip = bus->private_data;
 +
 +      if (power_up)
 +              pm_runtime_get_sync(&chip->pci->dev);
 +      else
 +              pm_runtime_put_sync(&chip->pci->dev);
 +}
 +
 +static DEFINE_MUTEX(card_list_lock);
 +static LIST_HEAD(card_list);
 +
 +static void azx_add_card_list(struct azx *chip)
 +{
 +      mutex_lock(&card_list_lock);
 +      list_add(&chip->list, &card_list);
 +      mutex_unlock(&card_list_lock);
 +}
 +
 +static void azx_del_card_list(struct azx *chip)
 +{
 +      mutex_lock(&card_list_lock);
 +      list_del_init(&chip->list);
 +      mutex_unlock(&card_list_lock);
 +}
 +
 +/* trigger power-save check at writing parameter */
 +static int param_set_xint(const char *val, const struct kernel_param *kp)
 +{
 +      struct azx *chip;
        struct hda_codec *c;
 -      int power_on = 0;
 +      int prev = power_save;
 +      int ret = param_set_int(val, kp);
  
 -      list_for_each_entry(c, &bus->codec_list, list) {
 -              if (c->power_on) {
 -                      power_on = 1;
 -                      break;
 -              }
 +      if (ret || prev == power_save)
 +              return ret;
 +
 +      mutex_lock(&card_list_lock);
 +      list_for_each_entry(chip, &card_list, list) {
 +              if (!chip->bus || chip->disabled)
 +                      continue;
 +              list_for_each_entry(c, &chip->bus->codec_list, list)
 +                      snd_hda_power_sync(c);
        }
 -      if (power_on)
 -              azx_init_chip(chip, 1);
 -      else if (chip->running && power_save_controller &&
 -               !bus->power_keep_link_on)
 -              azx_stop_chip(chip);
 +      mutex_unlock(&card_list_lock);
 +      return 0;
  }
 -#endif /* CONFIG_SND_HDA_POWER_SAVE */
 +#else
 +#define azx_add_card_list(chip) /* NOP */
 +#define azx_del_card_list(chip) /* NOP */
 +#endif /* CONFIG_PM */
  
 -#ifdef CONFIG_PM
 +#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
  /*
   * power management
   */
 -
  static int azx_suspend(struct device *dev)
  {
        struct pci_dev *pci = to_pci_dev(dev);
@@@ -2519,41 -2460,11 +2519,41 @@@ static int azx_resume(struct device *de
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
        return 0;
  }
 -static SIMPLE_DEV_PM_OPS(azx_pm, azx_suspend, azx_resume);
 +#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
 +
 +#ifdef CONFIG_PM_RUNTIME
 +static int azx_runtime_suspend(struct device *dev)
 +{
 +      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;
 +}
 +
 +static int azx_runtime_resume(struct device *dev)
 +{
 +      struct snd_card *card = dev_get_drvdata(dev);
 +      struct azx *chip = card->private_data;
 +
 +      azx_init_pci(chip);
 +      azx_init_chip(chip, 1);
 +      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)
 +};
 +
  #define AZX_PM_OPS    &azx_pm
  #else
 -#define azx_suspend(dev)
 -#define azx_resume(dev)
  #define AZX_PM_OPS    NULL
  #endif /* CONFIG_PM */
  
@@@ -2688,8 -2599,6 +2688,8 @@@ static int azx_free(struct azx *chip
  {
        int i;
  
 +      azx_del_card_list(chip);
 +
        azx_notifier_unregister(chip);
  
        if (use_vga_switcheroo(chip)) {
                pci_release_regions(chip->pci);
        pci_disable_device(chip->pci);
        kfree(chip->azx_dev);
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +      if (chip->fw)
 +              release_firmware(chip->fw);
 +#endif
        kfree(chip);
  
        return 0;
@@@ -2796,6 -2701,7 +2796,7 @@@ static struct snd_pci_quirk position_fi
        SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1043, 0x1b43, "ASUS K53E", POS_FIX_POSBUF),
        SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
@@@ -2997,7 -2903,6 +2998,7 @@@ static int __devinit azx_create(struct 
        chip->dev_index = dev;
        INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
        INIT_LIST_HEAD(&chip->pcm_list);
 +      INIT_LIST_HEAD(&chip->list);
        init_vga_switcheroo(chip);
  
        chip->position_fix[0] = chip->position_fix[1] =
@@@ -3232,7 -3137,7 +3233,7 @@@ static int DELAYED_INIT_MARK azx_first_
  
  static void power_down_all_codecs(struct azx *chip)
  {
 -#ifdef CONFIG_SND_HDA_POWER_SAVE
 +#ifdef CONFIG_PM
        /* The codecs were powered up in snd_hda_codec_new().
         * Now all initialization done, so turn them down if possible
         */
  #endif
  }
  
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +/* callback from request_firmware_nowait() */
 +static void azx_firmware_cb(const struct firmware *fw, void *context)
 +{
 +      struct snd_card *card = context;
 +      struct azx *chip = card->private_data;
 +      struct pci_dev *pci = chip->pci;
 +
 +      if (!fw) {
 +              snd_printk(KERN_ERR SFX "Cannot load firmware, aborting\n");
 +              goto error;
 +      }
 +
 +      chip->fw = fw;
 +      if (!chip->disabled) {
 +              /* continue probing */
 +              if (azx_probe_continue(chip))
 +                      goto error;
 +      }
 +      return; /* OK */
 +
 + error:
 +      snd_card_free(card);
 +      pci_set_drvdata(pci, NULL);
 +}
 +#endif
 +
  static int __devinit azx_probe(struct pci_dev *pci,
                               const struct pci_device_id *pci_id)
  {
        static int dev;
        struct snd_card *card;
        struct azx *chip;
 +      bool probe_now;
        int err;
  
        if (dev >= SNDRV_CARDS)
                return err;
        }
  
 -      /* set this here since it's referred in snd_hda_load_patch() */
        snd_card_set_dev(card, &pci->dev);
  
        err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
        if (err < 0)
                goto out_free;
        card->private_data = chip;
 +      probe_now = !chip->disabled;
  
 -      if (!chip->disabled) {
 +#ifdef CONFIG_SND_HDA_PATCH_LOADER
 +      if (patch[dev] && *patch[dev]) {
 +              snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
 +                         patch[dev]);
 +              err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
 +                                            &pci->dev, GFP_KERNEL, card,
 +                                            azx_firmware_cb);
 +              if (err < 0)
 +                      goto out_free;
 +              probe_now = false; /* continued in azx_firmware_cb() */
 +      }
 +#endif /* CONFIG_SND_HDA_PATCH_LOADER */
 +
 +      if (probe_now) {
                err = azx_probe_continue(chip);
                if (err < 0)
                        goto out_free;
  
        pci_set_drvdata(pci, card);
  
 +      if (pci_dev_run_wake(pci))
 +              pm_runtime_put_noidle(&pci->dev);
 +
        dev++;
        return 0;
  
@@@ -3346,13 -3207,12 +3347,13 @@@ static int DELAYED_INIT_MARK azx_probe_
        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]);
 -              err = snd_hda_load_patch(chip->bus, patch[dev]);
 +      if (chip->fw) {
 +              err = snd_hda_load_patch(chip->bus, chip->fw->size,
 +                                       chip->fw->data);
                if (err < 0)
                        goto out_free;
 +              release_firmware(chip->fw); /* no longer needed */
 +              chip->fw = NULL;
        }
  #endif
        if ((probe_only[dev] & 1) == 0) {
        chip->running = 1;
        power_down_all_codecs(chip);
        azx_notifier_register(chip);
 +      azx_add_card_list(chip);
  
        return 0;
  
@@@ -3390,10 -3249,6 +3391,10 @@@ out_free
  static void __devexit azx_remove(struct pci_dev *pci)
  {
        struct snd_card *card = pci_get_drvdata(pci);
 +
 +      if (pci_dev_run_wake(pci))
 +              pm_runtime_get_noresume(&pci->dev);
 +
        if (card)
                snd_card_free(card);
        pci_set_drvdata(pci, NULL);
index c16d0f822b5bec9341a9c162950c333f373f97b1,3d4722f0a1cacba8fc9a923f22dbf767433dbd6c..eef9c6cad25db835e3afbe47a6000d42532bf09c
@@@ -1075,7 -1075,7 +1075,7 @@@ static struct snd_kcontrol_new stac_smu
  
  static const char * const slave_pfxs[] = {
        "Front", "Surround", "Center", "LFE", "Side",
-       "Headphone", "Speaker", "IEC958",
+       "Headphone", "Speaker", "IEC958", "PCM",
        NULL
  };
  
@@@ -3226,12 -3226,9 +3226,12 @@@ static int create_multi_out_ctls(struc
                                idx = i;
                                break;
                        case AUTO_PIN_SPEAKER_OUT:
 -                              name = "Speaker";
 -                              idx = i;
 -                              break;
 +                              if (num_outs <= 1) {
 +                                      name = "Speaker";
 +                                      idx = i;
 +                                      break;
 +                              }
 +                              /* Fall through in case of multi speaker outs */
                        default:
                                name = chname[i];
                                idx = 0;
@@@ -4421,6 -4418,8 +4421,6 @@@ static int stac92xx_init(struct hda_cod
                stac_toggle_power_map(codec, nid, 0);
        }
  
 -      snd_hda_jack_report_sync(codec);
 -
        /* sync mute LED */
        if (spec->gpio_led) {
                if (spec->vmaster_mute.hook)
diff --combined sound/usb/endpoint.c
index 94b08a6087a3c1f265142a31f0855a5937aa1427,d6e2bb49c59c52f01288925fa52461eea510e78a..a83a18dbac254dcc13a456d7bdb2b331930126f3
@@@ -31,7 -31,6 +31,7 @@@
  #include "card.h"
  #include "endpoint.h"
  #include "pcm.h"
 +#include "quirks.h"
  
  #define EP_FLAG_ACTIVATED     0
  #define EP_FLAG_RUNNING               1
@@@ -142,7 -141,7 +142,7 @@@ int snd_usb_endpoint_implict_feedback_s
   *
   * For implicit feedback, next_packet_size() is unused.
   */
static int next_packet_size(struct snd_usb_endpoint *ep)
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)
  {
        unsigned long flags;
        int ret;
@@@ -171,11 -170,6 +171,11 @@@ static void retire_inbound_urb(struct s
  {
        struct urb *urb = urb_ctx->urb;
  
 +      if (unlikely(ep->skip_packets > 0)) {
 +              ep->skip_packets--;
 +              return;
 +      }
 +
        if (ep->sync_slave)
                snd_usb_handle_sync_urb(ep->sync_slave, ep, urb);
  
                ep->retire_data_urb(ep->data_subs, urb);
  }
  
- static void prepare_outbound_urb_sizes(struct snd_usb_endpoint *ep,
-                                      struct snd_urb_ctx *ctx)
- {
-       int i;
-       for (i = 0; i < ctx->packets; ++i)
-               ctx->packet_size[i] = next_packet_size(ep);
- }
  /*
   * Prepare a PLAYBACK urb for submission to the bus.
   */
@@@ -376,7 -361,6 +367,6 @@@ static void snd_complete_urb(struct ur
                        goto exit_clear;
                }
  
-               prepare_outbound_urb_sizes(ep, ctx);
                prepare_outbound_urb(ep, ctx);
        } else {
                retire_inbound_urb(ep, ctx);
@@@ -805,7 -789,9 +795,9 @@@ int snd_usb_endpoint_set_params(struct 
  /**
   * snd_usb_endpoint_start: start an snd_usb_endpoint
   *
-  * @ep: the endpoint to start
+  * @ep:               the endpoint to start
+  * @can_sleep:        flag indicating whether the operation is executed in
+  *            non-atomic context
   *
   * A call to this function will increment the use count of the endpoint.
   * In case it is not already running, the URBs for this endpoint will be
   *
   * Returns an error if the URB submission failed, 0 in all other cases.
   */
- int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
+ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
  {
        int err;
        unsigned int i;
        if (++ep->use_count != 1)
                return 0;
  
+       /* just to be sure */
+       deactivate_urbs(ep, 0, can_sleep);
+       if (can_sleep)
+               wait_clear_urbs(ep);
        ep->active_mask = 0;
        ep->unlink_mask = 0;
        ep->phase = 0;
  
 +      snd_usb_endpoint_start_quirk(ep);
 +
        /*
         * If this endpoint has a data endpoint as implicit feedback source,
         * don't start the urbs here. Instead, mark them all as available,
                        goto __error;
  
                if (usb_pipeout(ep->pipe)) {
-                       prepare_outbound_urb_sizes(ep, urb->context);
                        prepare_outbound_urb(ep, urb->context);
                } else {
                        prepare_inbound_urb(ep, urb->context);