I fixed my other suspend/resume problem - it was unrelated to spi. So
restoring the SSP registers is the fix. It's all working correctly for
me now.

I've never submitted a patch before so I'd appreciate a review of this
before I submit it properly:

Index: pxa2xx_spi.c
===================================================================
--- pxa2xx_spi.c        (revision 562)
+++ pxa2xx_spi.c        (working copy)
@@ -102,6 +102,12 @@
        u32 int_cr1;
        u32 clear_sr;
        u32 mask_sr;
+
+        /* saved state for suspend/resume */
+        u32 saved_sscr0;
+        u32 saved_sscr1;
+        u32 saved_sst0;
+        u32 saved_sspsp;

        /* Driver message queue */
        struct workqueue_struct *workqueue;
@@ -1570,11 +1576,16 @@
 static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct driver_data *drv_data = platform_get_drvdata(pdev);
+       void *reg = drv_data->ioaddr;
        int status = 0;

-       /* Check all childern for current power state */
+        /* Save register state */
+        drv_data->saved_sscr0 = read_SSCR0(reg);
+        drv_data->saved_sscr1 = read_SSCR1(reg);
+        if (drv_data->ssp_type != PXA25x_SSP)
+                drv_data->saved_sst0 = read_SSTO(reg);
+        drv_data->saved_sspsp = read_SSPSP(reg);
+
+       /* Check all children for current power state */
        if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) {
                dev_warn(&pdev->dev, "suspend aborted\n");
                return -1;
@@ -1592,13 +1604,21 @@
 static int pxa2xx_spi_resume(struct platform_device *pdev)
 {
        struct driver_data *drv_data = platform_get_drvdata(pdev);
+       void *reg = drv_data->ioaddr;
        int status = 0;

        /* Enable the SSP clock */
        pxa_set_cken(drv_data->master_info->clock_enable, 1);

+       /* Load saved SSP configuration */
+        write_SSCR0(0, reg);
+        write_SSCR1(drv_data->saved_sscr1, reg);
+        write_SSCR0(drv_data->saved_sscr0, reg);
+        write_SSITR(0, reg);
+       if (drv_data->ssp_type != PXA25x_SSP)
+                write_SSTO(drv_data->saved_sst0, reg);
+        write_SSPSP(drv_data->saved_sspsp, reg);
+
        /* Start the queue running */
        status = start_queue(drv_data);
        if (status != 0) {


On Fri, Feb 29, 2008 at 10:02 AM, Zik Saleeba <[EMAIL PROTECTED]> wrote:
> On Thu, Feb 21, 2008 at 2:32 PM, Zik Saleeba <[EMAIL PROTECTED]> wrote:
>  > I've been having some more problems with my SPI application on the
>  >  PXA270. When I suspend the system it all goes into suspend mode
>  >  correctly but when it comes back on resume any call to the pxa2xx_spi
>  >  code just hangs.
>
>  I've looked into this problem a bit more. It looks like suspend/resume
>  can never have worked on the pxa2xx spi subsystem.
>
>  One problem I've found is that after suspend the SSP registers don't
>  come back in their previous state. They need to be saved and restored.
>  I've added in some code to do that and it means that at least the
>  system doesn't hang as soon as spi is accessed during a resume. It
>  does however still hang at some later point. I'm still tracking that
>  one down.
>
>  I found that saving and restoring SSCR0, SSCR1, SSITR, SST0 (for
>  pxa270) and SSPSP was enough to bring the system back to life again.
>
>  Would more experienced people like to comment on whether I'm on the
>  right track here?
>
>  Cheers,
>  Zik
>

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general

Reply via email to