aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorDomen Puncer <domen.puncer@telargo.com>2007-07-12 08:12:31 -0400
committerJean Delvare <khali@hyperion.delvare>2007-07-12 08:12:31 -0400
commit254db9b5e7b1b0d38a4f177c2c23a5685c78221a (patch)
tree10dffafbbf287d61194fbe885a7e977de2d88242 /drivers/i2c/busses
parent1b144df1d7d69d6dd3394205933c8951dd8b6784 (diff)
i2c-mpc: work around missing-9th-clock-pulse bug
Work around a problem reported on: http://ozlabs.org/pipermail/linuxppc-embedded/2005-July/019038.html Without this patch I2C on mpc5200 becomes unusable after a while. Tested on mpc5200 boards by Matthias Fechner and me. Signed-off-by: Domen Puncer <domen.puncer@telargo.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-mpc.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index a769efc7f408..851c3ed513d0 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -74,6 +74,25 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
74 return IRQ_HANDLED; 74 return IRQ_HANDLED;
75} 75}
76 76
77/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
78 * the bus, because it wants to send ACK.
79 * Following sequence of enabling/disabling and sending start/stop generates
80 * the pulse, so it's all OK.
81 */
82static void mpc_i2c_fixup(struct mpc_i2c *i2c)
83{
84 writeccr(i2c, 0);
85 udelay(30);
86 writeccr(i2c, CCR_MEN);
87 udelay(30);
88 writeccr(i2c, CCR_MSTA | CCR_MTX);
89 udelay(30);
90 writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
91 udelay(30);
92 writeccr(i2c, CCR_MEN);
93 udelay(30);
94}
95
77static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) 96static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
78{ 97{
79 unsigned long orig_jiffies = jiffies; 98 unsigned long orig_jiffies = jiffies;
@@ -153,6 +172,7 @@ static void mpc_i2c_start(struct mpc_i2c *i2c)
153static void mpc_i2c_stop(struct mpc_i2c *i2c) 172static void mpc_i2c_stop(struct mpc_i2c *i2c)
154{ 173{
155 writeccr(i2c, CCR_MEN); 174 writeccr(i2c, CCR_MEN);
175 writeccr(i2c, 0);
156} 176}
157 177
158static int mpc_write(struct mpc_i2c *i2c, int target, 178static int mpc_write(struct mpc_i2c *i2c, int target,
@@ -245,6 +265,9 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
245 } 265 }
246 if (time_after(jiffies, orig_jiffies + HZ)) { 266 if (time_after(jiffies, orig_jiffies + HZ)) {
247 pr_debug("I2C: timeout\n"); 267 pr_debug("I2C: timeout\n");
268 if (readb(i2c->base + MPC_I2C_SR) ==
269 (CSR_MCF | CSR_MBB | CSR_RXAK))
270 mpc_i2c_fixup(i2c);
248 return -EIO; 271 return -EIO;
249 } 272 }
250 schedule(); 273 schedule();