All of lore.kernel.org
 help / color / mirror / Atom feed
* [rft/rfc/patch 00/22] Big I2C cleanup
@ 2012-06-13 15:50 Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 01/22] i2c: omap: simplify num_bytes handling Felipe Balbi
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

First of all, this isn't fully tested yet. I can
see some issues poping up after this patchset which
I'm not sure if it's a race condition somewhere or
the HW is just misbehaving.

All in all, the IRQ handler looks cleaner now. There's
still lots of things to be done and before I'm going any
further, I'd like help testing this patchset.

Note that on multiple boots you might face some issues
with the XDR IRQ which aparently keeps getting retriggered
even though it gets acked and properly cleared. I didn't
look yet if there's an errata for that.

I'll give myself a break of the I2C driver because it's
just driving me nuts already. If you have the balls to
look over the unfinished patches (see that there are
a few patches which could be combined, will do that later)
and help out testing, reviewing, commenting...

Next steps (after this set is done) would be to get rid
of that stupid, nonsensical FIFO clear before starting
every transfer, fix up NAK handling, clean up debugging
messages, figure out why sometimes IRQs don't fire (AKA
"controller timed out" crap) and lots more.

For convenience it's also located on the following git
branch:

git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git i2c

ps: boot tested on OMAP4 Panda. When it boots fine, it's actually
quite stable, I managed to do many transfers with the PMIC (checking
regulators' state) and it works very reliably (while true; cat
/sys/class/regulators/*/state; done works fine for multiple iterations);

Felipe Balbi (22):
  i2c: omap: simplify num_bytes handling
  i2c: omap: decrease indentation level on data handling
  i2c: omap: add blank lines
  i2c: omap: simplify omap_i2c_ack_stat()
  i2c: omap: split out [XR]DR and [XR]RDY
  i2c: omap: improve 1p153 errata handling
  i2c: omap: re-factor receive/transmit data loop
  i2c: omap: switch over to do {} while loop
  i2c: omap: ack IRQ in parts
  i2c: omap: switch I2C REV2 to threaded IRQ
  i2c: omap: get rid of "count" variable
  i2c: omap: get rid of the "complete" label
  i2c: omap: if controller is suspended, bail out
  i2c: omap: ack ARDY IRQ
  i2c: omap: switch to devm_* API
  i2c: omap: switch to platform_get_irq()
  i2c: omap: drop Access Ready IRQ
  i2c: omap: drop errata i207 from RRDY interrupt
  i2c: omap: bus: add a receiver flag
  i2c: omap: avoid unnecessary register read
  i2c: omap: no need to reinitialize "stat"
  i2c: omap: simplify errata check

 drivers/i2c/busses/i2c-omap.c |  386 +++++++++++++++++++++++------------------
 1 file changed, 216 insertions(+), 170 deletions(-)

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 01/22] i2c: omap: simplify num_bytes handling
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 02/22] i2c: omap: decrease indentation level on data handling Felipe Balbi
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

trivial patch, no functional changes

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 801df60..9b532cd 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -855,8 +855,7 @@ complete:
 							OMAP_I2C_BUFSTAT_REG)
 							>> 8) & 0x3F;
 			}
-			while (num_bytes) {
-				num_bytes--;
+			while (num_bytes--) {
 				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
 				if (dev->buf_len) {
 					*dev->buf++ = w;
@@ -898,8 +897,7 @@ complete:
 							OMAP_I2C_BUFSTAT_REG)
 							& 0x3F;
 			}
-			while (num_bytes) {
-				num_bytes--;
+			while (num_bytes--) {
 				w = 0;
 				if (dev->buf_len) {
 					w = *dev->buf++;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 02/22] i2c: omap: decrease indentation level on data handling
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 01/22] i2c: omap: simplify num_bytes handling Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 03/22] i2c: omap: add blank lines Felipe Balbi
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

trivial patch, no functional changes.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   63 ++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9b532cd..39d5583 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -856,22 +856,7 @@ complete:
 							>> 8) & 0x3F;
 			}
 			while (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 (!dev->buf_len) {
 					if (stat & OMAP_I2C_STAT_RRDY)
 						dev_err(dev->dev,
 							"RRDY IRQ while no data"
@@ -882,6 +867,21 @@ complete:
 								" requested\n");
 					break;
 				}
+
+				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+				*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--;
+					}
+				}
 			}
 			omap_i2c_ack_stat(dev,
 				stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
@@ -898,22 +898,7 @@ complete:
 							& 0x3F;
 			}
 			while (num_bytes--) {
-				w = 0;
-				if (dev->buf_len) {
-					w = *dev->buf++;
-					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) {
-							w |= *dev->buf++ << 8;
-							dev->buf_len--;
-						}
-					}
-				} else {
+				if (!dev->buf_len) {
 					if (stat & OMAP_I2C_STAT_XRDY)
 						dev_err(dev->dev,
 							"XRDY IRQ while no "
@@ -925,6 +910,20 @@ complete:
 					break;
 				}
 
+				w = *dev->buf++;
+				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) {
+						w |= *dev->buf++ << 8;
+						dev->buf_len--;
+					}
+				}
+
 				if ((dev->errata & I2C_OMAP3_1P153) &&
 				    errata_omap3_1p153(dev, &stat, &err))
 					goto complete;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 03/22] i2c: omap: add blank lines
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 01/22] i2c: omap: simplify num_bytes handling Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 02/22] i2c: omap: decrease indentation level on data handling Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 04/22] i2c: omap: simplify omap_i2c_ack_stat() Felipe Balbi
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

trivial patch to aid readability. No functional
changes.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 39d5583..07ae391 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -829,6 +829,7 @@ complete:
 			dev_err(dev->dev, "Arbitration lost\n");
 			err |= OMAP_I2C_STAT_AL;
 		}
+
 		/*
 		 * ProDB0017052: Clear ARDY bit twice
 		 */
@@ -841,6 +842,7 @@ complete:
 			omap_i2c_complete_cmd(dev, err);
 			return IRQ_HANDLED;
 		}
+
 		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
 			u8 num_bytes = 1;
 
@@ -887,6 +889,7 @@ complete:
 				stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
 			continue;
 		}
+
 		if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
 			u8 num_bytes = 1;
 			if (dev->fifo_size) {
@@ -934,10 +937,12 @@ complete:
 				stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
 			continue;
 		}
+
 		if (stat & OMAP_I2C_STAT_ROVR) {
 			dev_err(dev->dev, "Receive overrun\n");
 			dev->cmd_err |= OMAP_I2C_STAT_ROVR;
 		}
+
 		if (stat & OMAP_I2C_STAT_XUDF) {
 			dev_err(dev->dev, "Transmit underflow\n");
 			dev->cmd_err |= OMAP_I2C_STAT_XUDF;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 04/22] i2c: omap: simplify omap_i2c_ack_stat()
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (2 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 03/22] i2c: omap: add blank lines Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 05/22] i2c: omap: split out [XR]DR and [XR]RDY Felipe Balbi
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

stat & BIT(1) is the same as BIT(1), so let's
simplify things a bit by removing "stat &" from
all omap_i2c_ack_stat() calls.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 07ae391..fa9ddb6 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -774,8 +774,8 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
 
 	while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
 		if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
-			omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
-							OMAP_I2C_STAT_XDR));
+			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
+					OMAP_I2C_STAT_XDR));
 			*err |= OMAP_I2C_STAT_XUDF;
 			return -ETIMEDOUT;
 		}
@@ -835,10 +835,11 @@ complete:
 		 */
 		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
 					OMAP_I2C_STAT_AL)) {
-			omap_i2c_ack_stat(dev, stat &
-				(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
-				OMAP_I2C_STAT_ARDY));
+			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+						OMAP_I2C_STAT_RDR |
+						OMAP_I2C_STAT_XRDY |
+						OMAP_I2C_STAT_XDR |
+						OMAP_I2C_STAT_ARDY));
 			omap_i2c_complete_cmd(dev, err);
 			return IRQ_HANDLED;
 		}
@@ -885,8 +886,8 @@ complete:
 					}
 				}
 			}
-			omap_i2c_ack_stat(dev,
-				stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
+			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+						OMAP_I2C_STAT_RDR));
 			continue;
 		}
 
@@ -933,8 +934,8 @@ complete:
 
 				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
 			}
-			omap_i2c_ack_stat(dev,
-				stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
+			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
+						OMAP_I2C_STAT_XDR));
 			continue;
 		}
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 05/22] i2c: omap: split out [XR]DR and [XR]RDY
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (3 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 04/22] i2c: omap: simplify omap_i2c_ack_stat() Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 06/22] i2c: omap: improve 1p153 errata handling Felipe Balbi
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

While they do pretty much the same thing, there
are a few peculiarities. Specially WRT erratas,
it's best to split those out and re-factor the
read/write loop to another function which both
cases call.

This last part will be done on another patch.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |  130 +++++++++++++++++++++++++++++++----------
 1 file changed, 99 insertions(+), 31 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index fa9ddb6..9e6be9f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -844,36 +844,31 @@ complete:
 			return IRQ_HANDLED;
 		}
 
-		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
+		if (stat & OMAP_I2C_STAT_RDR) {
 			u8 num_bytes = 1;
 
 			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;
+				num_bytes = omap_i2c_read_reg(dev,
+						OMAP_I2C_BUFSTAT_REG);
+				num_bytes >>= 8;
+				num_bytes &= 0x3f;
 			}
+
 			while (num_bytes--) {
 				if (!dev->buf_len) {
-					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,
+					dev_err(dev->dev,
 							"RDR IRQ while no data"
-								" requested\n");
+							" requested\n");
 					break;
 				}
 
 				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
 				*dev->buf++ = w;
 				dev->buf_len--;
+
 				/*
 				 * Data reg in 2430, omap3 and
 				 * omap4 is 8 bit wide
@@ -886,29 +881,61 @@ complete:
 					}
 				}
 			}
-			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
-						OMAP_I2C_STAT_RDR));
+
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+			continue;
+		}
+
+		if (stat & OMAP_I2C_STAT_RRDY) {
+			u8 num_bytes = 1;
+
+			if (dev->errata & I2C_OMAP_ERRATA_I207)
+				i2c_omap_errata_i207(dev, stat);
+
+			if (dev->fifo_size)
+				num_bytes = dev->fifo_size;
+
+			while (num_bytes--) {
+				if (!dev->buf_len) {
+					dev_err(dev->dev,
+							"RRDY IRQ while no data"
+							" requested\n");
+					break;
+				}
+
+				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+				*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--;
+					}
+				}
+			}
+
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
 			continue;
 		}
 
-		if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
+		if (stat & OMAP_I2C_STAT_XDR) {
 			u8 num_bytes = 1;
+
 			if (dev->fifo_size) {
-				if (stat & OMAP_I2C_STAT_XRDY)
-					num_bytes = dev->fifo_size;
-				else    /* read TXSTAT on XDR interrupt */
-					num_bytes = omap_i2c_read_reg(dev,
-							OMAP_I2C_BUFSTAT_REG)
-							& 0x3F;
+				num_bytes = omap_i2c_read_reg(dev,
+						OMAP_I2C_BUFSTAT_REG);
+				num_bytes &= 0x3f;
 			}
+
 			while (num_bytes--) {
 				if (!dev->buf_len) {
-					if (stat & OMAP_I2C_STAT_XRDY)
-						dev_err(dev->dev,
-							"XRDY IRQ while no "
-							"data to send\n");
-					if (stat & OMAP_I2C_STAT_XDR)
-						dev_err(dev->dev,
+					dev_err(dev->dev,
 							"XDR IRQ while no "
 							"data to send\n");
 					break;
@@ -916,6 +943,7 @@ complete:
 
 				w = *dev->buf++;
 				dev->buf_len--;
+
 				/*
 				 * Data reg in 2430, omap3 and
 				 * omap4 is 8 bit wide
@@ -934,8 +962,48 @@ complete:
 
 				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
 			}
-			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
-						OMAP_I2C_STAT_XDR));
+
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
+			continue;
+		}
+
+		if (stat & OMAP_I2C_STAT_XRDY) {
+			u8 num_bytes = 1;
+
+			if (dev->fifo_size)
+				num_bytes = dev->fifo_size;
+
+			while (num_bytes--) {
+				if (!dev->buf_len) {
+					dev_err(dev->dev,
+							"XRDY IRQ while no "
+							"data to send\n");
+					break;
+				}
+
+				w = *dev->buf++;
+				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) {
+						w |= *dev->buf++ << 8;
+						dev->buf_len--;
+					}
+				}
+
+				if ((dev->errata & I2C_OMAP3_1P153) &&
+				    errata_omap3_1p153(dev, &stat, &err))
+					goto complete;
+
+				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+			}
+
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
 			continue;
 		}
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 06/22] i2c: omap: improve 1p153 errata handling
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (4 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 05/22] i2c: omap: split out [XR]DR and [XR]RDY Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 07/22] i2c: omap: re-factor receive/transmit data loop Felipe Balbi
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

Make it not depend on ISR's local variables
in order to make it easier to re-factor the
transmit data loop.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   47 +++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9e6be9f..d53ec25 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -768,21 +768,24 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
  * 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_1p153(struct omap_i2c_dev *dev)
 {
-	unsigned long timeout = 10000;
+	unsigned long	timeout = 10000;
+	u16		stat;
 
-	while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
-		if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
+	do {
+		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+		if (stat & OMAP_I2C_STAT_XUDF)
+			break;
+
+		if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
 			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
 					OMAP_I2C_STAT_XDR));
-			*err |= OMAP_I2C_STAT_XUDF;
 			return -ETIMEDOUT;
 		}
 
 		cpu_relax();
-		*stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
-	}
+	} while (--timeout);
 
 	if (!timeout) {
 		dev_err(dev->dev, "timeout waiting on XUDF bit\n");
@@ -956,9 +959,18 @@ complete:
 					}
 				}
 
-				if ((dev->errata & I2C_OMAP3_1P153) &&
-				    errata_omap3_1p153(dev, &stat, &err))
-					goto complete;
+				if (dev->errata & I2C_OMAP3_1P153) {
+					int ret;
+
+					ret = errata_omap3_1p153(dev);
+					stat = omap_i2c_read_reg(dev,
+							OMAP_I2C_STAT_REG);
+
+					if (ret < 0) {
+						err |= OMAP_I2C_STAT_XUDF;
+						goto complete;
+					}
+				}
 
 				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
 			}
@@ -996,9 +1008,18 @@ complete:
 					}
 				}
 
-				if ((dev->errata & I2C_OMAP3_1P153) &&
-				    errata_omap3_1p153(dev, &stat, &err))
-					goto complete;
+				if (dev->errata & I2C_OMAP3_1P153) {
+					int ret;
+
+					ret = errata_omap3_1p153(dev);
+					stat = omap_i2c_read_reg(dev,
+							OMAP_I2C_STAT_REG);
+
+					if (ret < 0) {
+						err |= OMAP_I2C_STAT_XUDF;
+						goto complete;
+					}
+				}
 
 				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
 			}
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 07/22] i2c: omap: re-factor receive/transmit data loop
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (5 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 06/22] i2c: omap: improve 1p153 errata handling Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 08/22] i2c: omap: switch over to do {} while loop Felipe Balbi
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

re-factor the common parts to a separate function,
so that code is easier to read and understand.

No functional changes.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |  209 +++++++++++++++++------------------------
 1 file changed, 84 insertions(+), 125 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d53ec25..3d714a0c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -795,12 +795,81 @@ static int errata_omap3_1p153(struct omap_i2c_dev *dev)
 	return 0;
 }
 
+static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
+		bool is_rdr)
+{
+	u16		w;
+
+	while (num_bytes--) {
+		if (!dev->buf_len) {
+			dev_err(dev->dev, "%s without data",
+					is_rdr ? "RDR" : "RRDY");
+			break;
+		}
+
+		w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+		*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--;
+			}
+		}
+	}
+}
+
+static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
+		bool is_xdr)
+{
+	u16		w;
+
+	while (num_bytes--) {
+		if (!dev->buf_len) {
+			dev_err(dev->dev, "%s without data",
+					is_xdr ? "XDR" : "XRDY");
+			break;
+		}
+
+		w = *dev->buf++;
+		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) {
+				w |= *dev->buf++ << 8;
+				dev->buf_len--;
+			}
+		}
+
+		if (dev->errata & I2C_OMAP3_1P153) {
+			int ret;
+
+			ret = errata_omap3_1p153(dev);
+			if (ret < 0)
+				return ret;
+		}
+
+		omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+	}
+
+	return 0;
+}
+
 static irqreturn_t
 omap_i2c_isr(int this_irq, void *dev_id)
 {
 	struct omap_i2c_dev *dev = dev_id;
 	u16 bits;
-	u16 stat, w;
+	u16 stat;
 	int err, count = 0;
 
 	if (pm_runtime_suspended(dev->dev))
@@ -860,31 +929,7 @@ complete:
 				num_bytes &= 0x3f;
 			}
 
-			while (num_bytes--) {
-				if (!dev->buf_len) {
-					dev_err(dev->dev,
-							"RDR IRQ while no data"
-							" requested\n");
-					break;
-				}
-
-				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-				*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--;
-					}
-				}
-			}
-
+			omap_i2c_receive_data(dev, num_bytes, true);
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
 			continue;
 		}
@@ -898,36 +943,13 @@ complete:
 			if (dev->fifo_size)
 				num_bytes = dev->fifo_size;
 
-			while (num_bytes--) {
-				if (!dev->buf_len) {
-					dev_err(dev->dev,
-							"RRDY IRQ while no data"
-							" requested\n");
-					break;
-				}
-
-				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-				*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--;
-					}
-				}
-			}
-
+			omap_i2c_receive_data(dev, num_bytes, false);
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
 			continue;
 		}
 
 		if (stat & OMAP_I2C_STAT_XDR) {
+			int ret;
 			u8 num_bytes = 1;
 
 			if (dev->fifo_size) {
@@ -936,43 +958,11 @@ complete:
 				num_bytes &= 0x3f;
 			}
 
-			while (num_bytes--) {
-				if (!dev->buf_len) {
-					dev_err(dev->dev,
-							"XDR IRQ while no "
-							"data to send\n");
-					break;
-				}
-
-				w = *dev->buf++;
-				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) {
-						w |= *dev->buf++ << 8;
-						dev->buf_len--;
-					}
-				}
-
-				if (dev->errata & I2C_OMAP3_1P153) {
-					int ret;
-
-					ret = errata_omap3_1p153(dev);
-					stat = omap_i2c_read_reg(dev,
-							OMAP_I2C_STAT_REG);
-
-					if (ret < 0) {
-						err |= OMAP_I2C_STAT_XUDF;
-						goto complete;
-					}
-				}
-
-				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+			ret = omap_i2c_transmit_data(dev, num_bytes, true);
+			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+			if (ret < 0) {
+				err |= OMAP_I2C_STAT_XUDF;
+				goto complete;
 			}
 
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
@@ -980,48 +970,17 @@ complete:
 		}
 
 		if (stat & OMAP_I2C_STAT_XRDY) {
+			int ret;
 			u8 num_bytes = 1;
 
 			if (dev->fifo_size)
 				num_bytes = dev->fifo_size;
 
-			while (num_bytes--) {
-				if (!dev->buf_len) {
-					dev_err(dev->dev,
-							"XRDY IRQ while no "
-							"data to send\n");
-					break;
-				}
-
-				w = *dev->buf++;
-				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) {
-						w |= *dev->buf++ << 8;
-						dev->buf_len--;
-					}
-				}
-
-				if (dev->errata & I2C_OMAP3_1P153) {
-					int ret;
-
-					ret = errata_omap3_1p153(dev);
-					stat = omap_i2c_read_reg(dev,
-							OMAP_I2C_STAT_REG);
-
-					if (ret < 0) {
-						err |= OMAP_I2C_STAT_XUDF;
-						goto complete;
-					}
-				}
-
-				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+			ret = omap_i2c_transmit_data(dev, num_bytes, false);
+			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+			if (ret < 0) {
+				err |= OMAP_I2C_STAT_XUDF;
+				goto complete;
 			}
 
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 08/22] i2c: omap: switch over to do {} while loop
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (6 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 07/22] i2c: omap: re-factor receive/transmit data loop Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 09/22] i2c: omap: ack IRQ in parts Felipe Balbi
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

this will make sure that we execute at least once.
No functional changes otherwise.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 3d714a0c..cf13a3e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -870,20 +870,29 @@ omap_i2c_isr(int this_irq, void *dev_id)
 	struct omap_i2c_dev *dev = dev_id;
 	u16 bits;
 	u16 stat;
-	int err, count = 0;
+	int err = 0, count = 0;
 
 	if (pm_runtime_suspended(dev->dev))
 		return IRQ_NONE;
 
-	bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
-	while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
+	do {
+		bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+		stat &= bits;
+
+		if (!stat) {
+			/* my work here is done */
+			omap_i2c_complete_cmd(dev, err);
+			return IRQ_HANDLED;
+		}
+
 		dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
 		if (count++ == 100) {
 			dev_warn(dev->dev, "Too much work in one IRQ\n");
-			break;
+			omap_i2c_complete_cmd(dev, err);
+			return IRQ_HANDLED;
 		}
 
-		err = 0;
 complete:
 		/*
 		 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
@@ -996,7 +1005,7 @@ complete:
 			dev_err(dev->dev, "Transmit underflow\n");
 			dev->cmd_err |= OMAP_I2C_STAT_XUDF;
 		}
-	}
+	} while (stat);
 
 	return count ? IRQ_HANDLED : IRQ_NONE;
 }
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 09/22] i2c: omap: ack IRQ in parts
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (7 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 08/22] i2c: omap: switch over to do {} while loop Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:50 ` [rft/rfc/patch 10/22] i2c: omap: switch I2C REV2 to threaded IRQ Felipe Balbi
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

According to flow diagrams on OMAP TRMs,
we should ACK the IRQ as they happen.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index cf13a3e..a9c1fa6 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -894,21 +894,20 @@ omap_i2c_isr(int this_irq, void *dev_id)
 		}
 
 complete:
-		/*
-		 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
-		 * acked after the data operation is complete.
-		 * Ref: TRM SWPU114Q Figure 18-31
-		 */
-		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
-				~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
-		if (stat & OMAP_I2C_STAT_NACK)
+		if (stat & OMAP_I2C_STAT_NACK) {
+			dev_err(dev->dev, "No Acknowledge\n");
 			err |= OMAP_I2C_STAT_NACK;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+			omap_i2c_complete_cmd(dev, err);
+			return IRQ_HANDLED;
+		}
 
 		if (stat & OMAP_I2C_STAT_AL) {
 			dev_err(dev->dev, "Arbitration lost\n");
 			err |= OMAP_I2C_STAT_AL;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+			omap_i2c_complete_cmd(dev, err);
+			return IRQ_HANDLED;
 		}
 
 		/*
@@ -999,11 +998,17 @@ complete:
 		if (stat & OMAP_I2C_STAT_ROVR) {
 			dev_err(dev->dev, "Receive overrun\n");
 			dev->cmd_err |= OMAP_I2C_STAT_ROVR;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
+			omap_i2c_complete_cmd(dev, err);
+			return IRQ_HANDLED;
 		}
 
 		if (stat & OMAP_I2C_STAT_XUDF) {
 			dev_err(dev->dev, "Transmit underflow\n");
 			dev->cmd_err |= OMAP_I2C_STAT_XUDF;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
+			omap_i2c_complete_cmd(dev, err);
+			return IRQ_HANDLED;
 		}
 	} while (stat);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 10/22] i2c: omap: switch I2C REV2 to threaded IRQ
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (8 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 09/22] i2c: omap: ack IRQ in parts Felipe Balbi
@ 2012-06-13 15:50 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 11/22] i2c: omap: get rid of "count" variable Felipe Balbi
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:50 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

that way all our IRQ handling will happen in
thread.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a9c1fa6..6e0b406 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -865,7 +865,23 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
 }
 
 static irqreturn_t
-omap_i2c_isr(int this_irq, void *dev_id)
+omap_i2c_isr(int irq, void *_dev)
+{
+	struct omap_i2c_dev	*dev = _dev;
+	u16			stat;
+	u16			bits;
+
+	stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+	bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+
+	if (stat & bits)
+		return IRQ_WAKE_THREAD;
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+omap_i2c_threaded_isr(int this_irq, void *dev_id)
 {
 	struct omap_i2c_dev *dev = dev_id;
 	u16 bits;
@@ -1055,7 +1071,6 @@ omap_i2c_probe(struct platform_device *pdev)
 	struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
 	struct device_node	*node = pdev->dev.of_node;
 	const struct of_device_id *match;
-	irq_handler_t isr;
 	int r;
 
 	/* NOTE: driver uses the static register mapping */
@@ -1155,9 +1170,12 @@ omap_i2c_probe(struct platform_device *pdev)
 	/* reset ASAP, clearing any IRQs */
 	omap_i2c_init(dev);
 
-	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
-								   omap_i2c_isr;
-	r = request_irq(dev->irq, isr, 0, pdev->name, dev);
+	if (dev->rev < OMAP_I2C_OMAP1_REV_2)
+		r = request_irq(dev->irq, omap_i2c_omap1_isr, 0,
+				pdev->name, dev);
+	else
+		r = request_threaded_irq(dev->irq, omap_i2c_isr,
+				omap_i2c_threaded_isr, 0, pdev->name, dev);
 
 	if (r) {
 		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 11/22] i2c: omap: get rid of "count" variable
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (9 preceding siblings ...)
  2012-06-13 15:50 ` [rft/rfc/patch 10/22] i2c: omap: switch I2C REV2 to threaded IRQ Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 12/22] i2c: omap: get rid of the "complete" label Felipe Balbi
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

now that we're running on a thread, there's
no problem in doing lots of work as IRQs won't
be disabled anymore.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6e0b406..dba174c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -886,7 +886,7 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 	struct omap_i2c_dev *dev = dev_id;
 	u16 bits;
 	u16 stat;
-	int err = 0, count = 0;
+	int err = 0;
 
 	if (pm_runtime_suspended(dev->dev))
 		return IRQ_NONE;
@@ -903,12 +903,6 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 		}
 
 		dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
-		if (count++ == 100) {
-			dev_warn(dev->dev, "Too much work in one IRQ\n");
-			omap_i2c_complete_cmd(dev, err);
-			return IRQ_HANDLED;
-		}
-
 complete:
 		if (stat & OMAP_I2C_STAT_NACK) {
 			dev_err(dev->dev, "No Acknowledge\n");
@@ -1028,7 +1022,7 @@ complete:
 		}
 	} while (stat);
 
-	return count ? IRQ_HANDLED : IRQ_NONE;
+	return IRQ_HANDLED;
 }
 
 static const struct i2c_algorithm omap_i2c_algo = {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 12/22] i2c: omap: get rid of the "complete" label
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (10 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 11/22] i2c: omap: get rid of "count" variable Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 13/22] i2c: omap: if controller is suspended, bail out Felipe Balbi
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

we can ack stat and complete the command from
the errata handling itself.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index dba174c..9dadfb1 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -903,7 +903,7 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 		}
 
 		dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
-complete:
+
 		if (stat & OMAP_I2C_STAT_NACK) {
 			dev_err(dev->dev, "No Acknowledge\n");
 			err |= OMAP_I2C_STAT_NACK;
@@ -980,7 +980,9 @@ complete:
 			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
 			if (ret < 0) {
 				err |= OMAP_I2C_STAT_XUDF;
-				goto complete;
+				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF |
+						OMAP_I2C_STAT_XDR);
+				omap_i2c_complete_cmd(dev, err);
 			}
 
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
@@ -998,7 +1000,9 @@ complete:
 			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
 			if (ret < 0) {
 				err |= OMAP_I2C_STAT_XUDF;
-				goto complete;
+				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF |
+						OMAP_I2C_STAT_XRDY);
+				omap_i2c_complete_cmd(dev, err);
 			}
 
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 13/22] i2c: omap: if controller is suspended, bail out
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (11 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 12/22] i2c: omap: get rid of the "complete" label Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 14/22] i2c: omap: ack ARDY IRQ Felipe Balbi
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

same check we had on the threaded IRQ handler,
copy it to the bottom half.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9dadfb1..e555681 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -871,6 +871,9 @@ omap_i2c_isr(int irq, void *_dev)
 	u16			stat;
 	u16			bits;
 
+	if (pm_runtime_suspended(dev->dev))
+		return IRQ_NONE;
+
 	stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
 	bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 14/22] i2c: omap: ack ARDY IRQ
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (12 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 13/22] i2c: omap: if controller is suspended, bail out Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 15/22] i2c: omap: switch to devm_* API Felipe Balbi
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

comment asks us to clear it twice, so let's
do so.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e555681..f30eb45 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -923,6 +923,9 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 			return IRQ_HANDLED;
 		}
 
+		if (stat & OMAP_I2C_STAT_ARDY)
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY);
+
 		/*
 		 * ProDB0017052: Clear ARDY bit twice
 		 */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 15/22] i2c: omap: switch to devm_* API
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (13 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 14/22] i2c: omap: ack ARDY IRQ Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 16/22] i2c: omap: switch to platform_get_irq() Felipe Balbi
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

that helps deleting some boiler plate code
and lets driver-core manage our resources
for us.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   50 +++++++++++++----------------------------
 1 file changed, 15 insertions(+), 35 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f30eb45..5e9e165 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1071,7 +1071,7 @@ omap_i2c_probe(struct platform_device *pdev)
 {
 	struct omap_i2c_dev	*dev;
 	struct i2c_adapter	*adap;
-	struct resource		*mem, *irq, *ioarea;
+	struct resource		*mem, *irq;
 	struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
 	struct device_node	*node = pdev->dev.of_node;
 	const struct of_device_id *match;
@@ -1083,23 +1083,17 @@ omap_i2c_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "no mem resource?\n");
 		return -ENODEV;
 	}
+
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!irq) {
 		dev_err(&pdev->dev, "no irq resource?\n");
 		return -ENODEV;
 	}
 
-	ioarea = request_mem_region(mem->start, resource_size(mem),
-			pdev->name);
-	if (!ioarea) {
-		dev_err(&pdev->dev, "I2C region already claimed\n");
-		return -EBUSY;
-	}
-
-	dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
+	dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
 	if (!dev) {
-		r = -ENOMEM;
-		goto err_release_region;
+		dev_err(&pdev->dev, "not enough memory\n");
+		return -ENOMEM;
 	}
 
 	match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -1122,10 +1116,10 @@ omap_i2c_probe(struct platform_device *pdev)
 
 	dev->dev = &pdev->dev;
 	dev->irq = irq->start;
-	dev->base = ioremap(mem->start, resource_size(mem));
+	dev->base = devm_request_and_ioremap(&pdev->dev, mem);
 	if (!dev->base) {
-		r = -ENOMEM;
-		goto err_free_mem;
+		dev_err(&pdev->dev, "ioremap failed\n");
+		return -ENOMEM;
 	}
 
 	platform_set_drvdata(pdev, dev);
@@ -1175,11 +1169,12 @@ omap_i2c_probe(struct platform_device *pdev)
 	omap_i2c_init(dev);
 
 	if (dev->rev < OMAP_I2C_OMAP1_REV_2)
-		r = request_irq(dev->irq, omap_i2c_omap1_isr, 0,
-				pdev->name, dev);
+		r = devm_request_irq(&pdev->dev, dev->irq, omap_i2c_omap1_isr,
+				0, pdev->name, dev);
 	else
-		r = request_threaded_irq(dev->irq, omap_i2c_isr,
-				omap_i2c_threaded_isr, 0, pdev->name, dev);
+		r = devm_request_threaded_irq(&pdev->dev, dev->irq,
+				omap_i2c_isr, omap_i2c_threaded_isr, 0,
+				pdev->name, dev);
 
 	if (r) {
 		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
@@ -1205,24 +1200,16 @@ omap_i2c_probe(struct platform_device *pdev)
 	r = i2c_add_numbered_adapter(adap);
 	if (r) {
 		dev_err(dev->dev, "failure adding adapter\n");
-		goto err_free_irq;
+		goto err_unuse_clocks;
 	}
 
 	of_i2c_register_devices(adap);
 
 	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);
-	iounmap(dev->base);
-err_free_mem:
-	platform_set_drvdata(pdev, NULL);
-	kfree(dev);
-err_release_region:
-	release_mem_region(mem->start, resource_size(mem));
 
 	return r;
 }
@@ -1231,17 +1218,10 @@ static int
 omap_i2c_remove(struct platform_device *pdev)
 {
 	struct omap_i2c_dev	*dev = platform_get_drvdata(pdev);
-	struct resource		*mem;
-
-	platform_set_drvdata(pdev, NULL);
 
-	free_irq(dev->irq, dev);
 	i2c_del_adapter(&dev->adapter);
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
-	iounmap(dev->base);
-	kfree(dev);
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(mem->start, resource_size(mem));
+
 	return 0;
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 16/22] i2c: omap: switch to platform_get_irq()
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (14 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 15/22] i2c: omap: switch to devm_* API Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 17/22] i2c: omap: drop Access Ready IRQ Felipe Balbi
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

that's a nice helper from drivers core which
will give us the exact IRQ number, instead
of a pointer to an IRQ resource.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5e9e165..b9c9407 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1071,10 +1071,11 @@ omap_i2c_probe(struct platform_device *pdev)
 {
 	struct omap_i2c_dev	*dev;
 	struct i2c_adapter	*adap;
-	struct resource		*mem, *irq;
+	struct resource		*mem;
 	struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
 	struct device_node	*node = pdev->dev.of_node;
 	const struct of_device_id *match;
+	int irq;
 	int r;
 
 	/* NOTE: driver uses the static register mapping */
@@ -1084,10 +1085,10 @@ omap_i2c_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!irq) {
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
-		return -ENODEV;
+		return irq;
 	}
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
@@ -1115,7 +1116,7 @@ omap_i2c_probe(struct platform_device *pdev)
 	}
 
 	dev->dev = &pdev->dev;
-	dev->irq = irq->start;
+	dev->irq = irq;
 	dev->base = devm_request_and_ioremap(&pdev->dev, mem);
 	if (!dev->base) {
 		dev_err(&pdev->dev, "ioremap failed\n");
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 17/22] i2c: omap: drop Access Ready IRQ
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (15 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 16/22] i2c: omap: switch to platform_get_irq() Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 18/22] i2c: omap: drop errata i207 from RRDY interrupt Felipe Balbi
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

documentation is very unclear about how that
works and testing shows that driver works without
it.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b9c9407..20f854d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -474,9 +474,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 		dev->errata |= I2C_OMAP_ERRATA_I207;
 
 	/* 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) ?
+	dev->iestate = OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY |
+		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) {
@@ -923,23 +922,6 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 			return IRQ_HANDLED;
 		}
 
-		if (stat & OMAP_I2C_STAT_ARDY)
-			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ARDY);
-
-		/*
-		 * ProDB0017052: Clear ARDY bit twice
-		 */
-		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
-					OMAP_I2C_STAT_AL)) {
-			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
-						OMAP_I2C_STAT_RDR |
-						OMAP_I2C_STAT_XRDY |
-						OMAP_I2C_STAT_XDR |
-						OMAP_I2C_STAT_ARDY));
-			omap_i2c_complete_cmd(dev, err);
-			return IRQ_HANDLED;
-		}
-
 		if (stat & OMAP_I2C_STAT_RDR) {
 			u8 num_bytes = 1;
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 18/22] i2c: omap: drop errata i207 from RRDY interrupt
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (16 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 17/22] i2c: omap: drop Access Ready IRQ Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 19/22] i2c: omap: bus: add a receiver flag Felipe Balbi
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

that errata refers only to RDR interrupt. It's safe
to drop it.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 20f854d..9274fcb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -943,9 +943,6 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 		if (stat & OMAP_I2C_STAT_RRDY) {
 			u8 num_bytes = 1;
 
-			if (dev->errata & I2C_OMAP_ERRATA_I207)
-				i2c_omap_errata_i207(dev, stat);
-
 			if (dev->fifo_size)
 				num_bytes = dev->fifo_size;
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 19/22] i2c: omap: bus: add a receiver flag
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (17 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 18/22] i2c: omap: drop errata i207 from RRDY interrupt Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 20/22] i2c: omap: avoid unnecessary register read Felipe Balbi
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

that way we can ignore TX IRQs while in receiver
mode and ignore RX IRQs while in transmitter mode.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9274fcb..5a7a223 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -199,6 +199,7 @@ struct omap_i2c_dev {
 						 */
 	u8			rev;
 	unsigned		b_hw:1;		/* bad h/w fixes */
+	unsigned		receiver:1;	/* true when we're in receiver mode */
 	u16			iestate;	/* Saved interrupt register */
 	u16			pscstate;
 	u16			scllstate;
@@ -537,6 +538,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
 	init_completion(&dev->cmd_complete);
 	dev->cmd_err = 0;
+	dev->receiver = !!(msg->flags & I2C_M_RD);
 
 	w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
 
@@ -898,6 +900,13 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
 		stat &= bits;
 
+		/* If we're in receiver mode, ignore XDR/XRDY */
+		if (dev->receiver) {
+			stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY);
+		} else {
+			stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY);
+		}
+
 		if (!stat) {
 			/* my work here is done */
 			omap_i2c_complete_cmd(dev, err);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 20/22] i2c: omap: avoid unnecessary register read
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (18 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 19/22] i2c: omap: bus: add a receiver flag Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 21/22] i2c: omap: no need to reinitialize "stat" Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 22/22] i2c: omap: simplify errata check Felipe Balbi
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

dev->buf_len will always contain the correct
number we're looking for. No need to read
from BUFSTAT register.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |   22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5a7a223..f2ab95a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -934,18 +934,15 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 		if (stat & OMAP_I2C_STAT_RDR) {
 			u8 num_bytes = 1;
 
-			if (dev->errata & I2C_OMAP_ERRATA_I207)
-				i2c_omap_errata_i207(dev, stat);
-
-			if (dev->fifo_size) {
-				num_bytes = omap_i2c_read_reg(dev,
-						OMAP_I2C_BUFSTAT_REG);
-				num_bytes >>= 8;
-				num_bytes &= 0x3f;
-			}
+			if (dev->fifo_size)
+				num_bytes = dev->buf_len;
 
 			omap_i2c_receive_data(dev, num_bytes, true);
 			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+
+			if (dev->errata & I2C_OMAP_ERRATA_I207)
+				i2c_omap_errata_i207(dev, stat);
+
 			continue;
 		}
 
@@ -964,11 +961,8 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 			int ret;
 			u8 num_bytes = 1;
 
-			if (dev->fifo_size) {
-				num_bytes = omap_i2c_read_reg(dev,
-						OMAP_I2C_BUFSTAT_REG);
-				num_bytes &= 0x3f;
-			}
+			if (dev->fifo_size)
+				num_bytes = dev->buf_len;
 
 			ret = omap_i2c_transmit_data(dev, num_bytes, true);
 			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 21/22] i2c: omap: no need to reinitialize "stat"
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (19 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 20/22] i2c: omap: avoid unnecessary register read Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  2012-06-13 15:51 ` [rft/rfc/patch 22/22] i2c: omap: simplify errata check Felipe Balbi
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

we will already loop again and that variable
will be reinitialized at the beginning of the
loop.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f2ab95a..492e340 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -965,7 +965,6 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 				num_bytes = dev->buf_len;
 
 			ret = omap_i2c_transmit_data(dev, num_bytes, true);
-			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
 			if (ret < 0) {
 				err |= OMAP_I2C_STAT_XUDF;
 				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF |
@@ -985,7 +984,6 @@ omap_i2c_threaded_isr(int this_irq, void *dev_id)
 				num_bytes = dev->fifo_size;
 
 			ret = omap_i2c_transmit_data(dev, num_bytes, false);
-			stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
 			if (ret < 0) {
 				err |= OMAP_I2C_STAT_XUDF;
 				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF |
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [rft/rfc/patch 22/22] i2c: omap: simplify errata check
  2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
                   ` (20 preceding siblings ...)
  2012-06-13 15:51 ` [rft/rfc/patch 21/22] i2c: omap: no need to reinitialize "stat" Felipe Balbi
@ 2012-06-13 15:51 ` Felipe Balbi
  21 siblings, 0 replies; 23+ messages in thread
From: Felipe Balbi @ 2012-06-13 15:51 UTC (permalink / raw)
  To: Shubhrajyoti Datta; +Cc: Tony Lindgren, Linux OMAP Mailing List, Felipe Balbi

omap_i2c_dev is allocated with kzalloc(),
so we need not initialize b_hw to zero.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 492e340..45c2bf7 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1135,9 +1135,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
 		dev->fifo_size = (dev->fifo_size / 2);
 
-		if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
-			dev->b_hw = 0; /* Disable hardware fixes */
-		else
+		if (dev->rev < OMAP_I2C_REV_ON_3530_4430)
 			dev->b_hw = 1; /* Enable hardware fixes */
 
 		/* calculate wakeup latency constraint for MPU */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2012-06-13 15:54 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-13 15:50 [rft/rfc/patch 00/22] Big I2C cleanup Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 01/22] i2c: omap: simplify num_bytes handling Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 02/22] i2c: omap: decrease indentation level on data handling Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 03/22] i2c: omap: add blank lines Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 04/22] i2c: omap: simplify omap_i2c_ack_stat() Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 05/22] i2c: omap: split out [XR]DR and [XR]RDY Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 06/22] i2c: omap: improve 1p153 errata handling Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 07/22] i2c: omap: re-factor receive/transmit data loop Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 08/22] i2c: omap: switch over to do {} while loop Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 09/22] i2c: omap: ack IRQ in parts Felipe Balbi
2012-06-13 15:50 ` [rft/rfc/patch 10/22] i2c: omap: switch I2C REV2 to threaded IRQ Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 11/22] i2c: omap: get rid of "count" variable Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 12/22] i2c: omap: get rid of the "complete" label Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 13/22] i2c: omap: if controller is suspended, bail out Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 14/22] i2c: omap: ack ARDY IRQ Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 15/22] i2c: omap: switch to devm_* API Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 16/22] i2c: omap: switch to platform_get_irq() Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 17/22] i2c: omap: drop Access Ready IRQ Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 18/22] i2c: omap: drop errata i207 from RRDY interrupt Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 19/22] i2c: omap: bus: add a receiver flag Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 20/22] i2c: omap: avoid unnecessary register read Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 21/22] i2c: omap: no need to reinitialize "stat" Felipe Balbi
2012-06-13 15:51 ` [rft/rfc/patch 22/22] i2c: omap: simplify errata check Felipe Balbi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.