return 0;
 }
 
+static int poll_busy(struct sh_mobile_i2c_data *pd)
+{
+       int i;
+
+       for (i = 1000; i; i--) {
+               u_int8_t val = iic_rd(pd, ICSR);
+
+               dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
+
+               /* the interrupt handler may wake us up before the
+                * transfer is finished, so poll the hardware
+                * until we're done.
+                */
+               if (!(val & ICSR_BUSY)) {
+                       /* handle missing acknowledge and arbitration lost */
+                       if ((val | pd->sr) & (ICSR_TACK | ICSR_AL))
+                               return -EIO;
+                       break;
+               }
+
+               udelay(10);
+       }
+
+       if (!i) {
+               dev_err(pd->dev, "Polling timed out\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
 static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
                              struct i2c_msg *msgs,
                              int num)
        struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
        struct i2c_msg  *msg;
        int err = 0;
-       u_int8_t val;
-       int i, k, retry_count;
+       int i, k;
 
        activate_ch(pd);
 
                        break;
                }
 
-               retry_count = 1000;
-again:
-               val = iic_rd(pd, ICSR);
-
-               dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
-
-               /* the interrupt handler may wake us up before the
-                * transfer is finished, so poll the hardware
-                * until we're done.
-                */
-               if (val & ICSR_BUSY) {
-                       udelay(10);
-                       if (retry_count--)
-                               goto again;
-
-                       err = -EIO;
-                       dev_err(pd->dev, "Polling timed out\n");
+               err = poll_busy(pd);
+               if (err < 0)
                        break;
-               }
-
-               /* handle missing acknowledge and arbitration lost */
-               if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) {
-                       err = -EIO;
-                       break;
-               }
        }
 
        deactivate_ch(pd);