8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-15 Thread [EMAIL PROTECTED]




Hi Jocke,

I changed the force_reinit() to

// Disable interrupts.
i2c-i2c_i2cmr = 0;
i2c-i2c_i2cer = 0xff;
// Clear enable
i2c-i2c_i2mod = ~1;
// Reset internal state
iip-iic_rstate = 0;
iip-iic_tstate = 0;

This seems to work and is less code than my old force_reinit().
On the other hand: This kind of CPM timeout will only occur on heavy I2C
bus conflicts. They should not appear at all. The code will not be executed
if a slave device does not answer! The original driver is from the year
2001 and nobody has mentioned problems of this kind before. Without
detailed knowledge of the CPM internals I feel much safer using my old
force_reinit(), which does a complete re-init.

Cajus




8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-15 Thread Joakim Tjernlund
 
 Hi Jocke,
 
 I changed the force_reinit() to
 
 // Disable interrupts.
 i2c-i2c_i2cmr = 0;
 i2c-i2c_i2cer = 0xff;
 // Clear enable
 i2c-i2c_i2mod = ~1;
 // Reset internal state
 iip-iic_rstate = 0;
 iip-iic_tstate = 0;
 
 This seems to work and is less code than my old force_reinit().
 On the other hand: This kind of CPM timeout will only occur on heavy I2C
 bus conflicts. They should not appear at all. The code will not be executed
 if a slave device does not answer! The original driver is from the year
 2001 and nobody has mentioned problems of this kind before. Without
 detailed knowledge of the CPM internals I feel much safer using my old
 force_reinit(), which does a complete re-init.

Good, however I think we should try to it simple, the code that is, and avoid
unneded bloat. I would like to see the shorter version in the kernel.

 Jocke



8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-13 Thread Joakim Tjernlund
 My description seems to be a little misleading.
 WITHOUT the force_reinit() my SPI driver reports transmission errors if the
 I2C bus has longer disturbances.
 WITH the force_reinit() my SPI driver works fine.
 This sounds like the I2C allocates a new buffer for every timed-out
 transmision. If all I2C buffers are full, the SPI buffers get overwritten
 !?
 I did not really trace back the problem, this is only my suspicion.
 Because the  force_reinit() resets all the buffer pointer to their init
 values the problem with the SPI does not occur.
 
 Cajus

I think the problem is that the CPM is still waiting on the SCL long after the 
timeout has happen.
A complete reinit will reset the I2C part of the CPM.

I think you should be able to get away with less, maybe it will enough to 
disable
I2C (i2c-i2c_i2mod = ~1) and/or clear internal state (iip-iic_rstate   = 0; 
iip-iic_tstate   = 0;)
after a timeout?

 Jocke



8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-12 Thread Debora Liu
Hello, Tjernlund

In message 2005-08-12 01:50:45 tjernlund at tjernlund.se you wrote:

Try changing all
  i2c-i2c_i2com |= 0x80;  /* Begin transmission */
to
  i2c-i2c_i2com |= 0x80 | 0x01;   /* Begin transmission */

That should remove the need to do force_reinit(cpm) I hope.
See http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019600.html for 
a litte more info.

Also, I think you should remove the busy wait code. Its not needed IMHO.

update i2c_algo_8xx.c as same

= = = = = = = = = = = = = = = = = = = =
 
Debora Liu
deboralh at fel.com.cn
2005-08-12






8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-12 Thread [EMAIL PROTECTED]




Hello Tjernlund, Hello Debora

Try changing all
  i2c-i2c_i2com |= 0x80;   /* Begin transmission */
to
  i2c-i2c_i2com |= 0x80 | 0x01;  /* Begin transmission */

That should remove the need to do force_reinit(cpm) I hope.

This is NOT working in every case!

It will work, on short bus-disturbances on the SCL line.
I suggest adding the | 0x01 even this will not help on every transmission
problem.

If you have longer disturbances on SCL or SDA, something in  the CPM will
prevent the I2C bus to continue working after the disturbances are gone.
Perhaps there is a problem with the buffer allocation.
I changed the i2c-algo-8xx.c to work with your patch and without the
force_reinit() code.
Then I set the SCL line to ground to simulate a longer bus disturbance.
After some timeouts my SPI bus, yes the SPI bus, reportet transmission
errors. Both bus-interfaces use the CPM. It looks like the SPI buffer gets
garbaged by the I2C interface.
With the force_reinit() this problem did not occur.

Cajus




8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-12 Thread Wolfgang Denk
In message OF29EF0D8D.F0A40A5C-ONC125705B.0028FA70-C125705B.002AF212 at 
de.abb.com you wrote:
 
 Then I set the SCL line to ground to simulate a longer bus disturbance.
 After some timeouts my SPI bus, yes the SPI bus, reportet transmission
 errors. Both bus-interfaces use the CPM. It looks like the SPI buffer gets
 garbaged by the I2C interface.

This is normal. We see similar problems even with  perfectly  legal
operations  on  the CPM. The SPI is running at lowest priority on the
CPM, and anything that  causes  higher  CPM  load  will  starve  SPI.
Obviously  your  operation  causes  the  CPM  to go into some strange
state.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
There are certain things men must do to remain men.
-- Kirk, The Ultimate Computer, stardate 4929.4



8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-11 Thread Cajus Hahn
Marcello,

my old version is from the linuxppc_2_4_devel CVS archive on 
www.denx.de:/cvsroot.
The i2c-algo-8xx.c there has the revision number 1.5.

Regards
Cajus



--- ../../i2c-algo-8xx.c2005-08-10 16:19:09.0 +0200
+++ drivers/i2c/i2c-algo-8xx.c  2005-08-10 08:03:46.0 +0200
@@ -19,12 +19,19 @@
  * moved into proper i2c interface; separated out platform specific
  * parts into i2c-rpx.c
  * Brad Parker (brad at heeltoe.com)
+ *
+ * added define for BUSY_WAIT and INTERRUPTIBLE_SLEEP, added I2C_ALGO_8XX_DATE 
+ ..VERSION
+ * fixed bug in cpm_iic_read and cpm_iic_write (timeout never detected if 
count  16)
+ * added force_reinit(): in certain cases (disturbances on the I2C bus) a 
timeout will
+ * occur. After this a complete re-initialisation will be necessary, otherwise 
all
+ * following transmissions will have a timeout.
+ * Cajus Hahn, 09.08.2005
  */
 
 // XXX todo
 // timeout sleep?
 
-/* $Id: i2c-algo-8xx.c,v 1.7 2002/08/03 22:48:18 ac9410 Exp $ */
+/* $Id: i2c-algo-8xx.c,v 1.2 2005/08/10 06:03:46 cajus Exp $ */
 
 #include linux/kernel.h
 #include linux/module.h
@@ -43,8 +50,16 @@
 #include linux/i2c.h
 #include linux/i2c-algo-8xx.h
 
+#define I2C_ALGO_8XX_DATE 20050809
+#define I2C_ALGO_8XX_VERSION 2.6.2
+
 #define CPM_MAX_READ   513
 /* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older 
CPU(earlier than rev D4) */
+#define I2C_BUSY_WAIT /* Uncomment this if you want to do a busy wait in 
cpm_iic_read and
+   cpm_iic_write. In a timeout case the CPU load 
will be 99.9% ! */
+#define I2C_INTERRUPTIBLE_SLEEP /* Uncomment this if you want the waiting in 
cpm_iic_read and
+ cpm_iic_write being interruptable by 
signals */
+
 static wait_queue_head_t iic_wait;
 static ushort r_tbase, r_rbase;
 
@@ -73,7 +88,11 @@
 
/* Get 'me going again.
*/
+#ifdef I2C_INTERRUPTIBLE_SLEEP
wake_up_interruptible(iic_wait);
+#else
+   wake_up(iic_wait);
+#endif
 }
 
 static void
@@ -201,20 +220,77 @@
 static void force_close(struct i2c_algo_8xx_data *cpm)
 {
volatile i2c8xx_t *i2c = cpm-i2c;
+
+if (cpm_debug)
+printk(KERN_DEBUG force_close());
+
if (cpm-reloc == 0) { /* micro code disabled */
volatile cpm8xx_t *cp = cpm-cp;
-
-   if (cpm_debug) printk(KERN_DEBUG force_close()\n);
cp-cp_cpcr =
mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) |
CPM_CR_FLG;
 
while (cp-cp_cpcr  CPM_CR_FLG);
}
+
i2c-i2c_i2cmr = 0x00;  /* Disable all interrupts */
i2c-i2c_i2cer = 0xff;
 }
 
+static void force_reinit(struct i2c_algo_8xx_data *cpm)
+{
+   volatile iic_t *iip = cpm-iip;
+   volatile i2c8xx_t *i2c = cpm-i2c;
+   volatile cpm8xx_t *cp = cpm-cp;
+   unsigned char brg;
+   bd_t *bd = (bd_t *)__res;
+
+   // Disable interrupts.
+   i2c-i2c_i2cmr = 0;
+   i2c-i2c_i2cer = 0xff;
+// Clear enable
+   i2c-i2c_i2mod = ~1;
+
+   // Initialize the parameter ram.
+   iip-iic_rstate = 0;
+   iip-iic_rdp = 0;
+   iip-iic_rbptr = 0;
+   iip-iic_rbc = 0;
+   iip-iic_rxtmp = 0;
+   iip-iic_tstate = 0;
+   iip-iic_tdp = 0;
+   iip-iic_tbptr = 0;
+   iip-iic_tbc = 0;
+   iip-iic_txtmp = 0;
+iip-iic_tbase = r_tbase;
+   iip-iic_rbase = r_rbase;
+   iip-iic_tfcr = SMC_EB;
+   iip-iic_rfcr = SMC_EB;
+   iip-iic_mrblr = CPM_MAX_READ;
+
+   if (cpm-reloc == 0)
+{
+   cp-cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | 
CPM_CR_FLG;
+   while (cp-cp_cpcr  CPM_CR_FLG);
+   }
+else
+{
+   iip-iic_rbptr = iip-iic_rbase;
+   iip-iic_tbptr = iip-iic_tbase;
+   iip-iic_rstate = 0;
+   iip-iic_tstate = 0;
+   }
+
+   // Select an arbitrary address.  Just make sure it is unique.
+   i2c-i2c_i2add = 0xfe;
+
+   // Make clock run at 60 KHz.
+   brg = (unsigned char) (bd-bi_intfreq/(32*2*6) -3);
+   i2c-i2c_i2brg = brg;
+
+   i2c-i2c_i2mod = 0x00;
+   i2c-i2c_i2com = 0x01; /* Master mode */
+}
 
 /* Read from IIC...
  * abyte = address byte, with r/w flag already set
@@ -227,7 +303,7 @@
volatile cpm8xx_t *cp = cpm-cp;
volatile cbd_t  *tbdf, *rbdf;
u_char *tb;
-   unsigned long flags, tmo;
+   unsigned long flags, tmo, timedout;
 
if (count = CPM_MAX_READ)
return -EINVAL;
@@ -269,7 +345,10 @@
rbdf-cbd_bufaddr = __pa(buf);
 
rbdf-cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT;
+timedout = 0;
+#ifdef I2C_BUSY_WAIT
if(count  16){
+#endif
/* Chip bug, set enable here */
local_irq_save(flags);
i2c-i2c_i2cmr = 0x13;  /* Enable some interupts */
@@ -278,23 +357,40 @@

8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-11 Thread Tjernlund
Try changing all
  i2c-i2c_i2com |= 0x80;   /* Begin transmission */
to
  i2c-i2c_i2com |= 0x80 | 0x01;/* Begin transmission */

That should remove the need to do force_reinit(cpm) I hope.
See http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019600.html for a 
litte more info.

Also, I think you should remove the busy wait code. Its not needed IMHO.

 Jocke



8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-10 Thread [EMAIL PROTECTED]




Hi all,

I had some problems on my MPC855M based board when I tried to access the
i2c bus.
The cause were some disturbances on the i2c bus. If a slave device or
another master device hold the SDA or SCL line low, the CPM will get into a
state, where no more transmissions are made. The  only way I found, to get
the CPM back to work, was a complete re-initialisation. - force_reinit()
In this case the busy-wait for transmissions with count  16 will lock the
complete system (CPU load 99.9%)
I added the define I2C_BUSY_WAIT to switch between faster access or safer
system.
I found out that the i2c-algo-8xx.c has a bug in cpm_iic_read() and
cpm_iic_write(): the timeout detection will not work in the case of count 
16.
I also added the define I2C_INTERRUPTIBLE_SLEEP: the old driver reported
IO-error (-EIO) if a timeout occured (which was not working, see above) or
if a signal was pending. This caused some problems if the process receives
user-signals. The driver will report IO-error, which is not correct. With
the busy-wait this effect might not be seen, because there will be no
process scheduling - no signals might be send.
My modified file is appended. The defines for  I2C_BUSY_WAIT and
I2C_INTERRUPTIBLE_SLEEP are active, which let the driver act like the old
one.
Maybe this is helpful for others too and some of the modifications find
it?s way into the official kernel tree.

Cajus Hahn

/*
 * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
 * Copyright (c) 1999 Dan Malek (dmalek at jlc.net).
 *
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * moved into proper i2c interface; separated out platform specific
 * parts into i2c-rpx.c
 * Brad Parker (brad at heeltoe.com)
 *
 * added define for BUSY_WAIT and INTERRUPTIBLE_SLEEP, added
I2C_ALGO_8XX_DATE + ..VERSION
 * fixed bug in cpm_iic_read and cpm_iic_write (timeout never detected if
count  16)
 * added force_reinit(): in certain cases (disturbances on the I2C bus) a
timeout will
 * occur. After this a complete re-initialisation will be necessary,
otherwise all
 * following transmissions will have a timeout.
 * Cajus Hahn, 09.08.2005
 */

// XXX todo
// timeout sleep?

/* $Id: i2c-algo-8xx.c,v 1.1.1.1 2004/12/10 08:44:35 cajus Exp $ */

#include linux/kernel.h
#include linux/module.h
#include linux/delay.h
#include linux/slab.h
#include linux/version.h
#include linux/init.h
#include asm/uaccess.h
#include linux/ioport.h
#include linux/errno.h
#include linux/sched.h

#include asm/mpc8xx.h
#include asm/commproc.h

#include linux/i2c.h
#include linux/i2c-algo-8xx.h

#define I2C_ALGO_8XX_DATE 20050809
#define I2C_ALGO_8XX_VERSION 2.6.2

#define CPM_MAX_READ513
/* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older
CPU(earlier than rev D4) */
#define I2C_BUSY_WAIT  /* Uncomment this if you want to do a busy wait in
cpm_iic_read and cpm_iic_write */
#define I2C_INTERRUPTIBLE_SLEEP /* Uncomment this if you want the waiting
in cpm_iic_read and
 cpm_iic_write beeing interruptable
by signals */

static wait_queue_head_t iic_wait;
static ushort r_tbase, r_rbase;

int cpm_scan = 0;
int cpm_debug = 0;

static  void
cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
 {
  volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;

  if (cpm_debug  1)
printk(KERN_DEBUG cpm_iic_interrupt(dev_id=%p)\n, dev_id);

#ifdef I2C_CHIP_ERRATA
  /* Chip errata, clear enable.
   * This seems to not be needed on rev D4 or newer CPUs.
   * Someone with an older CPU needs to verify this.
   */
  i2c-i2c_i2mod = ~1;
#endif

  /* Clear interrupt.
  */
  i2c-i2c_i2cer = 0xff;

  /* Get 'me going again.
  */
#ifdef I2C_INTERRUPTIBLE_SLEEP
  wake_up_interruptible(iic_wait);
#else
  wake_up(iic_wait);
#endif
}

static void
cpm_iic_init(struct i2c_algo_8xx_data *cpm_adap)
{
  volatile iic_t  *iip = cpm_adap-iip;
  volatile i2c8xx_t *i2c = cpm_adap-i2c;
  unsigned char brg;
  bd_t *bd = (bd_t *)__res;

  if (cpm_debug) printk(KERN_DEBUG cpm_iic_init() - iip=%p\n,iip);

  /* Initialize the parameter ram.
   * We need to make sure many things are initialized to zero,
   * especially in the case of a microcode patch.
   */
  iip-iic_rstate = 0;
  iip-iic_rdp = 0;
  

8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-10 Thread Debora Liu
Hello, cajus.hahn

In message 2005-08-10 15:27:57 cajus.hahn at de.abb.com you wrote:

Hi all,

I had some problems on my MPC855M based board when I tried to access the
i2c bus.

Try update i2c-algo-8xx.c

= = = = = = = = = = = = = = = = = = = =
 
Debora Liu
deboralh at fel.com.cn
  2005-08-10

begin 600 i2c_algo_8xx-port_to_2_6.patch
M.'AX.B!P;W)T(DR8RUA;=O7SAX!T;R`R+C8-@T*0F%S960@;VX at 5]M
M(%)I;FDGR!A;F0 at 2F]A:VEM(%1J97)N;'5N9=S('=OFL-@T*4VEG;F5D
M+6]F9BUB3H at 07)IW1E=2!397)G:[EMAIL PROTECTED]:VD at 1FEL:\@/%R:7-`
M8V%T:5DF%L;%BRYOF^#0H-DEN95X.B`R+C8M.'AX+V1R:79EG,O
M:3)C+V%L9V]S+VDR8RUA;=O+3AXYC#0H]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]#0HM+2T at +V1E=B]N=6QL3$Y-S`M,#$M,#$@,#`Z,#`Z,#`N,#`P,#`P
M,#`P(LP,#`P#0HK*RL@,BXV+3AX]DFEV97)S+VDR8R]A;=OR]I,F,M
M86QG;RTX'@N8PDR,#`U+3`X+3`X(#`Y.C4U.C,P+C`P,#`P,#`P,`M,#,P
M,[EMAIL PROTECTED],`K,2PV,3@0$`-[EMAIL PROTECTED](DR8RUA;=O+3AXYC
M(DR!DFEV97(@86QG;W)I=AMR!F;W(@35!#.%A8($-030T**R`J($-O
M'ER:6=H=`H8RD@,3DY.2!$86X at [EMAIL PROTECTED]1M86QE:T!J;,N;F5T*2X-
M[EMAIL PROTECTED]@T**R`@(!4:ES('!R;V=R86T@:7, at 9G)E92!S;V9T=V%R93L@6]U
M(-A;B!R961IW1R:6)U=4@:70 at 86YD+V]R(UO9EF0T**R`@(!I=!U
M;F1EB!T:[EMAIL PROTECTED]5R;7,@;[EMAIL 
PROTECTED]AE($=.52!'96YEF%L(%!U8FQI8R!,:6-E
M;G-E(%S('!U8FQIVAE9!B0T**R`@(!T:4 at 1G)E92!3;V9T=V%R92!
M;W5N9%T:6]N.R!E:71H97(@=F5RVEO;B`R(]F('1H92!,:6-E;G-E+!O
M@T**R`@(`H870@6]UB!O'1I;VXI(%N2!L871EB!V97)S:6]N+ at T*
M*PT**R`@(!4:ES('!R;V=R86T@:7, at 9ES=')I8G5T960@:[EMAIL PROTECTED]AE(AO
M[EMAIL PROTECTED]AA=!I=!W:6QL()E('5S969U;P-BL@([EMAIL 
PROTECTED](%=)5$A/550@
M04Y9(%=!4E)!3E19.R!W:71H;W5T([EMAIL PROTECTED]AE(EM[EMAIL PROTECTED]F%N
M='D@;V8-BL@([EMAIL PROTECTED],2519(]R($9)5$Y%4U, at 1D]2($$@
M4$%25$E#54Q!4B!055)[EMAIL PROTECTED]('1H90T**R`@(!'3E4 at 1V5N97)A
M;!0=6)L:6, at 3EC96YS92!F;W(@;6]R92!D971A:6QS+ at T**PT**R`@(!9
M;W4@VAO=6QD(AA=F4@F5C96EV960 at 82!C;W!Y(]F('1H92!'3E4 at 1V5N
M97)A;!0=6)L:6, at 3EC96YS90T**R`@(!A;]N9R!W:71H('1H:7,@')O
M9W)A;3L@:68@;F]T+!WFET92!T;R!T:4 at 1G)E92!3;V9T=V%R90T**R`@
M(!;W5N9%T:6]N+!);F,N+`V-S4 at 36%SR!!=F4L($-A;6)R:61G92P@
M34$@,#(Q,SDL(%5302X-[EMAIL PROTECTED]@T**R`J(UO=F5D(EN=\@')O5R(DR
M8R!I;G1EF9A8V4[('-E%R871E9!O=70@QA=9OFT@W!E8VEF:6,-
M[EMAIL PROTECTED])TR!I;G1O(DR8RUR'@N8PT**R`J($)R860 at 4%R:V5R(AB
MF%D0AE96QT;V4N8V]M*0T**R`J+PT**PT**R\O(%A86!T;V1O#0HK+R\@
M=EM96]U=!S;5E#\-BL-BLO*B`D260Z(DR8RUA;=O+3AXYC+'8@
M,2XW(#(P,#(O,[EMAIL PROTECTED],#,@,C([EMAIL 
PROTECTED],3@@86,Y-#$P($5X`D(HO#0HK#0HK
M(VEN8VQU94@/QI;G5X+VMEFYE;YH/@T**R-I;F-L=61E(#QL:6YU]M
M;V1U;4N:#X-BLC:6YC;'5D92`\;EN=7 at O95L87DN:#X-BLC:6YC;'5D
M92`\;EN=7 at OVQA8BYH/@T**R-I;F-L=61E(#QL:6YU]V97)S:[EMAIL PROTECTED]
M#0HK(VEN8VQU94@/QI;G5X+VEN:70N:#X-BLC:6YC;'5D92`\87-M+W5A
M8V-EW,N:#X-BLC:6YC;'5D92`\;EN=7 at O:6]P;W)[EMAIL PROTECTED](VEN8VQU
M94@/QI;G5X+V5R[EMAIL PROTECTED](VEN8VQU94@/QI;G5X+W-C:[EMAIL PROTECTED]
M#0HK#0HK(VEN8VQU94@/%S;2]M,X'@N:#X-BLC:6YC;'5D92`\87-M
M+V-O;6UP[EMAIL PROTECTED](VEN8VQU94@/QI;G5X+VDR8RYH/@T**R-I
M;F-L=61E(#QL:6YU]I,F,M86QG;RTX'@N:#X-BL-BLC95F:6YE($-0
M35]-05A?4D5!1`DU,3,-BLO*B!4[EMAIL PROTECTED];VUM96YT('1H:7,@:68@6]U
M(AA=F4 at 86X@;VQD97(@0U!5*5AFQI97(@=AA;B!R978 at 1#0I(HO#0HK
M+RH@(V1E9FEN92!),D-?0TA)4%]%4E)[EMAIL PROTECTED]BL-BMS=%T:6, at 8VAA
MB`J;6]D=6QE7VYA;64@/2`B:3)C7V%L9V]?.'AX(CL-BLC95F:6YE($1%
M0E5'4AL979E;P@P@2XN+BD at 9\@R!#0HK0D)6EF(ACU?95B
M=6@/CT@;5V96PI(%P-BL)0D)7!R:6YT:RA+15).7T1%0E5'((ESH@
M(B!X+!#0HK0D)0D@(`@(`@;6]D=6QE7VYA;64L(,C('DI.R!#0HK
M0D)[EMAIL PROTECTED];4H,D-BL-BMS=%T:6,@=V%I=%]Q=65U95]H96%D7W0@
M:6EC7W=A:70[#0HKW1A=EC('5S:]R=!R7W1B87-E+!R7W)B87-E.PT*
M*PT**VEN=!CU?V-A;B`](#`[#0HK:6YT(-P;5]D96)U9R`](#`[#0HK
M#0HKW1A=EC(!V;VED#0HK8W!M7VEI8U]I;G1EG)U'0H=F]I9`J95V
M7VED+!S=')U8W0@'1?F5GR`JF5GRD-BM[#0HK79O;%T:6QE(DR
M8SAX%]T(II,F,@/2`H:3)C.'[EMAIL PROTECTED]:60[#0HK#0HK41%0E5'
M4@R+`B8W!M7VEI8U]I;G1EG)U'0H95V7VED/25P*5QN(BP at 95V7VED
M*3L-BL-BLC:69D968 at 23)#7T-(25!?15)2051!#0HK2\J($-H:[EMAIL PROTECTED])R
M871A+!C;5AB!E;F%B;4N#0HK2`J(%1H:7,@V5E;7,@=\@;F]T()E
M(YE961E9!O;B!R978 at 1#0@;W(@;F5W97(@0U!5RX-BL)(H at 4V]M96]N
M92!W:71H(%N(]L95R($-052!N965DR!T;R!V97)[EMAIL PROTECTED]AIRX-BL)
M(HO#0HK6DR8RT^:3)C7VDR;6]D(8]('XQ.PT**R-E;F1I9 at T**PT**PDO
M*B!#;5AB!I;G1EG)U'0N#0HK2HO#0HK6DR8RT^:3)C7VDR8V5R(#T@
M,'AF9CL-BL-BL)+RH at 1V5T(=M92!G;VEN9R!A9V%I;BX-BL)*B\-BL)
M=V%K95]U%]I;G1EG)U'1I8FQE*9I:6-?=V%I=D[#0HK?0T**PT**W-T
M871I8R!V;VED#0HK8W!M7VEI8U]I;FET*'-TG5C=!I,F-?86QG;U\X'A?
M9%T82`J8W!M7V%D87`I#0HKPT**PEV;VQA=EL92!I:6-?=`D)*FEI`]
M(-P;5]A9%P+3YI:7`[#0HK79O;%T:6QE(DR8SAX%]T2II,F,@/2!C
MU?861AT^:3)C.PT**PEU;G-I9VYE9!C:%R()R9SL-BL)8F1?=`J
M8F0@/2`H8F1?=`J*5]?F5S.PT**PT**PE$14)51U`H,2P@(F-P;5]I:6-?
M:6YI=@I(T@:6EP/25P7XB+!I:7`I.PT**PT**PDO*B!);FET:6%L:7IE
M('1H92!P87)A;65T97(@F%M+ at [EMAIL PROTECTED]('1O(UA:V4@W5R
M92!M86YY('1H:6YGR!AF4@:6YI=EA;[EMAIL PROTECTED]\@F5R;RP-BL)(H@
M97-P96-I86QL2!I;B!T:4 at 8V%S92!O9B!A(UI8W)O8V]D92!P871C:X-

8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-10 Thread Wolfgang Denk
Dear Debora,

in message 20050810093254.3E98667EF5 at ozlabs.org you wrote:
 
 I had some problems on my MPC855M based board when I tried to access the
 i2c bus.
 
 Try update i2c-algo-8xx.c

I guess this will not solve Cajus' problems. Please take the time and
read his message again and you will see that his problems  will still
be present with your driver version. 

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
panic: can't find /



8xx: i2c-algo-8xx - fixed timeout detection and transmission errors

2005-08-10 Thread Marcelo Tosatti
On Wed, Aug 10, 2005 at 09:27:57AM +0200, cajus.hahn at de.abb.com wrote:
 
 
 
 
 Hi all,
 
 I had some problems on my MPC855M based board when I tried to access the
 i2c bus.
 The cause were some disturbances on the i2c bus. If a slave device or
 another master device hold the SDA or SCL line low, the CPM will get into a
 state, where no more transmissions are made. The  only way I found, to get
 the CPM back to work, was a complete re-initialisation. - force_reinit()
 In this case the busy-wait for transmissions with count  16 will lock the
 complete system (CPU load 99.9%)
 I added the define I2C_BUSY_WAIT to switch between faster access or safer
 system.
 I found out that the i2c-algo-8xx.c has a bug in cpm_iic_read() and
 cpm_iic_write(): the timeout detection will not work in the case of count 
 16.
 I also added the define I2C_INTERRUPTIBLE_SLEEP: the old driver reported
 IO-error (-EIO) if a timeout occured (which was not working, see above) or
 if a signal was pending. This caused some problems if the process receives
 user-signals. The driver will report IO-error, which is not correct. With
 the busy-wait this effect might not be seen, because there will be no
 process scheduling - no signals might be send.
 My modified file is appended. The defines for  I2C_BUSY_WAIT and
 I2C_INTERRUPTIBLE_SLEEP are active, which let the driver act like the old
 one.
 Maybe this is helpful for others too and some of the modifications find
 it?s way into the official kernel tree.

Cajus,

Can you please prepare a diff with diff -u against the old version and your
modified version of the driver? That way it becomes easier for everyone to 
stop the changes you have made.

Thanks in advance.

 
 Cajus Hahn
 
 /*
  * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM
  * Copyright (c) 1999 Dan Malek (dmalek at jlc.net).
  *
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * moved into proper i2c interface; separated out platform specific
  * parts into i2c-rpx.c
  * Brad Parker (brad at heeltoe.com)
  *
  * added define for BUSY_WAIT and INTERRUPTIBLE_SLEEP, added
 I2C_ALGO_8XX_DATE + ..VERSION
  * fixed bug in cpm_iic_read and cpm_iic_write (timeout never detected if
 count  16)
  * added force_reinit(): in certain cases (disturbances on the I2C bus) a
 timeout will
  * occur. After this a complete re-initialisation will be necessary,
 otherwise all
  * following transmissions will have a timeout.
  * Cajus Hahn, 09.08.2005
  */
 
 // XXX todo
 // timeout sleep?
 
 /* $Id: i2c-algo-8xx.c,v 1.1.1.1 2004/12/10 08:44:35 cajus Exp $ */
 
 #include linux/kernel.h
 #include linux/module.h
 #include linux/delay.h
 #include linux/slab.h
 #include linux/version.h
 #include linux/init.h
 #include asm/uaccess.h
 #include linux/ioport.h
 #include linux/errno.h
 #include linux/sched.h
 
 #include asm/mpc8xx.h
 #include asm/commproc.h
 
 #include linux/i2c.h
 #include linux/i2c-algo-8xx.h
 
 #define I2C_ALGO_8XX_DATE 20050809
 #define I2C_ALGO_8XX_VERSION 2.6.2
 
 #define CPM_MAX_READ513
 /* #define I2C_CHIP_ERRATA */ /* Try uncomment this if you have an older
 CPU(earlier than rev D4) */
 #define I2C_BUSY_WAIT  /* Uncomment this if you want to do a busy wait in
 cpm_iic_read and cpm_iic_write */
 #define I2C_INTERRUPTIBLE_SLEEP /* Uncomment this if you want the waiting
 in cpm_iic_read and
  cpm_iic_write beeing interruptable
 by signals */
 
 static wait_queue_head_t iic_wait;
 static ushort r_tbase, r_rbase;
 
 int cpm_scan = 0;
 int cpm_debug = 0;
 
 static  void
 cpm_iic_interrupt(void *dev_id, struct pt_regs *regs)
  {
   volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id;
 
   if (cpm_debug  1)
 printk(KERN_DEBUG cpm_iic_interrupt(dev_id=%p)\n, dev_id);
 
 #ifdef I2C_CHIP_ERRATA
   /* Chip errata, clear enable.
* This seems to not be needed on rev D4 or newer CPUs.
* Someone with an older CPU needs to verify this.
*/
   i2c-i2c_i2mod = ~1;
 #endif
 
   /* Clear interrupt.
   */
   i2c-i2c_i2cer = 0xff;
 
   /* Get 'me going again.
   */
 #ifdef I2C_INTERRUPTIBLE_SLEEP
   wake_up_interruptible(iic_wait);
 #else
   wake_up(iic_wait);
 #endif
 }
 
 static void
 cpm_iic_init(struct i2c_algo_8xx_data *cpm_adap)
 {
   volatile iic_t  *iip