diff --git a/include/sound/soc.h b/include/sound/soc.h
index fbe4c27..830b211 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -21,7 +21,7 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
-#define SND_SOC_VERSION "0.9rc5"
+#define SND_SOC_VERSION "0.9rc6"
 
 /*
  * Convenience kcontrol builders
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d3df3e8..bab1d82 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -422,12 +422,11 @@ static int wm8731_resume(struct platform
 
 	/* Sync reg_cache with the hardware */
 	for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
-		if (i == WM8731_RESET)
-			continue;
 		data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
 		data[1] = cache[i] & 0x00ff;
 		codec->hw_write(codec->control_data, data, 2);
 	}
+	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
 	wm8731_dpm_event(codec, codec->suspend_dpm_state);
 	return 0;
 }
@@ -455,16 +454,15 @@ static int wm8731_init(struct snd_soc_de
 	
 	wm8731_reset(codec);
 
-	/* charge output caps */
-	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D2);
-
 	/* register pcms */
 	if((ret = snd_soc_register_pcms(socdev)) < 0) {
-		wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
 		kfree(codec->reg_cache);
 		return ret;
 	}
 	
+	/* power on device */
+	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
+	
 	/* set the update bits */
 	reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
 	wm8731_write(codec, WM8731_LOUT1V, reg | 0x0100);
@@ -479,10 +477,6 @@ static int wm8731_init(struct snd_soc_de
 	wm8731_add_widgets(codec);
 	snd_soc_register_card(socdev);
 	
-	/* wait for caps to finish charging - liam make this thread */
-	ssleep(1);
-	wm8731_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
-
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index de7e969..e5a1025 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -48,6 +48,9 @@
 #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
 
+static struct workqueue_struct *wm8750_workq = NULL;
+static struct work_struct wm8750_dpm_work;
+
 /*
  * wm8750 register cache
  * We can't read the WM8750 register space when we 
@@ -645,7 +648,7 @@ static int wm8750_dpm_event(struct snd_s
 			wm8750_write(codec, WM8750_PWR1, 0x0000);
 			break;
 	}
-	
+	codec->dpm_state = event;
 	return 0;
 }
 
@@ -680,6 +683,12 @@ static struct snd_soc_pcm_codec wm8750_p
 	},
 };
 
+static void wm8750_work(void *data)
+{
+	struct snd_soc_codec *codec = (struct snd_soc_codec *)data;
+	wm8750_dpm_event(codec, codec->dpm_state);
+}
+
 static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -706,7 +715,15 @@ static int wm8750_resume(struct platform
 		codec->hw_write(codec->control_data, data, 2);
 	}
 	
-	wm8750_dpm_event(codec, codec->suspend_dpm_state);
+	wm8750_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
+	
+	/* charge wm8750 caps */
+	if(codec->suspend_dpm_state == SNDRV_CTL_POWER_D0) {
+		wm8750_dpm_event(codec, SNDRV_CTL_POWER_D2);
+		codec->dpm_state = SNDRV_CTL_POWER_D0;
+		queue_delayed_work(wm8750_workq, &wm8750_dpm_work, msecs_to_jiffies(1000));
+	}
+	
 	return 0;
 }
 
@@ -733,15 +750,16 @@ static int wm8750_init(struct snd_soc_de
 	
 	wm8750_reset(codec);
 
-	/* charge output caps */
-	wm8750_dpm_event(codec, SNDRV_CTL_POWER_D2);
-
 	/* register pcms */
 	if((ret = snd_soc_register_pcms(socdev)) < 0) {
-		wm8750_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
 		kfree(codec->reg_cache);
 		return ret;
 	}
+	
+	/* charge output caps */
+	wm8750_dpm_event(codec, SNDRV_CTL_POWER_D2);
+	codec->dpm_state = SNDRV_CTL_POWER_D3hot;
+	queue_delayed_work(wm8750_workq, &wm8750_dpm_work, msecs_to_jiffies(1000));
 
 	/* set the update bits */
 	reg = wm8750_read_reg_cache(codec, WM8750_LDAC);
@@ -764,10 +782,6 @@ static int wm8750_init(struct snd_soc_de
 	wm8750_add_controls(codec);
 	wm8750_add_widgets(codec);
 	snd_soc_register_card(socdev);
-	
-	/* wait for caps to finish charging - liam make this timer */
-	ssleep(1);
-	wm8750_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
 
 	return 0;
 }
@@ -877,8 +891,12 @@ static int wm8750_probe(struct platform_
 	socdev->codec = codec;
 	INIT_LIST_HEAD(&codec->dpm_widgets);
 	INIT_LIST_HEAD(&codec->dpm_paths);
-
 	wm8750_socdev = socdev;
+	INIT_WORK(&wm8750_dpm_work, wm8750_work, codec);
+	if((wm8750_workq = create_workqueue("wm8750")) == NULL) {
+		kfree(codec);
+		return -ENOMEM;
+	}
 
 	if (setup->i2c_address) {
 		normal_i2c[0] = setup->i2c_address;
@@ -902,7 +920,8 @@ static int wm8750_remove(struct platform
 
 	if (codec->control_data)
 		wm8750_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
-
+	if(wm8750_workq)
+		destroy_workqueue(wm8750_workq);
 	snd_soc_free_pcms(socdev);
 	i2c_del_driver(&wm8750_i2c_driver);
 	kfree(codec);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5ad2a1a..8fabc3e 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -53,6 +53,9 @@
 #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
 
+static struct workqueue_struct *wm8753_workq = NULL;
+static struct work_struct wm8753_dpm_work;
+
 /*
  * wm8753 register cache
  * We can't read the WM8753 register space when we 
@@ -1087,6 +1090,12 @@ static struct snd_soc_pcm_codec wm8753_p
 		.hmodes = &wm8753_hifi[0],},},
 };
 
+static void wm8753_work(void *data)
+{
+	struct snd_soc_codec *codec = (struct snd_soc_codec *)data;
+	wm8753_dpm_event(codec, codec->dpm_state);
+}
+
 static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1112,8 +1121,16 @@ static int wm8753_resume(struct platform
 		data[1] = cache[i] & 0x00ff;
 		codec->hw_write(codec->control_data, data, 2);
 	}
-
-	wm8753_dpm_event(codec, codec->suspend_dpm_state);
+	
+	wm8753_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
+		
+	/* charge wm8753 caps */
+	if(codec->suspend_dpm_state == SNDRV_CTL_POWER_D0) {
+		wm8753_dpm_event(codec, SNDRV_CTL_POWER_D2);
+		codec->dpm_state = SNDRV_CTL_POWER_D0;
+		queue_delayed_work(wm8753_workq, &wm8753_dpm_work, msecs_to_jiffies(1000));
+	}
+	
 	return 0;
 }
 
@@ -1140,16 +1157,17 @@ static int wm8753_init(struct snd_soc_de
 	
 	wm8753_reset(codec);
 
-	/* charge output caps */
-	wm8753_dpm_event(codec, SNDRV_CTL_POWER_D2);
-
 	/* register pcms */
 	if((ret = snd_soc_register_pcms(socdev)) < 0) {
-		wm8753_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
 		kfree(codec->reg_cache);
 		return ret;
 	}
 
+	/* charge output caps */
+	wm8753_dpm_event(codec, SNDRV_CTL_POWER_D2);
+	codec->dpm_state = SNDRV_CTL_POWER_D3hot;
+	queue_delayed_work(wm8753_workq, &wm8753_dpm_work, msecs_to_jiffies(1000));
+
 	/* set the update bits */
 	reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
 	wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
@@ -1172,10 +1190,6 @@ static int wm8753_init(struct snd_soc_de
 	wm8753_add_widgets(codec);
 	snd_soc_register_card(socdev);
 
-	/* wait for caps to finish charging - liam make this timer */
-	ssleep(1);
-	wm8753_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
-
 	return ret;
 }
 
@@ -1285,6 +1299,11 @@ static int wm8753_probe(struct platform_
 	INIT_LIST_HEAD(&codec->dpm_widgets);
 	INIT_LIST_HEAD(&codec->dpm_paths);
 	wm8753_socdev = socdev;
+	INIT_WORK(&wm8753_dpm_work, wm8753_work, codec);
+	if((wm8753_workq = create_workqueue("wm8753")) == NULL) {
+		kfree(codec);
+		return -ENOMEM;
+	}
 	
 	if (setup->i2c_address) {
 		normal_i2c[0] = setup->i2c_address;
@@ -1308,7 +1327,8 @@ static int wm8753_remove(struct platform
 
 	if (codec->control_data)
 		wm8753_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
-
+	if(wm8753_workq)
+		destroy_workqueue(wm8753_workq);
 	snd_soc_free_pcms(socdev);
 	i2c_del_driver(&wm8753_i2c_driver);
 	kfree(codec);
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 88d5659..a43ad60 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -48,9 +48,12 @@
 #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
 
-
 #define	WM8971_REG_COUNT		43
 
+static struct workqueue_struct *wm8971_workq = NULL;
+static struct work_struct wm8971_dpm_work;
+
+
 /*
  * wm8971 register cache
  * We can't read the WM8971 register space when we 
@@ -582,7 +585,7 @@ static int wm8971_dpm_event(struct snd_s
 			wm8971_write(codec, WM8971_PWR1, 0x0000);
 			break;
 	}
-	
+	codec->dpm_state = event;
 	return 0;
 }
 
@@ -617,6 +620,12 @@ static struct snd_soc_pcm_codec wm8971_p
 	},
 };
 
+static void wm8971_work(void *data)
+{
+	struct snd_soc_codec *codec = (struct snd_soc_codec *)data;
+	wm8971_dpm_event(codec, codec->dpm_state);
+}
+
 static int wm8971_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -642,8 +651,16 @@ static int wm8971_resume(struct platform
 		data[1] = cache[i] & 0x00ff;
 		codec->hw_write(codec->control_data, data, 2);
 	}
+		
+	wm8971_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
+		
+	/* charge wm8971 caps */
+	if(codec->suspend_dpm_state == SNDRV_CTL_POWER_D0) {
+		wm8971_dpm_event(codec, SNDRV_CTL_POWER_D2);
+		codec->dpm_state = SNDRV_CTL_POWER_D0;
+		queue_delayed_work(wm8971_workq, &wm8971_dpm_work, msecs_to_jiffies(1000));
+	}
 	
-	wm8971_dpm_event(codec, codec->suspend_dpm_state);
 	return 0;
 }
 
@@ -666,15 +683,17 @@ static int wm8971_init(struct snd_soc_de
 	
 	wm8971_reset(codec);
 
-	/* charge output caps */
-	wm8971_dpm_event(codec, SNDRV_CTL_POWER_D2);
-
 	/* register pcms */
 	if((ret = snd_soc_register_pcms(socdev)) < 0) {
-		wm8971_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
 		kfree(codec->reg_cache);
 		return ret;
 	}
+	
+	/* charge output caps */
+	wm8971_dpm_event(codec, SNDRV_CTL_POWER_D2);
+	codec->dpm_state = SNDRV_CTL_POWER_D3hot;
+	queue_delayed_work(wm8971_workq, &wm8971_dpm_work, msecs_to_jiffies(1000));
+	
 
 	/* set the update bits */
 	reg = wm8971_read_reg_cache(codec, WM8971_LDAC);
@@ -700,10 +719,6 @@ static int wm8971_init(struct snd_soc_de
 	wm8971_add_controls(codec);
 	wm8971_add_widgets(codec);
 	snd_soc_register_card(socdev);
-	
-	/* wait for caps to finish charging - liam make this timer */
-	ssleep(1);
-	wm8971_dpm_event(codec, SNDRV_CTL_POWER_D3hot);
 
 	return 0;
 }
@@ -812,9 +827,14 @@ static int wm8971_probe(struct platform_
 	socdev->codec = codec;
 	INIT_LIST_HEAD(&codec->dpm_widgets);
 	INIT_LIST_HEAD(&codec->dpm_paths);
-
 	wm8971_socdev = socdev;
-
+	
+	INIT_WORK(&wm8971_dpm_work, wm8971_work, codec);
+	if((wm8971_workq = create_workqueue("wm8971")) == NULL) {
+		kfree(codec);
+		return -ENOMEM;
+	}
+	
 	if (setup->i2c_address) {
 		normal_i2c[0] = setup->i2c_address;
 		codec->hw_write = (hw_write_t)i2c_master_send;
@@ -837,7 +857,8 @@ static int wm8971_remove(struct platform
 
 	if (codec->control_data)
 		wm8971_dpm_event(codec, SNDRV_CTL_POWER_D3cold);
-
+	if(wm8971_workq)
+		destroy_workqueue(wm8971_workq);
 	snd_soc_free_pcms(socdev);
 	i2c_del_driver(&wm8971_i2c_driver);
 	kfree(codec);
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 8063030..bc49e3c 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -15,9 +15,6 @@
  *  Revision history
  *    30th Nov 2005   Initial version.
  * 
- * TODO:
- *   Fill in (or delete) the gaps.
- * 
  */
  
 #include <linux/module.h>
@@ -37,8 +34,6 @@
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/corgi.h>
-//#include <asm/arch/spitz.h>
-
 #include <asm/arch/audio.h>
 
 #include "../codecs/wm8731.h"
@@ -50,7 +45,7 @@ static struct work_struct corgi_hp_event
 static irqreturn_t corgi_hp_isr(int irq, void *dev_id, struct pt_regs *fp)
 {
 	/* Delay the event slightly to debounce */
-	queue_delayed_work(corgi_hp_workq, &corgi_hp_event_work, jiffies + msecs_to_jiffies(500));
+	queue_delayed_work(corgi_hp_workq, &corgi_hp_event_work, msecs_to_jiffies(500));
 
 	return IRQ_HANDLED;
 }
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1da39a7..22840f4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -15,7 +15,6 @@
  *    25th Oct 2005   Working Codec, Interface and Platform registration.
  *
  *  TODO:
- *   o Finish machine layer - move machine stuff out pxa2xx-pcm.c
  *   o Add hw rules to enforce rates, etc.
  *   o More testing with other codecs/machines.
  *   o Add more codecs and platforms to ensure good API coverage.
@@ -465,6 +464,11 @@ static int soc_suspend(struct platform_d
 	int i;
 	
 	snd_soc_dpm_codec_mute(codec, 1);
+	codec->suspend_dpm_state = codec->dpm_state;
+
+	if (machine->suspend)
+		machine->suspend(pdev, state);
+	
 	for(i = 0; i < machine->nconfigs; i++) {
 		struct snd_soc_pcm_interface  *iface = machine->config[i].iface;
 		if (platform->suspend)
@@ -481,16 +485,12 @@ static int soc_suspend(struct platform_d
 		if(stream != NULL)
 			snd_soc_dpm_stream_event(codec, stream, SND_SOC_DPM_STREAM_SUSPEND);
 	}
-	
-	codec->suspend_dpm_state = codec->dpm_state;
 	codec->suspend_streams = codec->active_streams;
 	codec->active_streams = 0;
+	
 	if (codec_dev->suspend)
 		codec_dev->suspend(pdev, state);
 
-	if (machine->suspend)
-		machine->suspend(pdev, state);
-
 	return 0;
 }
 
@@ -502,13 +502,11 @@ static int soc_resume(struct platform_de
  	struct snd_soc_codec_device* codec_dev = socdev->codec_dev;
 	struct snd_soc_codec* codec = socdev->codec;
 	int i;
-	
-	if (machine->resume)
-		machine->resume(pdev);
 
+	snd_soc_dpm_codec_event(codec, SNDRV_CTL_POWER_D3hot);
 	if (codec_dev->resume)
 		codec_dev->resume(pdev);
-
+	
 	for(i = 0; i < codec->npcms; i++) {
 		char* stream = codec->pcms[i].playback.sname;
 		if(stream != NULL)
@@ -530,6 +528,9 @@ static int soc_resume(struct platform_de
 		if (platform->resume)
 			platform->resume(pdev, iface);
 	}
+	
+	if (machine->resume)
+		machine->resume(pdev);
 
 	return 0;
 }

