Commit cd4c1b41 authored by Nicholas Mc Guire's avatar Nicholas Mc Guire Committed by Dmitry Torokhov
Browse files

Input: cyapa - use time based retry loop



Using counter based retry loops for peripherals results in the delay
being significantly overrun during high-load situations where delay
functions tend to be vary imprecise and overrun there timeouts. So
condition the termination on the actual condition of 2s for the
re-calibration to have been successful.

As this is a very long delay there is no advantage in using
high-resolution timers thus switching this to msleep().

Signed-off-by: default avatarNicholas Mc Guire <hofrat@osadl.org>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent de901cc3
Loading
Loading
Loading
Loading
+12 −15
Original line number Diff line number Diff line
@@ -789,7 +789,7 @@ static ssize_t cyapa_gen3_do_calibrate(struct device *dev,
				     const char *buf, size_t count)
{
	struct cyapa *cyapa = dev_get_drvdata(dev);
	int tries;
	unsigned long timeout;
	int ret;

	ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
@@ -812,31 +812,28 @@ static ssize_t cyapa_gen3_do_calibrate(struct device *dev,
		goto out;
	}

	tries = 20;  /* max recalibration timeout 2s. */
	/* max recalibration timeout 2s. */
	timeout = jiffies + 2 * HZ;
	do {
		/*
		 * For this recalibration, the max time will not exceed 2s.
		 * The average time is approximately 500 - 700 ms, and we
		 * will check the status every 100 - 200ms.
		 */
		usleep_range(100000, 200000);

		msleep(100);
		ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS);
		if (ret < 0) {
			dev_err(dev, "Error reading dev status: %d\n",
				ret);
			dev_err(dev, "Error reading dev status: %d\n", ret);
			goto out;
		}
		if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL)
			break;
	} while (--tries);
		if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL) {
			dev_dbg(dev, "Calibration successful.\n");
			goto out;
		}
	} while (time_is_after_jiffies(timeout));

	if (tries == 0) {
	dev_err(dev, "Failed to calibrate. Timeout.\n");
	ret = -ETIMEDOUT;
		goto out;
	}
	dev_dbg(dev, "Calibration successful.\n");

out:
	return ret < 0 ? ret : count;