* [PATCHv8 01/18] I2C: OMAP: make omap_i2c_unidle/idle functions depend on CONFIG_PM_RUNTIME
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
The functions omap_i2c_unidle/idle are called from omap_i2c_runtime_resume
and omap_i2c_runtime_suspend which is compiled for CONFIG_PM_RUNTIME.
This patch removes the omap_i2c_unidle/idle functions and folds them
into the runtime callbacks.
This fixes the below warn when CONFIG_PM_RUNTIME is not defined
CC arch/arm/mach-omap2/board-ti8168evm.o
drivers/i2c/busses/i2c-omap.c:272: warning: 'omap_i2c_unidle' defined but not used
drivers/i2c/busses/i2c-omap.c:293: warning: 'omap_i2c_idle' defined but not used
CC net/ipv4/ip_forward.o
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 75 +++++++++++++++++-----------------------
1 files changed, 32 insertions(+), 43 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 801df60..4f4188d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -269,47 +269,6 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}
-static void omap_i2c_unidle(struct omap_i2c_dev *dev)
-{
- if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->syscstate);
- omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
- }
-
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
-}
-
-static void omap_i2c_idle(struct omap_i2c_dev *dev)
-{
- u16 iv;
-
- dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
- if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
- omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
- else
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
-
- if (dev->rev < OMAP_I2C_OMAP1_REV_2) {
- iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
- } else {
- omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
-
- /* Flush posted write */
- omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
- }
-}
-
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
u16 psc = 0, scll = 0, sclh = 0, buf = 0;
@@ -1163,8 +1122,22 @@ static int omap_i2c_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+ u16 iv;
+
+ _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
+ if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
+ omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
+ else
+ omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
+
+ if (_dev->rev < OMAP_I2C_OMAP1_REV_2) {
+ iv = omap_i2c_read_reg(_dev, OMAP_I2C_IV_REG); /* Read clears */
+ } else {
+ omap_i2c_write_reg(_dev, OMAP_I2C_STAT_REG, _dev->iestate);
- omap_i2c_idle(_dev);
+ /* Flush posted write */
+ omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
+ }
return 0;
}
@@ -1174,7 +1147,23 @@ static int omap_i2c_runtime_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
- omap_i2c_unidle(_dev);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
+ omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ }
+
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (_dev->iestate)
+ omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 01/18] I2C: OMAP: make omap_i2c_unidle/idle functions depend on CONFIG_PM_RUNTIME
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
The functions omap_i2c_unidle/idle are called from omap_i2c_runtime_resume
and omap_i2c_runtime_suspend which is compiled for CONFIG_PM_RUNTIME.
This patch removes the omap_i2c_unidle/idle functions and folds them
into the runtime callbacks.
This fixes the below warn when CONFIG_PM_RUNTIME is not defined
CC arch/arm/mach-omap2/board-ti8168evm.o
drivers/i2c/busses/i2c-omap.c:272: warning: 'omap_i2c_unidle' defined but not used
drivers/i2c/busses/i2c-omap.c:293: warning: 'omap_i2c_idle' defined but not used
CC net/ipv4/ip_forward.o
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 75 +++++++++++++++++-----------------------
1 files changed, 32 insertions(+), 43 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 801df60..4f4188d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -269,47 +269,6 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
}
-static void omap_i2c_unidle(struct omap_i2c_dev *dev)
-{
- if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->syscstate);
- omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
- }
-
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
-}
-
-static void omap_i2c_idle(struct omap_i2c_dev *dev)
-{
- u16 iv;
-
- dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
- if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
- omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
- else
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
-
- if (dev->rev < OMAP_I2C_OMAP1_REV_2) {
- iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */
- } else {
- omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
-
- /* Flush posted write */
- omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
- }
-}
-
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
u16 psc = 0, scll = 0, sclh = 0, buf = 0;
@@ -1163,8 +1122,22 @@ static int omap_i2c_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+ u16 iv;
+
+ _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
+ if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
+ omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
+ else
+ omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
+
+ if (_dev->rev < OMAP_I2C_OMAP1_REV_2) {
+ iv = omap_i2c_read_reg(_dev, OMAP_I2C_IV_REG); /* Read clears */
+ } else {
+ omap_i2c_write_reg(_dev, OMAP_I2C_STAT_REG, _dev->iestate);
- omap_i2c_idle(_dev);
+ /* Flush posted write */
+ omap_i2c_read_reg(_dev, OMAP_I2C_STAT_REG);
+ }
return 0;
}
@@ -1174,7 +1147,23 @@ static int omap_i2c_runtime_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
- omap_i2c_unidle(_dev);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
+ omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
+ omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ }
+
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (_dev->iestate)
+ omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 03/18] I2C: OMAP: Recover from Bus Busy condition
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Vikram Pandita, Jon Hunter,
Shubhrajyoti D
From: Vikram Pandita <vikram.pandita-l0cyMroinI0@public.gmane.org>
In case a peripheral is driving SDA bus low (ie. a start condition), provide
a constant clock output using the test mode of the OMAP I2C controller to
try and clear the bus. Soft reset I2C controller after attempting the bus clear
to ensure that controller is in a good state.
Based upon Vikram Pandita's patch from TI Android 3.0.
I acknowledge the contributions and suggestions of Jon and Hemant.
A couple differences from the original patch ...
1. Add a new function for bus clear
2. Ensure that the CON.I2C_EN bit is set when using the SYSTEST feature to
output a permanent clock. This bit needs to be set and typically it would
be set by the unidle function but this is not the case for all OMAP
generations.
3. Program the SYSTEST setting only the bits we care about. However, restore
SYSTEST registers to there original state as some OMAP generations do not
implement perform a soft-reset.
4. Clear the CON register after performing the bus clear, so when we call the
init function the controller is disabled and the init function will
re-enable later.
Original patch can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=a2ab04192ba25e60f95ba1ff3af5601a2d7b5bd1
Signed-off-by: Vikram Pandita <vikram.pandita-l0cyMroinI0@public.gmane.org>
Signed-off-by: Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 33 ++++++++++++++++++++++++++++++---
1 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e402ebb..a882558 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -147,16 +147,15 @@ enum {
#define OMAP_I2C_SCLH_HSSCLH 8
/* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
#define OMAP_I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
#define OMAP_I2C_SYSTEST_FREE (1 << 14) /* Free running mode */
#define OMAP_I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_TEST (2 << 12) /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_LOOP (3 << 12) /* Test mode select */
#define OMAP_I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense in */
#define OMAP_I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive out */
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-#endif
/* OCP_SYSSTATUS bit definitions */
#define SYSS_RESETDONE_MASK (1 << 0)
@@ -319,6 +318,7 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
dev->westate);
}
}
+ return 0;
}
static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -471,6 +471,31 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
}
/*
+ * Bus Clear
+ */
+static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
+{
+ u16 w;
+
+ /*
+ * Per the I2C specification, if we are stuck in a bus busy state
+ * we can attempt a bus clear to try and recover the bus by sending
+ * at least 9 clock pulses on SCL. Put the I2C in a test mode so it
+ * will output a continuous clock on SCL.
+ */
+ w = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, (OMAP_I2C_SYSTEST_ST_EN
+ | OMAP_I2C_SYSTEST_TMODE_TEST));
+ msleep(1);
+ omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, w);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_reset(dev);
+ omap_i2c_init(dev);
+ return omap_i2c_wait_for_bb(dev);
+}
+
+/*
* Low level master read/write transaction.
*/
static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
@@ -597,6 +622,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
+ r = omap_i2c_bus_clear(dev);
+ if (r < 0)
goto out;
if (dev->set_mpu_wkup_lat != NULL)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 03/18] I2C: OMAP: Recover from Bus Busy condition
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
From: Vikram Pandita <vikram.pandita@ti.com>
In case a peripheral is driving SDA bus low (ie. a start condition), provide
a constant clock output using the test mode of the OMAP I2C controller to
try and clear the bus. Soft reset I2C controller after attempting the bus clear
to ensure that controller is in a good state.
Based upon Vikram Pandita's patch from TI Android 3.0.
I acknowledge the contributions and suggestions of Jon and Hemant.
A couple differences from the original patch ...
1. Add a new function for bus clear
2. Ensure that the CON.I2C_EN bit is set when using the SYSTEST feature to
output a permanent clock. This bit needs to be set and typically it would
be set by the unidle function but this is not the case for all OMAP
generations.
3. Program the SYSTEST setting only the bits we care about. However, restore
SYSTEST registers to there original state as some OMAP generations do not
implement perform a soft-reset.
4. Clear the CON register after performing the bus clear, so when we call the
init function the controller is disabled and the init function will
re-enable later.
Original patch can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=a2ab04192ba25e60f95ba1ff3af5601a2d7b5bd1
Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 33 ++++++++++++++++++++++++++++++---
1 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e402ebb..a882558 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -147,16 +147,15 @@ enum {
#define OMAP_I2C_SCLH_HSSCLH 8
/* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
#define OMAP_I2C_SYSTEST_ST_EN (1 << 15) /* System test enable */
#define OMAP_I2C_SYSTEST_FREE (1 << 14) /* Free running mode */
#define OMAP_I2C_SYSTEST_TMODE_MASK (3 << 12) /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT (12) /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_TEST (2 << 12) /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_LOOP (3 << 12) /* Test mode select */
#define OMAP_I2C_SYSTEST_SCL_I (1 << 3) /* SCL line sense in */
#define OMAP_I2C_SYSTEST_SCL_O (1 << 2) /* SCL line drive out */
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-#endif
/* OCP_SYSSTATUS bit definitions */
#define SYSS_RESETDONE_MASK (1 << 0)
@@ -319,6 +318,7 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
dev->westate);
}
}
+ return 0;
}
static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -471,6 +471,31 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
}
/*
+ * Bus Clear
+ */
+static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
+{
+ u16 w;
+
+ /*
+ * Per the I2C specification, if we are stuck in a bus busy state
+ * we can attempt a bus clear to try and recover the bus by sending
+ * at least 9 clock pulses on SCL. Put the I2C in a test mode so it
+ * will output a continuous clock on SCL.
+ */
+ w = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, (OMAP_I2C_SYSTEST_ST_EN
+ | OMAP_I2C_SYSTEST_TMODE_TEST));
+ msleep(1);
+ omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, w);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_reset(dev);
+ omap_i2c_init(dev);
+ return omap_i2c_wait_for_bb(dev);
+}
+
+/*
* Low level master read/write transaction.
*/
static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
@@ -597,6 +622,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
+ r = omap_i2c_bus_clear(dev);
+ if (r < 0)
goto out;
if (dev->set_mpu_wkup_lat != NULL)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
Currently i2c register restore is done always.
Adding conditional restore.
The i2c register restore is done only if the context is lost.
Also remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
arch/arm/plat-omap/i2c.c | 3 ++
drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
include/linux/i2c-omap.h | 1 +
3 files changed, 38 insertions(+), 18 deletions(-)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
*/
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a882558..45389db 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
+#include <plat/omap_device.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -157,9 +158,6 @@ enum {
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK (1 << 0)
-
/* OCP_SYSCONFIG bit definitions */
#define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
#define SYSC_SIDLEMODE_MASK (0x3 << 3)
@@ -184,6 +182,7 @@ struct omap_i2c_dev {
u32 latency; /* maximum mpu wkup latency */
void (*set_mpu_wkup_lat)(struct device *dev,
long latency);
+ int (*get_context_loss_count)(struct device *dev);
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -206,6 +205,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+ int dev_lost_count;
};
static const u8 reg_map_ip_v1[] = {
@@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+ dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
@@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (dev->iestate)
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+}
static int omap_i2c_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
+ if (_dev->get_context_loss_count)
+ _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
@@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+ int loss_cnt;
- if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ if (_dev->get_context_loss_count) {
+ loss_cnt = _dev->get_context_loss_count(dev);
+ if (loss_cnt < 0)
+ return loss_cnt;
+
+ if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
+ return 0;
}
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (_dev->iestate)
- omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
+ omap_i2c_restore(_dev);
return 0;
}
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
u32 rev;
u32 flags;
void (*set_mpu_wkup_lat)(struct device *dev, long set);
+ int (*get_context_loss_count)(struct device *dev);
};
#endif
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
Currently i2c register restore is done always.
Adding conditional restore.
The i2c register restore is done only if the context is lost.
Also remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
arch/arm/plat-omap/i2c.c | 3 ++
drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
include/linux/i2c-omap.h | 1 +
3 files changed, 38 insertions(+), 18 deletions(-)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
*/
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a882558..45389db 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
+#include <plat/omap_device.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -157,9 +158,6 @@ enum {
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK (1 << 0)
-
/* OCP_SYSCONFIG bit definitions */
#define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
#define SYSC_SIDLEMODE_MASK (0x3 << 3)
@@ -184,6 +182,7 @@ struct omap_i2c_dev {
u32 latency; /* maximum mpu wkup latency */
void (*set_mpu_wkup_lat)(struct device *dev,
long latency);
+ int (*get_context_loss_count)(struct device *dev);
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -206,6 +205,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+ int dev_lost_count;
};
static const u8 reg_map_ip_v1[] = {
@@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+ dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
@@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (dev->iestate)
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+}
static int omap_i2c_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
+ if (_dev->get_context_loss_count)
+ _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
@@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+ int loss_cnt;
- if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ if (_dev->get_context_loss_count) {
+ loss_cnt = _dev->get_context_loss_count(dev);
+ if (loss_cnt < 0)
+ return loss_cnt;
+
+ if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
+ return 0;
}
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (_dev->iestate)
- omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
+ omap_i2c_restore(_dev);
return 0;
}
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
u32 rev;
u32 flags;
void (*set_mpu_wkup_lat)(struct device *dev, long set);
+ int (*get_context_loss_count)(struct device *dev);
};
#endif
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-16 18:13 ` Tony Lindgren
-1 siblings, 0 replies; 52+ messages in thread
From: Tony Lindgren @ 2012-04-16 18:13 UTC (permalink / raw)
To: Shubhrajyoti D
Cc: linux-omap, linux-i2c, linux-arm-kernel, ben-linux, w.sang, Kevin Hilman
* Shubhrajyoti D <shubhrajyoti@ti.com> [120412 06:10]:
> Currently i2c register restore is done always.
> Adding conditional restore.
> The i2c register restore is done only if the context is lost.
> Also remove the definition of SYSS_RESETDONE_MASK and use the
> one in omap_hwmod.h.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> arch/arm/plat-omap/i2c.c | 3 ++
> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
> include/linux/i2c-omap.h | 1 +
> 3 files changed, 38 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index db071bc..4ccab07 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
> */
> if (cpu_is_omap34xx())
> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
> +
> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> +
> pdev = omap_device_build(name, bus_id, oh, pdata,
> sizeof(struct omap_i2c_bus_platform_data),
> NULL, 0, 0);
This should be acked by Kevin, adding him to Cc.
For the arch/arm/plat-omap/i2c.c part:
Acked-by: Tony Lindgren <tony@atomide.com>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a882558..45389db 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -43,6 +43,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-omap.h>
> #include <linux/pm_runtime.h>
> +#include <plat/omap_device.h>
>
> /* I2C controller revisions */
> #define OMAP_I2C_OMAP1_REV_2 0x20
> @@ -157,9 +158,6 @@ enum {
> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>
> -/* OCP_SYSSTATUS bit definitions */
> -#define SYSS_RESETDONE_MASK (1 << 0)
> -
> /* OCP_SYSCONFIG bit definitions */
> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
> u32 latency; /* maximum mpu wkup latency */
> void (*set_mpu_wkup_lat)(struct device *dev,
> long latency);
> + int (*get_context_loss_count)(struct device *dev);
> u32 speed; /* Speed of bus in kHz */
> u32 dtrev; /* extra revision from DT */
> u32 flags;
> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
> u16 syscstate;
> u16 westate;
> u16 errata;
> + int dev_lost_count;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->speed = pdata->clkrate;
> dev->flags = pdata->flags;
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> + dev->get_context_loss_count = pdata->get_context_loss_count;
> dev->dtrev = pdata->rev;
> }
>
> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
> }
>
> #ifdef CONFIG_PM_RUNTIME
> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +}
> static int omap_i2c_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> u16 iv;
>
> + if (_dev->get_context_loss_count)
> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
> +
> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
> @@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> + int loss_cnt;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + if (_dev->get_context_loss_count) {
> + loss_cnt = _dev->get_context_loss_count(dev);
> + if (loss_cnt < 0)
> + return loss_cnt;
> +
> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
> + return 0;
> }
>
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + omap_i2c_restore(_dev);
>
> return 0;
> }
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index 92a0dc7..c76cbc0 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
> u32 rev;
> u32 flags;
> void (*set_mpu_wkup_lat)(struct device *dev, long set);
> + int (*get_context_loss_count)(struct device *dev);
> };
>
> #endif
> --
> 1.7.4.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-16 18:13 ` Tony Lindgren
0 siblings, 0 replies; 52+ messages in thread
From: Tony Lindgren @ 2012-04-16 18:13 UTC (permalink / raw)
To: linux-arm-kernel
* Shubhrajyoti D <shubhrajyoti@ti.com> [120412 06:10]:
> Currently i2c register restore is done always.
> Adding conditional restore.
> The i2c register restore is done only if the context is lost.
> Also remove the definition of SYSS_RESETDONE_MASK and use the
> one in omap_hwmod.h.
>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> arch/arm/plat-omap/i2c.c | 3 ++
> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
> include/linux/i2c-omap.h | 1 +
> 3 files changed, 38 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index db071bc..4ccab07 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
> */
> if (cpu_is_omap34xx())
> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
> +
> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> +
> pdev = omap_device_build(name, bus_id, oh, pdata,
> sizeof(struct omap_i2c_bus_platform_data),
> NULL, 0, 0);
This should be acked by Kevin, adding him to Cc.
For the arch/arm/plat-omap/i2c.c part:
Acked-by: Tony Lindgren <tony@atomide.com>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a882558..45389db 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -43,6 +43,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-omap.h>
> #include <linux/pm_runtime.h>
> +#include <plat/omap_device.h>
>
> /* I2C controller revisions */
> #define OMAP_I2C_OMAP1_REV_2 0x20
> @@ -157,9 +158,6 @@ enum {
> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>
> -/* OCP_SYSSTATUS bit definitions */
> -#define SYSS_RESETDONE_MASK (1 << 0)
> -
> /* OCP_SYSCONFIG bit definitions */
> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
> u32 latency; /* maximum mpu wkup latency */
> void (*set_mpu_wkup_lat)(struct device *dev,
> long latency);
> + int (*get_context_loss_count)(struct device *dev);
> u32 speed; /* Speed of bus in kHz */
> u32 dtrev; /* extra revision from DT */
> u32 flags;
> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
> u16 syscstate;
> u16 westate;
> u16 errata;
> + int dev_lost_count;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->speed = pdata->clkrate;
> dev->flags = pdata->flags;
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> + dev->get_context_loss_count = pdata->get_context_loss_count;
> dev->dtrev = pdata->rev;
> }
>
> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
> }
>
> #ifdef CONFIG_PM_RUNTIME
> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +}
> static int omap_i2c_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> u16 iv;
>
> + if (_dev->get_context_loss_count)
> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
> +
> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
> @@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> + int loss_cnt;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + if (_dev->get_context_loss_count) {
> + loss_cnt = _dev->get_context_loss_count(dev);
> + if (loss_cnt < 0)
> + return loss_cnt;
> +
> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
> + return 0;
> }
>
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + omap_i2c_restore(_dev);
>
> return 0;
> }
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index 92a0dc7..c76cbc0 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
> u32 rev;
> u32 flags;
> void (*set_mpu_wkup_lat)(struct device *dev, long set);
> + int (*get_context_loss_count)(struct device *dev);
> };
>
> #endif
> --
> 1.7.4.1
>
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-16 18:13 ` Tony Lindgren
@ 2012-04-17 5:50 ` Shubhrajyoti
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti @ 2012-04-17 5:50 UTC (permalink / raw)
To: Tony Lindgren
Cc: linux-omap, linux-i2c, linux-arm-kernel, ben-linux, w.sang, Kevin Hilman
On Monday 16 April 2012 11:43 PM, Tony Lindgren wrote:
> * Shubhrajyoti D <shubhrajyoti@ti.com> [120412 06:10]:
>> Currently i2c register restore is done always.
>> Adding conditional restore.
>> The i2c register restore is done only if the context is lost.
>> Also remove the definition of SYSS_RESETDONE_MASK and use the
>> one in omap_hwmod.h.
>>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>> ---
>> arch/arm/plat-omap/i2c.c | 3 ++
>> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
>> include/linux/i2c-omap.h | 1 +
>> 3 files changed, 38 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
>> index db071bc..4ccab07 100644
>> --- a/arch/arm/plat-omap/i2c.c
>> +++ b/arch/arm/plat-omap/i2c.c
>> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
>> */
>> if (cpu_is_omap34xx())
>> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
>> +
>> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
>> +
>> pdev = omap_device_build(name, bus_id, oh, pdata,
>> sizeof(struct omap_i2c_bus_platform_data),
>> NULL, 0, 0);
> This should be acked by Kevin,
I should have cced Kevin.
> adding him to Cc.
Thanks.
> For the arch/arm/plat-omap/i2c.c part:
>
> Acked-by: Tony Lindgren <tony@atomide.com>
>
Thanks.
^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-17 5:50 ` Shubhrajyoti
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti @ 2012-04-17 5:50 UTC (permalink / raw)
To: linux-arm-kernel
On Monday 16 April 2012 11:43 PM, Tony Lindgren wrote:
> * Shubhrajyoti D <shubhrajyoti@ti.com> [120412 06:10]:
>> Currently i2c register restore is done always.
>> Adding conditional restore.
>> The i2c register restore is done only if the context is lost.
>> Also remove the definition of SYSS_RESETDONE_MASK and use the
>> one in omap_hwmod.h.
>>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>> ---
>> arch/arm/plat-omap/i2c.c | 3 ++
>> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
>> include/linux/i2c-omap.h | 1 +
>> 3 files changed, 38 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
>> index db071bc..4ccab07 100644
>> --- a/arch/arm/plat-omap/i2c.c
>> +++ b/arch/arm/plat-omap/i2c.c
>> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
>> */
>> if (cpu_is_omap34xx())
>> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
>> +
>> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
>> +
>> pdev = omap_device_build(name, bus_id, oh, pdata,
>> sizeof(struct omap_i2c_bus_platform_data),
>> NULL, 0, 0);
> This should be acked by Kevin,
I should have cced Kevin.
> adding him to Cc.
Thanks.
> For the arch/arm/plat-omap/i2c.c part:
>
> Acked-by: Tony Lindgren <tony@atomide.com>
>
Thanks.
^ permalink raw reply [flat|nested] 52+ messages in thread
[parent not found: <1334235995-6727-5-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>]
* Re: [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-17 13:45 ` Kevin Hilman
-1 siblings, 0 replies; 52+ messages in thread
From: Kevin Hilman @ 2012-04-17 13:45 UTC (permalink / raw)
To: Shubhrajyoti D
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ
Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org> writes:
> Currently i2c register restore is done always.
> Adding conditional restore.
> The i2c register restore is done only if the context is lost.
OK, minor comment below.
> Also remove the definition of SYSS_RESETDONE_MASK and use the
> one in omap_hwmod.h.
The definition is removed, but I don't see any of the users removed.
If the users were cleaned up earlier in the series, then the removal of
this should be done with that, or as a separate patch. I don't see why
it belongs with this patch.
> Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
> ---
> arch/arm/plat-omap/i2c.c | 3 ++
> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
> include/linux/i2c-omap.h | 1 +
> 3 files changed, 38 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index db071bc..4ccab07 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
> */
> if (cpu_is_omap34xx())
> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
> +
> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> +
> pdev = omap_device_build(name, bus_id, oh, pdata,
> sizeof(struct omap_i2c_bus_platform_data),
> NULL, 0, 0);
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a882558..45389db 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -43,6 +43,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-omap.h>
> #include <linux/pm_runtime.h>
> +#include <plat/omap_device.h>
>
> /* I2C controller revisions */
> #define OMAP_I2C_OMAP1_REV_2 0x20
> @@ -157,9 +158,6 @@ enum {
> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>
> -/* OCP_SYSSTATUS bit definitions */
> -#define SYSS_RESETDONE_MASK (1 << 0)
> -
> /* OCP_SYSCONFIG bit definitions */
> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
> u32 latency; /* maximum mpu wkup latency */
> void (*set_mpu_wkup_lat)(struct device *dev,
> long latency);
> + int (*get_context_loss_count)(struct device *dev);
> u32 speed; /* Speed of bus in kHz */
> u32 dtrev; /* extra revision from DT */
> u32 flags;
> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
> u16 syscstate;
> u16 westate;
> u16 errata;
> + int dev_lost_count;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->speed = pdata->clkrate;
> dev->flags = pdata->flags;
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> + dev->get_context_loss_count = pdata->get_context_loss_count;
> dev->dtrev = pdata->rev;
> }
>
> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
> }
>
> #ifdef CONFIG_PM_RUNTIME
> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +}
> static int omap_i2c_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> u16 iv;
>
> + if (_dev->get_context_loss_count)
> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
> +
> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
> @@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> + int loss_cnt;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + if (_dev->get_context_loss_count) {
> + loss_cnt = _dev->get_context_loss_count(dev);
> + if (loss_cnt < 0)
> + return loss_cnt;
To avoid messing up driver state, upon error, you should probably
restore context, not abort.
> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
> + return 0;
Why the non-zero check?
Seems like all you need to check is if (_dev->dev_lost_count != loss_cnt).
Kevin
> }
>
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + omap_i2c_restore(_dev);
>
> return 0;
> }
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index 92a0dc7..c76cbc0 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
> u32 rev;
> u32 flags;
> void (*set_mpu_wkup_lat)(struct device *dev, long set);
> + int (*get_context_loss_count)(struct device *dev);
> };
>
> #endif
^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-17 13:45 ` Kevin Hilman
0 siblings, 0 replies; 52+ messages in thread
From: Kevin Hilman @ 2012-04-17 13:45 UTC (permalink / raw)
To: linux-arm-kernel
Shubhrajyoti D <shubhrajyoti@ti.com> writes:
> Currently i2c register restore is done always.
> Adding conditional restore.
> The i2c register restore is done only if the context is lost.
OK, minor comment below.
> Also remove the definition of SYSS_RESETDONE_MASK and use the
> one in omap_hwmod.h.
The definition is removed, but I don't see any of the users removed.
If the users were cleaned up earlier in the series, then the removal of
this should be done with that, or as a separate patch. I don't see why
it belongs with this patch.
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> arch/arm/plat-omap/i2c.c | 3 ++
> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
> include/linux/i2c-omap.h | 1 +
> 3 files changed, 38 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index db071bc..4ccab07 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
> */
> if (cpu_is_omap34xx())
> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
> +
> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> +
> pdev = omap_device_build(name, bus_id, oh, pdata,
> sizeof(struct omap_i2c_bus_platform_data),
> NULL, 0, 0);
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a882558..45389db 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -43,6 +43,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-omap.h>
> #include <linux/pm_runtime.h>
> +#include <plat/omap_device.h>
>
> /* I2C controller revisions */
> #define OMAP_I2C_OMAP1_REV_2 0x20
> @@ -157,9 +158,6 @@ enum {
> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>
> -/* OCP_SYSSTATUS bit definitions */
> -#define SYSS_RESETDONE_MASK (1 << 0)
> -
> /* OCP_SYSCONFIG bit definitions */
> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
> u32 latency; /* maximum mpu wkup latency */
> void (*set_mpu_wkup_lat)(struct device *dev,
> long latency);
> + int (*get_context_loss_count)(struct device *dev);
> u32 speed; /* Speed of bus in kHz */
> u32 dtrev; /* extra revision from DT */
> u32 flags;
> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
> u16 syscstate;
> u16 westate;
> u16 errata;
> + int dev_lost_count;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->speed = pdata->clkrate;
> dev->flags = pdata->flags;
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> + dev->get_context_loss_count = pdata->get_context_loss_count;
> dev->dtrev = pdata->rev;
> }
>
> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
> }
>
> #ifdef CONFIG_PM_RUNTIME
> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +}
> static int omap_i2c_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> u16 iv;
>
> + if (_dev->get_context_loss_count)
> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
> +
> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
> @@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> + int loss_cnt;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + if (_dev->get_context_loss_count) {
> + loss_cnt = _dev->get_context_loss_count(dev);
> + if (loss_cnt < 0)
> + return loss_cnt;
To avoid messing up driver state, upon error, you should probably
restore context, not abort.
> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
> + return 0;
Why the non-zero check?
Seems like all you need to check is if (_dev->dev_lost_count != loss_cnt).
Kevin
> }
>
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + omap_i2c_restore(_dev);
>
> return 0;
> }
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index 92a0dc7..c76cbc0 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
> u32 rev;
> u32 flags;
> void (*set_mpu_wkup_lat)(struct device *dev, long set);
> + int (*get_context_loss_count)(struct device *dev);
> };
>
> #endif
^ permalink raw reply [flat|nested] 52+ messages in thread
[parent not found: <87d376zd2v.fsf-l0cyMroinI0@public.gmane.org>]
* Re: [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-17 13:45 ` Kevin Hilman
@ 2012-04-17 15:08 ` Shubhrajyoti Datta
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti Datta @ 2012-04-17 15:08 UTC (permalink / raw)
To: Kevin Hilman
Cc: Shubhrajyoti D, linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ
Hi Kevin,
Thanks for your review,
On Tue, Apr 17, 2012 at 7:15 PM, Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org> wrote:
> Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org> writes:
>
>> Currently i2c register restore is done always.
>> Adding conditional restore.
>> The i2c register restore is done only if the context is lost.
>
> OK, minor comment below.
>
>> Also remove the definition of SYSS_RESETDONE_MASK and use the
>> one in omap_hwmod.h.
>
> The definition is removed, but I don't see any of the users removed.
> If the users were cleaned up earlier in the series, then the removal of
> this should be done with that, or as a separate patch. I don't see why
> it belongs with this patch.
I have not removed the users actually the macro was redefined.
I have instead used the definition in omap_hwmod.h which gets added
when I include omap_device.h
Let me know if you prefer a separate patch?
>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
>> ---
>> arch/arm/plat-omap/i2c.c | 3 ++
>> drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++--------------
>> include/linux/i2c-omap.h | 1 +
>> 3 files changed, 38 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
>> index db071bc..4ccab07 100644
>> --- a/arch/arm/plat-omap/i2c.c
>> +++ b/arch/arm/plat-omap/i2c.c
>> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
>> */
>> if (cpu_is_omap34xx())
>> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
>> +
>> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
>> +
>> pdev = omap_device_build(name, bus_id, oh, pdata,
>> sizeof(struct omap_i2c_bus_platform_data),
>> NULL, 0, 0);
>> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
>> index a882558..45389db 100644
>> --- a/drivers/i2c/busses/i2c-omap.c
>> +++ b/drivers/i2c/busses/i2c-omap.c
>> @@ -43,6 +43,7 @@
>> #include <linux/slab.h>
>> #include <linux/i2c-omap.h>
>> #include <linux/pm_runtime.h>
>> +#include <plat/omap_device.h>
>>
>> /* I2C controller revisions */
>> #define OMAP_I2C_OMAP1_REV_2 0x20
>> @@ -157,9 +158,6 @@ enum {
>> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
>> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>>
>> -/* OCP_SYSSTATUS bit definitions */
>> -#define SYSS_RESETDONE_MASK (1 << 0)
>> -
>> /* OCP_SYSCONFIG bit definitions */
>> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
>> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
>> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
>> u32 latency; /* maximum mpu wkup latency */
>> void (*set_mpu_wkup_lat)(struct device *dev,
>> long latency);
>> + int (*get_context_loss_count)(struct device *dev);
>> u32 speed; /* Speed of bus in kHz */
>> u32 dtrev; /* extra revision from DT */
>> u32 flags;
>> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
>> u16 syscstate;
>> u16 westate;
>> u16 errata;
>> + int dev_lost_count;
>> };
>>
>> static const u8 reg_map_ip_v1[] = {
>> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
>> dev->speed = pdata->clkrate;
>> dev->flags = pdata->flags;
>> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
>> + dev->get_context_loss_count = pdata->get_context_loss_count;
>> dev->dtrev = pdata->rev;
>> }
>>
>> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
>> }
>>
>> #ifdef CONFIG_PM_RUNTIME
>> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
>> +{
>> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
>> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
>> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
>> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
>> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
>> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
>> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> + /*
>> + * Don't write to this register if the IE state is 0 as it can
>> + * cause deadlock.
>> + */
>> + if (dev->iestate)
>> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
>> +
>> +}
>> static int omap_i2c_runtime_suspend(struct device *dev)
>> {
>> struct platform_device *pdev = to_platform_device(dev);
>> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
>> u16 iv;
>>
>> + if (_dev->get_context_loss_count)
>> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
>> +
>> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
>> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
>> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
>> @@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
>> {
>> struct platform_device *pdev = to_platform_device(dev);
>> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
>> + int loss_cnt;
>>
>> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
>> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
>> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> + if (_dev->get_context_loss_count) {
>> + loss_cnt = _dev->get_context_loss_count(dev);
>> + if (loss_cnt < 0)
>> + return loss_cnt;
>
> To avoid messing up driver state, upon error, you should probably
> restore context, not abort.
Agreed , will fix this.
>
>> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
>> + return 0;
>
> Why the non-zero check?
Actually the driver probe-->omap_i2c_init
here
<snip>
dev->pscstate = psc;
dev->scllstate = scll;
dev->sclhstate = sclh;
dev->bufstate = buf;
<snip>
variables are updated and the first write happens in the handler.
>
> Seems like all you need to check is if (_dev->dev_lost_count != loss_cnt).
>
> Kevin
>
>> }
>>
>> - /*
>> - * Don't write to this register if the IE state is 0 as it can
>> - * cause deadlock.
>> - */
>> - if (_dev->iestate)
>> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
>> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
>> + omap_i2c_restore(_dev);
>>
>> return 0;
>> }
>> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
>> index 92a0dc7..c76cbc0 100644
>> --- a/include/linux/i2c-omap.h
>> +++ b/include/linux/i2c-omap.h
>> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
>> u32 rev;
>> u32 flags;
>> void (*set_mpu_wkup_lat)(struct device *dev, long set);
>> + int (*get_context_loss_count)(struct device *dev);
>> };
>>
>> #endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-17 15:08 ` Shubhrajyoti Datta
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti Datta @ 2012-04-17 15:08 UTC (permalink / raw)
To: linux-arm-kernel
Hi Kevin,
Thanks for your review,
On Tue, Apr 17, 2012 at 7:15 PM, Kevin Hilman <khilman@ti.com> wrote:
> Shubhrajyoti D <shubhrajyoti@ti.com> writes:
>
>> ?Currently i2c register restore is done always.
>> ?Adding conditional restore.
>> ?The i2c register restore is done only if the context is lost.
>
> OK, minor comment below.
>
>> ?Also remove the definition of SYSS_RESETDONE_MASK and use the
>> ?one in omap_hwmod.h.
>
> The definition is removed, but I don't see any of the users removed.
> If the users were cleaned up earlier in the series, then the removal of
> this should be done with that, or as a separate patch. ?I don't see why
> it belongs with this patch.
I have not removed the users actually the macro was redefined.
I have instead used the definition in omap_hwmod.h which gets added
when I include omap_device.h
Let me know if you prefer a separate patch?
>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>> ---
>> ?arch/arm/plat-omap/i2c.c ? ? ?| ? ?3 ++
>> ?drivers/i2c/busses/i2c-omap.c | ? 52 ++++++++++++++++++++++++++--------------
>> ?include/linux/i2c-omap.h ? ? ?| ? ?1 +
>> ?3 files changed, 38 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
>> index db071bc..4ccab07 100644
>> --- a/arch/arm/plat-omap/i2c.c
>> +++ b/arch/arm/plat-omap/i2c.c
>> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
>> ? ? ? ?*/
>> ? ? ? if (cpu_is_omap34xx())
>> ? ? ? ? ? ? ? pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
>> +
>> + ? ? pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
>> +
>> ? ? ? pdev = omap_device_build(name, bus_id, oh, pdata,
>> ? ? ? ? ? ? ? ? ? ? ? sizeof(struct omap_i2c_bus_platform_data),
>> ? ? ? ? ? ? ? ? ? ? ? NULL, 0, 0);
>> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
>> index a882558..45389db 100644
>> --- a/drivers/i2c/busses/i2c-omap.c
>> +++ b/drivers/i2c/busses/i2c-omap.c
>> @@ -43,6 +43,7 @@
>> ?#include <linux/slab.h>
>> ?#include <linux/i2c-omap.h>
>> ?#include <linux/pm_runtime.h>
>> +#include <plat/omap_device.h>
>>
>> ?/* I2C controller revisions */
>> ?#define OMAP_I2C_OMAP1_REV_2 ? ? ? ? 0x20
>> @@ -157,9 +158,6 @@ enum {
>> ?#define OMAP_I2C_SYSTEST_SDA_I ? ? ? ? ? ? ? (1 << 1) ? ? ? ?/* SDA line sense in */
>> ?#define OMAP_I2C_SYSTEST_SDA_O ? ? ? ? ? ? ? (1 << 0) ? ? ? ?/* SDA line drive out */
>>
>> -/* OCP_SYSSTATUS bit definitions */
>> -#define SYSS_RESETDONE_MASK ? ? ? ? ?(1 << 0)
>> -
>> ?/* OCP_SYSCONFIG bit definitions */
>> ?#define SYSC_CLOCKACTIVITY_MASK ? ? ? ? ? ? ?(0x3 << 8)
>> ?#define SYSC_SIDLEMODE_MASK ? ? ? ? ?(0x3 << 3)
>> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
>> ? ? ? u32 ? ? ? ? ? ? ? ? ? ? latency; ? ? ? ?/* maximum mpu wkup latency */
>> ? ? ? void ? ? ? ? ? ? ? ? ? ?(*set_mpu_wkup_lat)(struct device *dev,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? long latency);
>> + ? ? int ? ? ? ? ? ? ? ? ? ? (*get_context_loss_count)(struct device *dev);
>> ? ? ? u32 ? ? ? ? ? ? ? ? ? ? speed; ? ? ? ? ?/* Speed of bus in kHz */
>> ? ? ? u32 ? ? ? ? ? ? ? ? ? ? dtrev; ? ? ? ? ?/* extra revision from DT */
>> ? ? ? u32 ? ? ? ? ? ? ? ? ? ? flags;
>> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
>> ? ? ? u16 ? ? ? ? ? ? ? ? ? ? syscstate;
>> ? ? ? u16 ? ? ? ? ? ? ? ? ? ? westate;
>> ? ? ? u16 ? ? ? ? ? ? ? ? ? ? errata;
>> + ? ? int ? ? ? ? ? ? ? ? ? ? dev_lost_count;
>> ?};
>>
>> ?static const u8 reg_map_ip_v1[] = {
>> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
>> ? ? ? ? ? ? ? dev->speed = pdata->clkrate;
>> ? ? ? ? ? ? ? dev->flags = pdata->flags;
>> ? ? ? ? ? ? ? dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
>> + ? ? ? ? ? ? dev->get_context_loss_count = pdata->get_context_loss_count;
>> ? ? ? ? ? ? ? dev->dtrev = pdata->rev;
>> ? ? ? }
>>
>> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
>> ?}
>>
>> ?#ifdef CONFIG_PM_RUNTIME
>> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
>> +{
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
>> + ? ? omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> + ? ? /*
>> + ? ? ?* Don't write to this register if the IE state is 0 as it can
>> + ? ? ?* cause deadlock.
>> + ? ? ?*/
>> + ? ? if (dev->iestate)
>> + ? ? ? ? ? ? omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
>> +
>> +}
>> ?static int omap_i2c_runtime_suspend(struct device *dev)
>> ?{
>> ? ? ? struct platform_device *pdev = to_platform_device(dev);
>> ? ? ? struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
>> ? ? ? u16 iv;
>>
>> + ? ? if (_dev->get_context_loss_count)
>> + ? ? ? ? ? ? _dev->dev_lost_count = _dev->get_context_loss_count(dev);
>> +
>> ? ? ? _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
>> ? ? ? if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
>> ? ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
>> @@ -1179,24 +1200,19 @@ static int omap_i2c_runtime_resume(struct device *dev)
>> ?{
>> ? ? ? struct platform_device *pdev = to_platform_device(dev);
>> ? ? ? struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
>> + ? ? int loss_cnt;
>>
>> - ? ? if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>> + ? ? if (_dev->get_context_loss_count) {
>> + ? ? ? ? ? ? loss_cnt = _dev->get_context_loss_count(dev);
>> + ? ? ? ? ? ? if (loss_cnt < 0)
>> + ? ? ? ? ? ? ? ? ? ? return loss_cnt;
>
> To avoid messing up driver state, upon error, you should probably
> restore context, not abort.
Agreed , will fix this.
>
>> + ? ? ? ? ? ? if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
>> + ? ? ? ? ? ? ? ? ? ? return 0;
>
> Why the non-zero check?
Actually the driver probe-->omap_i2c_init
here
<snip>
dev->pscstate = psc;
dev->scllstate = scll;
dev->sclhstate = sclh;
dev->bufstate = buf;
<snip>
variables are updated and the first write happens in the handler.
>
> Seems like all you need to check is if (_dev->dev_lost_count != loss_cnt).
>
> Kevin
>
>> ? ? ? }
>>
>> - ? ? /*
>> - ? ? ?* Don't write to this register if the IE state is 0 as it can
>> - ? ? ?* cause deadlock.
>> - ? ? ?*/
>> - ? ? if (_dev->iestate)
>> - ? ? ? ? ? ? omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
>> + ? ? if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
>> + ? ? ? ? ? ? omap_i2c_restore(_dev);
>>
>> ? ? ? return 0;
>> ?}
>> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
>> index 92a0dc7..c76cbc0 100644
>> --- a/include/linux/i2c-omap.h
>> +++ b/include/linux/i2c-omap.h
>> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
>> ? ? ? u32 ? ? ? ? ? ? rev;
>> ? ? ? u32 ? ? ? ? ? ? flags;
>> ? ? ? void ? ? ? ? ? ?(*set_mpu_wkup_lat)(struct device *dev, long set);
>> + ? ? int ? ? ? ? ? ? (*get_context_loss_count)(struct device *dev);
>> ?};
>>
>> ?#endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 52+ messages in thread
* Re: [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-17 15:08 ` Shubhrajyoti Datta
@ 2012-04-18 7:19 ` Datta, Shubhrajyoti
-1 siblings, 0 replies; 52+ messages in thread
From: Datta, Shubhrajyoti @ 2012-04-18 7:19 UTC (permalink / raw)
To: Shubhrajyoti Datta
Cc: Kevin Hilman, linux-omap, linux-i2c, linux-arm-kernel, ben-linux,
tony, w.sang
Hi Kevin,
> Hi Kevin,
> Thanks for your review,
>
> On Tue, Apr 17, 2012 at 7:15 PM, Kevin Hilman <khilman@ti.com> wrote:
>> Shubhrajyoti D <shubhrajyoti@ti.com> writes:
>>
>>> Currently i2c register restore is done always.
>>> Adding conditional restore.
>>> The i2c register restore is done only if the context is lost.
>>
>> OK, minor comment below.
Thanks for the suggestion of the error case restore.
Updated the patch. Also added Tony's ack for the plat part.
From 1ca222f6f50868e07d9a46575e73dd66fd2d542e Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <shubhrajyoti@ti.com>
Date: Tue, 17 Jan 2012 16:13:03 +0530
Subject: [PATCH] I2C: OMAP: I2C register restore only if context is lost
Currently i2c register restore is done always.
Adding conditional restore.
The i2c register restore is done only if the context is lost
or in case of error to be on the safe side.
Also remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.
Cc: Kevin Hilman <khilman@ti.com>
[For the arch/arm/plat-omap/i2c.c part]
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
arch/arm/plat-omap/i2c.c | 3 ++
drivers/i2c/busses/i2c-omap.c | 53 +++++++++++++++++++++++++++--------------
include/linux/i2c-omap.h | 1 +
3 files changed, 39 insertions(+), 18 deletions(-)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
*/
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a882558..76cf066 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
+#include <plat/omap_device.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -157,9 +158,6 @@ enum {
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK (1 << 0)
-
/* OCP_SYSCONFIG bit definitions */
#define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
#define SYSC_SIDLEMODE_MASK (0x3 << 3)
@@ -184,6 +182,7 @@ struct omap_i2c_dev {
u32 latency; /* maximum mpu wkup latency */
void (*set_mpu_wkup_lat)(struct device *dev,
long latency);
+ int (*get_context_loss_count)(struct device *dev);
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -206,6 +205,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+ int dev_lost_count;
};
static const u8 reg_map_ip_v1[] = {
@@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+ dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
@@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (dev->iestate)
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+}
static int omap_i2c_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
+ if (_dev->get_context_loss_count)
+ _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
@@ -1179,24 +1200,20 @@ static int omap_i2c_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+ int loss_cnt;
- if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ if (_dev->get_context_loss_count) {
+ loss_cnt = _dev->get_context_loss_count(dev);
+ if (loss_cnt < 0) {
+ omap_i2c_restore(_dev);
+ return 0;
+ }
+ if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
+ return 0;
}
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (_dev->iestate)
- omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
+ omap_i2c_restore(_dev);
return 0;
}
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
u32 rev;
u32 flags;
void (*set_mpu_wkup_lat)(struct device *dev, long set);
+ int (*get_context_loss_count)(struct device *dev);
};
#endif
--
1.7.5.4
--
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 related [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-18 7:19 ` Datta, Shubhrajyoti
0 siblings, 0 replies; 52+ messages in thread
From: Datta, Shubhrajyoti @ 2012-04-18 7:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi Kevin,
> Hi Kevin,
> Thanks for your review,
>
> On Tue, Apr 17, 2012 at 7:15 PM, Kevin Hilman <khilman@ti.com> wrote:
>> Shubhrajyoti D <shubhrajyoti@ti.com> writes:
>>
>>> ?Currently i2c register restore is done always.
>>> ?Adding conditional restore.
>>> ?The i2c register restore is done only if the context is lost.
>>
>> OK, minor comment below.
Thanks for the suggestion of the error case restore.
Updated the patch. Also added Tony's ack for the plat part.
>From 1ca222f6f50868e07d9a46575e73dd66fd2d542e Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <shubhrajyoti@ti.com>
Date: Tue, 17 Jan 2012 16:13:03 +0530
Subject: [PATCH] I2C: OMAP: I2C register restore only if context is lost
Currently i2c register restore is done always.
Adding conditional restore.
The i2c register restore is done only if the context is lost
or in case of error to be on the safe side.
Also remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.
Cc: Kevin Hilman <khilman@ti.com>
[For the arch/arm/plat-omap/i2c.c part]
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
arch/arm/plat-omap/i2c.c | 3 ++
drivers/i2c/busses/i2c-omap.c | 53 +++++++++++++++++++++++++++--------------
include/linux/i2c-omap.h | 1 +
3 files changed, 39 insertions(+), 18 deletions(-)
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
*/
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a882558..76cf066 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
#include <linux/slab.h>
#include <linux/i2c-omap.h>
#include <linux/pm_runtime.h>
+#include <plat/omap_device.h>
/* I2C controller revisions */
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -157,9 +158,6 @@ enum {
#define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
#define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK (1 << 0)
-
/* OCP_SYSCONFIG bit definitions */
#define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
#define SYSC_SIDLEMODE_MASK (0x3 << 3)
@@ -184,6 +182,7 @@ struct omap_i2c_dev {
u32 latency; /* maximum mpu wkup latency */
void (*set_mpu_wkup_lat)(struct device *dev,
long latency);
+ int (*get_context_loss_count)(struct device *dev);
u32 speed; /* Speed of bus in kHz */
u32 dtrev; /* extra revision from DT */
u32 flags;
@@ -206,6 +205,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+ int dev_lost_count;
};
static const u8 reg_map_ip_v1[] = {
@@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+ dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
@@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ /*
+ * Don't write to this register if the IE state is 0 as it can
+ * cause deadlock.
+ */
+ if (dev->iestate)
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+}
static int omap_i2c_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
+ if (_dev->get_context_loss_count)
+ _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
@@ -1179,24 +1200,20 @@ static int omap_i2c_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+ int loss_cnt;
- if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
- omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
- omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
- omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+ if (_dev->get_context_loss_count) {
+ loss_cnt = _dev->get_context_loss_count(dev);
+ if (loss_cnt < 0) {
+ omap_i2c_restore(_dev);
+ return 0;
+ }
+ if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
+ return 0;
}
- /*
- * Don't write to this register if the IE state is 0 as it can
- * cause deadlock.
- */
- if (_dev->iestate)
- omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
+ if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
+ omap_i2c_restore(_dev);
return 0;
}
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
u32 rev;
u32 flags;
void (*set_mpu_wkup_lat)(struct device *dev, long set);
+ int (*get_context_loss_count)(struct device *dev);
};
#endif
--
1.7.5.4
^ permalink raw reply related [flat|nested] 52+ messages in thread
* Re: [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
2012-04-18 7:19 ` Datta, Shubhrajyoti
@ 2012-04-18 14:08 ` Kevin Hilman
-1 siblings, 0 replies; 52+ messages in thread
From: Kevin Hilman @ 2012-04-18 14:08 UTC (permalink / raw)
To: Datta, Shubhrajyoti
Cc: Shubhrajyoti Datta, linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ
"Datta, Shubhrajyoti" <shubhrajyoti-l0cyMroinI0@public.gmane.org> writes:
> Hi Kevin,
>
>> Hi Kevin,
>> Thanks for your review,
>>
>> On Tue, Apr 17, 2012 at 7:15 PM, Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org> wrote:
>>> Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org> writes:
>>>
>>>> Currently i2c register restore is done always.
>>>> Adding conditional restore.
>>>> The i2c register restore is done only if the context is lost.
>>>
>>> OK, minor comment below.
>
> Thanks for the suggestion of the error case restore.
> Updated the patch. Also added Tony's ack for the plat part.
>
>
> From 1ca222f6f50868e07d9a46575e73dd66fd2d542e Mon Sep 17 00:00:00 2001
> From: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
> Date: Tue, 17 Jan 2012 16:13:03 +0530
> Subject: [PATCH] I2C: OMAP: I2C register restore only if context is lost
>
> Currently i2c register restore is done always.
> Adding conditional restore.
> The i2c register restore is done only if the context is lost
> or in case of error to be on the safe side.
> Also remove the definition of SYSS_RESETDONE_MASK and use the
> one in omap_hwmod.h.
>
> Cc: Kevin Hilman <khilman-l0cyMroinI0@public.gmane.org>
> [For the arch/arm/plat-omap/i2c.c part]
> Acked-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
> ---
> arch/arm/plat-omap/i2c.c | 3 ++
> drivers/i2c/busses/i2c-omap.c | 53 +++++++++++++++++++++++++++--------------
> include/linux/i2c-omap.h | 1 +
> 3 files changed, 39 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index db071bc..4ccab07 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
> */
> if (cpu_is_omap34xx())
> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
> +
> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> +
> pdev = omap_device_build(name, bus_id, oh, pdata,
> sizeof(struct omap_i2c_bus_platform_data),
> NULL, 0, 0);
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a882558..76cf066 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -43,6 +43,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-omap.h>
> #include <linux/pm_runtime.h>
> +#include <plat/omap_device.h>
>
> /* I2C controller revisions */
> #define OMAP_I2C_OMAP1_REV_2 0x20
> @@ -157,9 +158,6 @@ enum {
> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>
> -/* OCP_SYSSTATUS bit definitions */
> -#define SYSS_RESETDONE_MASK (1 << 0)
> -
Unrelated to this patch.
> /* OCP_SYSCONFIG bit definitions */
> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
> u32 latency; /* maximum mpu wkup latency */
> void (*set_mpu_wkup_lat)(struct device *dev,
> long latency);
> + int (*get_context_loss_count)(struct device *dev);
> u32 speed; /* Speed of bus in kHz */
> u32 dtrev; /* extra revision from DT */
> u32 flags;
> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
> u16 syscstate;
> u16 westate;
> u16 errata;
> + int dev_lost_count;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->speed = pdata->clkrate;
> dev->flags = pdata->flags;
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> + dev->get_context_loss_count = pdata->get_context_loss_count;
> dev->dtrev = pdata->rev;
> }
>
> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
> }
>
> #ifdef CONFIG_PM_RUNTIME
> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +}
> static int omap_i2c_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> u16 iv;
>
> + if (_dev->get_context_loss_count)
> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
> +
> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
> @@ -1179,24 +1200,20 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> + int loss_cnt;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + if (_dev->get_context_loss_count) {
> + loss_cnt = _dev->get_context_loss_count(dev);
> + if (loss_cnt < 0) {
> + omap_i2c_restore(_dev);
> + return 0;
> + }
> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
> + return 0;
Again, why does it matter if _dev->dev_lost_count != 0?
IMO, this is still more confusing than it needs to be. What is wrong
with
if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
return 0;
/* read current loss_cnt */
if (_dev->dev_lost_count != loss_cnt)
omap_i2c_restore(_dev);
return 0;
Kevin
>
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + omap_i2c_restore(_dev);
>
> return 0;
> }
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index 92a0dc7..c76cbc0 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
> u32 rev;
> u32 flags;
> void (*set_mpu_wkup_lat)(struct device *dev, long set);
> + int (*get_context_loss_count)(struct device *dev);
> };
>
> #endif
^ permalink raw reply [flat|nested] 52+ messages in thread
* [PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost
@ 2012-04-18 14:08 ` Kevin Hilman
0 siblings, 0 replies; 52+ messages in thread
From: Kevin Hilman @ 2012-04-18 14:08 UTC (permalink / raw)
To: linux-arm-kernel
"Datta, Shubhrajyoti" <shubhrajyoti@ti.com> writes:
> Hi Kevin,
>
>> Hi Kevin,
>> Thanks for your review,
>>
>> On Tue, Apr 17, 2012 at 7:15 PM, Kevin Hilman <khilman@ti.com> wrote:
>>> Shubhrajyoti D <shubhrajyoti@ti.com> writes:
>>>
>>>> ?Currently i2c register restore is done always.
>>>> ?Adding conditional restore.
>>>> ?The i2c register restore is done only if the context is lost.
>>>
>>> OK, minor comment below.
>
> Thanks for the suggestion of the error case restore.
> Updated the patch. Also added Tony's ack for the plat part.
>
>
> From 1ca222f6f50868e07d9a46575e73dd66fd2d542e Mon Sep 17 00:00:00 2001
> From: Shubhrajyoti D <shubhrajyoti@ti.com>
> Date: Tue, 17 Jan 2012 16:13:03 +0530
> Subject: [PATCH] I2C: OMAP: I2C register restore only if context is lost
>
> Currently i2c register restore is done always.
> Adding conditional restore.
> The i2c register restore is done only if the context is lost
> or in case of error to be on the safe side.
> Also remove the definition of SYSS_RESETDONE_MASK and use the
> one in omap_hwmod.h.
>
> Cc: Kevin Hilman <khilman@ti.com>
> [For the arch/arm/plat-omap/i2c.c part]
> Acked-by: Tony Lindgren <tony@atomide.com>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> arch/arm/plat-omap/i2c.c | 3 ++
> drivers/i2c/busses/i2c-omap.c | 53 +++++++++++++++++++++++++++--------------
> include/linux/i2c-omap.h | 1 +
> 3 files changed, 39 insertions(+), 18 deletions(-)
>
> diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
> index db071bc..4ccab07 100644
> --- a/arch/arm/plat-omap/i2c.c
> +++ b/arch/arm/plat-omap/i2c.c
> @@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
> */
> if (cpu_is_omap34xx())
> pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
> +
> + pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
> +
> pdev = omap_device_build(name, bus_id, oh, pdata,
> sizeof(struct omap_i2c_bus_platform_data),
> NULL, 0, 0);
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a882558..76cf066 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -43,6 +43,7 @@
> #include <linux/slab.h>
> #include <linux/i2c-omap.h>
> #include <linux/pm_runtime.h>
> +#include <plat/omap_device.h>
>
> /* I2C controller revisions */
> #define OMAP_I2C_OMAP1_REV_2 0x20
> @@ -157,9 +158,6 @@ enum {
> #define OMAP_I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense in */
> #define OMAP_I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive out */
>
> -/* OCP_SYSSTATUS bit definitions */
> -#define SYSS_RESETDONE_MASK (1 << 0)
> -
Unrelated to this patch.
> /* OCP_SYSCONFIG bit definitions */
> #define SYSC_CLOCKACTIVITY_MASK (0x3 << 8)
> #define SYSC_SIDLEMODE_MASK (0x3 << 3)
> @@ -184,6 +182,7 @@ struct omap_i2c_dev {
> u32 latency; /* maximum mpu wkup latency */
> void (*set_mpu_wkup_lat)(struct device *dev,
> long latency);
> + int (*get_context_loss_count)(struct device *dev);
> u32 speed; /* Speed of bus in kHz */
> u32 dtrev; /* extra revision from DT */
> u32 flags;
> @@ -206,6 +205,7 @@ struct omap_i2c_dev {
> u16 syscstate;
> u16 westate;
> u16 errata;
> + int dev_lost_count;
> };
>
> static const u8 reg_map_ip_v1[] = {
> @@ -1025,6 +1025,7 @@ omap_i2c_probe(struct platform_device *pdev)
> dev->speed = pdata->clkrate;
> dev->flags = pdata->flags;
> dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
> + dev->get_context_loss_count = pdata->get_context_loss_count;
> dev->dtrev = pdata->rev;
> }
>
> @@ -1151,12 +1152,32 @@ omap_i2c_remove(struct platform_device *pdev)
> }
>
> #ifdef CONFIG_PM_RUNTIME
> +static void omap_i2c_restore(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
> + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
> + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + /*
> + * Don't write to this register if the IE state is 0 as it can
> + * cause deadlock.
> + */
> + if (dev->iestate)
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +}
> static int omap_i2c_runtime_suspend(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> u16 iv;
>
> + if (_dev->get_context_loss_count)
> + _dev->dev_lost_count = _dev->get_context_loss_count(dev);
> +
> _dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
> if (_dev->dtrev == OMAP_I2C_IP_VERSION_2)
> omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1);
> @@ -1179,24 +1200,20 @@ static int omap_i2c_runtime_resume(struct device *dev)
> {
> struct platform_device *pdev = to_platform_device(dev);
> struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
> + int loss_cnt;
>
> - if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
> - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
> - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
> + if (_dev->get_context_loss_count) {
> + loss_cnt = _dev->get_context_loss_count(dev);
> + if (loss_cnt < 0) {
> + omap_i2c_restore(_dev);
> + return 0;
> + }
> + if (_dev->dev_lost_count == loss_cnt && _dev->dev_lost_count)
> + return 0;
Again, why does it matter if _dev->dev_lost_count != 0?
IMO, this is still more confusing than it needs to be. What is wrong
with
if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
return 0;
/* read current loss_cnt */
if (_dev->dev_lost_count != loss_cnt)
omap_i2c_restore(_dev);
return 0;
Kevin
>
> - /*
> - * Don't write to this register if the IE state is 0 as it can
> - * cause deadlock.
> - */
> - if (_dev->iestate)
> - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev->iestate);
> + if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
> + omap_i2c_restore(_dev);
>
> return 0;
> }
> diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
> index 92a0dc7..c76cbc0 100644
> --- a/include/linux/i2c-omap.h
> +++ b/include/linux/i2c-omap.h
> @@ -35,6 +35,7 @@ struct omap_i2c_bus_platform_data {
> u32 rev;
> u32 flags;
> void (*set_mpu_wkup_lat)(struct device *dev, long set);
> + int (*get_context_loss_count)(struct device *dev);
> };
>
> #endif
^ permalink raw reply [flat|nested] 52+ messages in thread
[parent not found: <CANQgH-af1VCutKqpq8jK1yTPHybgvnUNA3zdfQq4AYcWcJRtvA@mail.gmail.com>]
* [PATCHv8 08/18] I2C: OMAP: Fix the error handling
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
Currently in probe
pm_runtime_put(dev->dev);
...
/* i2c device drivers may be active on return from add_adapter() */
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(dev->dev, "failure adding adapter\n");
goto err_free_irq;
}
...
return 0;
err_free_irq:
free_irq(dev->irq, dev);
err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(dev->dev);
This may access the i2c registers without the clocks.
Attempting to fix the same by moving the pm_rintime_put after the error check.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2096726..a461097 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1095,8 +1095,6 @@ omap_i2c_probe(struct platform_device *pdev)
dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,
dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
- pm_runtime_put(dev->dev);
-
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
@@ -1116,6 +1114,8 @@ omap_i2c_probe(struct platform_device *pdev)
of_i2c_register_devices(adap);
+ pm_runtime_put(dev->dev);
+
return 0;
err_free_irq:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 08/18] I2C: OMAP: Fix the error handling
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
Currently in probe
pm_runtime_put(dev->dev);
...
/* i2c device drivers may be active on return from add_adapter() */
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(dev->dev, "failure adding adapter\n");
goto err_free_irq;
}
...
return 0;
err_free_irq:
free_irq(dev->irq, dev);
err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(dev->dev);
This may access the i2c registers without the clocks.
Attempting to fix the same by moving the pm_rintime_put after the error check.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2096726..a461097 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1095,8 +1095,6 @@ omap_i2c_probe(struct platform_device *pdev)
dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,
dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
- pm_runtime_put(dev->dev);
-
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
@@ -1116,6 +1114,8 @@ omap_i2c_probe(struct platform_device *pdev)
of_i2c_register_devices(adap);
+ pm_runtime_put(dev->dev);
+
return 0;
err_free_irq:
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 09/18] I2C: OMAP: Correct I2C revision for OMAP3
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Jon Hunter, Shubhrajyoti D
From: Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
The OMAP3530 is based upon the same silicon as the OMAP3430 and so the I2C
revision is the same for 3430 and 3530. However, the OMAP3630 device has the
same I2C revision as OMAP4. Correct the revision definition to reflect this.
This patch is based on work done by Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
Changes from his patch
- Update OMAP_I2C_REV_ON_3430 also to reflect that it is same as 3530
Signed-off-by: Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a461097..959e97c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,8 +50,8 @@
/* I2C controller revisions present on specific hardware */
#define OMAP_I2C_REV_ON_2430 0x36
-#define OMAP_I2C_REV_ON_3430 0x3C
-#define OMAP_I2C_REV_ON_3530_4430 0x40
+#define OMAP_I2C_REV_ON_3430_3530 0x3C
+#define OMAP_I2C_REV_ON_3630_4430 0x40
/* timeout waiting for the controller to respond */
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -298,7 +298,7 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
SYSC_AUTOIDLE_MASK);
- } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
+ } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
dev->syscstate = SYSC_AUTOIDLE_MASK;
dev->syscstate |= SYSC_ENAWAKEUP_MASK;
dev->syscstate |= (SYSC_IDLEMODE_SMART <<
@@ -1051,7 +1051,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
- if (dev->rev <= OMAP_I2C_REV_ON_3430)
+ if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
dev->errata |= I2C_OMAP3_1P153;
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
@@ -1069,7 +1069,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->fifo_size = (dev->fifo_size / 2);
- if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
+ if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 0; /* Disable hardware fixes */
else
dev->b_hw = 1; /* Enable hardware fixes */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 09/18] I2C: OMAP: Correct I2C revision for OMAP3
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
From: Jon Hunter <jon-hunter@ti.com>
The OMAP3530 is based upon the same silicon as the OMAP3430 and so the I2C
revision is the same for 3430 and 3530. However, the OMAP3630 device has the
same I2C revision as OMAP4. Correct the revision definition to reflect this.
This patch is based on work done by Jon Hunter <jon-hunter@ti.com>
Changes from his patch
- Update OMAP_I2C_REV_ON_3430 also to reflect that it is same as 3530
Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a461097..959e97c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,8 +50,8 @@
/* I2C controller revisions present on specific hardware */
#define OMAP_I2C_REV_ON_2430 0x36
-#define OMAP_I2C_REV_ON_3430 0x3C
-#define OMAP_I2C_REV_ON_3530_4430 0x40
+#define OMAP_I2C_REV_ON_3430_3530 0x3C
+#define OMAP_I2C_REV_ON_3630_4430 0x40
/* timeout waiting for the controller to respond */
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -298,7 +298,7 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
SYSC_AUTOIDLE_MASK);
- } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
+ } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
dev->syscstate = SYSC_AUTOIDLE_MASK;
dev->syscstate |= SYSC_ENAWAKEUP_MASK;
dev->syscstate |= (SYSC_IDLEMODE_SMART <<
@@ -1051,7 +1051,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
- if (dev->rev <= OMAP_I2C_REV_ON_3430)
+ if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
dev->errata |= I2C_OMAP3_1P153;
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
@@ -1069,7 +1069,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->fifo_size = (dev->fifo_size / 2);
- if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
+ if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 0; /* Disable hardware fixes */
else
dev->b_hw = 1; /* Enable hardware fixes */
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 10/18] I2C: OMAP: Don't check if wait_for_completion_timeout() returns less than zero
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
By definition, wait_for_completion_timeout() returns an unsigned value and
therefore, it is not necessary to check if the return value is less than zero
as this is not possible.
This is based on a patch from Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
Changes from his patch
- Declare a long as the wait_for_completion_timeout returns long.
Original patch is
http://git.omapzoom.org/?p=kernel/omap.git;a=commitdiff;h=ea02cece7b0000bc736e60c4188a11aaa74bc6e6
Cc : Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 959e97c..121c52e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -502,7 +502,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
struct i2c_msg *msg, int stop)
{
struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
- int r;
+ unsigned long timeout;
u16 w;
dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
@@ -570,12 +570,10 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
* REVISIT: We should abort the transfer on signals, but the bus goes
* into arbitration and we're currently unable to recover from it.
*/
- r = wait_for_completion_timeout(&dev->cmd_complete,
- OMAP_I2C_TIMEOUT);
+ timeout = wait_for_completion_timeout(&dev->cmd_complete,
+ OMAP_I2C_TIMEOUT);
dev->buf_len = 0;
- if (r < 0)
- return r;
- if (r == 0) {
+ if (timeout == 0) {
dev_err(dev->dev, "controller timed out\n");
omap_i2c_reset(dev);
omap_i2c_init(dev);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 10/18] I2C: OMAP: Don't check if wait_for_completion_timeout() returns less than zero
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
By definition, wait_for_completion_timeout() returns an unsigned value and
therefore, it is not necessary to check if the return value is less than zero
as this is not possible.
This is based on a patch from Jon Hunter <jon-hunter@ti.com>
Changes from his patch
- Declare a long as the wait_for_completion_timeout returns long.
Original patch is
http://git.omapzoom.org/?p=kernel/omap.git;a=commitdiff;h=ea02cece7b0000bc736e60c4188a11aaa74bc6e6
Cc : Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 959e97c..121c52e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -502,7 +502,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
struct i2c_msg *msg, int stop)
{
struct omap_i2c_dev *dev = i2c_get_adapdata(adap);
- int r;
+ unsigned long timeout;
u16 w;
dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
@@ -570,12 +570,10 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
* REVISIT: We should abort the transfer on signals, but the bus goes
* into arbitration and we're currently unable to recover from it.
*/
- r = wait_for_completion_timeout(&dev->cmd_complete,
- OMAP_I2C_TIMEOUT);
+ timeout = wait_for_completion_timeout(&dev->cmd_complete,
+ OMAP_I2C_TIMEOUT);
dev->buf_len = 0;
- if (r < 0)
- return r;
- if (r == 0) {
+ if (timeout == 0) {
dev_err(dev->dev, "controller timed out\n");
omap_i2c_reset(dev);
omap_i2c_init(dev);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 12/18] I2C: OMAP: Fix the crash in i2c remove
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D,
stable-u79uwXL29TY76Z2rM5mHXA
In omap_i2c_remove we are accessing the I2C_CON register without
enabling the clocks. Fix the same by enabling the clocks and disabling
it.
This fixes the following crash.
[ 154.723022] ------------[ cut here ]------------
[ 154.725677] WARNING: at arch/arm/mach-omap2/omap_l3_noc.c:112 l3_interrupt_handler+0x1b4/0x1c4()
[ 154.725677] L3 custom error: MASTER:MPU TARGET:L4 PER2
[ 154.742614] Modules linked in: i2c_omap(-)
[ 154.746948] Backtrace:
[ 154.746948] [<c0013078>] (dump_backtrace+0x0/0x110) from [<c026c158>] (dump_stack+0x18/0x1c)
[ 154.752716] r6:00000070 r5:c002c43c r4:df9b9e98 r3:df9b8000
[ 154.764465] [<c026c140>] (dump_stack+0x0/0x1c) from [<c0041a2c>] (warn_slowpath_common+0x5c/0x6c)
[ 154.768341] [<c00419d0>] (warn_slowpath_common+0x0/0x6c) from [<c0041ae0>] (warn_slowpath_fmt+0x38/0x40)
[ 154.776153] r8:00000180 r7:c0361594 r6:c0379b48 r5:00080003 r4:e0838b00
[ 154.790771] r3:00000009
[ 154.791778] [<c0041aa8>] (warn_slowpath_fmt+0x0/0x40) from [<c002c43c>] (l3_interrupt_handler+0x1b4/0x1c4)
[ 154.803710] r3:c0361598 r2:c02ef74c
[ 154.807403] [<c002c288>] (l3_interrupt_handler+0x0/0x1c4) from [<c0085f44>] (handle_irq_event_percpu+0x58/0
[ 154.818237] r8:0000002a r7:00000000 r6:00000000 r5:df808054 r4:df8893c0
[ 154.825378] [<c0085eec>] (handle_irq_event_percpu+0x0/0x188) from [<c00860b8>] (handle_irq_event+0x44/0x64)
[ 154.835662] [<c0086074>] (handle_irq_event+0x0/0x64) from [<c0088ec0>] (handle_fasteoi_irq+0xa4/0x10c)
[ 154.845458] r6:0000002a r5:df808054 r4:df808000 r3:c034a150
[ 154.846466] [<c0088e1c>] (handle_fasteoi_irq+0x0/0x10c) from [<c0085ed0>] (generic_handle_irq+0x30/0x38)
[ 154.854278] r5:c034aa48 r4:0000002a
[ 154.862091] [<c0085ea0>] (generic_handle_irq+0x0/0x38) from [<c000fd38>] (handle_IRQ+0x60/0xc0)
[ 154.874450] r4:c034ea70 r3:000001f8
[ 154.878234] [<c000fcd8>] (handle_IRQ+0x0/0xc0) from [<c0008478>] (gic_handle_irq+0x20/0x5c)
[ 154.887023] r7:ffffff40 r6:df9b9fb0 r5:c034e2b4 r4:0000001a
[ 154.887054] [<c0008458>] (gic_handle_irq+0x0/0x5c) from [<c000ea80>] (__irq_usr+0x40/0x60)
[ 154.901153] Exception stack(0xdf9b9fb0 to 0xdf9b9ff8)
[ 154.907104] 9fa0: beaf1f04 4006be00 0000000f 0000000c
[ 154.915710] 9fc0: 4006c000 00000000 00008034 ffffff40 00000007 00000000 00000000 0007b8d7
[ 154.916778] 9fe0: 00000000 beaf1b68 0000d23c 4005baf0 80000010 ffffffff
[ 154.931335] r6:ffffffff r5:80000010 r4:4005baf0 r3:beaf1f04
[ 154.937316] ---[ end trace 1b75b31a2719ed21 ]--
Cc: <stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 76b7b62..edc4826 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1129,7 +1129,9 @@ static int __devexit omap_i2c_remove(struct platform_device *pdev)
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
+ pm_runtime_get_sync(&pdev->dev);
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 12/18] I2C: OMAP: Fix the crash in i2c remove
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
In omap_i2c_remove we are accessing the I2C_CON register without
enabling the clocks. Fix the same by enabling the clocks and disabling
it.
This fixes the following crash.
[ 154.723022] ------------[ cut here ]------------
[ 154.725677] WARNING: at arch/arm/mach-omap2/omap_l3_noc.c:112 l3_interrupt_handler+0x1b4/0x1c4()
[ 154.725677] L3 custom error: MASTER:MPU TARGET:L4 PER2
[ 154.742614] Modules linked in: i2c_omap(-)
[ 154.746948] Backtrace:
[ 154.746948] [<c0013078>] (dump_backtrace+0x0/0x110) from [<c026c158>] (dump_stack+0x18/0x1c)
[ 154.752716] r6:00000070 r5:c002c43c r4:df9b9e98 r3:df9b8000
[ 154.764465] [<c026c140>] (dump_stack+0x0/0x1c) from [<c0041a2c>] (warn_slowpath_common+0x5c/0x6c)
[ 154.768341] [<c00419d0>] (warn_slowpath_common+0x0/0x6c) from [<c0041ae0>] (warn_slowpath_fmt+0x38/0x40)
[ 154.776153] r8:00000180 r7:c0361594 r6:c0379b48 r5:00080003 r4:e0838b00
[ 154.790771] r3:00000009
[ 154.791778] [<c0041aa8>] (warn_slowpath_fmt+0x0/0x40) from [<c002c43c>] (l3_interrupt_handler+0x1b4/0x1c4)
[ 154.803710] r3:c0361598 r2:c02ef74c
[ 154.807403] [<c002c288>] (l3_interrupt_handler+0x0/0x1c4) from [<c0085f44>] (handle_irq_event_percpu+0x58/0
[ 154.818237] r8:0000002a r7:00000000 r6:00000000 r5:df808054 r4:df8893c0
[ 154.825378] [<c0085eec>] (handle_irq_event_percpu+0x0/0x188) from [<c00860b8>] (handle_irq_event+0x44/0x64)
[ 154.835662] [<c0086074>] (handle_irq_event+0x0/0x64) from [<c0088ec0>] (handle_fasteoi_irq+0xa4/0x10c)
[ 154.845458] r6:0000002a r5:df808054 r4:df808000 r3:c034a150
[ 154.846466] [<c0088e1c>] (handle_fasteoi_irq+0x0/0x10c) from [<c0085ed0>] (generic_handle_irq+0x30/0x38)
[ 154.854278] r5:c034aa48 r4:0000002a
[ 154.862091] [<c0085ea0>] (generic_handle_irq+0x0/0x38) from [<c000fd38>] (handle_IRQ+0x60/0xc0)
[ 154.874450] r4:c034ea70 r3:000001f8
[ 154.878234] [<c000fcd8>] (handle_IRQ+0x0/0xc0) from [<c0008478>] (gic_handle_irq+0x20/0x5c)
[ 154.887023] r7:ffffff40 r6:df9b9fb0 r5:c034e2b4 r4:0000001a
[ 154.887054] [<c0008458>] (gic_handle_irq+0x0/0x5c) from [<c000ea80>] (__irq_usr+0x40/0x60)
[ 154.901153] Exception stack(0xdf9b9fb0 to 0xdf9b9ff8)
[ 154.907104] 9fa0: beaf1f04 4006be00 0000000f 0000000c
[ 154.915710] 9fc0: 4006c000 00000000 00008034 ffffff40 00000007 00000000 00000000 0007b8d7
[ 154.916778] 9fe0: 00000000 beaf1b68 0000d23c 4005baf0 80000010 ffffffff
[ 154.931335] r6:ffffffff r5:80000010 r4:4005baf0 r3:beaf1f04
[ 154.937316] ---[ end trace 1b75b31a2719ed21 ]--
Cc: <stable@vger.kernel.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 76b7b62..edc4826 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1129,7 +1129,9 @@ static int __devexit omap_i2c_remove(struct platform_device *pdev)
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
+ pm_runtime_get_sync(&pdev->dev);
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+ pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 13/18] I2C: OMAP: Handle error check for pm runtime
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
If PM runtime get_sync fails return with the error
so that no further reads/writes goes through the interface.
This will avoid possible abort. Add a error message in case
of failure with the cause of the failure.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index edc4826..95fb9f9 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -616,7 +616,11 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
int i;
int r;
- pm_runtime_get_sync(dev->dev);
+ r = pm_runtime_get_sync(dev->dev);
+ if (r < 0) {
+ dev_err(dev->dev, "pm_runtime_get_sync failed %d\n", r);
+ return r;
+ }
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
@@ -1039,7 +1043,11 @@ omap_i2c_probe(struct platform_device *pdev)
dev->regs = (u8 *)reg_map_ip_v1;
pm_runtime_enable(dev->dev);
- pm_runtime_get_sync(dev->dev);
+ r = pm_runtime_get_sync(dev->dev);
+ if (r < 0) {
+ dev_err(dev->dev, "pm_runtime_get_sync failed:%d\n", r);
+ return r;
+ }
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
@@ -1124,12 +1132,17 @@ err_unuse_clocks:
static int __devexit omap_i2c_remove(struct platform_device *pdev)
{
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
+ int ret;
platform_set_drvdata(pdev, NULL);
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
- pm_runtime_get_sync(&pdev->dev);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0) {
+ dev_err(dev->dev, "pm_runtime_get_sync failed %d\n", ret);
+ return ret;
+ }
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 13/18] I2C: OMAP: Handle error check for pm runtime
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
If PM runtime get_sync fails return with the error
so that no further reads/writes goes through the interface.
This will avoid possible abort. Add a error message in case
of failure with the cause of the failure.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index edc4826..95fb9f9 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -616,7 +616,11 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
int i;
int r;
- pm_runtime_get_sync(dev->dev);
+ r = pm_runtime_get_sync(dev->dev);
+ if (r < 0) {
+ dev_err(dev->dev, "pm_runtime_get_sync failed %d\n", r);
+ return r;
+ }
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
@@ -1039,7 +1043,11 @@ omap_i2c_probe(struct platform_device *pdev)
dev->regs = (u8 *)reg_map_ip_v1;
pm_runtime_enable(dev->dev);
- pm_runtime_get_sync(dev->dev);
+ r = pm_runtime_get_sync(dev->dev);
+ if (r < 0) {
+ dev_err(dev->dev, "pm_runtime_get_sync failed:%d\n", r);
+ return r;
+ }
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
@@ -1124,12 +1132,17 @@ err_unuse_clocks:
static int __devexit omap_i2c_remove(struct platform_device *pdev)
{
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
+ int ret;
platform_set_drvdata(pdev, NULL);
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
- pm_runtime_get_sync(&pdev->dev);
+ ret = pm_runtime_get_sync(&pdev->dev);
+ if (ret < 0) {
+ dev_err(dev->dev, "pm_runtime_get_sync failed %d\n", ret);
+ return ret;
+ }
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 15/18] I2C: OMAP: make the read ready processing a separate function
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
No functional change. Makes the read ready processing a separate
function. This is to avoid extremely long level of indentation.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 86 +++++++++++++++++++++-------------------
1 files changed, 45 insertions(+), 41 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 4815528..fbf65e2 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -786,6 +786,49 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
return 0;
}
+static int process_read_rdy(struct omap_i2c_dev *dev)
+{
+ u8 num_bytes = 1;
+ u16 stat, w;
+
+ if (dev->errata & I2C_OMAP_ERRATA_I207)
+ i2c_omap_errata_i207(dev, stat);
+
+ if (dev->fifo_size) {
+ if (stat & OMAP_I2C_STAT_RRDY)
+ num_bytes = dev->fifo_size;
+ else /* read RXSTAT on RDR interrupt */
+ num_bytes = (omap_i2c_read_reg(dev,
+ OMAP_I2C_BUFSTAT_REG) >> 8) & 0x3F;
+ }
+ while (num_bytes) {
+ num_bytes--;
+ w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+ if (dev->buf_len) {
+ *dev->buf++ = w;
+ dev->buf_len--;
+ /*
+ * Data reg in 2430, omap3 and omap4 is 8 bit wide
+ */
+ if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+ if (dev->buf_len) {
+ *dev->buf++ = w >> 8;
+ dev->buf_len--;
+ }
+ }
+ } else {
+ if (stat & OMAP_I2C_STAT_RRDY)
+ dev_err(dev->dev,
+ "RRDY IRQ while no data requested\n");
+ if (stat & OMAP_I2C_STAT_RDR)
+ dev_err(dev->dev,
+ "RDR IRQ while no data requested\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
static irqreturn_t
omap_i2c_isr(int this_irq, void *dev_id)
{
@@ -836,48 +879,9 @@ complete:
return IRQ_HANDLED;
}
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
- u8 num_bytes = 1;
-
- if (dev->errata & I2C_OMAP_ERRATA_I207)
- i2c_omap_errata_i207(dev, stat);
+ if (process_read_rdy(dev) == -EIO)
+ break;
- if (dev->fifo_size) {
- if (stat & OMAP_I2C_STAT_RRDY)
- num_bytes = dev->fifo_size;
- else /* read RXSTAT on RDR interrupt */
- num_bytes = (omap_i2c_read_reg(dev,
- OMAP_I2C_BUFSTAT_REG)
- >> 8) & 0x3F;
- }
- while (num_bytes) {
- num_bytes--;
- w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
- if (dev->buf_len) {
- *dev->buf++ = w;
- dev->buf_len--;
- /*
- * Data reg in 2430, omap3 and
- * omap4 is 8 bit wide
- */
- if (dev->flags &
- OMAP_I2C_FLAG_16BIT_DATA_REG) {
- if (dev->buf_len) {
- *dev->buf++ = w >> 8;
- dev->buf_len--;
- }
- }
- } else {
- if (stat & OMAP_I2C_STAT_RRDY)
- dev_err(dev->dev,
- "RRDY IRQ while no data"
- " requested\n");
- if (stat & OMAP_I2C_STAT_RDR)
- dev_err(dev->dev,
- "RDR IRQ while no data"
- " requested\n");
- break;
- }
- }
omap_i2c_ack_stat(dev,
stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
continue;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 15/18] I2C: OMAP: make the read ready processing a separate function
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
No functional change. Makes the read ready processing a separate
function. This is to avoid extremely long level of indentation.
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 86 +++++++++++++++++++++-------------------
1 files changed, 45 insertions(+), 41 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 4815528..fbf65e2 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -786,6 +786,49 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
return 0;
}
+static int process_read_rdy(struct omap_i2c_dev *dev)
+{
+ u8 num_bytes = 1;
+ u16 stat, w;
+
+ if (dev->errata & I2C_OMAP_ERRATA_I207)
+ i2c_omap_errata_i207(dev, stat);
+
+ if (dev->fifo_size) {
+ if (stat & OMAP_I2C_STAT_RRDY)
+ num_bytes = dev->fifo_size;
+ else /* read RXSTAT on RDR interrupt */
+ num_bytes = (omap_i2c_read_reg(dev,
+ OMAP_I2C_BUFSTAT_REG) >> 8) & 0x3F;
+ }
+ while (num_bytes) {
+ num_bytes--;
+ w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+ if (dev->buf_len) {
+ *dev->buf++ = w;
+ dev->buf_len--;
+ /*
+ * Data reg in 2430, omap3 and omap4 is 8 bit wide
+ */
+ if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+ if (dev->buf_len) {
+ *dev->buf++ = w >> 8;
+ dev->buf_len--;
+ }
+ }
+ } else {
+ if (stat & OMAP_I2C_STAT_RRDY)
+ dev_err(dev->dev,
+ "RRDY IRQ while no data requested\n");
+ if (stat & OMAP_I2C_STAT_RDR)
+ dev_err(dev->dev,
+ "RDR IRQ while no data requested\n");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+
static irqreturn_t
omap_i2c_isr(int this_irq, void *dev_id)
{
@@ -836,48 +879,9 @@ complete:
return IRQ_HANDLED;
}
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
- u8 num_bytes = 1;
-
- if (dev->errata & I2C_OMAP_ERRATA_I207)
- i2c_omap_errata_i207(dev, stat);
+ if (process_read_rdy(dev) == -EIO)
+ break;
- if (dev->fifo_size) {
- if (stat & OMAP_I2C_STAT_RRDY)
- num_bytes = dev->fifo_size;
- else /* read RXSTAT on RDR interrupt */
- num_bytes = (omap_i2c_read_reg(dev,
- OMAP_I2C_BUFSTAT_REG)
- >> 8) & 0x3F;
- }
- while (num_bytes) {
- num_bytes--;
- w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
- if (dev->buf_len) {
- *dev->buf++ = w;
- dev->buf_len--;
- /*
- * Data reg in 2430, omap3 and
- * omap4 is 8 bit wide
- */
- if (dev->flags &
- OMAP_I2C_FLAG_16BIT_DATA_REG) {
- if (dev->buf_len) {
- *dev->buf++ = w >> 8;
- dev->buf_len--;
- }
- }
- } else {
- if (stat & OMAP_I2C_STAT_RRDY)
- dev_err(dev->dev,
- "RRDY IRQ while no data"
- " requested\n");
- if (stat & OMAP_I2C_STAT_RDR)
- dev_err(dev->dev,
- "RDR IRQ while no data"
- " requested\n");
- break;
- }
- }
omap_i2c_ack_stat(dev,
stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
continue;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 17/18] I2C: OMAP: Do not set the XUDF if the underflow is not reached
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D,
Alexander Shishkin
Currently in the 1.153 errata handling while waiting for transmitter
underflow if NACK is got the XUDF flag is also set.
The flag is set after wait for the condition is over.
Cc: Alexander Shishkin <virtuoso-0lOfPCoBze7YtjvyW6yDsg@public.gmane.org>
Acked-by: Moiz Sonasath <m-sonasath-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2976a7e..9239e9c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -765,7 +765,6 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
- *err |= OMAP_I2C_STAT_XUDF;
return -ETIMEDOUT;
}
@@ -778,6 +777,7 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
return 0;
}
+ *err |= OMAP_I2C_STAT_XUDF;
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 17/18] I2C: OMAP: Do not set the XUDF if the underflow is not reached
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
Currently in the 1.153 errata handling while waiting for transmitter
underflow if NACK is got the XUDF flag is also set.
The flag is set after wait for the condition is over.
Cc: Alexander Shishkin <virtuoso@slind.org>
Acked-by: Moiz Sonasath <m-sonasath@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2976a7e..9239e9c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -765,7 +765,6 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
- *err |= OMAP_I2C_STAT_XUDF;
return -ETIMEDOUT;
}
@@ -778,6 +777,7 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
return 0;
}
+ *err |= OMAP_I2C_STAT_XUDF;
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 18/18] I2C: OMAP: Rename the 1p153 to the erratum id i462
2012-04-12 13:06 ` Shubhrajyoti D
@ 2012-04-12 13:06 ` Shubhrajyoti D
-1 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D, Jon Hunter
The section number in the recent errata document has changed.
Rename the erratum 1p153 to the unique id i462 instead, so that
it is easier to reference. Also change the function name and comments
to reflect the same.
Cc: Jon Hunter <jon-hunter-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9239e9c..c592497 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -170,7 +170,7 @@ enum {
/* Errata definitions */
#define I2C_OMAP_ERRATA_I207 (1 << 0)
-#define I2C_OMAP3_1P153 (1 << 1)
+#define I2C_OMAP_ERRATA_I462 (1 << 1)
struct omap_i2c_dev {
struct device *dev;
@@ -753,11 +753,11 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
#endif
/*
- * OMAP3430 Errata 1.153: When an XRDY/XDR is hit, wait for XUDF before writing
+ * OMAP3430 Errata i462: When an XRDY/XDR is hit, wait for XUDF before writing
* data to DATA_REG. Otherwise some data bytes can be lost while transferring
* them from the memory to the I2C interface.
*/
-static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
{
unsigned long timeout = 10000;
@@ -920,8 +920,8 @@ complete:
break;
}
- if ((dev->errata & I2C_OMAP3_1P153) &&
- errata_omap3_1p153(dev, &stat, &err))
+ if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
+ errata_omap3_i462(dev, &stat, &err))
goto complete;
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
@@ -1056,7 +1056,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->errata |= I2C_OMAP_ERRATA_I207;
if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
- dev->errata |= I2C_OMAP3_1P153;
+ dev->errata |= I2C_OMAP_ERRATA_I462;
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
u16 s;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread
* [PATCHv8 18/18] I2C: OMAP: Rename the 1p153 to the erratum id i462
@ 2012-04-12 13:06 ` Shubhrajyoti D
0 siblings, 0 replies; 52+ messages in thread
From: Shubhrajyoti D @ 2012-04-12 13:06 UTC (permalink / raw)
To: linux-arm-kernel
The section number in the recent errata document has changed.
Rename the erratum 1p153 to the unique id i462 instead, so that
it is easier to reference. Also change the function name and comments
to reflect the same.
Cc: Jon Hunter <jon-hunter@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
drivers/i2c/busses/i2c-omap.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9239e9c..c592497 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -170,7 +170,7 @@ enum {
/* Errata definitions */
#define I2C_OMAP_ERRATA_I207 (1 << 0)
-#define I2C_OMAP3_1P153 (1 << 1)
+#define I2C_OMAP_ERRATA_I462 (1 << 1)
struct omap_i2c_dev {
struct device *dev;
@@ -753,11 +753,11 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
#endif
/*
- * OMAP3430 Errata 1.153: When an XRDY/XDR is hit, wait for XUDF before writing
+ * OMAP3430 Errata i462: When an XRDY/XDR is hit, wait for XUDF before writing
* data to DATA_REG. Otherwise some data bytes can be lost while transferring
* them from the memory to the I2C interface.
*/
-static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
{
unsigned long timeout = 10000;
@@ -920,8 +920,8 @@ complete:
break;
}
- if ((dev->errata & I2C_OMAP3_1P153) &&
- errata_omap3_1p153(dev, &stat, &err))
+ if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
+ errata_omap3_i462(dev, &stat, &err))
goto complete;
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
@@ -1056,7 +1056,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->errata |= I2C_OMAP_ERRATA_I207;
if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
- dev->errata |= I2C_OMAP3_1P153;
+ dev->errata |= I2C_OMAP_ERRATA_I462;
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
u16 s;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 52+ messages in thread