* [PATCHv3 1/8] i2c: omap: Fix the revision register read
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
@ 2012-11-05 12:23 ` Shubhrajyoti D
2012-11-05 14:11 ` Felipe Balbi
2012-11-05 12:23 ` [PATCHv3 3/8] i2c: omap: remove the dtrev Shubhrajyoti D
` (5 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Shubhrajyoti D @ 2012-11-05 12:23 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
The revision register on OMAP4 is a 16-bit lo and a 16-bit
hi. Currently the driver reads only the lower 8-bits.
Fix the same by preventing the truncating of the rev register
for OMAP4.
Also use the scheme bit ie bit-14 of the hi register to know if it
is OMAP_I2C_IP_VERSION_2.
On platforms previous to OMAP4 the offset 0x04 is IE register whose
bit-14 reset value is 0, the code uses the same to its advantage.
Also since the omap_i2c_read_reg uses reg_map_ip_* a raw_readw is done
to fetch the revision register.
The dev->regs is populated after reading the rev_hi. A NULL check
has been added in the resume handler to prevent the access before
the setting of the regs.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
v3: Fix the comments.
drivers/i2c/busses/i2c-omap.c | 61 ++++++++++++++++++++++++++++++++---------
1 files changed, 48 insertions(+), 13 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index db31eae..5c6f538 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -49,9 +49,10 @@
#define OMAP_I2C_OMAP1_REV_2 0x20
/* I2C controller revisions present on specific hardware */
-#define OMAP_I2C_REV_ON_2430 0x36
-#define OMAP_I2C_REV_ON_3430_3530 0x3C
-#define OMAP_I2C_REV_ON_3630_4430 0x40
+#define OMAP_I2C_REV_ON_2430 0x00000036
+#define OMAP_I2C_REV_ON_3430_3530 0x0000003C
+#define OMAP_I2C_REV_ON_3630 0x00000040
+#define OMAP_I2C_REV_ON_4430_PLUS 0x50400002
/* timeout waiting for the controller to respond */
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -202,7 +203,7 @@ struct omap_i2c_dev {
* fifo_size==0 implies no fifo
* if set, should be trsh+1
*/
- u8 rev;
+ u32 rev;
unsigned b_hw:1; /* bad h/w fixes */
unsigned receiver:1; /* true when we're in receiver mode */
u16 iestate; /* Saved interrupt register */
@@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
- if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
+ if (dev->rev < OMAP_I2C_REV_ON_3630)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
@@ -1052,6 +1053,16 @@ static const struct of_device_id omap_i2c_of_match[] = {
MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
#endif
+#define OMAP_I2C_SCHEME(rev) ((rev & 0xc000) >> 14)
+
+#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) (rev >> 4)
+#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) (rev & 0xf)
+
+#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) ((rev & 0x0700) >> 7)
+#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) (rev & 0x1f)
+#define OMAP_I2C_SCHEME_0 0
+#define OMAP_I2C_SCHEME_1 1
+
static int __devinit
omap_i2c_probe(struct platform_device *pdev)
{
@@ -1064,6 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev)
const struct of_device_id *match;
int irq;
int r;
+ u32 rev;
+ u16 minor, major;
/* NOTE: driver uses the static register mapping */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1117,11 +1130,6 @@ omap_i2c_probe(struct platform_device *pdev)
dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
- if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
- dev->regs = (u8 *)reg_map_ip_v2;
- else
- dev->regs = (u8 *)reg_map_ip_v1;
-
pm_runtime_enable(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, OMAP_I2C_PM_TIMEOUT);
pm_runtime_use_autosuspend(dev->dev);
@@ -1130,7 +1138,31 @@ omap_i2c_probe(struct platform_device *pdev)
if (IS_ERR_VALUE(r))
goto err_free_mem;
- dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
+ /*
+ * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.
+ * On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset.
+ * Also since the omap_i2c_read_reg uses reg_map_ip_* a
+ * raw_readw is done.
+ */
+ rev = __raw_readw(dev->base + 0x04);
+
+ switch (OMAP_I2C_SCHEME(rev)) {
+ case OMAP_I2C_SCHEME_0:
+ dev->regs = (u8 *)reg_map_ip_v1;
+ dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG);
+ minor = OMAP_I2C_REV_SCHEME_0_MAJOR(dev->rev);
+ major = OMAP_I2C_REV_SCHEME_0_MAJOR(dev->rev);
+ break;
+ case OMAP_I2C_SCHEME_1:
+ /* FALLTHROUGH */
+ default:
+ dev->regs = (u8 *)reg_map_ip_v2;
+ rev = (rev << 16) |
+ omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO);
+ minor = OMAP_I2C_REV_SCHEME_1_MINOR(rev);
+ major = OMAP_I2C_REV_SCHEME_1_MAJOR(rev);
+ dev->rev = rev;
+ }
dev->errata = 0;
@@ -1155,7 +1187,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->fifo_size = (dev->fifo_size / 2);
- if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
+ if (dev->rev < OMAP_I2C_REV_ON_3630)
dev->b_hw = 1; /* Enable hardware fixes */
/* calculate wakeup latency constraint for MPU */
@@ -1198,7 +1230,7 @@ omap_i2c_probe(struct platform_device *pdev)
}
dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", adap->nr,
- dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
+ dev->dtrev, major, minor, dev->speed);
of_i2c_register_devices(adap);
@@ -1264,6 +1296,9 @@ 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);
+ if (!_dev->regs)
+ 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);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCHv3 1/8] i2c: omap: Fix the revision register read
2012-11-05 12:23 ` [PATCHv3 1/8] i2c: omap: Fix the revision register read Shubhrajyoti D
@ 2012-11-05 14:11 ` Felipe Balbi
0 siblings, 0 replies; 19+ messages in thread
From: Felipe Balbi @ 2012-11-05 14:11 UTC (permalink / raw)
To: Shubhrajyoti D
Cc: linux-omap, linux-i2c, linux-arm-kernel, ben-linux, tony,
b-cousson, balbi, w.sang
[-- Attachment #1: Type: text/plain, Size: 6067 bytes --]
On Mon, Nov 05, 2012 at 05:53:36PM +0530, Shubhrajyoti D wrote:
> The revision register on OMAP4 is a 16-bit lo and a 16-bit
> hi. Currently the driver reads only the lower 8-bits.
> Fix the same by preventing the truncating of the rev register
> for OMAP4.
>
> Also use the scheme bit ie bit-14 of the hi register to know if it
> is OMAP_I2C_IP_VERSION_2.
>
> On platforms previous to OMAP4 the offset 0x04 is IE register whose
> bit-14 reset value is 0, the code uses the same to its advantage.
>
> Also since the omap_i2c_read_reg uses reg_map_ip_* a raw_readw is done
> to fetch the revision register.
>
> The dev->regs is populated after reading the rev_hi. A NULL check
> has been added in the resume handler to prevent the access before
> the setting of the regs.
>
Reviewed-by: Felipe Balbi <balbi@ti.com>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
> v3: Fix the comments.
>
> drivers/i2c/busses/i2c-omap.c | 61 ++++++++++++++++++++++++++++++++---------
> 1 files changed, 48 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index db31eae..5c6f538 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -49,9 +49,10 @@
> #define OMAP_I2C_OMAP1_REV_2 0x20
>
> /* I2C controller revisions present on specific hardware */
> -#define OMAP_I2C_REV_ON_2430 0x36
> -#define OMAP_I2C_REV_ON_3430_3530 0x3C
> -#define OMAP_I2C_REV_ON_3630_4430 0x40
> +#define OMAP_I2C_REV_ON_2430 0x00000036
> +#define OMAP_I2C_REV_ON_3430_3530 0x0000003C
> +#define OMAP_I2C_REV_ON_3630 0x00000040
> +#define OMAP_I2C_REV_ON_4430_PLUS 0x50400002
>
> /* timeout waiting for the controller to respond */
> #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
> @@ -202,7 +203,7 @@ struct omap_i2c_dev {
> * fifo_size==0 implies no fifo
> * if set, should be trsh+1
> */
> - u8 rev;
> + u32 rev;
> unsigned b_hw:1; /* bad h/w fixes */
> unsigned receiver:1; /* true when we're in receiver mode */
> u16 iestate; /* Saved interrupt register */
> @@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
>
> omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
>
> - if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
> + if (dev->rev < OMAP_I2C_REV_ON_3630)
> dev->b_hw = 1; /* Enable hardware fixes */
>
> /* calculate wakeup latency constraint for MPU */
> @@ -1052,6 +1053,16 @@ static const struct of_device_id omap_i2c_of_match[] = {
> MODULE_DEVICE_TABLE(of, omap_i2c_of_match);
> #endif
>
> +#define OMAP_I2C_SCHEME(rev) ((rev & 0xc000) >> 14)
> +
> +#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) (rev >> 4)
> +#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) (rev & 0xf)
> +
> +#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) ((rev & 0x0700) >> 7)
> +#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) (rev & 0x1f)
> +#define OMAP_I2C_SCHEME_0 0
> +#define OMAP_I2C_SCHEME_1 1
> +
> static int __devinit
> omap_i2c_probe(struct platform_device *pdev)
> {
> @@ -1064,6 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev)
> const struct of_device_id *match;
> int irq;
> int r;
> + u32 rev;
> + u16 minor, major;
>
> /* NOTE: driver uses the static register mapping */
> mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> @@ -1117,11 +1130,6 @@ omap_i2c_probe(struct platform_device *pdev)
>
> dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
>
> - if (dev->dtrev == OMAP_I2C_IP_VERSION_2)
> - dev->regs = (u8 *)reg_map_ip_v2;
> - else
> - dev->regs = (u8 *)reg_map_ip_v1;
> -
> pm_runtime_enable(dev->dev);
> pm_runtime_set_autosuspend_delay(dev->dev, OMAP_I2C_PM_TIMEOUT);
> pm_runtime_use_autosuspend(dev->dev);
> @@ -1130,7 +1138,31 @@ omap_i2c_probe(struct platform_device *pdev)
> if (IS_ERR_VALUE(r))
> goto err_free_mem;
>
> - dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff;
> + /*
> + * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2.
> + * On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset.
> + * Also since the omap_i2c_read_reg uses reg_map_ip_* a
> + * raw_readw is done.
> + */
> + rev = __raw_readw(dev->base + 0x04);
> +
> + switch (OMAP_I2C_SCHEME(rev)) {
> + case OMAP_I2C_SCHEME_0:
> + dev->regs = (u8 *)reg_map_ip_v1;
> + dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG);
> + minor = OMAP_I2C_REV_SCHEME_0_MAJOR(dev->rev);
> + major = OMAP_I2C_REV_SCHEME_0_MAJOR(dev->rev);
> + break;
> + case OMAP_I2C_SCHEME_1:
> + /* FALLTHROUGH */
> + default:
> + dev->regs = (u8 *)reg_map_ip_v2;
> + rev = (rev << 16) |
> + omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO);
> + minor = OMAP_I2C_REV_SCHEME_1_MINOR(rev);
> + major = OMAP_I2C_REV_SCHEME_1_MAJOR(rev);
> + dev->rev = rev;
> + }
>
> dev->errata = 0;
>
> @@ -1155,7 +1187,7 @@ omap_i2c_probe(struct platform_device *pdev)
>
> dev->fifo_size = (dev->fifo_size / 2);
>
> - if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
> + if (dev->rev < OMAP_I2C_REV_ON_3630)
> dev->b_hw = 1; /* Enable hardware fixes */
>
> /* calculate wakeup latency constraint for MPU */
> @@ -1198,7 +1230,7 @@ omap_i2c_probe(struct platform_device *pdev)
> }
>
> dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", adap->nr,
> - dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
> + dev->dtrev, major, minor, dev->speed);
>
> of_i2c_register_devices(adap);
>
> @@ -1264,6 +1296,9 @@ 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);
>
> + if (!_dev->regs)
> + 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);
> --
> 1.7.5.4
>
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCHv3 3/8] i2c: omap: remove the dtrev
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
2012-11-05 12:23 ` [PATCHv3 1/8] i2c: omap: Fix the revision register read Shubhrajyoti D
@ 2012-11-05 12:23 ` Shubhrajyoti D
[not found] ` <1352118223-3796-4-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
2012-11-05 12:23 ` [PATCHv3 5/8] i2c: omap: re-factor omap_i2c_init function Shubhrajyoti D
` (4 subsequent siblings)
6 siblings, 1 reply; 19+ messages in thread
From: Shubhrajyoti D @ 2012-11-05 12:23 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
The dtrev is used only for the comments. Remove the same and use
the scheme instead to know if it is version2.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
v3: remove the scheme from the commments.
todo: remove the dtrev from hwmod etc.
drivers/i2c/busses/i2c-omap.c | 12 +++++-------
1 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 737d843..5f0c06c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -191,7 +191,6 @@ struct omap_i2c_dev {
u32 latency; /* maximum MPU wkup latency */
struct pm_qos_request pm_qos_request;
u32 speed; /* Speed of bus in kHz */
- u32 dtrev; /* extra revision from DT */
u32 flags;
u16 cmd_err;
u8 *buf;
@@ -1076,7 +1075,7 @@ omap_i2c_probe(struct platform_device *pdev)
int irq;
int r;
u32 rev;
- u16 minor, major;
+ u16 minor, major, scheme;
/* NOTE: driver uses the static register mapping */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1108,7 +1107,6 @@ omap_i2c_probe(struct platform_device *pdev)
u32 freq = 100000; /* default to 100000 Hz */
pdata = match->data;
- dev->dtrev = pdata->rev;
dev->flags = pdata->flags;
of_property_read_u32(node, "clock-frequency", &freq);
@@ -1117,7 +1115,6 @@ omap_i2c_probe(struct platform_device *pdev)
} else if (pdata != NULL) {
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
- dev->dtrev = pdata->rev;
}
dev->dev = &pdev->dev;
@@ -1146,7 +1143,8 @@ omap_i2c_probe(struct platform_device *pdev)
*/
rev = __raw_readw(dev->base + 0x04);
- switch (OMAP_I2C_SCHEME(rev)) {
+ scheme = OMAP_I2C_SCHEME(rev);
+ switch (scheme) {
case OMAP_I2C_SCHEME_0:
dev->regs = (u8 *)reg_map_ip_v1;
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG);
@@ -1230,8 +1228,8 @@ omap_i2c_probe(struct platform_device *pdev)
goto err_unuse_clocks;
}
- dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", adap->nr,
- dev->dtrev, major, minor, dev->speed);
+ dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n", adap->nr,
+ major, minor, dev->speed);
of_i2c_register_devices(adap);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCHv3 5/8] i2c: omap: re-factor omap_i2c_init function
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
2012-11-05 12:23 ` [PATCHv3 1/8] i2c: omap: Fix the revision register read Shubhrajyoti D
2012-11-05 12:23 ` [PATCHv3 3/8] i2c: omap: remove the dtrev Shubhrajyoti D
@ 2012-11-05 12:23 ` Shubhrajyoti D
2012-11-05 12:23 ` [PATCHv3 7/8] i2c: omap: Restore i2c context always Shubhrajyoti D
` (3 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Shubhrajyoti D @ 2012-11-05 12:23 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
re-factor omap_i2c_init() so that we can re-use it for resume.
While at it also remove the bufstate variable as we write it
in omap_i2c_resize_fifo for every transfer.
Reviewed-by: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 75 +++++++++++++++++++----------------------
1 files changed, 35 insertions(+), 40 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 88358d8..393bb22 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -209,7 +209,6 @@ struct omap_i2c_dev {
u16 pscstate;
u16 scllstate;
u16 sclhstate;
- u16 bufstate;
u16 syscstate;
u16 westate;
u16 errata;
@@ -275,9 +274,34 @@ 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_init(struct omap_i2c_dev *dev)
+{
+
+ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+
+ /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
+ omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+
+ /* SCL low and high time values */
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+ omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+ if (dev->rev >= OMAP_I2C_REV_ON_3430_3530)
+ omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+
+ /* Take the I2C module out of reset: */
+ 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_init(struct omap_i2c_dev *dev)
{
- u16 psc = 0, scll = 0, sclh = 0, buf = 0;
+ u16 psc = 0, scll = 0, sclh = 0;
u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
unsigned long fclk_rate = 12000000;
unsigned long timeout;
@@ -327,11 +351,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
* REVISIT: Some wkup sources might not be needed.
*/
dev->westate = OMAP_I2C_WE_ALL;
- omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
- dev->westate);
}
}
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
/*
@@ -416,28 +437,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
sclh = fclk_rate / (dev->speed * 2) - 7 + psc;
}
- /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */
- omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc);
-
- /* SCL low and high time values */
- omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
- omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
-
- /* Take the I2C module out of reset: */
- omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
-
- /* Enable interrupts */
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_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
- if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
- dev->pscstate = psc;
- dev->scllstate = scll;
- dev->sclhstate = sclh;
- dev->bufstate = buf;
- }
+
+ dev->pscstate = psc;
+ dev->scllstate = scll;
+ dev->sclhstate = sclh;
+
+ __omap_i2c_init(dev);
+
return 0;
}
@@ -1297,23 +1307,8 @@ static int omap_i2c_runtime_resume(struct device *dev)
if (!_dev->regs)
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);
- }
-
- /*
- * 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_init(_dev);
return 0;
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCHv3 7/8] i2c: omap: Restore i2c context always
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
` (2 preceding siblings ...)
2012-11-05 12:23 ` [PATCHv3 5/8] i2c: omap: re-factor omap_i2c_init function Shubhrajyoti D
@ 2012-11-05 12:23 ` Shubhrajyoti D
2012-11-05 12:23 ` [PATCHv3 8/8] i2c: omap: cleanup the sysc write Shubhrajyoti D
` (2 subsequent siblings)
6 siblings, 0 replies; 19+ messages in thread
From: Shubhrajyoti D @ 2012-11-05 12:23 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
Currently the restore is done based on the flag
OMAP_I2C_FLAG_RESET_REGS_POSTIDLE.
This helps the following
- The driver is always capable of restoring regardless
of the off mode support being there or not.
- While testing omap2430 it is found that in case of certain
error paths (timeout) a reset is done. However the restore
never happens as it is dependent on the POSTIDLE flag.
The other option would be to call a restore in the reset
case. As there are only a few registers to be restored
the penalty in the idle case should not be much.
Reviewed-by: Felipe Balbi <balbi-l0cyMroinI0@public.gmane.org>
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
Todo: the flag could be deleted if the patch is accepted.
drivers/i2c/busses/i2c-omap.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7393017..25f1564 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1316,8 +1316,7 @@ static int omap_i2c_runtime_resume(struct device *dev)
if (!_dev->regs)
return 0;
- if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE)
- __omap_i2c_init(_dev);
+ __omap_i2c_init(_dev);
return 0;
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCHv3 8/8] i2c: omap: cleanup the sysc write
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
` (3 preceding siblings ...)
2012-11-05 12:23 ` [PATCHv3 7/8] i2c: omap: Restore i2c context always Shubhrajyoti D
@ 2012-11-05 12:23 ` Shubhrajyoti D
[not found] ` <1352118223-3796-9-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
2012-11-13 12:50 ` [PATCHv3 0/7] i2c: omap: updates Shubhrajyoti Datta
2012-11-14 12:04 ` Wolfram Sang
6 siblings, 1 reply; 19+ messages in thread
From: Shubhrajyoti D @ 2012-11-05 12:23 UTC (permalink / raw)
To: linux-omap-u79uwXL29TY76Z2rM5mHXA
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ, Shubhrajyoti D
Currently after the reset the sysc is written with hardcoded values.
The patch reads the sysc register and writes back the same value
after reset.
- Some unnecessary rev checks can be optimised.
- Also due to whatever reason the hwmod flags are changed
we will not reset the values.
- In some of the cases the minor values of the 2430 register
is different(0x37) in that case the autoidle setting may be missed.
Signed-off-by: Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org>
---
drivers/i2c/busses/i2c-omap.c | 20 +++++---------------
1 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 25f1564..a09acdc 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -302,7 +302,11 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev)
static int omap_i2c_reset(struct omap_i2c_dev *dev)
{
unsigned long timeout;
+ u16 sysc;
+
if (dev->rev >= OMAP_I2C_OMAP1_REV_2) {
+ sysc = omap_i2c_read_reg(dev, OMAP_I2C_SYSC_REG);
+
/* Disable I2C controller before soft reset */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) &
@@ -324,22 +328,8 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
}
/* SYSC register is cleared by the reset; rewrite it */
- if (dev->rev == OMAP_I2C_REV_ON_2430) {
-
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
- SYSC_AUTOIDLE_MASK);
+ omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, sysc);
- } 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 <<
- __ffs(SYSC_SIDLEMODE_MASK));
- dev->syscstate |= (SYSC_CLOCKACTIVITY_FCLK <<
- __ffs(SYSC_CLOCKACTIVITY_MASK));
-
- omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
- dev->syscstate);
- }
}
return 0;
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCHv3 0/7] i2c: omap: updates
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
` (4 preceding siblings ...)
2012-11-05 12:23 ` [PATCHv3 8/8] i2c: omap: cleanup the sysc write Shubhrajyoti D
@ 2012-11-13 12:50 ` Shubhrajyoti Datta
2012-11-14 12:04 ` Wolfram Sang
6 siblings, 0 replies; 19+ messages in thread
From: Shubhrajyoti Datta @ 2012-11-13 12:50 UTC (permalink / raw)
To: Shubhrajyoti D
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0,
w.sang-bIcnvbaLZ9MEGnE8C9+IrQ
On Mon, Nov 5, 2012 at 5:53 PM, Shubhrajyoti D <shubhrajyoti-l0cyMroinI0@public.gmane.org> wrote:
>
> Does the followiing
> - Make the revision a 32- bit consisting of rev_lo amd rev_hi each
> of 16 bits.
>
> - Also use the revision register for the erratum i207.
> - Refactor the i2c_omap_init code.
>
> Adds a patch to remove the hardcoding sysc register. Instead
> read register ,reset and then writeback the read value.
>
> Also more cleanup is possible will check on that subsequently.
>
> Previous discussions can be found
> http://www.spinics.net/lists/linux-omap/msg81265.html
>
>
> Tested on OMAP4430sdp ,4460 ,omap3630 ,3430 and omap2430.
>
> For omap2 testing the below patch was used
> [PATCH] ARM: vfp: fix save and restore when running on pre-VFPv3 and CONFIG_VFPv3 set
>
If there are no further comments can this be considered for next.
Thanks and Regards,
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCHv3 0/7] i2c: omap: updates
[not found] ` <1352118223-3796-1-git-send-email-shubhrajyoti-l0cyMroinI0@public.gmane.org>
` (5 preceding siblings ...)
2012-11-13 12:50 ` [PATCHv3 0/7] i2c: omap: updates Shubhrajyoti Datta
@ 2012-11-14 12:04 ` Wolfram Sang
2012-11-14 13:09 ` Shubhrajyoti
6 siblings, 1 reply; 19+ messages in thread
From: Wolfram Sang @ 2012-11-14 12:04 UTC (permalink / raw)
To: Shubhrajyoti D
Cc: linux-omap-u79uwXL29TY76Z2rM5mHXA,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ben-linux-elnMNo+KYs3YtjvyW6yDsg, tony-4v6yS6AI5VpBDgjK7y7TUQ,
b-cousson-l0cyMroinI0, balbi-l0cyMroinI0
[-- Attachment #1: Type: text/plain, Size: 767 bytes --]
On Mon, Nov 05, 2012 at 05:53:35PM +0530, Shubhrajyoti D wrote:
> Shubhrajyoti D (8):
> i2c: omap: Fix the revision register read
> i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207
> i2c: omap: remove the dtrev
> ARM: i2c: omap: Remove the i207 errata flag
> i2c: omap: re-factor omap_i2c_init function
> i2c: omap: make reset a seperate function
> i2c: omap: Restore i2c context always
> i2c: omap: cleanup the sysc write
Pushed the series to for-next, after fixing a trivial merge conflict
caused by reverting the QoS patch.
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCHv3 0/7] i2c: omap: updates
2012-11-14 12:04 ` Wolfram Sang
@ 2012-11-14 13:09 ` Shubhrajyoti
0 siblings, 0 replies; 19+ messages in thread
From: Shubhrajyoti @ 2012-11-14 13:09 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-omap, linux-i2c, linux-arm-kernel, ben-linux, tony,
b-cousson, balbi
On Wednesday 14 November 2012 05:34 PM, Wolfram Sang wrote:
> On Mon, Nov 05, 2012 at 05:53:35PM +0530, Shubhrajyoti D wrote:
>
>> Shubhrajyoti D (8):
>> i2c: omap: Fix the revision register read
>> i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207
>> i2c: omap: remove the dtrev
>> ARM: i2c: omap: Remove the i207 errata flag
>> i2c: omap: re-factor omap_i2c_init function
>> i2c: omap: make reset a seperate function
>> i2c: omap: Restore i2c context always
>> i2c: omap: cleanup the sysc write
> Pushed the series to for-next, after fixing a trivial merge conflict
> caused by reverting the QoS patch.
Thanks.
>
^ permalink raw reply [flat|nested] 19+ messages in thread