* Re: [PATCH 04/12] I2C re-init for every cmd
@ 2008-09-11 15:55 chandra shekhar
2008-09-12 7:48 ` Högander Jouni
0 siblings, 1 reply; 8+ messages in thread
From: chandra shekhar @ 2008-09-11 15:55 UTC (permalink / raw)
To: jouni.hogander; +Cc: linux-omap
> Hi,
>
> Few comments inlined.
>
> Regards,
> Chandra
> ----- Original Message -----
> From: ""Högander" Jouni" <jouni.hogander@nokia.com>
> To: "ext Rajendra Nayak" <rnayak@ti.com>
> Cc: <linux-omap@vger.kernel.org>
> Sent: Thursday, September 11, 2008 3:34 PM
> Subject: Re: [PATCH 04/12] I2C re-init for every cmd
>
>
> "ext Rajendra Nayak" <rnayak@ti.com> writes:
>
>> This patch does i2c init/re-init for every transfer
>>
>> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
>> ---
>> drivers/i2c/busses/i2c-omap.c | 2 ++
>> 1 files changed, 2 insertions(+)
>>
>> Index: linux-omap-2.6/drivers/i2c/busses/i2c-omap.c
>> ===================================================================
>> --- linux-omap-2.6.orig/drivers/i2c/busses/i2c-omap.c 2008-09-01
>> 18:11:28.000000000 +0530
>> +++ linux-omap-2.6/drivers/i2c/busses/i2c-omap.c 2008-09-01 18:11:52.000000000
>> +0530
>> @@ -496,6 +496,8 @@ omap_i2c_xfer(struct i2c_adapter *adap,
>>
>> omap_i2c_unidle(dev);
>>
>> + omap_i2c_init(dev);
>> +
>> if ((r = omap_i2c_wait_for_bb(dev)) < 0)
>> goto out;
>
> This is causing unacceptable delays on i2c transfers. This is because
> occasionally reset loop in init function enters msleep. Is it
> necessary to reset i2c controller after off-mode?
>
> Any opinions on this:
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 3778735..4a27035 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -126,6 +126,14 @@
> /* I2C System Configuration Register (OMAP_I2C_SYSC): */
> #define OMAP_I2C_SYSC_SRST (1 << 1) /* Soft Reset */
>
> +struct omap3_i2c_regs {
> + u16 sysc;
> + u16 psc;
> + u16 scll;
> + u16 sclh;
> + u16 buf;
> +};
> +
>
>
>
> We can add this as a part of controller structure itself instaed of
> creating a new structure. we will store this
> psc, scll and others as a part of controller and just restore it. That
> way we can do away with omap3_i2c_save_context every time in clk
> disable.
>My patch is neither saving ctx on every clk disable. Just after init.
>
>
>
>
>
> struct omap_i2c_dev {
> struct device *dev;
> void __iomem *base; /* virtual */
> @@ -147,6 +155,9 @@ struct omap_i2c_dev {
> unsigned b_hw:1; /* bad h/w fixes */
> unsigned idle:1;
> u16 iestate; /* Saved interrupt register */
> +#ifdef CONFIG_ARCH_OMAP34XX
> + struct omap3_i2c_regs context;
> +#endif
>
>
>
> I guess this should work for all the platforms. at least for omap2/3
> it should work w/o any hiccups.
> I2C_BUF is the only register which will require cpu check..so while
> restoring we can put that check for 2430/34xx.
>Can we use off mode with omap2? Generally, should we build in
>save/restore code for other than omap3?
agreed..but i guess it will not compile for 2430 and prev. platforms.
omap3_i2c_save_context and restore definition is under macro
while call is not. let me know if i am missing something.
also is SYSC register restore needed??
>
>
> };
>
>
>
> static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
> @@ -160,6 +171,26 @@ static inline u16 omap_i2c_read_reg(struct
> omap_i2c_dev *i2c_dev, int reg)
> return __raw_readw(i2c_dev->base + reg);
> }
>
> +#ifdef CONFIG_ARCH_OMAP34XX
> +void omap3_i2c_save_context(struct omap_i2c_dev *dev)
> +{
> + dev->context.sysc = omap_i2c_read_reg(dev, OMAP_I2C_SYSC_REG);
> + dev->context.psc = omap_i2c_read_reg(dev, OMAP_I2C_PSC_REG);
> + dev->context.scll = omap_i2c_read_reg(dev, OMAP_I2C_SCLL_REG);
> + dev->context.sclh = omap_i2c_read_reg(dev, OMAP_I2C_SCLH_REG);
> + dev->context.buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
> +}
> +
>
>
> +void omap3_i2c_restore_context(struct omap_i2c_dev *dev)
> +{
> + omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev->context.sysc);
> + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->context.psc);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->context.scll);
> + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->context.sclh);
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->context.buf);
> +}
> +#endif
> +
>
> static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
> {
> if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
> @@ -210,6 +241,10 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
> clk_enable(dev->iclk);
> clk_enable(dev->fclk);
> dev->idle = 0;
> +
> + if (cpu_is_omap34xx())
> + omap3_i2c_restore_context(dev);
> +
> if (dev->iestate)
> omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> }
> @@ -344,6 +379,10 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
> OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
> (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
> +
> + if (cpu_is_omap34xx())
> + omap3_i2c_save_context(dev);
> +
>
>
>
> this will become redundant as data will be part of controller
> structure.
>
>
> return 0;
> }
>
> @@ -496,8 +535,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct
> i2c_msg msgs[], int num)
>
> omap_i2c_unidle(dev);
>
> - omap_i2c_init(dev);
> -
>
>
> instead of calling restore from clk_enable we can replace
> omap_i2c_init by omap3_i2c_restore_context. that way clock enable code
> will be clean.
Well, I though unidle could be ok as ie reg is already restored there?
>
>
>
> if ((r = omap_i2c_wait_for_bb(dev)) < 0)
> goto out;
>
> --
> Jouni Högander
>
> --
> 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
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 04/12] I2C re-init for every cmd
2008-09-11 15:55 [PATCH 04/12] I2C re-init for every cmd chandra shekhar
@ 2008-09-12 7:48 ` Högander Jouni
2008-09-15 6:57 ` shekhar, chandra
2008-09-16 9:25 ` Kevin Hilman
0 siblings, 2 replies; 8+ messages in thread
From: Högander Jouni @ 2008-09-12 7:48 UTC (permalink / raw)
To: ext chandra shekhar; +Cc: linux-omap
"ext chandra shekhar" <x0044955@ti.com> writes:
> agreed..but i guess it will not compile for 2430 and prev. platforms.
> omap3_i2c_save_context and restore definition is under macro
> while call is not. let me know if i am missing something.
>
> also is SYSC register restore needed??
Here is the second version. Does it look any better to you?
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 3778735..0a11621 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -147,6 +147,12 @@ struct omap_i2c_dev {
unsigned b_hw:1; /* bad h/w fixes */
unsigned idle:1;
u16 iestate; /* Saved interrupt register */
+#ifdef CONFIG_ARCH_OMAP34XX
+ u16 pscstate;
+ u16 scllstate;
+ u16 sclhstate;
+ u16 bufstate;
+#endif
};
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -209,16 +215,21 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
if (dev->iclk != NULL)
clk_enable(dev->iclk);
clk_enable(dev->fclk);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ 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);
+#endif
dev->idle = 0;
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 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);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
if (dev->rev1)
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
@@ -238,7 +249,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
- u16 psc = 0, scll = 0, sclh = 0;
+ u16 psc = 0, scll = 0, sclh = 0, buf = 0;
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
unsigned long fclk_rate = 12000000;
unsigned long timeout;
@@ -327,23 +338,30 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
- if (dev->fifo_size)
- /* Note: setup required fifo size - 1 */
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
- (dev->fifo_size - 1) << 8 | /* RTRSH */
- OMAP_I2C_BUF_RXFIF_CLR |
- (dev->fifo_size - 1) | /* XTRSH */
- OMAP_I2C_BUF_TXFIF_CLR);
+ if (dev->fifo_size) {
+ /* Note: setup required fifo size - 1. RTRSH and XTRSH */
+ buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
+ (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+ }
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
/* Enable interrupts */
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
- (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+ dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
- (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
+ (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ dev->pscstate = psc;
+ dev->scllstate = scll;
+ dev->sclhstate = sclh;
+ dev->bufstate = buf;
+#endif
+
return 0;
}
@@ -496,8 +514,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
omap_i2c_unidle(dev);
- omap_i2c_init(dev);
-
if ((r = omap_i2c_wait_for_bb(dev)) < 0)
goto out;
--
Jouni Högander
--
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] 8+ messages in thread
* Re: [PATCH 04/12] I2C re-init for every cmd
2008-09-12 7:48 ` Högander Jouni
@ 2008-09-15 6:57 ` shekhar, chandra
2008-09-16 9:25 ` Kevin Hilman
1 sibling, 0 replies; 8+ messages in thread
From: shekhar, chandra @ 2008-09-15 6:57 UTC (permalink / raw)
To: "Högander" Jouni; +Cc: linux-omap
Hi,
This patch looks ok.
i would have preferred runtime check for 34xx. It will be a bit overhead for
previous platforms.
but will be good for multi-omap support.
----- Original Message -----
From: ""Högander" Jouni" <jouni.hogander@nokia.com>
To: "ext chandra shekhar" <x0044955@ti.com>
Cc: <linux-omap@vger.kernel.org>
Sent: Friday, September 12, 2008 1:18 PM
Subject: Re: [PATCH 04/12] I2C re-init for every cmd
"ext chandra shekhar" <x0044955@ti.com> writes:
> agreed..but i guess it will not compile for 2430 and prev. platforms.
> omap3_i2c_save_context and restore definition is under macro
> while call is not. let me know if i am missing something.
>
> also is SYSC register restore needed??
Here is the second version. Does it look any better to you?
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 3778735..0a11621 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -147,6 +147,12 @@ struct omap_i2c_dev {
unsigned b_hw:1; /* bad h/w fixes */
unsigned idle:1;
u16 iestate; /* Saved interrupt register */
+#ifdef CONFIG_ARCH_OMAP34XX
+ u16 pscstate;
+ u16 scllstate;
+ u16 sclhstate;
+ u16 bufstate;
+#endif
};
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -209,16 +215,21 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
if (dev->iclk != NULL)
clk_enable(dev->iclk);
clk_enable(dev->fclk);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ 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);
+#endif
dev->idle = 0;
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 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);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
if (dev->rev1)
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
@@ -238,7 +249,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
- u16 psc = 0, scll = 0, sclh = 0;
+ u16 psc = 0, scll = 0, sclh = 0, buf = 0;
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
unsigned long fclk_rate = 12000000;
unsigned long timeout;
@@ -327,23 +338,30 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
- if (dev->fifo_size)
- /* Note: setup required fifo size - 1 */
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
- (dev->fifo_size - 1) << 8 | /* RTRSH */
- OMAP_I2C_BUF_RXFIF_CLR |
- (dev->fifo_size - 1) | /* XTRSH */
- OMAP_I2C_BUF_TXFIF_CLR);
+ if (dev->fifo_size) {
+ /* Note: setup required fifo size - 1. RTRSH and XTRSH */
+ buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
+ (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+ }
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
/* Enable interrupts */
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
- (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+ dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
- (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
+ (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR)
: 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ dev->pscstate = psc;
+ dev->scllstate = scll;
+ dev->sclhstate = sclh;
+ dev->bufstate = buf;
+#endif
+
return 0;
}
@@ -496,8 +514,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg
msgs[], int num)
omap_i2c_unidle(dev);
- omap_i2c_init(dev);
-
if ((r = omap_i2c_wait_for_bb(dev)) < 0)
goto out;
--
Jouni Högander
--
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] 8+ messages in thread
* Re: [PATCH 04/12] I2C re-init for every cmd
2008-09-12 7:48 ` Högander Jouni
2008-09-15 6:57 ` shekhar, chandra
@ 2008-09-16 9:25 ` Kevin Hilman
2008-09-16 10:13 ` Högander Jouni
1 sibling, 1 reply; 8+ messages in thread
From: Kevin Hilman @ 2008-09-16 9:25 UTC (permalink / raw)
To: Högander Jouni; +Cc: ext chandra shekhar, linux-omap
jouni.hogander@nokia.com (Högander Jouni) writes:
> "ext chandra shekhar" <x0044955@ti.com> writes:
>
>> agreed..but i guess it will not compile for 2430 and prev. platforms.
>> omap3_i2c_save_context and restore definition is under macro
>> while call is not. let me know if i am missing something.
>>
>> also is SYSC register restore needed??
>
> Here is the second version. Does it look any better to you?
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 3778735..0a11621 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -147,6 +147,12 @@ struct omap_i2c_dev {
> unsigned b_hw:1; /* bad h/w fixes */
> unsigned idle:1;
> u16 iestate; /* Saved interrupt register */
> +#ifdef CONFIG_ARCH_OMAP34XX
> + u16 pscstate;
> + u16 scllstate;
> + u16 sclhstate;
> + u16 bufstate;
> +#endif
> };
>
> static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
> @@ -209,16 +215,21 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
> if (dev->iclk != NULL)
> clk_enable(dev->iclk);
> clk_enable(dev->fclk);
> +
> +#ifdef CONFIG_ARCH_OMAP34XX
> + 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);
> +#endif
The above should also be inside an if cpu_is_omap34xx() block so
it works correctly on multi-omap kernels.
Kevin
> dev->idle = 0;
> - if (dev->iestate)
> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 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);
> omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
> if (dev->rev1)
> iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
> @@ -238,7 +249,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
>
> static int omap_i2c_init(struct omap_i2c_dev *dev)
> {
> - u16 psc = 0, scll = 0, sclh = 0;
> + u16 psc = 0, scll = 0, sclh = 0, buf = 0;
> u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> unsigned long fclk_rate = 12000000;
> unsigned long timeout;
> @@ -327,23 +338,30 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
> omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
>
> - if (dev->fifo_size)
> - /* Note: setup required fifo size - 1 */
> - omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
> - (dev->fifo_size - 1) << 8 | /* RTRSH */
> - OMAP_I2C_BUF_RXFIF_CLR |
> - (dev->fifo_size - 1) | /* XTRSH */
> - OMAP_I2C_BUF_TXFIF_CLR);
> + if (dev->fifo_size) {
> + /* Note: setup required fifo size - 1. RTRSH and XTRSH */
> + buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
> + (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
> + }
>
> /* Take the I2C module out of reset: */
> omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>
> /* Enable interrupts */
> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
> - (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
> + dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
> OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
> OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
> - (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
> + (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> +#ifdef CONFIG_ARCH_OMAP34XX
> + dev->pscstate = psc;
> + dev->scllstate = scll;
> + dev->sclhstate = sclh;
> + dev->bufstate = buf;
> +#endif
> +
> return 0;
> }
>
> @@ -496,8 +514,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>
> omap_i2c_unidle(dev);
>
> - omap_i2c_init(dev);
> -
> if ((r = omap_i2c_wait_for_bb(dev)) < 0)
> goto out;
>
> --
> Jouni Högander
>
> --
> 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
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 04/12] I2C re-init for every cmd
2008-09-16 9:25 ` Kevin Hilman
@ 2008-09-16 10:13 ` Högander Jouni
2008-09-17 9:45 ` [PATCH PM-0] OMAP3: I2C: Implement i2c save/restore Jouni Hogander
0 siblings, 1 reply; 8+ messages in thread
From: Högander Jouni @ 2008-09-16 10:13 UTC (permalink / raw)
To: ext Kevin Hilman; +Cc: ext chandra shekhar, linux-omap
[-- Attachment #1: Type: text/plain, Size: 780 bytes --]
"ext Kevin Hilman" <khilman@deeprootsystems.com> writes:
> jouni.hogander@nokia.com (Högander Jouni) writes:
>
>> @@ -209,16 +215,21 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
>> if (dev->iclk != NULL)
>> clk_enable(dev->iclk);
>> clk_enable(dev->fclk);
>> +
>> +#ifdef CONFIG_ARCH_OMAP34XX
>> + 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);
>> +#endif
>
> The above should also be inside an if cpu_is_omap34xx() block so
> it works correctly on multi-omap kernels.
Here you are:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-OMAP3-I2C-Implement-i2c-save-restore.patch --]
[-- Type: text/x-diff, Size: 3723 bytes --]
>From 24db406dfb2ba6c9069b70c2efd1134ea29c23eb Mon Sep 17 00:00:00 2001
From: Jouni Hogander <jouni.hogander@nokia.com>
Date: Tue, 16 Sep 2008 13:03:24 +0300
Subject: [RFC] OMAP3: I2C: Implement i2c save/restore
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
drivers/i2c/busses/i2c-omap.c | 52 ++++++++++++++++++++++++++++------------
1 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 3778735..6f6cfcc 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -147,6 +147,12 @@ struct omap_i2c_dev {
unsigned b_hw:1; /* bad h/w fixes */
unsigned idle:1;
u16 iestate; /* Saved interrupt register */
+#ifdef CONFIG_ARCH_OMAP34XX
+ u16 pscstate;
+ u16 scllstate;
+ u16 sclhstate;
+ u16 bufstate;
+#endif
};
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -209,16 +215,23 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
if (dev->iclk != NULL)
clk_enable(dev->iclk);
clk_enable(dev->fclk);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx()) {
+ 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);
+ }
+#endif
dev->idle = 0;
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 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);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
if (dev->rev1)
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
@@ -238,7 +251,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
- u16 psc = 0, scll = 0, sclh = 0;
+ u16 psc = 0, scll = 0, sclh = 0, buf = 0;
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
unsigned long fclk_rate = 12000000;
unsigned long timeout;
@@ -327,23 +340,32 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
- if (dev->fifo_size)
- /* Note: setup required fifo size - 1 */
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
- (dev->fifo_size - 1) << 8 | /* RTRSH */
- OMAP_I2C_BUF_RXFIF_CLR |
- (dev->fifo_size - 1) | /* XTRSH */
- OMAP_I2C_BUF_TXFIF_CLR);
+ if (dev->fifo_size) {
+ /* Note: setup required fifo size - 1. RTRSH and XTRSH */
+ buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
+ (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+ }
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
/* Enable interrupts */
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
- (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+ dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
- (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
+ (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (cpu_is_omap34xx()) {
+ dev->pscstate = psc;
+ dev->scllstate = scll;
+ dev->sclhstate = sclh;
+ dev->bufstate = buf;
+ }
+#endif
+
return 0;
}
@@ -496,8 +518,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
omap_i2c_unidle(dev);
- omap_i2c_init(dev);
-
if ((r = omap_i2c_wait_for_bb(dev)) < 0)
goto out;
--
1.5.5
[-- Attachment #3: Type: text/plain, Size: 24 bytes --]
--
Jouni Högander
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH PM-0] OMAP3: I2C: Implement i2c save/restore
2008-09-16 10:13 ` Högander Jouni
@ 2008-09-17 9:45 ` Jouni Hogander
2008-09-17 11:18 ` Kevin Hilman
0 siblings, 1 reply; 8+ messages in thread
From: Jouni Hogander @ 2008-09-17 9:45 UTC (permalink / raw)
To: linux-omap
Save and restore needed registers instead of re-init.
Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
---
drivers/i2c/busses/i2c-omap.c | 47 +++++++++++++++++++++++++++--------------
1 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a661ed3..211d7b5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -147,6 +147,10 @@ struct omap_i2c_dev {
unsigned b_hw:1; /* bad h/w fixes */
unsigned idle:1;
u16 iestate; /* Saved interrupt register */
+ u16 pscstate;
+ u16 scllstate;
+ u16 sclhstate;
+ u16 bufstate;
};
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -209,16 +213,22 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
if (dev->iclk != NULL)
clk_enable(dev->iclk);
clk_enable(dev->fclk);
+
+ if (cpu_is_omap34xx()) {
+ 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);
+ }
+
dev->idle = 0;
- if (dev->iestate)
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 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);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
if (dev->rev1)
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
@@ -238,7 +248,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
static int omap_i2c_init(struct omap_i2c_dev *dev)
{
- u16 psc = 0, scll = 0, sclh = 0;
+ u16 psc = 0, scll = 0, sclh = 0, buf = 0;
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
unsigned long fclk_rate = 12000000;
unsigned long timeout;
@@ -327,23 +337,30 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
- if (dev->fifo_size)
- /* Note: setup required fifo size - 1 */
- omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
- (dev->fifo_size - 1) << 8 | /* RTRSH */
- OMAP_I2C_BUF_RXFIF_CLR |
- (dev->fifo_size - 1) | /* XTRSH */
- OMAP_I2C_BUF_TXFIF_CLR);
+ if (dev->fifo_size) {
+ /* Note: setup required fifo size - 1. RTRSH and XTRSH */
+ buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
+ (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+ omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+ }
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
/* Enable interrupts */
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
- (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+ dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
- (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
+ (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
+ omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+ if (cpu_is_omap34xx()) {
+ dev->pscstate = psc;
+ dev->scllstate = scll;
+ dev->sclhstate = sclh;
+ dev->bufstate = buf;
+ }
+
return 0;
}
@@ -503,8 +520,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
omap_i2c_unidle(dev);
- omap_i2c_init(dev);
-
if ((r = omap_i2c_wait_for_bb(dev)) < 0)
goto out;
--
1.5.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH PM-0] OMAP3: I2C: Implement i2c save/restore
2008-09-17 9:45 ` [PATCH PM-0] OMAP3: I2C: Implement i2c save/restore Jouni Hogander
@ 2008-09-17 11:18 ` Kevin Hilman
2008-09-17 11:25 ` Felipe Balbi
0 siblings, 1 reply; 8+ messages in thread
From: Kevin Hilman @ 2008-09-17 11:18 UTC (permalink / raw)
To: Jouni Hogander; +Cc: linux-omap
Jouni Hogander <jouni.hogander@nokia.com> writes:
> Save and restore needed registers instead of re-init.
>
> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
Ack. Pushing to pm-0 today.
Kevin
> ---
> drivers/i2c/busses/i2c-omap.c | 47 +++++++++++++++++++++++++++--------------
> 1 files changed, 31 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index a661ed3..211d7b5 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -147,6 +147,10 @@ struct omap_i2c_dev {
> unsigned b_hw:1; /* bad h/w fixes */
> unsigned idle:1;
> u16 iestate; /* Saved interrupt register */
> + u16 pscstate;
> + u16 scllstate;
> + u16 sclhstate;
> + u16 bufstate;
> };
>
> static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
> @@ -209,16 +213,22 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
> if (dev->iclk != NULL)
> clk_enable(dev->iclk);
> clk_enable(dev->fclk);
> +
> + if (cpu_is_omap34xx()) {
> + 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);
> + }
> +
> dev->idle = 0;
> - if (dev->iestate)
> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 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);
> omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
> if (dev->rev1)
> iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
> @@ -238,7 +248,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
>
> static int omap_i2c_init(struct omap_i2c_dev *dev)
> {
> - u16 psc = 0, scll = 0, sclh = 0;
> + u16 psc = 0, scll = 0, sclh = 0, buf = 0;
> u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
> unsigned long fclk_rate = 12000000;
> unsigned long timeout;
> @@ -327,23 +337,30 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
> omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
> omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
>
> - if (dev->fifo_size)
> - /* Note: setup required fifo size - 1 */
> - omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG,
> - (dev->fifo_size - 1) << 8 | /* RTRSH */
> - OMAP_I2C_BUF_RXFIF_CLR |
> - (dev->fifo_size - 1) | /* XTRSH */
> - OMAP_I2C_BUF_TXFIF_CLR);
> + if (dev->fifo_size) {
> + /* Note: setup required fifo size - 1. RTRSH and XTRSH */
> + buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
> + (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
> + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
> + }
>
> /* Take the I2C module out of reset: */
> omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
>
> /* Enable interrupts */
> - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG,
> - (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
> + dev->iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
> OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK |
> OMAP_I2C_IE_AL) | ((dev->fifo_size) ?
> - (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0));
> + (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
> + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
> +
> + if (cpu_is_omap34xx()) {
> + dev->pscstate = psc;
> + dev->scllstate = scll;
> + dev->sclhstate = sclh;
> + dev->bufstate = buf;
> + }
> +
> return 0;
> }
>
> @@ -503,8 +520,6 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
>
> omap_i2c_unidle(dev);
>
> - omap_i2c_init(dev);
> -
> if ((r = omap_i2c_wait_for_bb(dev)) < 0)
> goto out;
>
> --
> 1.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH PM-0] OMAP3: I2C: Implement i2c save/restore
2008-09-17 11:18 ` Kevin Hilman
@ 2008-09-17 11:25 ` Felipe Balbi
0 siblings, 0 replies; 8+ messages in thread
From: Felipe Balbi @ 2008-09-17 11:25 UTC (permalink / raw)
To: ext Kevin Hilman; +Cc: Jouni Hogander, linux-omap
On Wed, Sep 17, 2008 at 02:18:57PM +0300, ext Kevin Hilman wrote:
> Jouni Hogander <jouni.hogander@nokia.com> writes:
>
> > Save and restore needed registers instead of re-init.
> >
> > Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com>
>
> Ack. Pushing to pm-0 today.
About that, pm-0 only appears in source.mvista.com. Anyway of pushing it
to kernel.org as well ??
--
balbi
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-09-17 11:26 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-11 15:55 [PATCH 04/12] I2C re-init for every cmd chandra shekhar
2008-09-12 7:48 ` Högander Jouni
2008-09-15 6:57 ` shekhar, chandra
2008-09-16 9:25 ` Kevin Hilman
2008-09-16 10:13 ` Högander Jouni
2008-09-17 9:45 ` [PATCH PM-0] OMAP3: I2C: Implement i2c save/restore Jouni Hogander
2008-09-17 11:18 ` Kevin Hilman
2008-09-17 11:25 ` Felipe Balbi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox