Hi,

On Thu, 3 Mar 2011 09:07:22 +0800
"Jayaraman, Venkat" <[email protected]> wrote:

> Feng,
>       The attached patch causes a panic. There is some bad pointer
> reference somewhere in the changed code. Also increasing the time to
> 10s still produces the message.

I guess it's a 10ms not 10s here?


And sorry for the panic, I didn't try the patch on my platform as the
error msg doesn't show up (I did see the msg before by myself).

Here is a updated one, which consider the driver init phase where
there is no valid spi_transfer yet.
--------------------
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c
index 0f7ed08..0262992 100644
--- a/drivers/spi/dw_spi.c
+++ b/drivers/spi/dw_spi.c
@@ -164,7 +164,16 @@ static inline void mrst_spi_debugfs_remove(struct dw_spi 
*dws)
 
 static void wait_till_not_busy(struct dw_spi *dws)
 {
-       unsigned long end = jiffies + 1 + usecs_to_jiffies(5000);
+       int end, wait_us;
+
+       if (dws->cur_chip) {
+               wait_us = dws->fifo_len * 16 * USEC_PER_SEC / 
dws->cur_chip->speed_hz;
+               /* Give it a 50% safe buffer */
+               wait_us += wait_us >> 1;
+       } else
+               wait_us = 5000;
+
+       end = jiffies + 1 + usecs_to_jiffies(wait_us);
 
        while (time_before(jiffies, end)) {
                if (!(dw_readw(dws, sr) & SR_BUSY))
@@ -172,7 +181,8 @@ static void wait_till_not_busy(struct dw_spi *dws)
                cpu_relax();
        }
        dev_err(&dws->master->dev,
-               "DW SPI: Status keeps busy for 5000us after a read/write!\n");
+               "DW SPI: HW keeps busy for %d us after a read/write!\n",
+               wait_us);
 }
 
 static void flush(struct dw_spi *dws)

Thanks,
Feng

> 
> Thanks
> Venkat 
> 
> -----Original Message-----
> From: Tang, Feng 
> Sent: Tuesday, March 01, 2011 7:41 PM
> To: Tang, Feng
> Cc: Jayaraman, Venkat; [email protected]; [email protected]
> Subject: Re: [Meego-kernel] Question on Designware SPI Controller
> Driver
> 
> On Wed, 2 Mar 2011 10:41:18 +0800
> "Tang, Feng" <[email protected]> wrote:
> 
> > Hi Venkat,
> > 
> > If you disable the "mrst" earlyprintk, then there is no conflict.
> > 
> > As I said in last email, if you still randomly see it, it's fine.
> > The basic idea for the busy wait (code is listed here) is simple,
> > after write/read the FIFO wait till the HW register tell us it's
> > not busy
> > 
> > static void wait_till_not_busy(struct dw_spi *dws) {
> >         unsigned long end = jiffies + 1 + usecs_to_jiffies(5000);
> > 
> >         while (time_before(jiffies, end)) {
> >                 if (!(dw_readw(dws, sr) & SR_BUSY))
> >                         return;
> >                 cpu_relax();
> >         }
> >         dev_err(&dws->master->dev,
> >                 "DW SPI: Status keeps busy for 5000us after a 
> > read/write!\n"); }
> > 
> > 5000 us should be enough for dumping the DW spi controller's FIFO 
> > (which is 40 words deep) even for a low speed UART slave device at 
> > 115200 bps.
> > 
> > If you still see lots of that message, can you enlarge that 5000 to 
> > 100000 to check if it's gone?
> > 
> > Thanks,
> > Feng
> 
> 
> Venkat,
> 
> You can also try the attached debug patch, which adjust the wait time
> dynamically.
> 
> ----------------------------------------------------------
> diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index
> 0f7ed08..e136897 100644 --- a/drivers/spi/dw_spi.c
> +++ b/drivers/spi/dw_spi.c
> @@ -164,7 +164,13 @@ static inline void
> mrst_spi_debugfs_remove(struct dw_spi *dws) 
>  static void wait_till_not_busy(struct dw_spi *dws)  {
> -     unsigned long end = jiffies + 1 + usecs_to_jiffies(5000);
> +     int end, wait_us;
> +
> +     wait_us = dws->fifo_len * 16 * USEC_PER_SEC /
> dws->cur_chip->speed_hz;
> +     /* Give it a 50% safe buffer */
> +     wait_us += wait_us >> 1;
> +
> +     end = jiffies + 1 + usecs_to_jiffies(wait_us);
>  
>       while (time_before(jiffies, end)) {
>               if (!(dw_readw(dws, sr) & SR_BUSY))
> @@ -172,7 +178,8 @@ static void wait_till_not_busy(struct dw_spi *dws)
>               cpu_relax();
>       }
>       dev_err(&dws->master->dev,
> -             "DW SPI: Status keeps busy for 5000us after a
> read/write!\n");
> +             "DW SPI: HW keeps busy for %d us after a
> read/write!\n",
> +             wait_us);
>  }
>  
>  static void flush(struct dw_spi *dws)
> 
> 
> Thanks,
> Feng
> 
_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to