diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2013-01-17 04:45:56 -0500 |
---|---|---|
committer | Wolfram Sang <wolfram@the-dreams.de> | 2013-02-10 13:55:23 -0500 |
commit | 4b3823184f80c1d3950e5e63e2303653f2decdf8 (patch) | |
tree | 6d447ba361ee19b65ce6e24dcc1123dac8a4220b /drivers/i2c | |
parent | 5687265b3127024089dc0b25956772405b9f53d3 (diff) |
i2c: sh_mobile: eliminate an open-coded "goto" loop
Eliminate an open-coded "goto" loop by introducing a function.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Wolfram Sang <wolfram@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index daaf0ebe8177..2767ea8e98a7 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -495,6 +495,37 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg) | |||
495 | return 0; | 495 | return 0; |
496 | } | 496 | } |
497 | 497 | ||
498 | static int poll_busy(struct sh_mobile_i2c_data *pd) | ||
499 | { | ||
500 | int i; | ||
501 | |||
502 | for (i = 1000; i; i--) { | ||
503 | u_int8_t val = iic_rd(pd, ICSR); | ||
504 | |||
505 | dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); | ||
506 | |||
507 | /* the interrupt handler may wake us up before the | ||
508 | * transfer is finished, so poll the hardware | ||
509 | * until we're done. | ||
510 | */ | ||
511 | if (!(val & ICSR_BUSY)) { | ||
512 | /* handle missing acknowledge and arbitration lost */ | ||
513 | if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) | ||
514 | return -EIO; | ||
515 | break; | ||
516 | } | ||
517 | |||
518 | udelay(10); | ||
519 | } | ||
520 | |||
521 | if (!i) { | ||
522 | dev_err(pd->dev, "Polling timed out\n"); | ||
523 | return -ETIMEDOUT; | ||
524 | } | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
498 | static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, | 529 | static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, |
499 | struct i2c_msg *msgs, | 530 | struct i2c_msg *msgs, |
500 | int num) | 531 | int num) |
@@ -502,8 +533,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, | |||
502 | struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); | 533 | struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); |
503 | struct i2c_msg *msg; | 534 | struct i2c_msg *msg; |
504 | int err = 0; | 535 | int err = 0; |
505 | u_int8_t val; | 536 | int i, k; |
506 | int i, k, retry_count; | ||
507 | 537 | ||
508 | activate_ch(pd); | 538 | activate_ch(pd); |
509 | 539 | ||
@@ -527,31 +557,9 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, | |||
527 | break; | 557 | break; |
528 | } | 558 | } |
529 | 559 | ||
530 | retry_count = 1000; | 560 | err = poll_busy(pd); |
531 | again: | 561 | if (err < 0) |
532 | val = iic_rd(pd, ICSR); | ||
533 | |||
534 | dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); | ||
535 | |||
536 | /* the interrupt handler may wake us up before the | ||
537 | * transfer is finished, so poll the hardware | ||
538 | * until we're done. | ||
539 | */ | ||
540 | if (val & ICSR_BUSY) { | ||
541 | udelay(10); | ||
542 | if (retry_count--) | ||
543 | goto again; | ||
544 | |||
545 | err = -EIO; | ||
546 | dev_err(pd->dev, "Polling timed out\n"); | ||
547 | break; | 562 | break; |
548 | } | ||
549 | |||
550 | /* handle missing acknowledge and arbitration lost */ | ||
551 | if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) { | ||
552 | err = -EIO; | ||
553 | break; | ||
554 | } | ||
555 | } | 563 | } |
556 | 564 | ||
557 | deactivate_ch(pd); | 565 | deactivate_ch(pd); |