[PATCHv8 04/18] I2C: OMAP: I2C register restore only if context is lost

Datta, Shubhrajyoti shubhrajyoti at ti.com
Fri Apr 20 10:17:44 EDT 2012


On Fri, Apr 20, 2012 at 7:43 PM, Datta, Shubhrajyoti
<shubhrajyoti at ti.com> wrote:
>
>
>
> On Wed, Apr 18, 2012 at 7:38 PM, Kevin Hilman <khilman at ti.com> wrote:
>>
>> "
>
>
>> >  #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.
>
>
Actually if this is not removed we get a warn as the header file gets
added when I add omap_device.h and the compiler sees a redefinition. However
I agree that it can be a seperate patch.

 Here is the updated patch with your comments.
 Thanks.
>From c5efbe2bb050c113a1cb1b959a8890578ba9b237 Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <shubhrajyoti at ti.com>
Date: Fri, 20 Apr 2012 11:15:28 +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.

Cc: Kevin Hilman <khilman at ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti at ti.com>
---
 arch/arm/plat-omap/i2c.c      |    3 +++
 drivers/i2c/busses/i2c-omap.c |   35 ++++++++++++++++++++++++++---------
 include/linux/i2c-omap.h      |    1 +
 3 files changed, 30 insertions(+), 9 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 f5094b1..d95b01b 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
@@ -185,6 +186,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;
@@ -207,6 +209,7 @@ struct omap_i2c_dev {
 	u16			syscstate;
 	u16			westate;
 	u16			errata;
+	int			dev_lost_count;
 };

 static const u8 reg_map_ip_v1[] = {
@@ -989,6 +992,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;
 	}

@@ -1133,12 +1137,26 @@ 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);
+
+}
 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);

 	omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
@@ -1159,16 +1177,15 @@ 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))
+		return 0;

-	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 (_dev->dev_lost_count != loss_cnt)
+			omap_i2c_restore(_dev);
 	}

 	/*
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



More information about the linux-arm-kernel mailing list