Skip to contentSkip to conversation

OMAP2: Spi: Force CS to be in inactive state after off-mode transition

PATCH Superseded Gregory CLEMENT 2 participants 3 messages Nov 12, 2010 SPI

v3 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/1 OMAP2: Spi: Force CS to be in inactive state after off-mode transition

When SPI wake up from OFF mode, CS is in the wrong state: force it to the inactive state.

During the system life, I monitored the CS behavior using a oscilloscope. I also activated debug in omap2_mcspi, so I saw when driver disable the clocks and Each time the CS was in the correct state.
It was only when system was put suspend to ram with off-mode activated that on resume the CS was in wrong state( ie activated).

---
 drivers/spi/omap2_mcspi.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)
drivers/spi/omap2_mcspi.c +28 -0
index 2a651e6..708990e 100644
@@ -1305,11 +1305,40 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:omap2_mcspi");
 +#ifdef	CONFIG_PM
+/* When SPI wake up, CS is in wrong state: force it to unactive state*/
+static int omap2_mcspi_resume(struct platform_device *pdev)
+{
+	struct spi_master	*master;
+	struct omap2_mcspi	*mcspi;
+	struct omap2_mcspi_cs *cs;
+
+	master = dev_get_drvdata(&pdev->dev);
+	mcspi = spi_master_get_devdata(master);
+	omap2_mcspi_enable_clocks(master);
+	/* We need to togle CS state for OMAP take this chang in account*/
+
+	list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs,
+			    node)
+    {
+        MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1);
+		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+        MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0);
+		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+    }
+	omap2_mcspi_disable_clocks(master);
+    return 0;
+}
+#else
+#define	omap2_mcspi_resume	NULL
+#endif
+
 static struct platform_driver omap2_mcspi_driver = {
 	.driver = {
 		.name =		"omap2_mcspi",
 		.owner =	THIS_MODULE,
 	},
+	.resume =	omap2_mcspi_resume,
 	.remove =	__exit_p(omap2_mcspi_remove),
 };
 -- 1.7.0.4
#1 lore raw
Quoted 11 lines · Gregory CLEMENT

When SPI wake up from OFF mode, CS is in the wrong state: force it to the inactive state.

During the system life, I monitored the CS behavior using a oscilloscope. I also activated debug in omap2_mcspi, so I saw when driver disable the clocks and
Each time the CS was in the correct state.
It was only when system was put suspend to ram with off-mode activated that on resume the CS was in wrong state( ie activated).

Lots of whitespace issues in this patch, please run through checkpatch.

Quoted 9 lines
---
 drivers/spi/omap2_mcspi.c |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)
drivers/spi/omap2_mcspi.c +0 -0
index 2a651e6..708990e 100644

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct · line 1309

Quoted 5 lines
drivers/spi/omap2_mcspi.c +1 -0
@@ -1305,11 +1305,40 @@ static int __exit omap2_mcspi_remove(struct
 platform_device *pdev)
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:omap2_mcspi");
 +#ifdef	CONFIG_PM
+/* When SPI wake up, CS is in wrong state: force it to unactive state*/

This comment should be more specific that only this condition happens only on off-mode wakeups

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1317

Quoted 9 lines
drivers/spi/omap2_mcspi.c +9 -0
+static int omap2_mcspi_resume(struct platform_device *pdev)
+{
+	struct spi_master	*master;
+	struct omap2_mcspi	*mcspi;
+	struct omap2_mcspi_cs *cs;
+
+	master = dev_get_drvdata(&pdev->dev);
+	mcspi = spi_master_get_devdata(master);
+	omap2_mcspi_enable_clocks(master);

insert blank line here

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct · line 1320

Quoted 2 lines
drivers/spi/omap2_mcspi.c +2 -0
+	/* We need to togle CS state for OMAP take this chang in account*/
+

remove blank line here

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1322

Quoted 3 lines
drivers/spi/omap2_mcspi.c +3 -0
+	list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs,
+			    node)
+    {

this '{' belongs on like above

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1327

Quoted 5 lines
drivers/spi/omap2_mcspi.c +5 -0
+        MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1);
+		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+        MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0);
+		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+    }

Rather than force the state to a hard-coded value, it seems better if the driver instead restore the previous state, which could be saved during suspend.

Quoted 6 lines
drivers/spi/omap2_mcspi.c +6 -0
+	omap2_mcspi_disable_clocks(master);
+    return 0;
+}
+#else
+#define	omap2_mcspi_resume	NULL
+#endif

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1343

Quoted 10 lines
drivers/spi/omap2_mcspi.c +2 -0
+
 static struct platform_driver omap2_mcspi_driver = {
 	.driver = {
 		.name =		"omap2_mcspi",
 		.owner =	THIS_MODULE,
 	},
+	.resume =	omap2_mcspi_resume,
 	.remove =	__exit_p(omap2_mcspi_remove),
 };
 -- 1.7.0.4

Kevin

#2 lore raw
Quoted 12 lines · Kevin Hilman
Quoted 10 lines · Gregory CLEMENT

When SPI wake up from OFF mode, CS is in the wrong state: force it to the inactive state.

During the system life, I monitored the CS behavior using a oscilloscope. I also activated debug in omap2_mcspi, so I saw when driver disable the clocks and
Each time the CS was in the correct state.
It was only when system was put suspend to ram with off-mode activated that on resume the CS was in wrong state( ie activated).

Quoted 4 lines
Quoted 1 line

Lots of whitespace issues in this patch, please run through checkpatch.

Right, I forgot to use it this time.

Quoted 4 lines
Quoted 4 lines
---
  drivers/spi/omap2_mcspi.c |   29 +++++++++++++++++++++++++++++
  1 files changed, 29 insertions(+), 0 deletions(-)
Quoted 13 lines

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct · line 1309

Quoted 10 lines
drivers/spi/omap2_mcspi.c +1 -0
index 2a651e6..708990e 100644
@@ -1305,11 +1305,40 @@ static int __exit omap2_mcspi_remove(struct
 platform_device *pdev)
  /* work with hotplug and coldplug */
  MODULE_ALIAS("platform:omap2_mcspi");
  +#ifdef	CONFIG_PM
+/* When SPI wake up, CS is in wrong state: force it to unactive state*/

This comment should be more specific that only this condition happens only on off-mode wakeups

OK it will be added in the next version.

Quoted 23 lines

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1317

Quoted 9 lines
drivers/spi/omap2_mcspi.c +9 -0
+static int omap2_mcspi_resume(struct platform_device *pdev)
+{
+	struct spi_master	*master;
+	struct omap2_mcspi	*mcspi;
+	struct omap2_mcspi_cs *cs;
+
+	master = dev_get_drvdata(&pdev->dev);
+	mcspi = spi_master_get_devdata(master);
+	omap2_mcspi_enable_clocks(master);

insert blank line here

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct · line 1320

Quoted 2 lines
drivers/spi/omap2_mcspi.c +2 -0
+	/* We need to togle CS state for OMAP take this chang in account*/
+

remove blank line here

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1322

Quoted 3 lines
drivers/spi/omap2_mcspi.c +3 -0
+	list_for_each_entry(cs,&omap2_mcspi_ctx[master->bus_num - 1].cs,
+			    node)
+    {

this '{' belongs on like above

Quoted 9 lines

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1327

Quoted 5 lines
drivers/spi/omap2_mcspi.c +5 -0
+        MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1);
+		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+        MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0);
+		__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+    }

Rather than force the state to a hard-coded value, it seems better if the driver instead restore the previous state, which could be saved during suspend.

Well it would be surprising that driver was suspended in middle of a transaction (CS in active state). But it is pretty easy to get this information, so I will do this. It will be indeed cleaner.

Quoted 18 lines
Quoted 6 lines
drivers/spi/omap2_mcspi.c +6 -0
+	omap2_mcspi_disable_clocks(master);
+    return 0;
+}
+#else
+#define	omap2_mcspi_resume	NULL
+#endif

drivers/spi/omap2_mcspi.c static int __exit omap2_mcspi_remove(struct platform_device *pdev) · line 1343

Quoted 10 lines
drivers/spi/omap2_mcspi.c +2 -0
+
  static struct platform_driver omap2_mcspi_driver = {
  	.driver = {
  		.name =		"omap2_mcspi",
  		.owner =	THIS_MODULE,
  	},
+	.resume =	omap2_mcspi_resume,
  	.remove =	__exit_p(omap2_mcspi_remove),
  };
  -- 1.7.0.4

Kevin

Signature · 4 lines
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com