[media] omap4iss: Use a common macro for all sleep-based poll loops
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Fri, 28 Mar 2014 18:27:32 +0000 (15:27 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Fri, 23 May 2014 15:02:57 +0000 (12:02 -0300)
Instead of implementing usleep_range-based poll loops manually (and
slightly differently), create a generic iss_poll_wait_timeout() macro
and use it through the driver.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/staging/media/omap4iss/iss.c
drivers/staging/media/omap4iss/iss.h
drivers/staging/media/omap4iss/iss_csi2.c

index 219519d0f0296b02a3514a4b40f89fcb567fff58..217d719625cec699f60269039699a26575558dd3 100644 (file)
@@ -734,18 +734,17 @@ static int iss_pipeline_is_last(struct media_entity *me)
 
 static int iss_reset(struct iss_device *iss)
 {
-       unsigned long timeout = 0;
+       unsigned int timeout;
 
        iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG,
                    ISS_HL_SYSCONFIG_SOFTRESET);
 
-       while (iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
-              ISS_HL_SYSCONFIG_SOFTRESET) {
-               if (timeout++ > 100) {
-                       dev_alert(iss->dev, "cannot reset ISS\n");
-                       return -ETIMEDOUT;
-               }
-               usleep_range(10, 10);
+       timeout = iss_poll_condition_timeout(
+               !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
+               ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 10);
+       if (timeout) {
+               dev_err(iss->dev, "ISS reset timeout\n");
+               return -ETIMEDOUT;
        }
 
        iss->crashed = 0;
@@ -754,7 +753,7 @@ static int iss_reset(struct iss_device *iss)
 
 static int iss_isp_reset(struct iss_device *iss)
 {
-       unsigned long timeout = 0;
+       unsigned int timeout;
 
        /* Fist, ensure that the ISP is IDLE (no transactions happening) */
        iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
@@ -763,29 +762,24 @@ static int iss_isp_reset(struct iss_device *iss)
 
        iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY);
 
-       for (;;) {
-               if (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
-                   ISP5_CTRL_MSTANDBY_WAIT)
-                       break;
-               if (timeout++ > 1000) {
-                       dev_alert(iss->dev, "cannot set ISP5 to standby\n");
-                       return -ETIMEDOUT;
-               }
-               usleep_range(1000, 1500);
+       timeout = iss_poll_condition_timeout(
+               iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
+               ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500);
+       if (timeout) {
+               dev_err(iss->dev, "ISP5 standby timeout\n");
+               return -ETIMEDOUT;
        }
 
        /* Now finally, do the reset */
        iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
                    ISP5_SYSCONFIG_SOFTRESET);
 
-       timeout = 0;
-       while (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
-              ISP5_SYSCONFIG_SOFTRESET) {
-               if (timeout++ > 1000) {
-                       dev_alert(iss->dev, "cannot reset ISP5\n");
-                       return -ETIMEDOUT;
-               }
-               usleep_range(1000, 1500);
+       timeout = iss_poll_condition_timeout(
+               !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
+               ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500);
+       if (timeout) {
+               dev_err(iss->dev, "ISP5 reset timeout\n");
+               return -ETIMEDOUT;
        }
 
        return 0;
index 346db9233171544cad54338c4f2a5ed03587f986..05cd9bf3b41ff67f26e38b99533238446bde5fe9 100644 (file)
@@ -233,4 +233,18 @@ void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res,
        iss_reg_write(iss, res, offset, (v & ~clr) | set);
 }
 
+#define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival)  \
+({                                                                     \
+       unsigned long __timeout = jiffies + usecs_to_jiffies(timeout);  \
+       unsigned int __min_ival = (min_ival);                           \
+       unsigned int __max_ival = (max_ival);                           \
+       bool __cond;                                                    \
+       while (!(__cond = (cond))) {                                    \
+               if (time_after(jiffies, __timeout))                     \
+                       break;                                          \
+               usleep_range(__min_ival, __max_ival);                   \
+       }                                                               \
+       !__cond;                                                        \
+})
+
 #endif /* _OMAP4_ISS_H_ */
index 61fc350eb251547b98d868e5de20e2ba03be930a..3296115525d7b637a1c746fbc10428ac3751e085 100644 (file)
@@ -487,9 +487,7 @@ static void csi2_irq_status_set(struct iss_csi2_device *csi2, int enable)
  */
 int omap4iss_csi2_reset(struct iss_csi2_device *csi2)
 {
-       u8 soft_reset_retries = 0;
-       u32 reg;
-       int i;
+       unsigned int timeout;
 
        if (!csi2->available)
                return -ENODEV;
@@ -500,37 +498,22 @@ int omap4iss_csi2_reset(struct iss_csi2_device *csi2)
        iss_reg_set(csi2->iss, csi2->regs1, CSI2_SYSCONFIG,
                    CSI2_SYSCONFIG_SOFT_RESET);
 
-       do {
-               reg = iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS)
-                   & CSI2_SYSSTATUS_RESET_DONE;
-               if (reg == CSI2_SYSSTATUS_RESET_DONE)
-                       break;
-               soft_reset_retries++;
-               if (soft_reset_retries < 5)
-                       usleep_range(100, 100);
-       } while (soft_reset_retries < 5);
-
-       if (soft_reset_retries == 5) {
-               dev_err(csi2->iss->dev,
-                       "CSI2: Soft reset try count exceeded!\n");
+       timeout = iss_poll_condition_timeout(
+               iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS) &
+               CSI2_SYSSTATUS_RESET_DONE, 500, 100, 100);
+       if (timeout) {
+               dev_err(csi2->iss->dev, "CSI2: Soft reset timeout!\n");
                return -EBUSY;
        }
 
        iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_CFG,
                    CSI2_COMPLEXIO_CFG_RESET_CTRL);
 
-       i = 100;
-       do {
-               reg = iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1)
-                   & REGISTER1_RESET_DONE_CTRLCLK;
-               if (reg == REGISTER1_RESET_DONE_CTRLCLK)
-                       break;
-               usleep_range(100, 100);
-       } while (--i > 0);
-
-       if (i == 0) {
-               dev_err(csi2->iss->dev,
-                       "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
+       timeout = iss_poll_condition_timeout(
+               iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1) &
+               REGISTER1_RESET_DONE_CTRLCLK, 10000, 100, 100);
+       if (timeout) {
+               dev_err(csi2->iss->dev, "CSI2: CSI2_96M_FCLK reset timeout!\n");
                return -EBUSY;
        }