Commit 05b1b986 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 47a963f1
Loading
Loading
Loading
Loading
+20 −26
Original line number Diff line number Diff line
@@ -734,19 +734,18 @@ 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");
	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;
	}
		usleep_range(10, 10);
	}

	iss->crashed = 0;
	return 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,30 +762,25 @@ 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");
	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;
	}
		usleep_range(1000, 1500);
	}

	/* 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");
	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;
	}
		usleep_range(1000, 1500);
	}

	return 0;
}
+14 −0
Original line number Diff line number Diff line
@@ -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_ */
+11 −28
Original line number Diff line number Diff line
@@ -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;
	}