From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:41:55
Changes since v1:
- removed tabification on patch 6/17
- removed dev_err() which was introduced on patch 09/17
Changes since v2:
- do not set full fifo depth in the RDR interrupt.
- some changelog updates.
- rebase to the Wolfram's tree.
Changes since v3:
- Remove a redundant read of status register
- Read the dev->buf_len variable instead of the register
as the information of the remaining bytes is there.
Changes since v4:
- Ack the arbitration lost.
- Rebase to the i2c-embedded/for-next branch.
Changes since v5:
- Rebase to latest mainline
- Added some more cleanup patches so as have a consolidated series.
Changes since v6:
- Fix comments on setting the pdev to NULL.
- Trivial changelog update
Previous discussions can be found here
http://www.spinics.net/lists/linux-i2c/msg09482.html
This is the cleanup only series.
Tested on omap4sdp and 3430sdp.
The following changes since commit 55d512e245bc7699a8800e23df1a24195dd08217:
Linux 3.6-rc5 (2012-09-08 16:43:45 -0700)
are available in the git repository at:
git://gitorious.org/linus-tree/linus-tree.git for_3.7/i2c/big_cleanup
Felipe Balbi (22):
i2c: omap: switch to devm_* API
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 i462 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 to platform_get_irq()
i2c: omap: bus: add a receiver flag
i2c: omap: simplify errata check
i2c: omap: always return IRQ_HANDLED
i2c: omap: simplify IRQ exit path
i2c: omap: resize fifos before each message
i2c: omap: get rid of the "complete" label
i2c: omap: always return IRQ_HANDLED
i2c: omap: switch to threaded IRQ support
i2c: omap: remove unnecessary pm_runtime_suspended check
i2c: omap: switch over to autosuspend API
i2c: omap: sanitize exit path
Shubhrajyoti D (1):
i2c: omap: remove redundant status read
drivers/i2c/busses/i2c-omap.c | 442 +++++++++++++++++++++++++----------------
1 files changed, 271 insertions(+), 171 deletions(-)
--
1.7.5.4
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:41:57
From: Felipe Balbi <redacted>
trivial patch, no functional changes
If the fifo is disabled or fifo_size is 0 the num_bytes
is set to 1. Else it is set to fifo_size or in case of a
draining interrupt the remaining bytes in the buff stat.
So the zero check is redundant and can be safely optimised.
Signed-off-by: Felipe Balbi <redacted>
Reviewed-by : Santosh Shilimkar [off-list ref]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:41:58
From: Felipe Balbi <redacted>
The patch intends to decrease the indentation level on the
data handling
by using the fact that else of if (dev->buf_len) is same as
if (!dev->buf_len)
if (dev->buf_len) {
aaa;
} else {
bbb;
break;
}
to
if (!dev->buf_len) {
bbb;
break;
}
aaa;
Hence no functional changes.
Signed-off-by: Felipe Balbi <redacted>
Reviewed-by : Santosh Shilimkar [off-list ref]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 63 ++++++++++++++++++++---------------------
1 files changed, 31 insertions(+), 32 deletions(-)
@@ -813,22 +813,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--;-/*-*Dataregin2430,omap3and-*omap4is8bitwide-*/-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"
@@ -855,22 +855,7 @@ complete:&0x3F;}while(num_bytes--){-w=0;-if(dev->buf_len){-w=*dev->buf++;-dev->buf_len--;-/*-*Dataregin2430,omap3and-*omap4is8bitwide-*/-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 "
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:00
From: Felipe Balbi <redacted>
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.
Code snippet (extremely simplified):
if (stat & NACK) {
...
omap_i2c_ack_stat(dev, stat & NACK);
}
if (stat & RDR) {
...
omap_i2c_ack_stat(dev, stat & RDR);
}
and so on. The tricky place is only WRT errata handling, for example:
if (*stat & (NACK | AL)) {
omap_i2c_ack_stat(dev, *stat & (XRDY | XDR));
...
}
but in this case, the errata says we must clear XRDY and XDR if that
errata triggers, so if they just got enabled or not, it doesn't matter.
Another tricky place is RDR | RRDY (likewise for XDR | XRDY):
if (stat & (RDR | RRDY)) {
...
omap_i2c_ack_stat(dev, stat & (RDR | RRDY));
}
again here there will be no issues because those IRQs never fire
simultaneously and one will only after after we have handled the
previous, that's because the same FIFO is used anyway and we won't shift
data into FIFO until we tell the IP "hey, I'm done with the FIFO, you
can shift more data"
Signed-off-by: Felipe Balbi <redacted>
Reviewed-by : Santosh Shilimkar [off-list ref]
[Added the explaination from the discurssion to the commit logs]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:01
From: Felipe Balbi <redacted>
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 <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 126 ++++++++++++++++++++++++++++++-----------
1 files changed, 92 insertions(+), 34 deletions(-)
@@ -801,36 +801,62 @@ complete:returnIRQ_HANDLED;}-if(stat&(OMAP_I2C_STAT_RRDY|OMAP_I2C_STAT_RDR)){+if(stat&OMAP_I2C_STAT_RDR){u8num_bytes=1;+if(dev->fifo_size)+num_bytes=dev->buf_len;++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--;++/*+*Dataregin2430,omap3and+*omap4is8bitwide+*/+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){+u8num_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--;+/**Dataregin2430,omap3and*omap4is8bitwide
@@ -843,36 +869,68 @@ 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){u8num_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;++if(dev->fifo_size)+num_bytes=dev->buf_len;++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--;++/*+*Dataregin2430,omap3and+*omap4is8bitwide+*/+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))+gotocomplete;++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){+u8num_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--;+/**Dataregin2430,omap3and*omap4is8bitwide
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:02
From: Felipe Balbi <redacted>
Make it not depend on ISR's local variables
in order to make it easier to re-factor the
transmit data loop.
Also since we are waiting for XUDF(Transmitter underflow) just before
writing data lets not flag the underflow.
This is anyways going to go once we write
the data.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 43 ++++++++++++++++++++++++++++------------
1 files changed, 30 insertions(+), 13 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:03
From: Felipe Balbi <redacted>
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 <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 204 ++++++++++++++++------------------------
1 files changed, 82 insertions(+), 122 deletions(-)
@@ -752,12 +752,81 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)return0;}+staticvoidomap_i2c_receive_data(structomap_i2c_dev*dev,u8num_bytes,+boolis_rdr)+{+u16w;++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--;++/*+*Dataregin2430,omap3and+*omap4is8bitwide+*/+if(dev->flags&OMAP_I2C_FLAG_16BIT_DATA_REG){+if(dev->buf_len){+*dev->buf++=w>>8;+dev->buf_len--;+}+}+}+}++staticintomap_i2c_transmit_data(structomap_i2c_dev*dev,u8num_bytes,+boolis_xdr)+{+u16w;++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--;++/*+*Dataregin2430,omap3and+*omap4is8bitwide+*/+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){+intret;++ret=errata_omap3_i462(dev);+if(ret<0)+returnret;+}++omap_i2c_write_reg(dev,OMAP_I2C_DATA_REG,w);+}++return0;+}+staticirqreturn_tomap_i2c_isr(intthis_irq,void*dev_id){structomap_i2c_dev*dev=dev_id;u16bits;-u16stat,w;+u16stat;interr,count=0;if(pm_runtime_suspended(dev->dev))
@@ -810,30 +879,7 @@ complete:if(dev->fifo_size)num_bytes=dev->buf_len;-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--;--/*-*Dataregin2430,omap3and-*omap4is8bitwide-*/-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);if(dev->errata&I2C_OMAP_ERRATA_I207)i2c_omap_errata_i207(dev,stat);
@@ -848,77 +894,22 @@ 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--;--/*-*Dataregin2430,omap3and-*omap4is8bitwide-*/-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){u8num_bytes=1;+intret;if(dev->fifo_size)num_bytes=dev->buf_len;-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--;--/*-*Dataregin2430,omap3and-*omap4is8bitwide-*/-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){-intret;--ret=errata_omap3_i462(dev);-stat=omap_i2c_read_reg(dev,-OMAP_I2C_STAT_REG);--if(ret<0)-gotocomplete;-}--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)+gotocomplete;omap_i2c_ack_stat(dev,OMAP_I2C_STAT_XDR);continue;
@@ -926,46 +917,15 @@ complete:if(stat&OMAP_I2C_STAT_XRDY){u8num_bytes=1;+intret;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--;--/*-*Dataregin2430,omap3and-*omap4is8bitwide-*/-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){-intret;--ret=errata_omap3_i462(dev);-stat=omap_i2c_read_reg(dev,-OMAP_I2C_STAT_REG);--if(ret<0)-gotocomplete;-}--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)+gotocomplete;omap_i2c_ack_stat(dev,OMAP_I2C_STAT_XRDY);continue;
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:04
From: Felipe Balbi <redacted>
this will make sure that we execute at least once.
No functional changes otherwise.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
@@ -827,20 +827,28 @@ omap_i2c_isr(int this_irq, void *dev_id)structomap_i2c_dev*dev=dev_id;u16bits;u16stat;-interr,count=0;+interr=0,count=0;if(pm_runtime_suspended(dev->dev))returnIRQ_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 */+returnIRQ_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);+returnIRQ_HANDLED;}-err=0;complete:/**Ackthestatinonego,but[R/X]DRand[R/X]RDYshouldbe
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:05
From: Felipe Balbi <redacted>
According to flow diagrams on OMAP TRMs,
we should ACK the IRQ as they happen.
Signed-off-by: Felipe Balbi <redacted>
[Ack the stat OMAP_I2C_STAT_AL in case of arbitration lost]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 28 ++++++++++++++++------------
1 files changed, 16 insertions(+), 12 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:06
From: Felipe Balbi <redacted>
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 <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:07
From: Felipe Balbi <redacted>
that way we can ignore TX IRQs while in receiver
mode and ignore RX IRQs while in transmitter mode.
Signed-off-by: Felipe Balbi <redacted>
[Remove unnecessary braces]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
@@ -199,6 +199,7 @@ struct omap_i2c_dev {*/u8rev;unsignedb_hw:1;/* bad h/w fixes */+unsignedreceiver:1;/* true when we're in receiver mode */u16iestate;/* Saved interrupt register */u16pscstate;u16scllstate;
@@ -492,6 +493,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;
@@ -837,6 +839,12 @@ omap_i2c_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 */returnIRQ_HANDLED;
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:08
From: Felipe Balbi <redacted>
omap_i2c_dev is allocated with kzalloc(),
so we need not initialize b_hw to zero.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:09
From: Felipe Balbi <redacted>
Always return IRQ_HANDLED otherwise we could get our IRQ line disabled due
to many spurious IRQs.
Signed-off-by: Felipe Balbi <redacted>
[Trivial changes to commitlogs]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:10
From: Felipe Balbi <redacted>
instead of having multiple return points, use
a goto statement to make that clearer.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 20 ++++++++------------
1 files changed, 8 insertions(+), 12 deletions(-)
@@ -853,24 +853,21 @@ omap_i2c_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);-returnIRQ_HANDLED;+gotoout;}complete:if(stat&OMAP_I2C_STAT_NACK){err|=OMAP_I2C_STAT_NACK;omap_i2c_ack_stat(dev,OMAP_I2C_STAT_NACK);-omap_i2c_complete_cmd(dev,err);-returnIRQ_HANDLED;+gotoout;}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_AL);-omap_i2c_complete_cmd(dev,err);-returnIRQ_HANDLED;+gotoout;}/*
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:11
From: Felipe Balbi <redacted>
This patch will try to avoid the usage of
draining feature by reconfiguring the FIFO
the start condition of each message based
on the message's size.
By doing that, we will be better utilizing
the FIFO when doing big transfers.
While at that also drop the now unneeded
check for dev->buf_len as we always know
the amount of data to be transmitted.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 83 +++++++++++++++++++++++++----------------
1 files changed, 51 insertions(+), 32 deletions(-)
@@ -193,6 +193,7 @@ struct omap_i2c_dev {u8*regs;size_tbuf_len;structi2c_adapteradapter;+u8threshold;u8fifo_size;/* use as flag and value*fifo_size==0impliesnofifo*ifset,shouldbetrsh+1
@@ -418,13 +419,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)omap_i2c_write_reg(dev,OMAP_I2C_SCLL_REG,scll);omap_i2c_write_reg(dev,OMAP_I2C_SCLH_REG,sclh);-if(dev->fifo_size){-/* Note: setup required fifo size - 1. RTRSH and XTRSH */-buf=(dev->fifo_size-1)<<8|OMAP_I2C_BUF_RXFIF_CLR|-(dev->fifo_size-1)|OMAP_I2C_BUF_TXFIF_CLR;-omap_i2c_write_reg(dev,OMAP_I2C_BUF_REG,buf);-}-/* Take the I2C module out of reset: */omap_i2c_write_reg(dev,OMAP_I2C_CON_REG,OMAP_I2C_CON_EN);
@@ -478,6 +511,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,if(msg->len==0)return-EINVAL;+dev->receiver=!!(msg->flags&I2C_M_RD);+omap_i2c_resize_fifo(dev,msg->len,dev->receiver);+omap_i2c_write_reg(dev,OMAP_I2C_SA_REG,msg->addr);/* REVISIT: Could the STB bit of I2C_CON be used with probing? */
@@ -493,7 +529,6 @@ 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;
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:12
From: Felipe Balbi <redacted>
we can ack stat and complete the command from
the errata handling itself.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 16 +++++++++++++---
1 files changed, 13 insertions(+), 3 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:13
Remove the redundant read of the status register.
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:14
From: Felipe Balbi <redacted>
even if our clocks are disabled, we still
handled the IRQ, so we should return IRQ_HANDLED.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:15
From: Felipe Balbi <redacted>
for OMAP2, we can easily switch over to threaded
IRQs on the I2C driver. This will allow us to
spend less time in hardirq context.
Signed-off-by: Felipe Balbi <redacted>
[Trivial formating changes]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 43 +++++++++++++++++++++++++++++++++++-----
1 files changed, 37 insertions(+), 6 deletions(-)
@@ -877,6 +900,7 @@ omap_i2c_isr(int this_irq, void *dev_id)if(!stat){/* my work here is done */+spin_unlock_irqrestore(&dev->lock,flags);returnIRQ_HANDLED;}
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:16
From: Felipe Balbi <redacted>
before starting any messages we call pm_runtime_get_sync()
which will make sure that by the time we program a transfer
and our IRQ handler gets called, we're not suspended
anymore.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:17
From: Felipe Balbi <redacted>
this helps us reduce unnecessary pm transitions
in case we have another i2c message starting soon.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
@@ -55,6 +55,9 @@/* timeout waiting for the controller to respond */#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))+/* timeout for pm runtime autosuspend */+#define OMAP_I2C_PM_TIMEOUT 1000 /* ms */+/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */enum{OMAP_I2C_REV_REG=0,
From: Shubhrajyoti D <hidden> Date: 2012-09-11 09:42:18
From: Felipe Balbi <redacted>
move the goto out label one line down, so that
it can be used when stat is read as zero. All
other exits, can be done with a break statement.
While at that, also break out as soon as we
complete draining IRQ, since at that time
we know we transferred everything there was
to be transferred.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 26 +++++++++++++-------------
1 files changed, 13 insertions(+), 13 deletions(-)
@@ -901,27 +901,26 @@ omap_i2c_isr_thread(int this_irq, void *dev_id)if(!stat){/* my work here is done */-spin_unlock_irqrestore(&dev->lock,flags);-returnIRQ_HANDLED;+gotoout;}dev_dbg(dev->dev,"IRQ (ISR = 0x%04x)\n",stat);if(count++==100){dev_warn(dev->dev,"Too much work in one IRQ\n");-gotoout;+break;}if(stat&OMAP_I2C_STAT_NACK){err|=OMAP_I2C_STAT_NACK;omap_i2c_ack_stat(dev,OMAP_I2C_STAT_NACK);-gotoout;+break;}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_AL);-gotoout;+break;}/*
On Tuesday 11 September 2012 03:11 PM, Shubhrajyoti D wrote:
Changes since v1:
- removed tabification on patch 6/17
- removed dev_err() which was introduced on patch 09/17
Changes since v2:
- do not set full fifo depth in the RDR interrupt.
- some changelog updates.
- rebase to the Wolfram's tree.
Changes since v3:
- Remove a redundant read of status register
- Read the dev->buf_len variable instead of the register
as the information of the remaining bytes is there.
Changes since v4:
- Ack the arbitration lost.
- Rebase to the i2c-embedded/for-next branch.
Changes since v5:
- Rebase to latest mainline
- Added some more cleanup patches so as have a consolidated series.
Changes since v6:
- Fix comments on setting the pdev to NULL.
- Trivial changelog update
Previous discussions can be found here
http://www.spinics.net/lists/linux-i2c/msg09482.html
Also this gives better performance
With the patches:
Performance counter stats for '/build/i2c/bin/i2cdump -y -f 1 0x48
b':
78.796376 task-clock # 0.453 CPUs
utilized
516 context-switches # 0.007
M/sec
0 CPU-migrations # 0.000
K/sec
114 page-faults # 0.001 M/sec
0.174011183 seconds time elapsed
Without the patches
Performance counter stats for '/build/i2c/bin/i2cdump -y -f 1 0x48
b':
123.504640 task-clock # 0.049 CPUs
utilized
337 context-switches # 0.003
M/sec
0 CPU-migrations # 0.000
K/sec
144 page-faults # 0.001
M/sec
2.534424040 seconds time elapsed
The auto suspend is probably the one :-)
This is the cleanup only series.
Tested on omap4sdp and 3430sdp.
The following changes since commit 55d512e245bc7699a8800e23df1a24195dd08217:
Linux 3.6-rc5 (2012-09-08 16:43:45 -0700)
are available in the git repository at:
git://gitorious.org/linus-tree/linus-tree.git for_3.7/i2c/big_cleanup
Felipe Balbi (22):
i2c: omap: switch to devm_* API
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 i462 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 to platform_get_irq()
i2c: omap: bus: add a receiver flag
i2c: omap: simplify errata check
i2c: omap: always return IRQ_HANDLED
i2c: omap: simplify IRQ exit path
i2c: omap: resize fifos before each message
i2c: omap: get rid of the "complete" label
i2c: omap: always return IRQ_HANDLED
i2c: omap: switch to threaded IRQ support
i2c: omap: remove unnecessary pm_runtime_suspended check
i2c: omap: switch over to autosuspend API
i2c: omap: sanitize exit path
Shubhrajyoti D (1):
i2c: omap: remove redundant status read
drivers/i2c/busses/i2c-omap.c | 442 +++++++++++++++++++++++++----------------
1 files changed, 271 insertions(+), 171 deletions(-)
From: Felipe Balbi <hidden> Date: 2012-09-11 12:05:54
Hi,
On Tue, Sep 11, 2012 at 03:48:34PM +0530, Shubhrajyoti wrote:
On Tuesday 11 September 2012 03:11 PM, Shubhrajyoti D wrote:
quoted
Changes since v1:
- removed tabification on patch 6/17
- removed dev_err() which was introduced on patch 09/17
Changes since v2:
- do not set full fifo depth in the RDR interrupt.
- some changelog updates.
- rebase to the Wolfram's tree.
Changes since v3:
- Remove a redundant read of status register
- Read the dev->buf_len variable instead of the register
as the information of the remaining bytes is there.
Changes since v4:
- Ack the arbitration lost.
- Rebase to the i2c-embedded/for-next branch.
Changes since v5:
- Rebase to latest mainline
- Added some more cleanup patches so as have a consolidated series.
Changes since v6:
- Fix comments on setting the pdev to NULL.
- Trivial changelog update
Previous discussions can be found here
http://www.spinics.net/lists/linux-i2c/msg09482.html
Also this gives better performance
With the patches:
Performance counter stats for '/build/i2c/bin/i2cdump -y -f 1 0x48
b':
78.796376 task-clock # 0.453 CPUs
utilized
516 context-switches # 0.007
M/sec
0 CPU-migrations # 0.000
K/sec
114 page-faults # 0.001 M/sec
0.174011183 seconds time elapsed
Without the patches
Performance counter stats for '/build/i2c/bin/i2cdump -y -f 1 0x48
b':
123.504640 task-clock # 0.049 CPUs
utilized
337 context-switches # 0.003
M/sec
0 CPU-migrations # 0.000
K/sec
144 page-faults # 0.001
M/sec
2.534424040 seconds time elapsed
The auto suspend is probably the one :-)
From: Wolfram Sang <hidden> Date: 2012-09-11 21:51:12
On Tue, Sep 11, 2012 at 03:12:15PM +0530, Shubhrajyoti D wrote:
quoted hunk
From: Felipe Balbi <redacted>
for OMAP2, we can easily switch over to threaded
IRQs on the I2C driver. This will allow us to
spend less time in hardirq context.
Signed-off-by: Felipe Balbi <redacted>
[Trivial formating changes]
Signed-off-by: Shubhrajyoti D <redacted>
---
drivers/i2c/busses/i2c-omap.c | 43 +++++++++++++++++++++++++++++++++++-----
1 files changed, 37 insertions(+), 6 deletions(-)
From: Wolfram Sang <hidden> Date: 2012-09-11 21:53:41
On Tue, Sep 11, 2012 at 03:12:14PM +0530, Shubhrajyoti D wrote:
From: Felipe Balbi <redacted>
even if our clocks are disabled, we still
handled the IRQ, so we should return IRQ_HANDLED.
Signed-off-by: Felipe Balbi <redacted>
Signed-off-by: Shubhrajyoti D <redacted>
From: Wolfram Sang <hidden> Date: 2012-09-11 22:00:48
On Tue, Sep 11, 2012 at 03:11:55PM +0530, Shubhrajyoti D wrote:
Changes since v1:
- removed tabification on patch 6/17
- removed dev_err() which was introduced on patch 09/17
Changes since v2:
- do not set full fifo depth in the RDR interrupt.
- some changelog updates.
- rebase to the Wolfram's tree.
Changes since v3:
- Remove a redundant read of status register
- Read the dev->buf_len variable instead of the register
as the information of the remaining bytes is there.
Changes since v4:
- Ack the arbitration lost.
- Rebase to the i2c-embedded/for-next branch.
Changes since v5:
- Rebase to latest mainline
- Added some more cleanup patches so as have a consolidated series.
Changes since v6:
- Fix comments on setting the pdev to NULL.
- Trivial changelog update
On Wednesday 12 September 2012 03:30 AM, Wolfram Sang wrote:
quoted
Changes since v6:
quoted
- Fix comments on setting the pdev to NULL.
- Trivial changelog update
Looks mostly good, thanks. Only a few comments. Oh, and I still get
reports about a section mismatch ;)
I am using omap2plus_defconfig
$ make --ver
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
$ make CONFIG_DEBUG_SECTION_MISMATCH=y uImage
....
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
KSYM .tmp_kallsyms1.o
KSYM .tmp_kallsyms2.o
LD vmlinux
SYSMAP System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
GZIP arch/arm/boot/compressed/piggy.gzip
CC arch/arm/boot/compressed/misc.o
CC arch/arm/boot/compressed/decompress.o
CC arch/arm/boot/compressed/string.o
AS arch/arm/boot/compressed/piggy.gzip.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-3.6.0-rc5-00022-g49fb6db
Created: Wed Sep 12 15:24:21 2012
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4074688 Bytes = 3979.19 kB = 3.89 MB
Load Address: 80008000
Entry Point: 80008000
Image arch/arm/boot/uImage is ready
I donot see the warning. Am I missing something?
From: Wolfram Sang <hidden> Date: 2012-09-12 10:18:50
I donot see the warning. Am I missing something?
I deleted my logfiles already. Ignore it for now, if it comes up again
with your new series, I will give a more detailed pointer.
Thanks,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120912/fa1222fb/attachment.sig>
From: Wolfram Sang <hidden> Date: 2012-09-12 13:44:27
On Wed, Sep 12, 2012 at 12:18:50PM +0200, Wolfram Sang wrote:
quoted
I donot see the warning. Am I missing something?
I deleted my logfiles already. Ignore it for now, if it comes up again
with your new series, I will give a more detailed pointer.
Sorry, the section mismatch was not related to I2C it seems:
WARNING: vmlinux.o(.data+0x30958): Section mismatch in reference from the variable rx51_si4713_dev to the (unknown reference) .init.data:(unknown)
The variable rx51_si4713_dev references
the (unknown reference) __initdata (unknown)
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
Got it with an "allnoconfig" and then selecting MMU and OMAP.
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20120912/bb3a742e/attachment.sig>
On Wed, Sep 12, 2012 at 7:14 PM, Wolfram Sang [off-list ref] wrote:
On Wed, Sep 12, 2012 at 12:18:50PM +0200, Wolfram Sang wrote:
quoted
quoted
I donot see the warning. Am I missing something?
I deleted my logfiles already. Ignore it for now, if it comes up again
with your new series, I will give a more detailed pointer.
Sorry, the section mismatch was not related to I2C it seems:
Thanks for the report just sent a patch fixing that.
WARNING: vmlinux.o(.data+0x30958): Section mismatch in reference from the variable rx51_si4713_dev to the (unknown reference) .init.data:(unknown)
The variable rx51_si4713_dev references
the (unknown reference) __initdata (unknown)
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console
Got it with an "allnoconfig" and then selecting MMU and OMAP.
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iEYEARECAAYFAlBQkbsACgkQD27XaX1/VRtbuACgkBa0lOIN551eec9TSetVPsCE
Ew0AoKizKon3DIILpERWJIwzAXdgRVDc
=T4Yq
-----END PGP SIGNATURE-----