Commit b04e68d1 authored by Richard Fitzgerald's avatar Richard Fitzgerald Committed by Lee Jones

mfd: madera: Don't use regmap_read_poll_timeout to poll for BOOT_DONE

While polling for BOOT_DONE the chip could NAK a read because it is
still booting, which would terminate the regmap_read_poll_timeout()
with an error.

Instead implement a polling loop that ignores read errors so we
always poll until the chip signals boot or the loop times out.
Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 6b269a41
...@@ -132,32 +132,39 @@ const char *madera_name_from_type(enum madera_type type) ...@@ -132,32 +132,39 @@ const char *madera_name_from_type(enum madera_type type)
} }
EXPORT_SYMBOL_GPL(madera_name_from_type); EXPORT_SYMBOL_GPL(madera_name_from_type);
#define MADERA_BOOT_POLL_MAX_INTERVAL_US 5000 #define MADERA_BOOT_POLL_INTERVAL_USEC 5000
#define MADERA_BOOT_POLL_TIMEOUT_US 25000 #define MADERA_BOOT_POLL_TIMEOUT_USEC 25000
static int madera_wait_for_boot(struct madera *madera) static int madera_wait_for_boot(struct madera *madera)
{ {
ktime_t timeout;
unsigned int val; unsigned int val;
int ret; int ret = 0;
/* /*
* We can't use an interrupt as we need to runtime resume to do so, * We can't use an interrupt as we need to runtime resume to do so,
* so we poll the status bit. This won't race with the interrupt * so we poll the status bit. This won't race with the interrupt
* handler because it will be blocked on runtime resume. * handler because it will be blocked on runtime resume.
* The chip could NAK a read request while it is booting so ignore
* errors from regmap_read.
*/ */
ret = regmap_read_poll_timeout(madera->regmap, timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
MADERA_IRQ1_RAW_STATUS_1, regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
val, while (!(val & MADERA_BOOT_DONE_STS1) &&
(val & MADERA_BOOT_DONE_STS1), !ktime_after(ktime_get(), timeout)) {
MADERA_BOOT_POLL_MAX_INTERVAL_US, usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
MADERA_BOOT_POLL_TIMEOUT_US); MADERA_BOOT_POLL_INTERVAL_USEC);
regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
if (ret) };
dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret);
if (!(val & MADERA_BOOT_DONE_STS1)) {
dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
ret = -ETIMEDOUT;
}
/* /*
* BOOT_DONE defaults to unmasked on boot so we must ack it. * BOOT_DONE defaults to unmasked on boot so we must ack it.
* Do this unconditionally to avoid interrupt storms. * Do this even after a timeout to avoid interrupt storms.
*/ */
regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1, regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
MADERA_BOOT_DONE_EINT1); MADERA_BOOT_DONE_EINT1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment