public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] OMAP3 McSPI:  Adds context save/restore
@ 2009-01-21 10:24 Hemanth V
  2009-01-21 17:16 ` Kevin Hilman
  0 siblings, 1 reply; 12+ messages in thread
From: Hemanth V @ 2009-01-21 10:24 UTC (permalink / raw)
  To: linux-omap

From: Hemanth V <hemanthv@ti.com>

This patch adds context save/restore feature to McSPI driver. This has been
tested by instrumenting the driver code i.e by adding a McSPI softreset
in omap2_mcspi_disable_clocks function.

Signed-off-by: Hemanth V <hemanthv@ti.com>

---
 drivers/spi/omap2_mcspi.c |   88 +++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 76 insertions(+), 12 deletions(-)

Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
===================================================================
--- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c	2009-01-21 15:03:12.000000000
+0530
+++ linux-omap-2.6/drivers/spi/omap2_mcspi.c	2009-01-21 15:05:20.000000000 +0530
@@ -133,6 +133,15 @@
 	int			word_len;
 };

+struct omap2_mcspi_regs {
+	u32 sysconfig;
+	u32 modulctrl;
+	u32 chconf0;
+	u32 wakeupenable;
+};
+
+static struct omap2_mcspi_regs omap2_mcspi_ctx[4];
+
 static struct workqueue_struct *omap2_mcspi_wq;

 #define MOD_REG_BIT(val, mask, set) do { \
@@ -219,6 +228,63 @@
 	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
 }

+static void omap2_mcspi_save_ctx(struct omap2_mcspi *mcspi)
+{
+	struct spi_master *spi_cntrl;
+	spi_cntrl = mcspi->master;
+
+	/* McSPI : context save */
+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl =
+		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL);
+
+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig =
+		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG);
+
+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 =
+		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0);
+
+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable =
+		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE);
+}
+
+static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
+{
+	struct spi_master *spi_cntrl;
+	spi_cntrl = mcspi->master;
+
+	/*McSPI : context restore */
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
+}
+static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
+{
+	omap2_mcspi_save_ctx(mcspi);
+
+	clk_disable(mcspi->ick);
+	clk_disable(mcspi->fck);
+}
+
+static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
+{
+	if (clk_enable(mcspi->ick))
+		return -ENODEV;
+	if (clk_enable(mcspi->fck))
+		return -ENODEV;
+
+	omap2_mcspi_restore_ctx(mcspi);
+
+	return 0;
+}
+
 static unsigned
 omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
 {
@@ -649,11 +715,11 @@
 			return ret;
 	}

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -ENODEV;
+
 	ret = omap2_mcspi_setup_transfer(spi, NULL);
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);

 	return ret;
 }
@@ -685,8 +751,8 @@
 	mcspi = container_of(work, struct omap2_mcspi, work);
 	spin_lock_irq(&mcspi->lock);

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return;

 	/* We only enable one channel at a time -- the one whose message is
 	 * at the head of the queue -- although this controller would gladly
@@ -788,8 +854,7 @@
 		spin_lock_irq(&mcspi->lock);
 	}

-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);

 	spin_unlock_irq(&mcspi->lock);
 }
@@ -877,8 +942,8 @@
 	struct spi_master	*master = mcspi->master;
 	u32			tmp;

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -1;

 	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
 			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
@@ -896,8 +961,7 @@

 	omap2_mcspi_set_master_mode(master);

-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);
 	return 0;
 }


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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-21 10:24 [PATCH] OMAP3 McSPI: Adds context save/restore Hemanth V
@ 2009-01-21 17:16 ` Kevin Hilman
  2009-01-22  5:48   ` Hemanth V
  0 siblings, 1 reply; 12+ messages in thread
From: Kevin Hilman @ 2009-01-21 17:16 UTC (permalink / raw)
  To: Hemanth V; +Cc: linux-omap

"Hemanth V" <hemanthv@ti.com> writes:

> From: Hemanth V <hemanthv@ti.com>
>
> This patch adds context save/restore feature to McSPI driver. This has been
> tested by instrumenting the driver code i.e by adding a McSPI softreset
> in omap2_mcspi_disable_clocks function.

Were you able to test this on the PM branch with off-mode enabled?

Some general comments:

The save/restore only affects a small number of registers and ones
that do not change very often.

So, I think the save/restore would be more efficiently done by getting
rid of the 'save_ctx' and using shadow regs in memory.  IOW, when ever
the registers are changed in the code, just update the copy in
omap2_mcspi_ctx.  Then you do not need a save_ctx function, you only
need a restore.

Also, the restore should normally check whether its powerdomain
actually went off before restoring.  The OMAP PM layer has the
function omap_pm_get_last_off_on_transaction_id() for this.

However, In the case of this driver, for only 4 registers it's
probably faster to just always restore.

> Signed-off-by: Hemanth V <hemanthv@ti.com>
>
> ---
>  drivers/spi/omap2_mcspi.c |   88 +++++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 76 insertions(+), 12 deletions(-)
>
> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
> ===================================================================
> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c	2009-01-21 15:03:12.000000000
> +0530
> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c	2009-01-21 15:05:20.000000000 +0530
> @@ -133,6 +133,15 @@
>  	int			word_len;
>  };
>
> +struct omap2_mcspi_regs {
> +	u32 sysconfig;
> +	u32 modulctrl;
> +	u32 chconf0;
> +	u32 wakeupenable;
> +};
> +
> +static struct omap2_mcspi_regs omap2_mcspi_ctx[4];
> +

Can you use a symbolic constant here instead of 4?  Something like
MAX_SPI_CONTROLLERS with a comment saying someting about omap2 having
3 and omap3 having 4.

>  static struct workqueue_struct *omap2_mcspi_wq;
>
>  #define MOD_REG_BIT(val, mask, set) do { \
> @@ -219,6 +228,63 @@
>  	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
>  }
>
> +static void omap2_mcspi_save_ctx(struct omap2_mcspi *mcspi)
> +{
> +	struct spi_master *spi_cntrl;
> +	spi_cntrl = mcspi->master;
> +
> +	/* McSPI : context save */
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl =
> +		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL);
> +
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig =
> +		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG);
> +
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 =
> +		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0);
> +
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable =
> +		mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE);
> +}
> +
> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
> +{
> +	struct spi_master *spi_cntrl;
> +	spi_cntrl = mcspi->master;
> +
> +	/*McSPI : context restore */
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
> +}
> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	omap2_mcspi_save_ctx(mcspi);
> +
> +	clk_disable(mcspi->ick);
> +	clk_disable(mcspi->fck);
> +}
> +
> +static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	if (clk_enable(mcspi->ick))
> +		return -ENODEV;
> +	if (clk_enable(mcspi->fck))
> +		return -ENODEV;
> +
> +	omap2_mcspi_restore_ctx(mcspi);
> +
> +	return 0;
> +}
> +
>  static unsigned
>  omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>  {
> @@ -649,11 +715,11 @@
>  			return ret;
>  	}
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -ENODEV;
> +
>  	ret = omap2_mcspi_setup_transfer(spi, NULL);
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>
>  	return ret;
>  }
> @@ -685,8 +751,8 @@
>  	mcspi = container_of(work, struct omap2_mcspi, work);
>  	spin_lock_irq(&mcspi->lock);
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return;
>
>  	/* We only enable one channel at a time -- the one whose message is
>  	 * at the head of the queue -- although this controller would gladly
> @@ -788,8 +854,7 @@
>  		spin_lock_irq(&mcspi->lock);
>  	}
>
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>
>  	spin_unlock_irq(&mcspi->lock);
>  }
> @@ -877,8 +942,8 @@
>  	struct spi_master	*master = mcspi->master;
>  	u32			tmp;
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -1;
>
>  	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
>  			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
> @@ -896,8 +961,7 @@
>
>  	omap2_mcspi_set_master_mode(master);
>
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>  	return 0;
>  }
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-21 17:16 ` Kevin Hilman
@ 2009-01-22  5:48   ` Hemanth V
  2009-01-23  6:56     ` Hemanth V
  0 siblings, 1 reply; 12+ messages in thread
From: Hemanth V @ 2009-01-22  5:48 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap

From: "Kevin Hilman" <khilman@deeprootsystems.com>
> "Hemanth V" <hemanthv@ti.com> writes:
>
>> From: Hemanth V <hemanthv@ti.com>
>>
>> This patch adds context save/restore feature to McSPI driver. This has 
>> been
>> tested by instrumenting the driver code i.e by adding a McSPI softreset
>> in omap2_mcspi_disable_clocks function.
>
> Were you able to test this on the PM branch with off-mode enabled?

Since OFF-mode is currently not working on 3430SDP board, I have tested this 
with instrumentation on the PM branch. The instrumentation was to do a 
softreset on clock disable to ensure all registers are reset to default 
values. Hence when you enable the clocks, context restore would get tested.

>
> Some general comments:
>
> The save/restore only affects a small number of registers and ones
> that do not change very often.
>
> So, I think the save/restore would be more efficiently done by getting
> rid of the 'save_ctx' and using shadow regs in memory.  IOW, when ever
> the registers are changed in the code, just update the copy in
> omap2_mcspi_ctx.  Then you do not need a save_ctx function, you only
> need a restore.

Yes I agree, will change this.

>
> Also, the restore should normally check whether its powerdomain
> actually went off before restoring.  The OMAP PM layer has the
> function omap_pm_get_last_off_on_transaction_id() for this.
>
> However, In the case of this driver, for only 4 registers it's
> probably faster to just always restore.

>
>> Signed-off-by: Hemanth V <hemanthv@ti.com>
>>
>> ---
>>  drivers/spi/omap2_mcspi.c |   88 
>> +++++++++++++++++++++++++++++++++++++++-------
>>  1 files changed, 76 insertions(+), 12 deletions(-)
>>
>> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
>> ===================================================================
>> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c 2009-01-21 
>> 15:03:12.000000000
>> +0530
>> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c 2009-01-21 
>> 15:05:20.000000000 +0530
>> @@ -133,6 +133,15 @@
>>  int word_len;
>>  };
>>
>> +struct omap2_mcspi_regs {
>> + u32 sysconfig;
>> + u32 modulctrl;
>> + u32 chconf0;
>> + u32 wakeupenable;
>> +};
>> +
>> +static struct omap2_mcspi_regs omap2_mcspi_ctx[4];
>> +
>
> Can you use a symbolic constant here instead of 4?  Something like
> MAX_SPI_CONTROLLERS with a comment saying someting about omap2 having
> 3 and omap3 having 4.

Yes, will changes this.

>
>>  static struct workqueue_struct *omap2_mcspi_wq;
>>
>>  #define MOD_REG_BIT(val, mask, set) do { \
>> @@ -219,6 +228,63 @@
>>  mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
>>  }
>>
>> +static void omap2_mcspi_save_ctx(struct omap2_mcspi *mcspi)
>> +{
>> + struct spi_master *spi_cntrl;
>> + spi_cntrl = mcspi->master;
>> +
>> + /* McSPI : context save */
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl =
>> + mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL);
>> +
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig =
>> + mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG);
>> +
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 =
>> + mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0);
>> +
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable =
>> + mcspi_read_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE);
>> +}
>> +
>> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
>> +{
>> + struct spi_master *spi_cntrl;
>> + spi_cntrl = mcspi->master;
>> +
>> + /*McSPI : context restore */
>> + mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
>> +
>> + mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
>> +
>> + mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
>> +
>> + mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
>> + omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
>> +}
>> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
>> +{
>> + omap2_mcspi_save_ctx(mcspi);
>> +
>> + clk_disable(mcspi->ick);
>> + clk_disable(mcspi->fck);
>> +}
>> +
>> +static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
>> +{
>> + if (clk_enable(mcspi->ick))
>> + return -ENODEV;
>> + if (clk_enable(mcspi->fck))
>> + return -ENODEV;
>> +
>> + omap2_mcspi_restore_ctx(mcspi);
>> +
>> + return 0;
>> +}
>> +
>>  static unsigned
>>  omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
>>  {
>> @@ -649,11 +715,11 @@
>>  return ret;
>>  }
>>
>> - clk_enable(mcspi->ick);
>> - clk_enable(mcspi->fck);
>> + if (omap2_mcspi_enable_clocks(mcspi))
>> + return -ENODEV;
>> +
>>  ret = omap2_mcspi_setup_transfer(spi, NULL);
>> - clk_disable(mcspi->fck);
>> - clk_disable(mcspi->ick);
>> + omap2_mcspi_disable_clocks(mcspi);
>>
>>  return ret;
>>  }
>> @@ -685,8 +751,8 @@
>>  mcspi = container_of(work, struct omap2_mcspi, work);
>>  spin_lock_irq(&mcspi->lock);
>>
>> - clk_enable(mcspi->ick);
>> - clk_enable(mcspi->fck);
>> + if (omap2_mcspi_enable_clocks(mcspi))
>> + return;
>>
>>  /* We only enable one channel at a time -- the one whose message is
>>  * at the head of the queue -- although this controller would gladly
>> @@ -788,8 +854,7 @@
>>  spin_lock_irq(&mcspi->lock);
>>  }
>>
>> - clk_disable(mcspi->fck);
>> - clk_disable(mcspi->ick);
>> + omap2_mcspi_disable_clocks(mcspi);
>>
>>  spin_unlock_irq(&mcspi->lock);
>>  }
>> @@ -877,8 +942,8 @@
>>  struct spi_master *master = mcspi->master;
>>  u32 tmp;
>>
>> - clk_enable(mcspi->ick);
>> - clk_enable(mcspi->fck);
>> + if (omap2_mcspi_enable_clocks(mcspi))
>> + return -1;
>>
>>  mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
>>  OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
>> @@ -896,8 +961,7 @@
>>
>>  omap2_mcspi_set_master_mode(master);
>>
>> - clk_disable(mcspi->fck);
>> - clk_disable(mcspi->ick);
>> + omap2_mcspi_disable_clocks(mcspi);
>>  return 0;
>>  }
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> 


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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-22  5:48   ` Hemanth V
@ 2009-01-23  6:56     ` Hemanth V
  2009-01-23 17:05       ` Kevin Hilman
  0 siblings, 1 reply; 12+ messages in thread
From: Hemanth V @ 2009-01-23  6:56 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap

From: Hemanth V <hemanthv@ti.com>

This patch adds context save/restore feature to McSPI driver. This has been
tested by instrumenting the driver code i.e by adding a McSPI softreset
in omap2_mcspi_disable_clocks function.

This patch includes review comment fixes

Signed-off-by: Hemanth V <hemanthv@ti.com>

---
 drivers/spi/omap2_mcspi.c |   94 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 74 insertions(+), 20 deletions(-)

Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
===================================================================
--- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c
+++ linux-omap-2.6/drivers/spi/omap2_mcspi.c
@@ -41,6 +41,9 @@

 #define OMAP2_MCSPI_MAX_FREQ		48000000

+/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
+#define OMAP2_MCSPI_MAX_CTRL 		4
+
 #define OMAP2_MCSPI_REVISION		0x00
 #define OMAP2_MCSPI_SYSCONFIG		0x10
 #define OMAP2_MCSPI_SYSSTATUS		0x14
@@ -133,6 +136,15 @@
 	int			word_len;
 };

+struct omap2_mcspi_regs {
+	u32 sysconfig;
+	u32 modulctrl;
+	u32 chconf0;
+	u32 wakeupenable;
+};
+
+static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
+
 static struct workqueue_struct *omap2_mcspi_wq;

 #define MOD_REG_BIT(val, mask, set) do { \
@@ -217,6 +229,45 @@
 	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
 	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
 	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
+
+	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
+}
+
+static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
+{
+	struct spi_master *spi_cntrl;
+	spi_cntrl = mcspi->master;
+
+	/*McSPI : context restore */
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
+
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
+}
+static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
+{
+	clk_disable(mcspi->ick);
+	clk_disable(mcspi->fck);
+}
+
+static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
+{
+	if (clk_enable(mcspi->ick))
+		return -ENODEV;
+	if (clk_enable(mcspi->fck))
+		return -ENODEV;
+
+	omap2_mcspi_restore_ctx(mcspi);
+
+	return 0;
 }

 static unsigned
@@ -486,10 +537,12 @@
 {
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi *mcspi;
+	struct spi_master *spi_cntrl;
 	u32 l = 0, div = 0;
 	u8 word_len = spi->bits_per_word;

 	mcspi = spi_master_get_devdata(spi->master);
+	spi_cntrl = mcspi->master;

 	if (t != NULL && t->bits_per_word)
 		word_len = t->bits_per_word;
@@ -537,6 +590,8 @@

 	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);

+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
+
 	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
 			OMAP2_MCSPI_MAX_FREQ / (1 << div),
 			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
@@ -649,11 +704,11 @@
 			return ret;
 	}

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -ENODEV;
+
 	ret = omap2_mcspi_setup_transfer(spi, NULL);
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);

 	return ret;
 }
@@ -685,8 +740,8 @@
 	mcspi = container_of(work, struct omap2_mcspi, work);
 	spin_lock_irq(&mcspi->lock);

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return;

 	/* We only enable one channel at a time -- the one whose message is
 	 * at the head of the queue -- although this controller would gladly
@@ -788,8 +843,7 @@
 		spin_lock_irq(&mcspi->lock);
 	}

-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);

 	spin_unlock_irq(&mcspi->lock);
 }
@@ -877,8 +931,8 @@
 	struct spi_master	*master = mcspi->master;
 	u32			tmp;

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -1;

 	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
 			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
@@ -886,18 +940,18 @@
 		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
 	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));

-	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
-			OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
-			OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
-			OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
-
-	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
-			OMAP2_MCSPI_WAKEUPENABLE_WKEN);
+	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
+		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
+		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
+	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
+	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
+
+	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
+	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
+	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;

 	omap2_mcspi_set_master_mode(master);
-
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);
 	return 0;
 }





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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-23  6:56     ` Hemanth V
@ 2009-01-23 17:05       ` Kevin Hilman
  2009-01-27  6:50         ` Hemanth V
  0 siblings, 1 reply; 12+ messages in thread
From: Kevin Hilman @ 2009-01-23 17:05 UTC (permalink / raw)
  To: Hemanth V; +Cc: linux-omap

"Hemanth V" <hemanthv@ti.com> writes:

> From: Hemanth V <hemanthv@ti.com>
>
> This patch adds context save/restore feature to McSPI driver. This has been
> tested by instrumenting the driver code i.e by adding a McSPI softreset
> in omap2_mcspi_disable_clocks function.
>
> This patch includes review comment fixes
>
> Signed-off-by: Hemanth V <hemanthv@ti.com>

Thanks, this looks much better. 

Could you add a comment/description just before the definition of
omap2_mcspi_regs which describes how the save/restore works, and
that any modifying of these registers must also update the
shadow regs.

Also, one very minor comment cleanup below.

After this, I'll apply it to the pm branch.

Thanks,

Kevin

> ---
>  drivers/spi/omap2_mcspi.c |   94 ++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 74 insertions(+), 20 deletions(-)
>
> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
> ===================================================================
> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c
> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c
> @@ -41,6 +41,9 @@
>
>  #define OMAP2_MCSPI_MAX_FREQ		48000000
>
> +/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
> +#define OMAP2_MCSPI_MAX_CTRL 		4
> +
>  #define OMAP2_MCSPI_REVISION		0x00
>  #define OMAP2_MCSPI_SYSCONFIG		0x10
>  #define OMAP2_MCSPI_SYSSTATUS		0x14
> @@ -133,6 +136,15 @@
>  	int			word_len;
>  };
>
> +struct omap2_mcspi_regs {
> +	u32 sysconfig;
> +	u32 modulctrl;
> +	u32 chconf0;
> +	u32 wakeupenable;
> +};
> +
> +static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
> +
>  static struct workqueue_struct *omap2_mcspi_wq;
>
>  #define MOD_REG_BIT(val, mask, set) do { \
> @@ -217,6 +229,45 @@
>  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
>  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
>  	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
> +
> +	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
> +}
> +
> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
> +{
> +	struct spi_master *spi_cntrl;
> +	spi_cntrl = mcspi->master;
> +
> +	/*McSPI : context restore */

add space after /*

> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
> +
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
> +}
> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	clk_disable(mcspi->ick);
> +	clk_disable(mcspi->fck);
> +}
> +
> +static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	if (clk_enable(mcspi->ick))
> +		return -ENODEV;
> +	if (clk_enable(mcspi->fck))
> +		return -ENODEV;
> +
> +	omap2_mcspi_restore_ctx(mcspi);
> +
> +	return 0;
>  }
>
>  static unsigned
> @@ -486,10 +537,12 @@
>  {
>  	struct omap2_mcspi_cs *cs = spi->controller_state;
>  	struct omap2_mcspi *mcspi;
> +	struct spi_master *spi_cntrl;
>  	u32 l = 0, div = 0;
>  	u8 word_len = spi->bits_per_word;
>
>  	mcspi = spi_master_get_devdata(spi->master);
> +	spi_cntrl = mcspi->master;
>
>  	if (t != NULL && t->bits_per_word)
>  		word_len = t->bits_per_word;
> @@ -537,6 +590,8 @@
>
>  	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
>
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
> +
>  	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
>  			OMAP2_MCSPI_MAX_FREQ / (1 << div),
>  			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
> @@ -649,11 +704,11 @@
>  			return ret;
>  	}
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -ENODEV;
> +
>  	ret = omap2_mcspi_setup_transfer(spi, NULL);
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>
>  	return ret;
>  }
> @@ -685,8 +740,8 @@
>  	mcspi = container_of(work, struct omap2_mcspi, work);
>  	spin_lock_irq(&mcspi->lock);
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return;
>
>  	/* We only enable one channel at a time -- the one whose message is
>  	 * at the head of the queue -- although this controller would gladly
> @@ -788,8 +843,7 @@
>  		spin_lock_irq(&mcspi->lock);
>  	}
>
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>
>  	spin_unlock_irq(&mcspi->lock);
>  }
> @@ -877,8 +931,8 @@
>  	struct spi_master	*master = mcspi->master;
>  	u32			tmp;
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -1;
>
>  	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
>  			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
> @@ -886,18 +940,18 @@
>  		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
>  	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
>
> -	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
> -			OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> -			OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> -			OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
> -
> -	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
> -			OMAP2_MCSPI_WAKEUPENABLE_WKEN);
> +	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> +		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> +		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
> +	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
> +	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
> +
> +	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
> +	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
> +	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;
>
>  	omap2_mcspi_set_master_mode(master);
> -
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>  	return 0;
>  }

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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-23 17:05       ` Kevin Hilman
@ 2009-01-27  6:50         ` Hemanth V
  2009-01-27 14:59           ` Kevin Hilman
  0 siblings, 1 reply; 12+ messages in thread
From: Hemanth V @ 2009-01-27  6:50 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap

From: Hemanth V <hemanthv@ti.com>

This patch adds context save/restore feature to McSPI driver. This has been
tested by instrumenting the driver code i.e by adding a McSPI softreset
in omap2_mcspi_disable_clocks function.

This patch includes review comment fixes

Signed-off-by: Hemanth V <hemanthv@ti.com>

---
 drivers/spi/omap2_mcspi.c |   97 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 77 insertions(+), 20 deletions(-)

Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
===================================================================
--- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c
+++ linux-omap-2.6/drivers/spi/omap2_mcspi.c
@@ -41,6 +41,9 @@

 #define OMAP2_MCSPI_MAX_FREQ		48000000

+/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
+#define OMAP2_MCSPI_MAX_CTRL 		4
+
 #define OMAP2_MCSPI_REVISION		0x00
 #define OMAP2_MCSPI_SYSCONFIG		0x10
 #define OMAP2_MCSPI_SYSSTATUS		0x14
@@ -133,6 +136,18 @@
 	int			word_len;
 };

+/* used for context save and restore, structure members to be updated whenever
+ * corresponding registers are modified.
+ */
+struct omap2_mcspi_regs {
+	u32 sysconfig;
+	u32 modulctrl;
+	u32 chconf0;
+	u32 wakeupenable;
+};
+
+static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
+
 static struct workqueue_struct *omap2_mcspi_wq;

 #define MOD_REG_BIT(val, mask, set) do { \
@@ -217,6 +232,45 @@
 	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
 	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
 	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
+
+	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
+}
+
+static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
+{
+	struct spi_master *spi_cntrl;
+	spi_cntrl = mcspi->master;
+
+	/* McSPI : context restore */
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
+
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
+}
+static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
+{
+	clk_disable(mcspi->ick);
+	clk_disable(mcspi->fck);
+}
+
+static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
+{
+	if (clk_enable(mcspi->ick))
+		return -ENODEV;
+	if (clk_enable(mcspi->fck))
+		return -ENODEV;
+
+	omap2_mcspi_restore_ctx(mcspi);
+
+	return 0;
 }

 static unsigned
@@ -486,10 +540,12 @@
 {
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi *mcspi;
+	struct spi_master *spi_cntrl;
 	u32 l = 0, div = 0;
 	u8 word_len = spi->bits_per_word;

 	mcspi = spi_master_get_devdata(spi->master);
+	spi_cntrl = mcspi->master;

 	if (t != NULL && t->bits_per_word)
 		word_len = t->bits_per_word;
@@ -537,6 +593,8 @@

 	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);

+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
+
 	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
 			OMAP2_MCSPI_MAX_FREQ / (1 << div),
 			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
@@ -649,11 +707,11 @@
 			return ret;
 	}

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -ENODEV;
+
 	ret = omap2_mcspi_setup_transfer(spi, NULL);
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);

 	return ret;
 }
@@ -685,8 +743,8 @@
 	mcspi = container_of(work, struct omap2_mcspi, work);
 	spin_lock_irq(&mcspi->lock);

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return;

 	/* We only enable one channel at a time -- the one whose message is
 	 * at the head of the queue -- although this controller would gladly
@@ -788,8 +846,7 @@
 		spin_lock_irq(&mcspi->lock);
 	}

-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);

 	spin_unlock_irq(&mcspi->lock);
 }
@@ -877,8 +934,8 @@
 	struct spi_master	*master = mcspi->master;
 	u32			tmp;

-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -1;

 	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
 			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
@@ -886,18 +943,18 @@
 		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
 	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));

-	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
-			OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
-			OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
-			OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
-
-	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
-			OMAP2_MCSPI_WAKEUPENABLE_WKEN);
+	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
+		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
+		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
+	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
+	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
+
+	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
+	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
+	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;

 	omap2_mcspi_set_master_mode(master);
-
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);
 	return 0;
 }






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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-27  6:50         ` Hemanth V
@ 2009-01-27 14:59           ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2009-01-27 14:59 UTC (permalink / raw)
  To: Hemanth V; +Cc: linux-omap

"Hemanth V" <hemanthv@ti.com> writes:

> From: Hemanth V <hemanthv@ti.com>
>
> This patch adds context save/restore feature to McSPI driver. This has been
> tested by instrumenting the driver code i.e by adding a McSPI softreset
> in omap2_mcspi_disable_clocks function.
>
> This patch includes review comment fixes
>
> Signed-off-by: Hemanth V <hemanthv@ti.com>

This patch has line-wrapping problems, please re-send.

Kevin

> ---
>  drivers/spi/omap2_mcspi.c |   97 ++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 77 insertions(+), 20 deletions(-)
>
> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
> ===================================================================
> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c
> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c
> @@ -41,6 +41,9 @@
>
>  #define OMAP2_MCSPI_MAX_FREQ		48000000
>
> +/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
> +#define OMAP2_MCSPI_MAX_CTRL 		4
> +
>  #define OMAP2_MCSPI_REVISION		0x00
>  #define OMAP2_MCSPI_SYSCONFIG		0x10
>  #define OMAP2_MCSPI_SYSSTATUS		0x14
> @@ -133,6 +136,18 @@
>  	int			word_len;
>  };
>
> +/* used for context save and restore, structure members to be updated whenever
> + * corresponding registers are modified.
> + */
> +struct omap2_mcspi_regs {
> +	u32 sysconfig;
> +	u32 modulctrl;
> +	u32 chconf0;
> +	u32 wakeupenable;
> +};
> +
> +static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
> +
>  static struct workqueue_struct *omap2_mcspi_wq;
>
>  #define MOD_REG_BIT(val, mask, set) do { \
> @@ -217,6 +232,45 @@
>  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
>  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
>  	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
> +
> +	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
> +}
> +
> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
> +{
> +	struct spi_master *spi_cntrl;
> +	spi_cntrl = mcspi->master;
> +
> +	/* McSPI : context restore */
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
> +
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
> +}
> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	clk_disable(mcspi->ick);
> +	clk_disable(mcspi->fck);
> +}
> +
> +static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	if (clk_enable(mcspi->ick))
> +		return -ENODEV;
> +	if (clk_enable(mcspi->fck))
> +		return -ENODEV;
> +
> +	omap2_mcspi_restore_ctx(mcspi);
> +
> +	return 0;
>  }
>
>  static unsigned
> @@ -486,10 +540,12 @@
>  {
>  	struct omap2_mcspi_cs *cs = spi->controller_state;
>  	struct omap2_mcspi *mcspi;
> +	struct spi_master *spi_cntrl;
>  	u32 l = 0, div = 0;
>  	u8 word_len = spi->bits_per_word;
>
>  	mcspi = spi_master_get_devdata(spi->master);
> +	spi_cntrl = mcspi->master;
>
>  	if (t != NULL && t->bits_per_word)
>  		word_len = t->bits_per_word;
> @@ -537,6 +593,8 @@
>
>  	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
>
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
> +
>  	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
>  			OMAP2_MCSPI_MAX_FREQ / (1 << div),
>  			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
> @@ -649,11 +707,11 @@
>  			return ret;
>  	}
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -ENODEV;
> +
>  	ret = omap2_mcspi_setup_transfer(spi, NULL);
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>
>  	return ret;
>  }
> @@ -685,8 +743,8 @@
>  	mcspi = container_of(work, struct omap2_mcspi, work);
>  	spin_lock_irq(&mcspi->lock);
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return;
>
>  	/* We only enable one channel at a time -- the one whose message is
>  	 * at the head of the queue -- although this controller would gladly
> @@ -788,8 +846,7 @@
>  		spin_lock_irq(&mcspi->lock);
>  	}
>
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>
>  	spin_unlock_irq(&mcspi->lock);
>  }
> @@ -877,8 +934,8 @@
>  	struct spi_master	*master = mcspi->master;
>  	u32			tmp;
>
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -1;
>
>  	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
>  			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
> @@ -886,18 +943,18 @@
>  		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
>  	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
>
> -	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
> -			OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> -			OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> -			OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
> -
> -	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
> -			OMAP2_MCSPI_WAKEUPENABLE_WKEN);
> +	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> +		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> +		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
> +	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
> +	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
> +
> +	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
> +	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
> +	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;
>
>  	omap2_mcspi_set_master_mode(master);
> -
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>  	return 0;
>  }

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

* [PATCH] OMAP3 McSPI:  Adds context save/restore
@ 2009-01-28  9:11 Nayak, Rajendra
  2009-01-28 16:18 ` Kevin Hilman
  2009-01-29 19:06 ` Imre Deak
  0 siblings, 2 replies; 12+ messages in thread
From: Nayak, Rajendra @ 2009-01-28  9:11 UTC (permalink / raw)
  To: linux-omap@vger.kernel.org; +Cc: Kevin Hilman, V, Hemanth

From: Hemanth V <hemanthv@ti.com>

This patch adds context save/restore feature to McSPI driver.
This has been tested by instrumenting the driver code i.e by 
adding a McSPI softreset in omap2_mcspi_disable_clocks function.

This patch includes review comment fixes

Signed-off-by: Hemanth V <hemanthv@ti.com>

---
 drivers/spi/omap2_mcspi.c |   97 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 77 insertions(+), 20 deletions(-)

Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
===================================================================
--- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c	2009-01-27 11:45:06.000000000 +0530
+++ linux-omap-2.6/drivers/spi/omap2_mcspi.c	2009-01-27 11:53:16.000000000 +0530
@@ -41,6 +41,9 @@
 
 #define OMAP2_MCSPI_MAX_FREQ		48000000
 
+/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
+#define OMAP2_MCSPI_MAX_CTRL 		4
+
 #define OMAP2_MCSPI_REVISION		0x00
 #define OMAP2_MCSPI_SYSCONFIG		0x10
 #define OMAP2_MCSPI_SYSSTATUS		0x14
@@ -133,6 +136,18 @@
 	int			word_len;
 };
 
+/* used for context save and restore, structure members to be updated whenever
+ * corresponding registers are modified.
+ */
+struct omap2_mcspi_regs {
+	u32 sysconfig;
+	u32 modulctrl;
+	u32 chconf0;
+	u32 wakeupenable;
+};
+
+static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
+
 static struct workqueue_struct *omap2_mcspi_wq;
 
 #define MOD_REG_BIT(val, mask, set) do { \
@@ -217,6 +232,45 @@
 	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
 	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
 	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
+
+	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
+}
+
+static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
+{
+	struct spi_master *spi_cntrl;
+	spi_cntrl = mcspi->master;
+
+	/* McSPI: context restore */
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
+
+
+	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
+			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
+}
+static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
+{
+	clk_disable(mcspi->ick);
+	clk_disable(mcspi->fck);
+}
+
+static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
+{
+	if (clk_enable(mcspi->ick))
+		return -ENODEV;
+	if (clk_enable(mcspi->fck))
+		return -ENODEV;
+
+	omap2_mcspi_restore_ctx(mcspi);
+
+	return 0;
 }
 
 static unsigned
@@ -486,10 +540,12 @@
 {
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi *mcspi;
+	struct spi_master *spi_cntrl;
 	u32 l = 0, div = 0;
 	u8 word_len = spi->bits_per_word;
 
 	mcspi = spi_master_get_devdata(spi->master);
+	spi_cntrl = mcspi->master;
 
 	if (t != NULL && t->bits_per_word)
 		word_len = t->bits_per_word;
@@ -537,6 +593,8 @@
 
 	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
 
+	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
+
 	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
 			OMAP2_MCSPI_MAX_FREQ / (1 << div),
 			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
@@ -649,11 +707,11 @@
 			return ret;
 	}
 
-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -ENODEV;
+
 	ret = omap2_mcspi_setup_transfer(spi, NULL);
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);
 
 	return ret;
 }
@@ -685,8 +743,8 @@
 	mcspi = container_of(work, struct omap2_mcspi, work);
 	spin_lock_irq(&mcspi->lock);
 
-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return;
 
 	/* We only enable one channel at a time -- the one whose message is
 	 * at the head of the queue -- although this controller would gladly
@@ -788,8 +846,7 @@
 		spin_lock_irq(&mcspi->lock);
 	}
 
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);
 
 	spin_unlock_irq(&mcspi->lock);
 }
@@ -877,8 +934,8 @@
 	struct spi_master	*master = mcspi->master;
 	u32			tmp;
 
-	clk_enable(mcspi->ick);
-	clk_enable(mcspi->fck);
+	if (omap2_mcspi_enable_clocks(mcspi))
+		return -1;
 
 	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
 			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
@@ -886,18 +943,18 @@
 		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
 	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
 
-	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
-			OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
-			OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
-			OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
-
-	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
-			OMAP2_MCSPI_WAKEUPENABLE_WKEN);
+	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
+		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
+		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
+	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
+	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
+
+	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
+	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
+	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;
 
 	omap2_mcspi_set_master_mode(master);
-
-	clk_disable(mcspi->fck);
-	clk_disable(mcspi->ick);
+	omap2_mcspi_disable_clocks(mcspi);
 	return 0;
 }
 

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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-28  9:11 Nayak, Rajendra
@ 2009-01-28 16:18 ` Kevin Hilman
  2009-01-29 19:06 ` Imre Deak
  1 sibling, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2009-01-28 16:18 UTC (permalink / raw)
  To: Nayak, Rajendra; +Cc: linux-omap@vger.kernel.org, V, Hemanth

"Nayak, Rajendra" <rnayak@ti.com> writes:

> From: Hemanth V <hemanthv@ti.com>
>
> This patch adds context save/restore feature to McSPI driver.
> This has been tested by instrumenting the driver code i.e by 
> adding a McSPI softreset in omap2_mcspi_disable_clocks function.
>
> This patch includes review comment fixes
>
> Signed-off-by: Hemanth V <hemanthv@ti.com>

Thanks, pushed to PM branch.

Kevin


> ---
>  drivers/spi/omap2_mcspi.c |   97 ++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 77 insertions(+), 20 deletions(-)
>
> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
> ===================================================================
> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c	2009-01-27 11:45:06.000000000 +0530
> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c	2009-01-27 11:53:16.000000000 +0530
> @@ -41,6 +41,9 @@
>  
>  #define OMAP2_MCSPI_MAX_FREQ		48000000
>  
> +/* OMAP2 has 3 SPI controllers, while OMAP3 has 4 */
> +#define OMAP2_MCSPI_MAX_CTRL 		4
> +
>  #define OMAP2_MCSPI_REVISION		0x00
>  #define OMAP2_MCSPI_SYSCONFIG		0x10
>  #define OMAP2_MCSPI_SYSSTATUS		0x14
> @@ -133,6 +136,18 @@
>  	int			word_len;
>  };
>  
> +/* used for context save and restore, structure members to be updated whenever
> + * corresponding registers are modified.
> + */
> +struct omap2_mcspi_regs {
> +	u32 sysconfig;
> +	u32 modulctrl;
> +	u32 chconf0;
> +	u32 wakeupenable;
> +};
> +
> +static struct omap2_mcspi_regs omap2_mcspi_ctx[OMAP2_MCSPI_MAX_CTRL];
> +
>  static struct workqueue_struct *omap2_mcspi_wq;
>  
>  #define MOD_REG_BIT(val, mask, set) do { \
> @@ -217,6 +232,45 @@
>  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_MS, 0);
>  	MOD_REG_BIT(l, OMAP2_MCSPI_MODULCTRL_SINGLE, 1);
>  	mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);
> +
> +	omap2_mcspi_ctx[master->bus_num - 1].modulctrl = l;
> +}
> +
> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
> +{
> +	struct spi_master *spi_cntrl;
> +	spi_cntrl = mcspi->master;
> +
> +	/* McSPI: context restore */
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
> +
> +
> +	mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
> +			omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
> +}
> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	clk_disable(mcspi->ick);
> +	clk_disable(mcspi->fck);
> +}
> +
> +static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi)
> +{
> +	if (clk_enable(mcspi->ick))
> +		return -ENODEV;
> +	if (clk_enable(mcspi->fck))
> +		return -ENODEV;
> +
> +	omap2_mcspi_restore_ctx(mcspi);
> +
> +	return 0;
>  }
>  
>  static unsigned
> @@ -486,10 +540,12 @@
>  {
>  	struct omap2_mcspi_cs *cs = spi->controller_state;
>  	struct omap2_mcspi *mcspi;
> +	struct spi_master *spi_cntrl;
>  	u32 l = 0, div = 0;
>  	u8 word_len = spi->bits_per_word;
>  
>  	mcspi = spi_master_get_devdata(spi->master);
> +	spi_cntrl = mcspi->master;
>  
>  	if (t != NULL && t->bits_per_word)
>  		word_len = t->bits_per_word;
> @@ -537,6 +593,8 @@
>  
>  	mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
>  
> +	omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
> +
>  	dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
>  			OMAP2_MCSPI_MAX_FREQ / (1 << div),
>  			(spi->mode & SPI_CPHA) ? "trailing" : "leading",
> @@ -649,11 +707,11 @@
>  			return ret;
>  	}
>  
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -ENODEV;
> +
>  	ret = omap2_mcspi_setup_transfer(spi, NULL);
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>  
>  	return ret;
>  }
> @@ -685,8 +743,8 @@
>  	mcspi = container_of(work, struct omap2_mcspi, work);
>  	spin_lock_irq(&mcspi->lock);
>  
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return;
>  
>  	/* We only enable one channel at a time -- the one whose message is
>  	 * at the head of the queue -- although this controller would gladly
> @@ -788,8 +846,7 @@
>  		spin_lock_irq(&mcspi->lock);
>  	}
>  
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>  
>  	spin_unlock_irq(&mcspi->lock);
>  }
> @@ -877,8 +934,8 @@
>  	struct spi_master	*master = mcspi->master;
>  	u32			tmp;
>  
> -	clk_enable(mcspi->ick);
> -	clk_enable(mcspi->fck);
> +	if (omap2_mcspi_enable_clocks(mcspi))
> +		return -1;
>  
>  	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
>  			OMAP2_MCSPI_SYSCONFIG_SOFTRESET);
> @@ -886,18 +943,18 @@
>  		tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS);
>  	} while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
>  
> -	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
> -			OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> -			OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> -			OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
> -
> -	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
> -			OMAP2_MCSPI_WAKEUPENABLE_WKEN);
> +	tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
> +		OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
> +		OMAP2_MCSPI_SYSCONFIG_SMARTIDLE;
> +	mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp);
> +	omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp;
> +
> +	tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN;
> +	mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp);
> +	omap2_mcspi_ctx[master->bus_num - 1].wakeupenable = tmp;
>  
>  	omap2_mcspi_set_master_mode(master);
> -
> -	clk_disable(mcspi->fck);
> -	clk_disable(mcspi->ick);
> +	omap2_mcspi_disable_clocks(mcspi);
>  	return 0;
>  }
>  

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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-28  9:11 Nayak, Rajendra
  2009-01-28 16:18 ` Kevin Hilman
@ 2009-01-29 19:06 ` Imre Deak
  2009-01-30  6:23   ` Hemanth V
  1 sibling, 1 reply; 12+ messages in thread
From: Imre Deak @ 2009-01-29 19:06 UTC (permalink / raw)
  To: ext Nayak, Rajendra; +Cc: linux-omap@vger.kernel.org, Kevin Hilman, V, Hemanth

On Wed, Jan 28, 2009 at 10:11:29AM +0100, ext Nayak, Rajendra wrote:
> From: Hemanth V <hemanthv@ti.com>
> 
> This patch adds context save/restore feature to McSPI driver.
> This has been tested by instrumenting the driver code i.e by
> adding a McSPI softreset in omap2_mcspi_disable_clocks function.
> 
> This patch includes review comment fixes
> 
> Signed-off-by: Hemanth V <hemanthv@ti.com>
> 
> ---
>  drivers/spi/omap2_mcspi.c |   97 ++++++++++++++++++++++++++++++++++++----------
>  1 files changed, 77 insertions(+), 20 deletions(-)
> 
> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
> ===================================================================
> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c       2009-01-27 11:45:06.000000000 +0530
> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c    2009-01-27 11:53:16.000000000 +0530
>
> [...]
>
> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
> +{
> +       struct spi_master *spi_cntrl;
> +       spi_cntrl = mcspi->master;
> +
> +       /* McSPI: context restore */
> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl);
> +
> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig);
> +
> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);

You have to restore this to the proper CHCONF register. And in the
current form you have to restore all of them.

> +
> +
> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable);
> +}
> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
> +{
> +       clk_disable(mcspi->ick);
> +       clk_disable(mcspi->fck);
> +}
> +
> [...]
>
> @@ -537,6 +593,8 @@
> 
>         mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
> 
> +       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;

And here save it to a slot based on CS.

--Imre



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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-29 19:06 ` Imre Deak
@ 2009-01-30  6:23   ` Hemanth V
  2009-01-30  8:06     ` Imre Deak
  0 siblings, 1 reply; 12+ messages in thread
From: Hemanth V @ 2009-01-30  6:23 UTC (permalink / raw)
  To: Imre Deak, ext Nayak, Rajendra; +Cc: linux-omap, Kevin Hilman


----- Original Message ----- 
From: "Imre Deak" <imre.deak@nokia.com>
To: "ext Nayak, Rajendra" <rnayak@ti.com>
Cc: <linux-omap@vger.kernel.org>; "Kevin Hilman" 
<khilman@deeprootsystems.com>; "V, Hemanth" <hemanthv@ti.com>
Sent: Friday, January 30, 2009 12:36 AM
Subject: Re: [PATCH] OMAP3 McSPI: Adds context save/restore


> On Wed, Jan 28, 2009 at 10:11:29AM +0100, ext Nayak, Rajendra wrote:
>> From: Hemanth V <hemanthv@ti.com>
>>
>> This patch adds context save/restore feature to McSPI driver.
>> This has been tested by instrumenting the driver code i.e by
>> adding a McSPI softreset in omap2_mcspi_disable_clocks function.
>>
>> This patch includes review comment fixes
>>
>> Signed-off-by: Hemanth V <hemanthv@ti.com>
>>
>> ---
>>  drivers/spi/omap2_mcspi.c |   97 
>> ++++++++++++++++++++++++++++++++++++----------
>>  1 files changed, 77 insertions(+), 20 deletions(-)
>>
>> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
>> ===================================================================
>> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c       2009-01-27 
>> 11:45:06.000000000 +0530
>> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c    2009-01-27 
>> 11:53:16.000000000 +0530
>>
>> [...]
>>
>> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
>> +{
>> +       struct spi_master *spi_cntrl;
>> +       spi_cntrl = mcspi->master;
>> +
>> +       /* McSPI: context restore */
>> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
>> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 
>> 1].modulctrl);
>> +
>> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
>> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 
>> 1].sysconfig);
>> +
>> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
>> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
>
> You have to restore this to the proper CHCONF register. And in the
> current form you have to restore all of them.

Currently only CS0 CHCONF i.e chconf0 is being saved and restored, since its 
the only one configured and used
by the driver.

>
>> +
>> +
>> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
>> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 
>> 1].wakeupenable);
>> +}
>> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
>> +{
>> +       clk_disable(mcspi->ick);
>> +       clk_disable(mcspi->fck);
>> +}
>> +
>> [...]
>>
>> @@ -537,6 +593,8 @@
>>
>>         mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
>>
>> +       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
>
> And here save it to a slot based on CS.
>
> --Imre
>
>
>
> 


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

* Re: [PATCH] OMAP3 McSPI:  Adds context save/restore
  2009-01-30  6:23   ` Hemanth V
@ 2009-01-30  8:06     ` Imre Deak
  0 siblings, 0 replies; 12+ messages in thread
From: Imre Deak @ 2009-01-30  8:06 UTC (permalink / raw)
  To: ext Hemanth V
  Cc: ext Nayak, Rajendra, linux-omap@vger.kernel.org, Kevin Hilman

On Fri, Jan 30, 2009 at 07:23:16AM +0100, ext Hemanth V wrote:
> 
> ----- Original Message -----
> From: "Imre Deak" <imre.deak@nokia.com>
> To: "ext Nayak, Rajendra" <rnayak@ti.com>
> Cc: <linux-omap@vger.kernel.org>; "Kevin Hilman"
> <khilman@deeprootsystems.com>; "V, Hemanth" <hemanthv@ti.com>
> Sent: Friday, January 30, 2009 12:36 AM
> Subject: Re: [PATCH] OMAP3 McSPI: Adds context save/restore
> 
> 
> > On Wed, Jan 28, 2009 at 10:11:29AM +0100, ext Nayak, Rajendra wrote:
> >> From: Hemanth V <hemanthv@ti.com>
> >>
> >> This patch adds context save/restore feature to McSPI driver.
> >> This has been tested by instrumenting the driver code i.e by
> >> adding a McSPI softreset in omap2_mcspi_disable_clocks function.
> >>
> >> This patch includes review comment fixes
> >>
> >> Signed-off-by: Hemanth V <hemanthv@ti.com>
> >>
> >> ---
> >>  drivers/spi/omap2_mcspi.c |   97
> >> ++++++++++++++++++++++++++++++++++++----------
> >>  1 files changed, 77 insertions(+), 20 deletions(-)
> >>
> >> Index: linux-omap-2.6/drivers/spi/omap2_mcspi.c
> >> ===================================================================
> >> --- linux-omap-2.6.orig/drivers/spi/omap2_mcspi.c       2009-01-27
> >> 11:45:06.000000000 +0530
> >> +++ linux-omap-2.6/drivers/spi/omap2_mcspi.c    2009-01-27
> >> 11:53:16.000000000 +0530
> >>
> >> [...]
> >>
> >> +static void omap2_mcspi_restore_ctx(struct omap2_mcspi *mcspi)
> >> +{
> >> +       struct spi_master *spi_cntrl;
> >> +       spi_cntrl = mcspi->master;
> >> +
> >> +       /* McSPI: context restore */
> >> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL,
> >> +                       omap2_mcspi_ctx[spi_cntrl->bus_num -
> >> 1].modulctrl);
> >> +
> >> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG,
> >> +                       omap2_mcspi_ctx[spi_cntrl->bus_num -
> >> 1].sysconfig);
> >> +
> >> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_CHCONF0,
> >> +                       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0);
> >
> > You have to restore this to the proper CHCONF register. And in the
> > current form you have to restore all of them.
> 
> Currently only CS0 CHCONF i.e chconf0 is being saved and restored, since its
> the only one configured and used
> by the driver.

What do you mean, your specific HW configuration has only an SPI device
with CS0? This driver _will_ use all CHCONFx registers based on what CS
lines are used by the SPI devices on a given board.

--Imre

> 
> >
> >> +
> >> +
> >> +       mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE,
> >> +                       omap2_mcspi_ctx[spi_cntrl->bus_num -
> >> 1].wakeupenable);
> >> +}
> >> +static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi)
> >> +{
> >> +       clk_disable(mcspi->ick);
> >> +       clk_disable(mcspi->fck);
> >> +}
> >> +
> >> [...]
> >>
> >> @@ -537,6 +593,8 @@
> >>
> >>         mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l);
> >>
> >> +       omap2_mcspi_ctx[spi_cntrl->bus_num - 1].chconf0 = l;
> >
> > And here save it to a slot based on CS.
> >
> > --Imre
> >
> >
> >
> >
> 

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

end of thread, other threads:[~2009-01-30  8:09 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-21 10:24 [PATCH] OMAP3 McSPI: Adds context save/restore Hemanth V
2009-01-21 17:16 ` Kevin Hilman
2009-01-22  5:48   ` Hemanth V
2009-01-23  6:56     ` Hemanth V
2009-01-23 17:05       ` Kevin Hilman
2009-01-27  6:50         ` Hemanth V
2009-01-27 14:59           ` Kevin Hilman
  -- strict thread matches above, loose matches on Subject: below --
2009-01-28  9:11 Nayak, Rajendra
2009-01-28 16:18 ` Kevin Hilman
2009-01-29 19:06 ` Imre Deak
2009-01-30  6:23   ` Hemanth V
2009-01-30  8:06     ` Imre Deak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox