diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-mpc.c')
-rw-r--r-- | drivers/i2c/busses/i2c-mpc.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index c6b6898592b1..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 | */ | ||
82 | static 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 | |||
77 | static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) | 96 | static 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) | |||
153 | static void mpc_i2c_stop(struct mpc_i2c *i2c) | 172 | static 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 | ||
158 | static int mpc_write(struct mpc_i2c *i2c, int target, | 178 | static 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(); |
@@ -327,9 +350,10 @@ static int fsl_i2c_probe(struct platform_device *pdev) | |||
327 | platform_set_drvdata(pdev, i2c); | 350 | platform_set_drvdata(pdev, i2c); |
328 | 351 | ||
329 | i2c->adap = mpc_ops; | 352 | i2c->adap = mpc_ops; |
353 | i2c->adap.nr = pdev->id; | ||
330 | i2c_set_adapdata(&i2c->adap, i2c); | 354 | i2c_set_adapdata(&i2c->adap, i2c); |
331 | i2c->adap.dev.parent = &pdev->dev; | 355 | i2c->adap.dev.parent = &pdev->dev; |
332 | if ((result = i2c_add_adapter(&i2c->adap)) < 0) { | 356 | if ((result = i2c_add_numbered_adapter(&i2c->adap)) < 0) { |
333 | printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); | 357 | printk(KERN_ERR "i2c-mpc - failed to add adapter\n"); |
334 | goto fail_add; | 358 | goto fail_add; |
335 | } | 359 | } |