@@ -495,15 +495,45 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
495495 return 0 ;
496496}
497497
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+
498529static int sh_mobile_i2c_xfer (struct i2c_adapter * adapter ,
499530 struct i2c_msg * msgs ,
500531 int num )
501532{
502533 struct sh_mobile_i2c_data * pd = i2c_get_adapdata (adapter );
503534 struct i2c_msg * msg ;
504535 int err = 0 ;
505- u_int8_t val ;
506- int i , k , retry_count ;
536+ int i , k ;
507537
508538 activate_ch (pd );
509539
@@ -527,31 +557,9 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
527557 break ;
528558 }
529559
530- retry_count = 1000 ;
531- again :
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" );
560+ err = poll_busy (pd );
561+ if (err < 0 )
547562 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- }
555563 }
556564
557565 deactivate_ch (pd );
0 commit comments