return arizona_dvfs_sysclk_ev(w, kcontrol, event);
 }
 
+static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w,
+                  struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+       struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
+       unsigned int v;
+       int ret;
+
+       switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v);
+               if (ret != 0) {
+                       dev_err(codec->dev,
+                               "Failed to read SYSCLK state: %d\n", ret);
+                       return -EIO;
+               }
+
+               v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT;
+
+               if (v >= 3) {
+                       ret = arizona_dvfs_up(codec, ARIZONA_DVFS_ADSP1_RQ);
+                       if (ret) {
+                               dev_err(codec->dev,
+                                       "Failed to raise DVFS: %d\n", ret);
+                               return ret;
+                       }
+               }
+               break;
+
+       case SND_SOC_DAPM_POST_PMD:
+               ret = arizona_dvfs_down(codec, ARIZONA_DVFS_ADSP1_RQ);
+               if (ret)
+                       dev_warn(codec->dev,
+                                "Failed to lower DVFS: %d\n", ret);
+               break;
+
+       default:
+               break;
+       }
+
+       return wm_adsp2_early_event(w, kcontrol, event);
+}
+
 static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
 {
 ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"),
 ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"),
 
-WM_ADSP2("DSP1", 0),
+WM_ADSP2_E("DSP1", 0, wm5102_adsp_power_ev),
 
 SND_SOC_DAPM_OUTPUT("HPOUT1L"),
 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
        wm5102->core.adsp[0].mem = wm5102_dsp1_regions;
        wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions);
 
-       ret = wm_adsp2_init(&wm5102->core.adsp[0], true);
+       ret = wm_adsp2_init(&wm5102->core.adsp[0]);
        if (ret != 0)
                return ret;
 
 
                wm5110->core.adsp[i].num_mems
                        = ARRAY_SIZE(wm5110_dsp1_regions);
 
-               ret = wm_adsp2_init(&wm5110->core.adsp[i], false);
+               ret = wm_adsp2_init(&wm5110->core.adsp[i]);
                if (ret != 0)
                        return ret;
        }
 
                return;
        }
 
-       if (dsp->dvfs) {
-               ret = regmap_read(dsp->regmap,
-                                 dsp->base + ADSP2_CLOCKING, &val);
-               if (ret != 0) {
-                       adsp_err(dsp, "Failed to read clocking: %d\n", ret);
-                       return;
-               }
-
-               if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
-                       ret = regulator_enable(dsp->dvfs);
-                       if (ret != 0) {
-                               adsp_err(dsp,
-                                        "Failed to enable supply: %d\n",
-                                        ret);
-                               return;
-                       }
-
-                       ret = regulator_set_voltage(dsp->dvfs,
-                                                   1800000,
-                                                   1800000);
-                       if (ret != 0) {
-                               adsp_err(dsp,
-                                        "Failed to raise supply: %d\n",
-                                        ret);
-                               return;
-                       }
-               }
-       }
-
        ret = wm_adsp2_ena(dsp);
        if (ret != 0)
                return;
                regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
                regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
 
-               if (dsp->dvfs) {
-                       ret = regulator_set_voltage(dsp->dvfs, 1200000,
-                                                   1800000);
-                       if (ret != 0)
-                               adsp_warn(dsp,
-                                         "Failed to lower supply: %d\n",
-                                         ret);
-
-                       ret = regulator_disable(dsp->dvfs);
-                       if (ret != 0)
-                               adsp_err(dsp,
-                                        "Failed to enable supply: %d\n",
-                                        ret);
-               }
-
                list_for_each_entry(ctl, &dsp->ctl_list, list)
                        ctl->enabled = 0;
 
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_event);
 
-int wm_adsp2_init(struct wm_adsp *dsp, bool dvfs)
+int wm_adsp2_init(struct wm_adsp *dsp)
 {
        int ret;
 
        INIT_LIST_HEAD(&dsp->ctl_list);
        INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
 
-       if (dvfs) {
-               dsp->dvfs = devm_regulator_get(dsp->dev, "DCVDD");
-               if (IS_ERR(dsp->dvfs)) {
-                       ret = PTR_ERR(dsp->dvfs);
-                       adsp_err(dsp, "Failed to get DCVDD: %d\n", ret);
-                       return ret;
-               }
-
-               ret = regulator_enable(dsp->dvfs);
-               if (ret != 0) {
-                       adsp_err(dsp, "Failed to enable DCVDD: %d\n", ret);
-                       return ret;
-               }
-
-               ret = regulator_set_voltage(dsp->dvfs, 1200000, 1800000);
-               if (ret != 0) {
-                       adsp_err(dsp, "Failed to initialise DVFS: %d\n", ret);
-                       return ret;
-               }
-
-               ret = regulator_disable(dsp->dvfs);
-               if (ret != 0) {
-                       adsp_err(dsp, "Failed to disable DCVDD: %d\n", ret);
-                       return ret;
-               }
-       }
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_init);
 
 
 #include "wmfw.h"
 
-struct regulator;
-
 struct wm_adsp_region {
        int type;
        unsigned int base;
        int fw_ver;
        bool running;
 
-       struct regulator *dvfs;
-
        struct list_head ctl_list;
 
        struct work_struct boot_work;
        SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
                wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
 
-#define WM_ADSP2(wname, num) \
+#define WM_ADSP2_E(wname, num, event_fn) \
 {      .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \
-       .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \
-       .event_flags = SND_SOC_DAPM_PRE_PMU }, \
+       .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
+       .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \
 {      .id = snd_soc_dapm_out_drv, .name = wname, \
        .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \
        .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD }
 
+#define WM_ADSP2(wname, num) \
+       WM_ADSP2_E(wname, num, wm_adsp2_early_event)
+
 extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];
 extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];
 
 int wm_adsp1_init(struct wm_adsp *dsp);
-int wm_adsp2_init(struct wm_adsp *dsp, bool dvfs);
+int wm_adsp2_init(struct wm_adsp *dsp);
 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
                   struct snd_kcontrol *kcontrol, int event);
 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,