r4111 - branches/src/target/kernel/2.6.24.x/patches

werner at sita.openmoko.org werner at sita.openmoko.org
Tue Feb 26 01:29:02 CET 2008


Author: werner
Date: 2008-02-26 01:28:56 +0100 (Tue, 26 Feb 2008)
New Revision: 4111

Added:
   branches/src/target/kernel/2.6.24.x/patches/fix-i2c-s3c2410-resume-race.patch
Modified:
   branches/src/target/kernel/2.6.24.x/patches/series
Log:
fix-i2c-s3c2410-resume-race.patch

From: Andy Green <andy at openmoko.com>

There is a nasty race between i2c-s3c2410 resume and resume of I2C
driver and the client drivers -- the watchdog device actually gets to
use the dead I2C bus before it is reinitialized by the I2C driver
resume!  This patch makes sure any customers get turned away until
the shopkeeper has woken up.

Signed-off-by: Andy Green <andy at openmoko.com>
---

 drivers/i2c/busses/i2c-s3c2410.c |   32 +++++++++++++++++++++++++++++++-
 1 files changed, 31 insertions(+), 1 deletions(-)



Added: branches/src/target/kernel/2.6.24.x/patches/fix-i2c-s3c2410-resume-race.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/fix-i2c-s3c2410-resume-race.patch	2008-02-24 23:07:00 UTC (rev 4110)
+++ branches/src/target/kernel/2.6.24.x/patches/fix-i2c-s3c2410-resume-race.patch	2008-02-26 00:28:56 UTC (rev 4111)
@@ -0,0 +1,102 @@
+fix-i2c-s3c2410-resume-race.patch
+
+From: Andy Green <andy at openmoko.com>
+
+There is a nasty race between i2c-s3c2410 resume and resume of I2C
+driver and the client drivers -- the watchdog device actually gets to
+use the dead I2C bus before it is reinitialized by the I2C driver
+resume!  This patch makes sure any customers get turned away until
+the shopkeeper has woken up.
+
+Signed-off-by: Andy Green <andy at openmoko.com>
+
+---
+
+ drivers/i2c/busses/i2c-s3c2410.c |   32 +++++++++++++++++++++++++++++++-
+ 1 files changed, 31 insertions(+), 1 deletions(-)
+
+Index: linux-2.6.24/drivers/i2c/busses/i2c-s3c2410.c
+===================================================================
+--- linux-2.6.24.orig/drivers/i2c/busses/i2c-s3c2410.c
++++ linux-2.6.24/drivers/i2c/busses/i2c-s3c2410.c
+@@ -71,6 +71,8 @@ struct s3c24xx_i2c {
+ 	struct resource		*irq;
+ 	struct resource		*ioarea;
+ 	struct i2c_adapter	adap;
++
++	int			suspended;
+ };
+ 
+ /* default platform data to use if not supplied in the platform_device
+@@ -156,6 +158,14 @@ static inline void s3c24xx_i2c_disable_i
+ 	unsigned long tmp;
+ 	
+ 	tmp = readl(i2c->regs + S3C2410_IICCON);
++
++/* S3c2442 datasheet
++ *
++ * If the IICCON[5]=0, IICCON[4] does not operate correctly.
++ * So, It is recommended that you should set IICCON[5]=1,
++ * although you does not use the IIC interrupt.
++ */
++
+ 	writel(tmp & ~S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
+ }
+ 
+@@ -282,7 +292,7 @@ static int i2s_s3c_irq_nextbyte(struct s
+ 
+ 	case STATE_STOP:
+ 		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __FUNCTION__);
+-		s3c24xx_i2c_disable_irq(i2c);		
++		s3c24xx_i2c_disable_irq(i2c);
+ 		goto out_ack;
+ 
+ 	case STATE_START:
+@@ -502,6 +512,12 @@ static int s3c24xx_i2c_doxfer(struct s3c
+ 	unsigned long timeout;
+ 	int ret;
+ 
++	if (i2c->suspended) {
++		dev_err(i2c->dev, "Hey I am still asleep, retry later\n");
++		ret = -EAGAIN;
++		goto out;
++	}
++
+ 	ret = s3c24xx_i2c_set_master(i2c);
+ 	if (ret != 0) {
+ 		dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
+@@ -886,6 +902,17 @@ static int s3c24xx_i2c_remove(struct pla
+ }
+ 
+ #ifdef CONFIG_PM
++
++static int s3c24xx_i2c_suspend(struct platform_device *dev, pm_message_t state)
++{
++	struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
++
++	if (i2c != NULL)
++		i2c->suspended++;
++
++	return 0;
++}
++
+ static int s3c24xx_i2c_resume(struct platform_device *dev)
+ {
+ 	struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
+@@ -893,6 +920,8 @@ static int s3c24xx_i2c_resume(struct pla
+ 	if (i2c != NULL)
+ 		s3c24xx_i2c_init(i2c);
+ 
++	i2c->suspended--;
++
+ 	return 0;
+ }
+ 
+@@ -915,6 +944,7 @@ static struct platform_driver s3c2410_i2
+ static struct platform_driver s3c2440_i2c_driver = {
+ 	.probe		= s3c24xx_i2c_probe,
+ 	.remove		= s3c24xx_i2c_remove,
++	.suspend	= s3c24xx_i2c_suspend,
+ 	.resume		= s3c24xx_i2c_resume,
+ 	.driver		= {
+ 		.owner	= THIS_MODULE,

Modified: branches/src/target/kernel/2.6.24.x/patches/series
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/series	2008-02-24 23:07:00 UTC (rev 4110)
+++ branches/src/target/kernel/2.6.24.x/patches/series	2008-02-26 00:28:56 UTC (rev 4111)
@@ -5,6 +5,9 @@
 asoc-neo1973_wm8753-power.patch
 asoc-core-suspend_resume.patch
 
+# this looks like a bug in upstream
+fix-i2c-s3c2410-resume-race.patch
+
 # GTA01 core feature set
 s3c2410-bbt.patch
 gta01-pcf50606.patch





More information about the commitlog mailing list