aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2014-03-28 14:27:32 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-23 11:02:57 -0400
commit05b1b986b540fe48f98a09b087b054754d67ef41 (patch)
treedcd07a9d12a358ec4982235f5d5b2cf5d248c754 /drivers/staging
parent47a963f1025690824a3f00e27d1d161a0f01cd88 (diff)
[media] omap4iss: Use a common macro for all sleep-based poll loops
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>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/omap4iss/iss.c46
-rw-r--r--drivers/staging/media/omap4iss/iss.h14
-rw-r--r--drivers/staging/media/omap4iss/iss_csi2.c39
3 files changed, 45 insertions, 54 deletions
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 219519d0f029..217d719625ce 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -734,18 +734,17 @@ static int iss_pipeline_is_last(struct media_entity *me)
734 734
735static int iss_reset(struct iss_device *iss) 735static int iss_reset(struct iss_device *iss)
736{ 736{
737 unsigned long timeout = 0; 737 unsigned int timeout;
738 738
739 iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG, 739 iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG,
740 ISS_HL_SYSCONFIG_SOFTRESET); 740 ISS_HL_SYSCONFIG_SOFTRESET);
741 741
742 while (iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) & 742 timeout = iss_poll_condition_timeout(
743 ISS_HL_SYSCONFIG_SOFTRESET) { 743 !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
744 if (timeout++ > 100) { 744 ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 10);
745 dev_alert(iss->dev, "cannot reset ISS\n"); 745 if (timeout) {
746 return -ETIMEDOUT; 746 dev_err(iss->dev, "ISS reset timeout\n");
747 } 747 return -ETIMEDOUT;
748 usleep_range(10, 10);
749 } 748 }
750 749
751 iss->crashed = 0; 750 iss->crashed = 0;
@@ -754,7 +753,7 @@ static int iss_reset(struct iss_device *iss)
754 753
755static int iss_isp_reset(struct iss_device *iss) 754static int iss_isp_reset(struct iss_device *iss)
756{ 755{
757 unsigned long timeout = 0; 756 unsigned int timeout;
758 757
759 /* Fist, ensure that the ISP is IDLE (no transactions happening) */ 758 /* Fist, ensure that the ISP is IDLE (no transactions happening) */
760 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, 759 iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
@@ -763,29 +762,24 @@ static int iss_isp_reset(struct iss_device *iss)
763 762
764 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY); 763 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY);
765 764
766 for (;;) { 765 timeout = iss_poll_condition_timeout(
767 if (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) & 766 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
768 ISP5_CTRL_MSTANDBY_WAIT) 767 ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500);
769 break; 768 if (timeout) {
770 if (timeout++ > 1000) { 769 dev_err(iss->dev, "ISP5 standby timeout\n");
771 dev_alert(iss->dev, "cannot set ISP5 to standby\n"); 770 return -ETIMEDOUT;
772 return -ETIMEDOUT;
773 }
774 usleep_range(1000, 1500);
775 } 771 }
776 772
777 /* Now finally, do the reset */ 773 /* Now finally, do the reset */
778 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG, 774 iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
779 ISP5_SYSCONFIG_SOFTRESET); 775 ISP5_SYSCONFIG_SOFTRESET);
780 776
781 timeout = 0; 777 timeout = iss_poll_condition_timeout(
782 while (iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) & 778 !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
783 ISP5_SYSCONFIG_SOFTRESET) { 779 ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500);
784 if (timeout++ > 1000) { 780 if (timeout) {
785 dev_alert(iss->dev, "cannot reset ISP5\n"); 781 dev_err(iss->dev, "ISP5 reset timeout\n");
786 return -ETIMEDOUT; 782 return -ETIMEDOUT;
787 }
788 usleep_range(1000, 1500);
789 } 783 }
790 784
791 return 0; 785 return 0;
diff --git a/drivers/staging/media/omap4iss/iss.h b/drivers/staging/media/omap4iss/iss.h
index 346db9233171..05cd9bf3b41f 100644
--- a/drivers/staging/media/omap4iss/iss.h
+++ b/drivers/staging/media/omap4iss/iss.h
@@ -233,4 +233,18 @@ void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res,
233 iss_reg_write(iss, res, offset, (v & ~clr) | set); 233 iss_reg_write(iss, res, offset, (v & ~clr) | set);
234} 234}
235 235
236#define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival) \
237({ \
238 unsigned long __timeout = jiffies + usecs_to_jiffies(timeout); \
239 unsigned int __min_ival = (min_ival); \
240 unsigned int __max_ival = (max_ival); \
241 bool __cond; \
242 while (!(__cond = (cond))) { \
243 if (time_after(jiffies, __timeout)) \
244 break; \
245 usleep_range(__min_ival, __max_ival); \
246 } \
247 !__cond; \
248})
249
236#endif /* _OMAP4_ISS_H_ */ 250#endif /* _OMAP4_ISS_H_ */
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index 61fc350eb251..3296115525d7 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -487,9 +487,7 @@ static void csi2_irq_status_set(struct iss_csi2_device *csi2, int enable)
487 */ 487 */
488int omap4iss_csi2_reset(struct iss_csi2_device *csi2) 488int omap4iss_csi2_reset(struct iss_csi2_device *csi2)
489{ 489{
490 u8 soft_reset_retries = 0; 490 unsigned int timeout;
491 u32 reg;
492 int i;
493 491
494 if (!csi2->available) 492 if (!csi2->available)
495 return -ENODEV; 493 return -ENODEV;
@@ -500,37 +498,22 @@ int omap4iss_csi2_reset(struct iss_csi2_device *csi2)
500 iss_reg_set(csi2->iss, csi2->regs1, CSI2_SYSCONFIG, 498 iss_reg_set(csi2->iss, csi2->regs1, CSI2_SYSCONFIG,
501 CSI2_SYSCONFIG_SOFT_RESET); 499 CSI2_SYSCONFIG_SOFT_RESET);
502 500
503 do { 501 timeout = iss_poll_condition_timeout(
504 reg = iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS) 502 iss_reg_read(csi2->iss, csi2->regs1, CSI2_SYSSTATUS) &
505 & CSI2_SYSSTATUS_RESET_DONE; 503 CSI2_SYSSTATUS_RESET_DONE, 500, 100, 100);
506 if (reg == CSI2_SYSSTATUS_RESET_DONE) 504 if (timeout) {
507 break; 505 dev_err(csi2->iss->dev, "CSI2: Soft reset timeout!\n");
508 soft_reset_retries++;
509 if (soft_reset_retries < 5)
510 usleep_range(100, 100);
511 } while (soft_reset_retries < 5);
512
513 if (soft_reset_retries == 5) {
514 dev_err(csi2->iss->dev,
515 "CSI2: Soft reset try count exceeded!\n");
516 return -EBUSY; 506 return -EBUSY;
517 } 507 }
518 508
519 iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_CFG, 509 iss_reg_set(csi2->iss, csi2->regs1, CSI2_COMPLEXIO_CFG,
520 CSI2_COMPLEXIO_CFG_RESET_CTRL); 510 CSI2_COMPLEXIO_CFG_RESET_CTRL);
521 511
522 i = 100; 512 timeout = iss_poll_condition_timeout(
523 do { 513 iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1) &
524 reg = iss_reg_read(csi2->iss, csi2->phy->phy_regs, REGISTER1) 514 REGISTER1_RESET_DONE_CTRLCLK, 10000, 100, 100);
525 & REGISTER1_RESET_DONE_CTRLCLK; 515 if (timeout) {
526 if (reg == REGISTER1_RESET_DONE_CTRLCLK) 516 dev_err(csi2->iss->dev, "CSI2: CSI2_96M_FCLK reset timeout!\n");
527 break;
528 usleep_range(100, 100);
529 } while (--i > 0);
530
531 if (i == 0) {
532 dev_err(csi2->iss->dev,
533 "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
534 return -EBUSY; 517 return -EBUSY;
535 } 518 }
536 519