aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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) {