All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
@ 2009-08-20  9:42 Shine Liu
  2009-08-20 10:15 ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-20  9:42 UTC (permalink / raw)
  To: alsa-devel; +Cc: broonie

s3c24xx dma has the auto reload feature, when the the trnasfer is done,
CURR_TC(DSTAT[19:0], current value of transfer count) reaches 0, and DMA
ACK becomes 1, and then, TC(DCON[19:0]) will be loaded into CURR_TC. So
the transmission is repeated.

IRQ is issued while auto reload occurs. We change the DISRC and
DCON[19:0] in the ISR, but at this time, the auto reload has been
performed already. The first block is being re-transmitted by the DMA.

So we need rewrite the DISRC and DCON[19:0] for the next block
immediatly after the this block has been started to be transported.

The function s3c2410_dma_started() is for this perpose, which is called
in the form of "s3c2410_dma_ctrl(prtd->params->channel,
S3C2410_DMAOP_STARTED);" in s3c24xx_pcm_trigger().

But it is not correct. DMA transmission won't start until DMA REQ signal
arrived, it is the time s3c24xx_snd_txctrl(1) or s3c24xx_snd_rxctrl(1)
is called in s3c24xx_i2s_trigger().

In the current framework, s3c24xx_pcm_trigger() is always called before
s3c24xx_pcm_trigger(). So the s3c2410_dma_started() should be called in
s3c24xx_pcm_trigger() after s3c24xx_snd_txctrl(1) or
s3c24xx_snd_rxctrl(1) is called in this function.

However, s3c2410_dma_started() is dma related, to call this function we
should provide the channel number, which is given by
substream->runtime->private_data->params->channel. The private_data
points to a struct s3c24xx_runtime_data object, which is define in
s3c24xx_pcm.c, so s3c2410_dma_started() can't be called in s3c24xx_i2s.c

To move the struct s3c24xx_runtime_data defination to s3c24xx-pcm.h is
one solution.

If not moved, the patch shold be like:


Signed-off-by: Shine Liu <shinel@foxmail.com>
----------------------------------------------------------------

--- a/sound/soc/s3c24xx/s3c24xx-pcm.h	2009-08-14 06:43:34.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.h	2009-08-20 16:06:14.000000000 +0800
@@ -28,4 +28,6 @@
 extern struct snd_soc_platform s3c24xx_soc_platform;
 extern struct snd_ac97_bus_ops s3c24xx_ac97_ops;
 
+void s3c24xx_pcm_dma_started(struct snd_pcm_substream *substream);
+
 #endif
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-14 06:43:34.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-20 15:56:46.000000000 +0800
@@ -66,6 +66,28 @@
 	struct s3c24xx_pcm_dma_params *params;
 };
 
+/* s3c24xx_pcm_dma_started
+ *
+ * To load the second dma buffer immediately after the 
+ * first dma buffer has been started transferring, so that 
+ * in the dma autoreload situation, the first data block
+ * won't be re-transferred after the first irq issued.
+ * 
+ * This function is called in the s3c24xx-i2s-trigger() of 
+ * s3c24xx-i2s.c, just after the dma transfer is really started.
+ *
+ * It's ugly here. Need a elegant way to fix this bug.
+ * FIXME
+ *
+ */
+
+void s3c24xx_pcm_dma_started(struct snd_pcm_substream *substream)
+{
+	struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+	s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
+
+}
+
 /* s3c24xx_pcm_enqueue
  *
  * place a dma buffer onto the queue for the dma system
@@ -255,7 +277,6 @@
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		prtd->state |= ST_RUNNING;
 		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
-		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-14 06:43:34.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-20 16:08:06.000000000 +0800
@@ -296,6 +296,9 @@
 			s3c24xx_snd_rxctrl(1);
 		else
 			s3c24xx_snd_txctrl(1);
+
+		/* DMA transfer is really started, equeue the next buffer */
+		s3c24xx_pcm_dma_started(substream);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20  9:42 [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time Shine Liu
@ 2009-08-20 10:15 ` Mark Brown
  2009-08-20 11:59   ` Shine Liu
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2009-08-20 10:15 UTC (permalink / raw)
  To: Shine Liu; +Cc: alsa-devel

On Thu, Aug 20, 2009 at 05:42:11PM +0800, Shine Liu wrote:

> In the current framework, s3c24xx_pcm_trigger() is always called before
> s3c24xx_pcm_trigger(). So the s3c2410_dma_started() should be called in
> s3c24xx_pcm_trigger() after s3c24xx_snd_txctrl(1) or
> s3c24xx_snd_rxctrl(1) is called in this function.

I suspect some of the function names in your description here are
incorrect :) Another option is to provide a callback in the private data
passed to the DMA driver which the DMA driver can call at the
appropriate point during setup.

Someone will presumably also need to take care of the same things in the
other S3C DAI drivers too, though it should be possible to arrange
things so that can be done seperately.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 10:15 ` Mark Brown
@ 2009-08-20 11:59   ` Shine Liu
  2009-08-20 12:18     ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-20 11:59 UTC (permalink / raw)
  To: Mark Brown; +Cc: ben, alsa-devel

On Thu, 2009-08-20 at 11:15 +0100, Mark Brown wrote:
> On Thu, Aug 20, 2009 at 05:42:11PM +0800, Shine Liu wrote:
> 
> > In the current framework, s3c24xx_pcm_trigger() is always called before
> > s3c24xx_pcm_trigger(). So the s3c2410_dma_started() should be called in
> > s3c24xx_pcm_trigger() after s3c24xx_snd_txctrl(1) or
> > s3c24xx_snd_rxctrl(1) is called in this function.
> 
> I suspect some of the function names in your description here are
> incorrect :) Another option is to provide a callback in the private data
> passed to the DMA driver which the DMA driver can call at the
> appropriate point during setup.

Sorry for the mistake. Should be s3c24xx_pcm_trigger() is always called
before s3c24xx_i2s_trigger() in current framework :
s3c24xx_pcm_trigger() is called via platform->pcm_ops->trigger and
s3c24xx_i2s_trigger() is called via cpu_dai->ops->trigger.

The problem is that DMA driver doesn't know when the DMA transfer has
been really started. The DMA setup is done in s3c24xx_pcm_trigger(), in
which all DMA related registers are set. But it doesn't mean the DMA
transfer is started at this point because the DMA REQ signal has not
arrived which is generated by the IIS. DMA driver has no way to know
when the DMA REQ signal arrived. So the s3c24xx DMA driver provids a
s3c2410_dma_started() method to let the user call when he knows the DMA
transfer has been started.

> 
> Someone will presumably also need to take care of the same things in the
> other S3C DAI drivers too, though it should be possible to arrange
> things so that can be done seperately.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 11:59   ` Shine Liu
@ 2009-08-20 12:18     ` Mark Brown
  2009-08-20 13:38       ` Shine Liu
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2009-08-20 12:18 UTC (permalink / raw)
  To: Shine Liu; +Cc: ben, alsa-devel

On Thu, Aug 20, 2009 at 07:59:48PM +0800, Shine Liu wrote:
> On Thu, 2009-08-20 at 11:15 +0100, Mark Brown wrote:

> > incorrect :) Another option is to provide a callback in the private data
> > passed to the DMA driver which the DMA driver can call at the
> > appropriate point during setup.

> arrived which is generated by the IIS. DMA driver has no way to know
> when the DMA REQ signal arrived. So the s3c24xx DMA driver provids a
> s3c2410_dma_started() method to let the user call when he knows the DMA
> transfer has been started.

Yes, I understand the problem.  The callback I suggest above ought to
allow the appropriate sequencing - the DMA driver can call the callback
to start the DAI in between starting the DMA and kicking the DMA API to
queue the next block.  That would avoid the abstraction problems.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 12:18     ` Mark Brown
@ 2009-08-20 13:38       ` Shine Liu
  2009-08-20 14:52         ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-20 13:38 UTC (permalink / raw)
  To: Mark Brown; +Cc: ben, alsa-devel

On Thu, 2009-08-20 at 13:18 +0100, Mark Brown wrote:
> 
> Yes, I understand the problem.  The callback I suggest above ought to
> allow the appropriate sequencing - the DMA driver can call the callback
> to start the DAI in between starting the DMA and kicking the DMA API to
> queue the next block.  That would avoid the abstraction problems.
> 

Callback is a elegant way to solve the problem. But I have a question
that when should the DMA driver call the callback funtion? There is no
event to tell it to call. Periodly checking? It will not only cause
latency but also increase the system load. 

Thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 13:38       ` Shine Liu
@ 2009-08-20 14:52         ` Mark Brown
  2009-08-20 15:45           ` Shine Liu
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2009-08-20 14:52 UTC (permalink / raw)
  To: Shine Liu; +Cc: ben, alsa-devel

On Thu, Aug 20, 2009 at 09:38:00PM +0800, Shine Liu wrote:

> Callback is a elegant way to solve the problem. But I have a question
> that when should the DMA driver call the callback funtion? There is no
> event to tell it to call. Periodly checking? It will not only cause
> latency but also increase the system load. 

The callback doesn't need to be set up within the trigger function - if
it's done before the trigger functions are called then the DMA trigger
can call it.  Off the top of my head I'd expect it's possible to set it
up when the device is opened.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 14:52         ` Mark Brown
@ 2009-08-20 15:45           ` Shine Liu
  2009-08-20 18:47             ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-20 15:45 UTC (permalink / raw)
  To: Mark Brown; +Cc: ben, alsa-devel


> The callback doesn't need to be set up within the trigger function - if
> it's done before the trigger functions are called then the DMA trigger
> can call it.  Off the top of my head I'd expect it's possible to set it
> up when the device is opened.

Who call the DMA trigger? When? In any of the platform/cpu_dai trigger
functions?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 15:45           ` Shine Liu
@ 2009-08-20 18:47             ` Mark Brown
  2009-08-21 10:00               ` Shine Liu
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2009-08-20 18:47 UTC (permalink / raw)
  To: Shine Liu; +Cc: ben, alsa-devel

On Thu, Aug 20, 2009 at 11:45:07PM +0800, Shine Liu wrote:

> > The callback doesn't need to be set up within the trigger function - if
> > it's done before the trigger functions are called then the DMA trigger
> > can call it.  Off the top of my head I'd expect it's possible to set it
> > up when the device is opened.

> Who call the DMA trigger? When? In any of the platform/cpu_dai trigger
> functions?

It's called ultimately by user space; within ASoC it's always called by
the core trigger function in the fixed order that it has.  The open()
callback would be a safe place to do the setup - that's called before
anything else.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-20 18:47             ` Mark Brown
@ 2009-08-21 10:00               ` Shine Liu
  2009-08-23 10:28                 ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-21 10:00 UTC (permalink / raw)
  To: Mark Brown; +Cc: ben, alsa-devel


> 
> It's called ultimately by user space; within ASoC it's always called by
> the core trigger function in the fixed order that it has.  The open()
> callback would be a safe place to do the setup - that's called before
> anything else.
> 
> 

I've finished a draft patch in the callback manner. Waiting for any
suggestion. Thanks.


-----------------------------------------------------------------

diff -Nur a/arch/arm/plat-s3c24xx/include/plat/dma-plat.h b/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
--- a/arch/arm/plat-s3c24xx/include/plat/dma-plat.h	2009-08-14 06:43:34.000000000 +0800
+++ b/arch/arm/plat-s3c24xx/include/plat/dma-plat.h	2009-08-21 14:14:12.000000000 +0800
@@ -76,6 +76,27 @@
 
 extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
 
+enum s3c24xx_dma_channel_event {
+	CHANNEL_EVENT_START,
+	CHANNEL_EVENT_STOP,
+	CHANNEL_EVENT_MAX,
+};
+
+struct s3c24xx_dma_channel_trigger {
+	unsigned int channel;
+	/* trigger event */
+	enum s3c24xx_dma_channel_event event;
+	/* pravate date to the callback function */
+	void *private_data;
+	/* callback funtion to generate the DMA REQ signal */
+	void (*gen_request)(void *private_data);
+	/* callback funtion to end the DMA request */
+	void (*end_request)(void *private_data);
+};
+
+/* trigger the DMA engine to start, called from the client */
+extern void s3c24xx_dma_trigger(struct s3c24xx_dma_channel_trigger *client);
+
 /* DMA init code, called from the cpu support code */
 
 extern int s3c2410_dma_init(void);
diff -Nur a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
--- a/arch/arm/plat-s3c24xx/dma.c	2009-08-14 06:43:34.000000000 +0800
+++ b/arch/arm/plat-s3c24xx/dma.c	2009-08-21 14:30:41.000000000 +0800
@@ -1008,6 +1008,34 @@
 
 EXPORT_SYMBOL(s3c2410_dma_ctrl);
 
+void s3c24xx_dma_trigger(struct s3c24xx_dma_channel_trigger *client)
+{
+	if(!client || !(client->channel < DMACH_MAX)) {
+ 		pr_debug("%s: Invalid parameter\n", __func__);
+		return;
+	}
+
+	switch(client->event) {
+	case CHANNEL_EVENT_START:
+		s3c2410_dma_ctrl(client->channel, S3C2410_DMAOP_START);
+		if(client->gen_request)
+			client->gen_request(client->private_data);
+		s3c2410_dma_ctrl(client->channel, S3C2410_DMAOP_STARTED);
+		return;
+	case CHANNEL_EVENT_STOP:
+		s3c2410_dma_ctrl(client->channel, S3C2410_DMAOP_STOP);
+		if(client->end_request)
+			client->end_request(client->private_data);
+		/* should be set to a vaild value in the next request */
+		client->channel = DMACH_MAX;
+		return;
+	default:
+		pr_debug("%s: Invalid event\n", __func__);
+	}
+}
+
+EXPORT_SYMBOL(s3c24xx_dma_trigger);
+
 /* DMA configuration for each channel
  *
  * DISRCC -> source of the DMA (AHB,APB)
diff -Nur a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-14 06:43:34.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-21 15:08:07.000000000 +0800
@@ -38,6 +38,7 @@
 
 #include <plat/regs-iis.h>
 
+#define __USE_S3C24XX_PCM_RUNTIME
 #include "s3c24xx-pcm.h"
 #include "s3c24xx-i2s.h"
 
@@ -278,6 +279,7 @@
 static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 			       struct snd_soc_dai *dai)
 {
+	struct s3c24xx_pcm_runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
 	pr_debug("Entered %s\n", __func__);
@@ -292,24 +294,32 @@
 				goto exit_err;
 		}
 
+		spin_lock(&prtd->lock);
+		prtd->client.private_data= (void *)1;
 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-			s3c24xx_snd_rxctrl(1);
+			prtd->client.gen_request = (void *)s3c24xx_snd_rxctrl;
 		else
-			s3c24xx_snd_txctrl(1);
+			prtd->client.gen_request = (void *)s3c24xx_snd_txctrl;
+		spin_unlock(&prtd->lock);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		spin_lock(&prtd->lock);
+		prtd->client.private_data= (void *)0;
 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-			s3c24xx_snd_rxctrl(0);
+			prtd->client.end_request = (void *)s3c24xx_snd_rxctrl;
 		else
-			s3c24xx_snd_txctrl(0);
+			prtd->client.end_request = (void *)s3c24xx_snd_txctrl;
+		spin_unlock(&prtd->lock);
 		break;
 	default:
 		ret = -EINVAL;
-		break;
+		goto exit_err;
 	}
 
+	s3c24xx_dma_trigger(&prtd->client);
+
 exit_err:
 	return ret;
 }
diff -Nur a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c24xx-pcm.h
--- a/sound/soc/s3c24xx/s3c24xx-pcm.h	2009-08-14 06:43:34.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.h	2009-08-21 14:40:05.000000000 +0800
@@ -22,6 +22,25 @@
 	int dma_size;			/* Size of the DMA transfer */
 };
 
+#ifdef __USE_S3C24XX_PCM_RUNTIME
+
+#include <plat/dma-plat.h>
+
+struct s3c24xx_pcm_runtime_data {
+	spinlock_t lock;
+	int state;
+	unsigned int dma_loaded;
+	unsigned int dma_limit;
+	unsigned int dma_period;
+	dma_addr_t dma_start;
+	dma_addr_t dma_pos;
+	dma_addr_t dma_end;
+	struct s3c24xx_pcm_dma_params *params;
+	struct s3c24xx_dma_channel_trigger client;
+};
+
+#endif
+
 #define S3C24XX_DAI_I2S			0
 
 /* platform data */
diff -Nur a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-14 06:43:34.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-21 14:47:29.000000000 +0800
@@ -31,6 +31,7 @@
 #include <mach/dma.h>
 #include <plat/audio.h>
 
+#define __USE_S3C24XX_PCM_RUNTIME
 #include "s3c24xx-pcm.h"
 
 static const struct snd_pcm_hardware s3c24xx_pcm_hardware = {
@@ -54,18 +55,6 @@
 	.fifo_size		= 32,
 };
 
-struct s3c24xx_runtime_data {
-	spinlock_t lock;
-	int state;
-	unsigned int dma_loaded;
-	unsigned int dma_limit;
-	unsigned int dma_period;
-	dma_addr_t dma_start;
-	dma_addr_t dma_pos;
-	dma_addr_t dma_end;
-	struct s3c24xx_pcm_dma_params *params;
-};
-
 /* s3c24xx_pcm_enqueue
  *
  * place a dma buffer onto the queue for the dma system
@@ -73,7 +62,7 @@
 */
 static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream)
 {
-	struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = substream->runtime->private_data;
 	dma_addr_t pos = prtd->dma_pos;
 	int ret;
 
@@ -110,7 +99,7 @@
 				enum s3c2410_dma_buffresult result)
 {
 	struct snd_pcm_substream *substream = dev_id;
-	struct s3c24xx_runtime_data *prtd;
+	struct s3c24xx_pcm_runtime_data *prtd;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -135,7 +124,7 @@
 	struct snd_pcm_hw_params *params)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct s3c24xx_runtime_data *prtd = runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = runtime->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data;
 	unsigned long totbytes = params_buffer_bytes(params);
@@ -187,7 +176,7 @@
 
 static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = substream->runtime->private_data;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -204,7 +193,7 @@
 
 static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
 	pr_debug("Entered %s\n", __func__);
@@ -242,7 +231,7 @@
 
 static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = substream->runtime->private_data;
 	int ret = 0;
 
 	pr_debug("Entered %s\n", __func__);
@@ -254,15 +243,15 @@
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		prtd->state |= ST_RUNNING;
-		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
-		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
+		prtd->client.channel = prtd->params->channel;
+		prtd->client.event = CHANNEL_EVENT_START;
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		prtd->state &= ~ST_RUNNING;
-		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
+		prtd->client.event = CHANNEL_EVENT_STOP;
 		break;
 
 	default:
@@ -279,7 +268,7 @@
 s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct s3c24xx_runtime_data *prtd = runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = runtime->private_data;
 	unsigned long res;
 	dma_addr_t src, dst;
 
@@ -314,16 +303,18 @@
 static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct s3c24xx_runtime_data *prtd;
+	struct s3c24xx_pcm_runtime_data *prtd;
 
 	pr_debug("Entered %s\n", __func__);
 
 	snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware);
 
-	prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
+	prtd = kzalloc(sizeof(struct s3c24xx_pcm_runtime_data), GFP_KERNEL);
 	if (prtd == NULL)
 		return -ENOMEM;
 
+	prtd->client.channel = DMACH_MAX;
+
 	spin_lock_init(&prtd->lock);
 
 	runtime->private_data = prtd;
@@ -333,7 +324,7 @@
 static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct s3c24xx_runtime_data *prtd = runtime->private_data;
+	struct s3c24xx_pcm_runtime_data *prtd = runtime->private_data;
 
 	pr_debug("Entered %s\n", __func__);

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-21 10:00               ` Shine Liu
@ 2009-08-23 10:28                 ` Mark Brown
  2009-08-23 11:37                   ` Shine Liu
  2009-08-25  3:04                   ` [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time Shine Liu
  0 siblings, 2 replies; 18+ messages in thread
From: Mark Brown @ 2009-08-23 10:28 UTC (permalink / raw)
  To: Shine Liu; +Cc: ben, alsa-devel

On Fri, Aug 21, 2009 at 06:00:39PM +0800, Shine Liu wrote:

> I've finished a draft patch in the callback manner. Waiting for any
> suggestion. Thanks.

This isn't quite what I was expecting - what I was expecting was more
that the I2S driver would set up a function on startup which would be
called by the ASoC DMA driver from its trigger function.  It does look
like a reasonable approach, though.

The way you've got things at the minute at least all the other S3C ASoC
drivers will need to be updated to match the change in the DMA driver.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-23 10:28                 ` Mark Brown
@ 2009-08-23 11:37                   ` Shine Liu
       [not found]                     ` <20090824101733.GA3591@rakim.wolfsonmicro.main>
  2009-08-25  3:04                   ` [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time Shine Liu
  1 sibling, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-23 11:37 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, ben-linux


> 
> This isn't quite what I was expecting - what I was expecting was more
> that the I2S driver would set up a function on startup which would be
> called by the ASoC DMA driver from its trigger function.  It does look
> like a reasonable approach, though.

Yes, I understand what you exactly want. I was intend to register the
callback function on I2S startup, but finally I found it is not possible
because there are two callback functions for the DMA driver:
s3c24xx_snd_txctrl() and s3c24xx_snd_rxctrl(), however, there's only one
slot for the callback function. So I choose not to setup the callback
functions dynamicly, when the task is playback, the callback funtion is
s3c24xx_snd_txctrl() and when the task is record, the funtion is
s3c24xx_snd_rxctrl().

However, there's another way to archive what you expect: combine the
s3c24xx_snd_txctrl() and s3c24xx_snd_rxctrl() into one function. That
would be like:

struct s3c24xx_snd_ctrl_data {
	int event;	//start or stop
	int direction;	//playback or record
};

static void s3c24xx_snd_ctrl(struct s3c24xx_snd_ctrl_data* data)
{
	if(data->direction == SNDRV_PCM_STREAM_PLAYBACK)
		s3c24xx_snd_txctrl(data->event);
	eles
		s3c24xx_snd_rxctrl(data->event);
}

Then we can register this callback funtion on I2S startup.

> 
> The way you've got things at the minute at least all the other S3C ASoC
> drivers will need to be updated to match the change in the DMA driver.
> 

I have posted the DMA driver patch to linux-arm-kernel yesterday:
http://lists.arm.linux.org.uk/lurker/message/20090822.153940.e15e3bd7.en.html

Hope there is no problem to merge the patch.

If the dma patch is accepted, I will post a formal patch here for ASoC
S3C24XX.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
       [not found]                     ` <20090824101733.GA3591@rakim.wolfsonmicro.main>
@ 2009-08-24 11:54                       ` Shine Liu
  2009-08-24 12:05                         ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-24 11:54 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, ben-linux


> ...but there's no need for the struct, just pass two arguments to the
> function, the event and either the substream or the direction.  The
> substream is probably easier since otherwise all the callers will need
> to parse the direction.

Finally, I decide to place the callback function in struct
s3c2410_dma_client instead of add a new struct:

 struct s3c2410_dma_client {

       ....

       /* callback funtion from client to generate the DMA REQ signal */
       int (*gen_request)(void *);

       /* callback funtion from client to end the DMA request */
       int (*end_request)(void *);

       /* argument for the callback function */
       void            *private_data;
 };

I think the callback function should have only one argument. If we have
more than one argument to pass, just embbed them into a internal struct
known to the callback funtions and pass the pointer to the object of
this struct to the callback function. 

If not, more filed will be needed in struct s3c2410_dma_client to place
the arguments. I think it's redundant for the generic DMA driver.

I've posted five new patches which regist the callback functions either
in the I2S/AC97 probe phase or by directly assiged in the source code
depended by whether the callback functions and the object of struct
s3c2410_dma_client are in the same source file.

Look forward for further comments on these patches. There should be some
defects in them.

Thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-24 11:54                       ` Shine Liu
@ 2009-08-24 12:05                         ` Mark Brown
  2009-08-24 13:31                           ` Shine Liu
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2009-08-24 12:05 UTC (permalink / raw)
  To: Shine Liu; +Cc: alsa-devel, ben-linux

On Mon, Aug 24, 2009 at 07:54:40PM +0800, Shine Liu wrote:

> If not, more filed will be needed in struct s3c2410_dma_client to place
> the arguments. I think it's redundant for the generic DMA driver.

But why are you changing the core DMA code in the first place?  The ASoC
drivers have split front end and DMA code but this is not the normal
case for a DMA client.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time
  2009-08-24 12:05                         ` Mark Brown
@ 2009-08-24 13:31                           ` Shine Liu
  0 siblings, 0 replies; 18+ messages in thread
From: Shine Liu @ 2009-08-24 13:31 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, ben-linux


> But why are you changing the core DMA code in the first place?  The ASoC
> drivers have split front end and DMA code but this is not the normal
> case for a DMA client.

I think your idea of the callback is very elegant and I appreciate this
way to solve the problem so I try to add new API for the core DMA to
achive this goal.

Well, if there are two arguments for the callback function passed though
struct struct s3c2410_dma_client, it's also reasonable. If there are
more arguments to pass, maybe this is not the best solution. Use a
internal struct to wrapper more arguments into one object and pass the
pointer is just a candidate. 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time
  2009-08-23 10:28                 ` Mark Brown
  2009-08-23 11:37                   ` Shine Liu
@ 2009-08-25  3:04                   ` Shine Liu
  2009-08-25 10:33                     ` Mark Brown
  1 sibling, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-25  3:04 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, ben-linux


Hi Mark,

    There's a candidate patch for the bug of s3c2410_dma_started()
called at improper time. This patch also covers all S3C I2C/AC97 ASoC
drivers affected by this bug.

    The previous patches try to fix this bug in the DMA callback way. It
's elegant and should be the proper way to fix the bug but the changes
is a little large and need be well discussed and tested.

     I think before we fix the bug in the callback way, we can use this
patch provisionally for a while though it seems a little ugly. 

     This patch is created against linux-2.6.31-rc7, and has been well
tested under s3c2440 platform with I2S DAI.

Best Regards,

Shine 



Signed-off-by: Shine Liu <liuxian@redflag-linux.com>
----------------------------------------------------


--- a/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-24 15:57:23.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-25 10:29:12.000000000 +0800
@@ -255,7 +255,6 @@
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		prtd->state |= ST_RUNNING;
 		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
-		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-24 15:57:23.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-25 10:05:02.000000000 +0800
@@ -279,9 +279,14 @@
 			       struct snd_soc_dai *dai)
 {
 	int ret = 0;
+	int channel;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 
 	pr_debug("Entered %s\n", __func__);
 
+	channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -296,6 +301,13 @@
 			s3c24xx_snd_rxctrl(1);
 		else
 			s3c24xx_snd_txctrl(1);
+		/* DMA engine has just been started at this point,
+		 * load the next buffer to DMA to meet the reqirement 
+		 * of the auto reload mechanism.
+		 * Ugly here, but it is the simplest way.
+		 * Will be fixed if DMA callback API provided.
+		 */
+		s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
--- a/sound/soc/s3c24xx/s3c2443-ac97.c	2009-08-24 15:57:23.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c	2009-08-25 10:08:57.000000000 +0800
@@ -290,6 +290,9 @@
 				struct snd_soc_dai *dai)
 {
 	u32 ac_glbctrl;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 	switch (cmd) {
@@ -312,6 +315,14 @@
 	}
 	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 
+	/* DMA engine has just been started at this point,
+	 * load the next buffer to DMA to meet the reqirement 
+	 * of the auto reload mechanism.
+	 * Ugly here, but it is the simplest way.
+	 * Will be fixed if DMA callback API provided.
+	 */
+	s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+
 	return 0;
 }
 
@@ -334,6 +345,9 @@
 				    int cmd, struct snd_soc_dai *dai)
 {
 	u32 ac_glbctrl;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 	switch (cmd) {
@@ -349,6 +363,14 @@
 	}
 	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 
+	/* DMA engine has just been started at this point,
+	 * load the next buffer to DMA to meet the reqirement 
+	 * of the auto reload mechanism.
+	 * Ugly here, but it is the simplest way.
+	 * Will be fixed if DMA callback API provided.
+	 */
+	s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+
 	return 0;
 }
 
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c	2009-08-25 10:25:40.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c	2009-08-25 10:15:34.000000000 +0800
@@ -387,6 +387,8 @@
 	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 	unsigned long irqs;
 	int ret = 0;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -416,6 +418,18 @@
 			s3c2412_snd_txctrl(i2s, 1);
 
 		local_irq_restore(irqs);
+
+		/* DMA engine has just been started at this point,
+		 * load the next buffer to DMA to meet the reqirement 
+		 * of the auto reload mechanism.
+		 * Ugly here, but it is the simplest way.
+		 * Will be fixed if DMA callback API provided.
+		 * 
+		 * S3C64XX doesn't have the auto reload problem, 
+		 * only for S3C24XX. This call won't bother S3C64XX.
+		 */
+		s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time
  2009-08-25  3:04                   ` [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time Shine Liu
@ 2009-08-25 10:33                     ` Mark Brown
  2009-08-25 12:05                       ` Shine Liu
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2009-08-25 10:33 UTC (permalink / raw)
  To: Shine Liu; +Cc: alsa-devel, ben-linux

On Tue, Aug 25, 2009 at 11:04:26AM +0800, Shine Liu wrote:

>      I think before we fix the bug in the callback way, we can use this
> patch provisionally for a while though it seems a little ugly. 

I can't prevail on you to do this with a callback within the ASoC code
only?  This really does seem like something that's created by the way
ASoC is structured rather than a general S3C DMA issue so I'm not sure
that the arch/arm code needs to be changed at all.

Otherwise the patch looks OK, in fact I'd tone down the comments about
it being a hack to do this - ASoC DAI and PCM drivers are supposed to be
fairly closely tied to each other.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time
  2009-08-25 10:33                     ` Mark Brown
@ 2009-08-25 12:05                       ` Shine Liu
  2009-08-25 12:12                         ` Mark Brown
  0 siblings, 1 reply; 18+ messages in thread
From: Shine Liu @ 2009-08-25 12:05 UTC (permalink / raw)
  To: Mark Brown; +Cc: alsa-devel, ben-linux


> Otherwise the patch looks OK, in fact I'd tone down the comments about
> it being a hack to do this - ASoC DAI and PCM drivers are supposed to be
> fairly closely tied to each other.
> 

Yes, I agree with you. I have cut down the unnecessary comments in the
patch. Thank you for your appropriate suggestion.

Shine




Signed-off-by: Shine Liu <liuxian@redflag-linux.com>
Signed-off-by: Shine Liu <shinel@foxmail.com>


--- a/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-24 15:57:23.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c	2009-08-25 10:29:12.000000000 +0800
@@ -255,7 +255,6 @@
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		prtd->state |= ST_RUNNING;
 		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
-		s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
--- a/sound/soc/s3c24xx/s3c2443-ac97.c	2009-08-25 10:22:31.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c	2009-08-25 19:38:44.000000000 +0800
@@ -290,6 +290,9 @@
 				struct snd_soc_dai *dai)
 {
 	u32 ac_glbctrl;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 	switch (cmd) {
@@ -312,6 +315,8 @@
 	}
 	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 
+	s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+
 	return 0;
 }
 
@@ -334,6 +339,9 @@
 				    int cmd, struct snd_soc_dai *dai)
 {
 	u32 ac_glbctrl;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 	switch (cmd) {
@@ -349,6 +357,8 @@
 	}
 	writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
 
+	s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+
 	return 0;
 }
 
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-25 10:25:40.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c	2009-08-25 19:39:32.000000000 +0800
@@ -279,6 +279,9 @@
 			       struct snd_soc_dai *dai)
 {
 	int ret = 0;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -296,6 +299,8 @@
 			s3c24xx_snd_rxctrl(1);
 		else
 			s3c24xx_snd_txctrl(1);
+
+		s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c	2009-08-25 10:25:40.000000000 +0800
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c	2009-08-25 19:38:35.000000000 +0800
@@ -387,6 +387,8 @@
 	int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
 	unsigned long irqs;
 	int ret = 0;
+	int channel = ((struct s3c24xx_pcm_dma_params *)
+		  rtd->dai->cpu_dai->dma_data)->channel;
 
 	pr_debug("Entered %s\n", __func__);
 
@@ -416,6 +418,14 @@
 			s3c2412_snd_txctrl(i2s, 1);
 
 		local_irq_restore(irqs);
+
+		/*
+		 * Load the next buffer to DMA to meet the reqirement 
+		 * of the auto reload mechanism of S3C24XX.
+		 * This call won't bother S3C64XX.
+		 */
+		s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
+
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time
  2009-08-25 12:05                       ` Shine Liu
@ 2009-08-25 12:12                         ` Mark Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2009-08-25 12:12 UTC (permalink / raw)
  To: Shine Liu; +Cc: alsa-devel, ben-linux

On Tue, Aug 25, 2009 at 08:05:50PM +0800, Shine Liu wrote:

> Yes, I agree with you. I have cut down the unnecessary comments in the
> patch. Thank you for your appropriate suggestion.

I've applied this, taking the commit message from your original e-mail
with a slight update to reflect the final solution.  Thanks for all your
patient work on this.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-08-25 12:12 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-20  9:42 [PATCH] ASoC: s3c24xx platform: Fix s3c2410_dma_started called at wrong time Shine Liu
2009-08-20 10:15 ` Mark Brown
2009-08-20 11:59   ` Shine Liu
2009-08-20 12:18     ` Mark Brown
2009-08-20 13:38       ` Shine Liu
2009-08-20 14:52         ` Mark Brown
2009-08-20 15:45           ` Shine Liu
2009-08-20 18:47             ` Mark Brown
2009-08-21 10:00               ` Shine Liu
2009-08-23 10:28                 ` Mark Brown
2009-08-23 11:37                   ` Shine Liu
     [not found]                     ` <20090824101733.GA3591@rakim.wolfsonmicro.main>
2009-08-24 11:54                       ` Shine Liu
2009-08-24 12:05                         ` Mark Brown
2009-08-24 13:31                           ` Shine Liu
2009-08-25  3:04                   ` [PATCH] ASoC: S3C platform: Fix s3c2410_dma_started() called at improper time Shine Liu
2009-08-25 10:33                     ` Mark Brown
2009-08-25 12:05                       ` Shine Liu
2009-08-25 12:12                         ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.