aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorDomen Puncer <domen.puncer@telargo.com>2007-08-14 12:37:14 -0400
committerJean Delvare <khali@hyperion.delvare>2007-08-14 12:37:14 -0400
commit5af0e07f87e7d9be2a9db514af1e338341240f6d (patch)
tree832666718356a281e52653ab9cd6abc30e082fbe /drivers/i2c
parent432ca994bf7107e88916fd9606ca7402a4571359 (diff)
i2c-mpc: Don't disable I2C module on stop condition
Disabling module on stop doesn't work on some CPUs (ie. mpc8241, as reported by Guennadi Liakhovetski), so remove that. Disable I2C module on errors/interrupts to prevent it from locking up on mpc5200b. Signed-off-by: Domen Puncer <domen.puncer@telargo.com> Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-mpc.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f7a81e999672..d8de4ac88b7d 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -105,6 +105,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
105 schedule(); 105 schedule();
106 if (time_after(jiffies, orig_jiffies + timeout)) { 106 if (time_after(jiffies, orig_jiffies + timeout)) {
107 pr_debug("I2C: timeout\n"); 107 pr_debug("I2C: timeout\n");
108 writeccr(i2c, 0);
108 result = -EIO; 109 result = -EIO;
109 break; 110 break;
110 } 111 }
@@ -116,10 +117,12 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
116 result = wait_event_interruptible_timeout(i2c->queue, 117 result = wait_event_interruptible_timeout(i2c->queue,
117 (i2c->interrupt & CSR_MIF), timeout * HZ); 118 (i2c->interrupt & CSR_MIF), timeout * HZ);
118 119
119 if (unlikely(result < 0)) 120 if (unlikely(result < 0)) {
120 pr_debug("I2C: wait interrupted\n"); 121 pr_debug("I2C: wait interrupted\n");
121 else if (unlikely(!(i2c->interrupt & CSR_MIF))) { 122 writeccr(i2c, 0);
123 } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
122 pr_debug("I2C: wait timeout\n"); 124 pr_debug("I2C: wait timeout\n");
125 writeccr(i2c, 0);
123 result = -ETIMEDOUT; 126 result = -ETIMEDOUT;
124 } 127 }
125 128
@@ -172,7 +175,6 @@ static void mpc_i2c_start(struct mpc_i2c *i2c)
172static void mpc_i2c_stop(struct mpc_i2c *i2c) 175static void mpc_i2c_stop(struct mpc_i2c *i2c)
173{ 176{
174 writeccr(i2c, CCR_MEN); 177 writeccr(i2c, CCR_MEN);
175 writeccr(i2c, 0);
176} 178}
177 179
178static int mpc_write(struct mpc_i2c *i2c, int target, 180static int mpc_write(struct mpc_i2c *i2c, int target,
@@ -261,6 +263,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
261 while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) { 263 while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
262 if (signal_pending(current)) { 264 if (signal_pending(current)) {
263 pr_debug("I2C: Interrupted\n"); 265 pr_debug("I2C: Interrupted\n");
266 writeccr(i2c, 0);
264 return -EINTR; 267 return -EINTR;
265 } 268 }
266 if (time_after(jiffies, orig_jiffies + HZ)) { 269 if (time_after(jiffies, orig_jiffies + HZ)) {