mirror of https://gitee.com/openkylin/linux.git
[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>
This commit is contained in:
parent
47a963f102
commit
05b1b986b5
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue