diff mbox

[PATCHv3,06/17] i2c: omap: split out [XR]DR and [XR]RDY

Message ID 1340964817-8599-7-git-send-email-shubhrajyoti@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shubhrajyoti Datta June 29, 2012, 10:13 a.m. UTC
From: Felipe Balbi <balbi@ti.com>

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.

While at that, also avoid an unncessary register
read since dev->fifo_len will always contain the
correct amount of data to be transferred.

Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
---
 drivers/i2c/busses/i2c-omap.c |  126 ++++++++++++++++++++++++++++++----------
 1 files changed, 94 insertions(+), 32 deletions(-)

Comments

Felipe Balbi July 2, 2012, 11:56 a.m. UTC | #1
Hi,

On Fri, Jun 29, 2012 at 03:43:26PM +0530, Shubhrajyoti D wrote:
> From: Felipe Balbi <balbi@ti.com>
> 
> 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.
> 
> While at that, also avoid an unncessary register
> read since dev->fifo_len will always contain the
> correct amount of data to be transferred.

this statement isn't valid anymore, but I'd like it to be. See below

> Signed-off-by: Felipe Balbi <balbi@ti.com>
> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
> ---
>  drivers/i2c/busses/i2c-omap.c |  126 ++++++++++++++++++++++++++++++----------
>  1 files changed, 94 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
> index 359ee08..45bd731 100644
> --- a/drivers/i2c/busses/i2c-omap.c
> +++ b/drivers/i2c/busses/i2c-omap.c
> @@ -820,36 +820,64 @@ 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->fifo_size)
> +				num_bytes = (omap_i2c_read_reg(dev,
> +						OMAP_I2C_BUFSTAT_REG) >> 8)
> +						& 0x3F;

I wanted to avoid reading registers if we don't have to. This value will
be sitting in dev->buf_len.
Shubhrajyoti Datta July 2, 2012, noon UTC | #2
On Mon, Jul 2, 2012 at 5:26 PM, Felipe Balbi <balbi@ti.com> wrote:
> Hi,
>
> On Fri, Jun 29, 2012 at 03:43:26PM +0530, Shubhrajyoti D wrote:
>> From: Felipe Balbi <balbi@ti.com>
>>
>> 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.
>>
>> While at that, also avoid an unncessary register
>> read since dev->fifo_len will always contain the
>> correct amount of data to be transferred.
>
> this statement isn't valid anymore, but I'd like it to be. See below
>
>> Signed-off-by: Felipe Balbi <balbi@ti.com>
>> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
>> ---
>>  drivers/i2c/busses/i2c-omap.c |  126 ++++++++++++++++++++++++++++++----------
>>  1 files changed, 94 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
>> index 359ee08..45bd731 100644
>> --- a/drivers/i2c/busses/i2c-omap.c
>> +++ b/drivers/i2c/busses/i2c-omap.c
>> @@ -820,36 +820,64 @@ 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->fifo_size)
>> +                             num_bytes = (omap_i2c_read_reg(dev,
>> +                                             OMAP_I2C_BUFSTAT_REG) >> 8)
>> +                                             & 0x3F;
>
> I wanted to avoid reading registers if we don't have to. This value will
> be sitting in dev->buf_len.

Yes will fix this and resend.

>
> --
> balbi
--
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
diff mbox

Patch

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 359ee08..45bd731 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -820,36 +820,64 @@  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->fifo_size)
+				num_bytes = (omap_i2c_read_reg(dev,
+						OMAP_I2C_BUFSTAT_REG) >> 8)
+						& 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--;
+					}
+				}
+			}
+
 			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;
-			}
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+			continue;
+		}
+
+		if (stat & OMAP_I2C_STAT_RRDY) {
+			u8 num_bytes = 1;
+
+			if (dev->fifo_size)
+				num_bytes = dev->fifo_size;
+
 			while (num_bytes--) {
 				if (!dev->buf_len) {
-					if (stat & OMAP_I2C_STAT_RRDY)
-						dev_err(dev->dev,
+					dev_err(dev->dev,
 							"RRDY IRQ while no data"
-								" requested\n");
-					if (stat & OMAP_I2C_STAT_RDR)
-						dev_err(dev->dev,
-							"RDR IRQ while no data"
-								" requested\n");
+							" 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
@@ -862,36 +890,70 @@  complete:
 					}
 				}
 			}
-			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
-						OMAP_I2C_STAT_RDR));
+
+			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,
+
+			if (dev->fifo_size)
+				num_bytes = omap_i2c_read_reg(dev,
 							OMAP_I2C_BUFSTAT_REG)
 							& 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_OMAP_ERRATA_I462) &&
+				    errata_omap3_i462(dev, &stat, &err))
+					goto complete;
+
+				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
 			}
+
+			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) {
-					if (stat & OMAP_I2C_STAT_XRDY)
-						dev_err(dev->dev,
+					dev_err(dev->dev,
 							"XRDY IRQ while no "
 							"data to send\n");
-					if (stat & OMAP_I2C_STAT_XDR)
-						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
@@ -910,8 +972,8 @@  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_XRDY);
 			continue;
 		}