aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2010-03-22 03:23:16 -0400
committerBen Dooks <ben-linux@fluff.org>2010-05-19 19:18:58 -0400
commitdd7319a5289deb4e17beb8851d343e7930b32c3b (patch)
tree6d6d7ba0727debac654901402fdcbeaad5f931f2 /drivers/i2c
parent1bc2962e530527de829bf4b1eb99f24dc25d1828 (diff)
i2c-bfin-twi: integrate timeout timer with completion interface
There isn't much point in managing our own custom timeout timer when the completion interface already includes support for it. This makes the resulting code much simpler and robust. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c125
1 files changed, 66 insertions, 59 deletions
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index f1e14dd590c9..441134a1df92 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -25,8 +25,6 @@
25#include <asm/portmux.h> 25#include <asm/portmux.h>
26#include <asm/irq.h> 26#include <asm/irq.h>
27 27
28#define POLL_TIMEOUT (2 * HZ)
29
30/* SMBus mode*/ 28/* SMBus mode*/
31#define TWI_I2C_MODE_STANDARD 1 29#define TWI_I2C_MODE_STANDARD 1
32#define TWI_I2C_MODE_STANDARDSUB 2 30#define TWI_I2C_MODE_STANDARDSUB 2
@@ -44,8 +42,6 @@ struct bfin_twi_iface {
44 int cur_mode; 42 int cur_mode;
45 int manual_stop; 43 int manual_stop;
46 int result; 44 int result;
47 int timeout_count;
48 struct timer_list timeout_timer;
49 struct i2c_adapter adap; 45 struct i2c_adapter adap;
50 struct completion complete; 46 struct completion complete;
51 struct i2c_msg *pmsg; 47 struct i2c_msg *pmsg;
@@ -169,16 +165,13 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
169 write_INT_MASK(iface, 0); 165 write_INT_MASK(iface, 0);
170 write_MASTER_CTL(iface, 0); 166 write_MASTER_CTL(iface, 0);
171 SSYNC(); 167 SSYNC();
172 /* If it is a quick transfer, only address bug no data, 168 /* If it is a quick transfer, only address without data,
173 * not an err, return 1. 169 * not an err, return 1.
170 * If address is acknowledged return 1.
174 */ 171 */
175 if (iface->writeNum == 0 && (mast_stat & BUFRDERR)) 172 if ((iface->writeNum == 0 && (mast_stat & BUFRDERR))
173 || !(mast_stat & ANAK))
176 iface->result = 1; 174 iface->result = 1;
177 /* If address not acknowledged return -1,
178 * else return 0.
179 */
180 else if (!(mast_stat & ANAK))
181 iface->result = 0;
182 } 175 }
183 complete(&iface->complete); 176 complete(&iface->complete);
184 return; 177 return;
@@ -250,9 +243,9 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
250 write_INT_MASK(iface, 0); 243 write_INT_MASK(iface, 0);
251 write_MASTER_CTL(iface, 0); 244 write_MASTER_CTL(iface, 0);
252 SSYNC(); 245 SSYNC();
253 complete(&iface->complete);
254 } 246 }
255 } 247 }
248 complete(&iface->complete);
256} 249}
257 250
258/* Interrupt handler */ 251/* Interrupt handler */
@@ -262,36 +255,15 @@ static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)
262 unsigned long flags; 255 unsigned long flags;
263 256
264 spin_lock_irqsave(&iface->lock, flags); 257 spin_lock_irqsave(&iface->lock, flags);
265 del_timer(&iface->timeout_timer);
266 bfin_twi_handle_interrupt(iface); 258 bfin_twi_handle_interrupt(iface);
267 spin_unlock_irqrestore(&iface->lock, flags); 259 spin_unlock_irqrestore(&iface->lock, flags);
268 return IRQ_HANDLED; 260 return IRQ_HANDLED;
269} 261}
270 262
271static void bfin_twi_timeout(unsigned long data)
272{
273 struct bfin_twi_iface *iface = (struct bfin_twi_iface *)data;
274 unsigned long flags;
275
276 spin_lock_irqsave(&iface->lock, flags);
277 bfin_twi_handle_interrupt(iface);
278 if (iface->result == 0) {
279 iface->timeout_count--;
280 if (iface->timeout_count > 0) {
281 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
282 add_timer(&iface->timeout_timer);
283 } else {
284 iface->result = -1;
285 complete(&iface->complete);
286 }
287 }
288 spin_unlock_irqrestore(&iface->lock, flags);
289}
290
291/* 263/*
292 * Generic i2c master transfer entrypoint 264 * One i2c master transfer
293 */ 265 */
294static int bfin_twi_master_xfer(struct i2c_adapter *adap, 266static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
295 struct i2c_msg *msgs, int num) 267 struct i2c_msg *msgs, int num)
296{ 268{
297 struct bfin_twi_iface *iface = adap->algo_data; 269 struct bfin_twi_iface *iface = adap->algo_data;
@@ -319,7 +291,6 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
319 iface->transPtr = pmsg->buf; 291 iface->transPtr = pmsg->buf;
320 iface->writeNum = iface->readNum = pmsg->len; 292 iface->writeNum = iface->readNum = pmsg->len;
321 iface->result = 0; 293 iface->result = 0;
322 iface->timeout_count = 10;
323 init_completion(&(iface->complete)); 294 init_completion(&(iface->complete));
324 /* Set Transmit device address */ 295 /* Set Transmit device address */
325 write_MASTER_ADDR(iface, pmsg->addr); 296 write_MASTER_ADDR(iface, pmsg->addr);
@@ -358,30 +329,49 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
358 iface->manual_stop = 1; 329 iface->manual_stop = 1;
359 } 330 }
360 331
361 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
362 add_timer(&iface->timeout_timer);
363
364 /* Master enable */ 332 /* Master enable */
365 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN | 333 write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
366 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | 334 ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
367 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); 335 ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
368 SSYNC(); 336 SSYNC();
369 337
370 wait_for_completion(&iface->complete); 338 while (!iface->result) {
371 339 if (!wait_for_completion_timeout(&iface->complete,
372 rc = iface->result; 340 adap->timeout)) {
341 iface->result = -1;
342 dev_err(&adap->dev, "master transfer timeout\n");
343 }
344 }
373 345
374 if (rc == 1) 346 if (iface->result == 1)
375 return num; 347 rc = iface->cur_msg + 1;
376 else 348 else
377 return rc; 349 rc = iface->result;
350
351 return rc;
378} 352}
379 353
380/* 354/*
381 * SMBus type transfer entrypoint 355 * Generic i2c master transfer entrypoint
382 */ 356 */
357static int bfin_twi_master_xfer(struct i2c_adapter *adap,
358 struct i2c_msg *msgs, int num)
359{
360 int i, ret = 0;
383 361
384int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, 362 for (i = 0; i < adap->retries; i++) {
363 ret = bfin_twi_do_master_xfer(adap, msgs, num);
364 if (ret > 0)
365 break;
366 }
367
368 return ret;
369}
370
371/*
372 * One I2C SMBus transfer
373 */
374int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
385 unsigned short flags, char read_write, 375 unsigned short flags, char read_write,
386 u8 command, int size, union i2c_smbus_data *data) 376 u8 command, int size, union i2c_smbus_data *data)
387{ 377{
@@ -469,7 +459,6 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
469 iface->manual_stop = 0; 459 iface->manual_stop = 0;
470 iface->read_write = read_write; 460 iface->read_write = read_write;
471 iface->command = command; 461 iface->command = command;
472 iface->timeout_count = 10;
473 init_completion(&(iface->complete)); 462 init_completion(&(iface->complete));
474 463
475 /* FIFO Initiation. Data in FIFO should be discarded before 464 /* FIFO Initiation. Data in FIFO should be discarded before
@@ -486,9 +475,6 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
486 write_MASTER_ADDR(iface, addr); 475 write_MASTER_ADDR(iface, addr);
487 SSYNC(); 476 SSYNC();
488 477
489 iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
490 add_timer(&iface->timeout_timer);
491
492 switch (iface->cur_mode) { 478 switch (iface->cur_mode) {
493 case TWI_I2C_MODE_STANDARDSUB: 479 case TWI_I2C_MODE_STANDARDSUB:
494 write_XMT_DATA8(iface, iface->command); 480 write_XMT_DATA8(iface, iface->command);
@@ -550,10 +536,8 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
550 else if (iface->readNum > 255) { 536 else if (iface->readNum > 255) {
551 write_MASTER_CTL(iface, 0xff << 6); 537 write_MASTER_CTL(iface, 0xff << 6);
552 iface->manual_stop = 1; 538 iface->manual_stop = 1;
553 } else { 539 } else
554 del_timer(&iface->timeout_timer);
555 break; 540 break;
556 }
557 } 541 }
558 } 542 }
559 write_INT_MASK(iface, MCOMP | MERR | 543 write_INT_MASK(iface, MCOMP | MERR |
@@ -569,7 +553,13 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
569 } 553 }
570 SSYNC(); 554 SSYNC();
571 555
572 wait_for_completion(&iface->complete); 556 while (!iface->result) {
557 if (!wait_for_completion_timeout(&iface->complete,
558 adap->timeout)) {
559 iface->result = -1;
560 dev_err(&adap->dev, "smbus transfer timeout\n");
561 }
562 }
573 563
574 rc = (iface->result >= 0) ? 0 : -1; 564 rc = (iface->result >= 0) ? 0 : -1;
575 565
@@ -577,6 +567,25 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
577} 567}
578 568
579/* 569/*
570 * Generic I2C SMBus transfer entrypoint
571 */
572int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
573 unsigned short flags, char read_write,
574 u8 command, int size, union i2c_smbus_data *data)
575{
576 int i, ret = 0;
577
578 for (i = 0; i < adap->retries; i++) {
579 ret = bfin_twi_do_smbus_xfer(adap, addr, flags,
580 read_write, command, size, data);
581 if (ret == 0)
582 break;
583 }
584
585 return ret;
586}
587
588/*
580 * Return what the adapter supports 589 * Return what the adapter supports
581 */ 590 */
582static u32 bfin_twi_functionality(struct i2c_adapter *adap) 591static u32 bfin_twi_functionality(struct i2c_adapter *adap)
@@ -667,10 +676,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
667 goto out_error_no_irq; 676 goto out_error_no_irq;
668 } 677 }
669 678
670 init_timer(&(iface->timeout_timer));
671 iface->timeout_timer.function = bfin_twi_timeout;
672 iface->timeout_timer.data = (unsigned long)iface;
673
674 p_adap = &iface->adap; 679 p_adap = &iface->adap;
675 p_adap->nr = pdev->id; 680 p_adap->nr = pdev->id;
676 strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name)); 681 strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
@@ -678,6 +683,8 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
678 p_adap->algo_data = iface; 683 p_adap->algo_data = iface;
679 p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; 684 p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
680 p_adap->dev.parent = &pdev->dev; 685 p_adap->dev.parent = &pdev->dev;
686 p_adap->timeout = 5 * HZ;
687 p_adap->retries = 3;
681 688
682 rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi"); 689 rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
683 if (rc) { 690 if (rc) {