uru4000: fix race condition on waiting power up irq
It can come before we finish reading the status register on some cases. Arm the irq handler early, and fix the state machine to handle early irq properly. https://bugs.freedesktop.org/show_bug.cgi?id=57834
This commit is contained in:
parent
a5ec0b30e1
commit
7e1646c382
1 changed files with 20 additions and 11 deletions
|
@ -994,16 +994,19 @@ static void init_scanpwr_irq_cb(struct fp_img_dev *dev, int status,
|
||||||
uint16_t type, void *user_data)
|
uint16_t type, void *user_data)
|
||||||
{
|
{
|
||||||
struct fpi_ssm *ssm = user_data;
|
struct fpi_ssm *ssm = user_data;
|
||||||
|
struct uru4k_dev *urudev = dev->priv;
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
fpi_ssm_mark_aborted(ssm, status);
|
fpi_ssm_mark_aborted(ssm, status);
|
||||||
else if (type != IRQDATA_SCANPWR_ON)
|
else if (type != IRQDATA_SCANPWR_ON)
|
||||||
fp_dbg("ignoring interrupt");
|
fp_dbg("ignoring interrupt");
|
||||||
else if (ssm->cur_state != INIT_AWAIT_SCAN_POWER)
|
else if (ssm->cur_state != INIT_AWAIT_SCAN_POWER) {
|
||||||
fp_err("ignoring scanpwr interrupt due to being in wrong state %d",
|
fp_dbg("early scanpwr interrupt");
|
||||||
ssm->cur_state);
|
urudev->scanpwr_irq_timeouts = -1;
|
||||||
else
|
} else {
|
||||||
|
fp_dbg("late scanpwr interrupt");
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_scanpwr_timeout(void *user_data)
|
static void init_scanpwr_timeout(void *user_data)
|
||||||
|
@ -1053,14 +1056,21 @@ static void init_run_state(struct fpi_ssm *ssm)
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
case INIT_POWERUP: ;
|
case INIT_POWERUP: ;
|
||||||
|
if (!IRQ_HANDLER_IS_RUNNING(urudev)) {
|
||||||
|
fpi_ssm_mark_aborted(ssm, -EIO);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
urudev->irq_cb_data = ssm;
|
||||||
|
urudev->irq_cb = init_scanpwr_irq_cb;
|
||||||
|
|
||||||
struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state,
|
struct fpi_ssm *powerupsm = fpi_ssm_new(dev->dev, powerup_run_state,
|
||||||
POWERUP_NUM_STATES);
|
POWERUP_NUM_STATES);
|
||||||
powerupsm->priv = dev;
|
powerupsm->priv = dev;
|
||||||
fpi_ssm_start_subsm(ssm, powerupsm);
|
fpi_ssm_start_subsm(ssm, powerupsm);
|
||||||
break;
|
break;
|
||||||
case INIT_AWAIT_SCAN_POWER:
|
case INIT_AWAIT_SCAN_POWER:
|
||||||
if (!IRQ_HANDLER_IS_RUNNING(urudev)) {
|
if (urudev->scanpwr_irq_timeouts < 0) {
|
||||||
fpi_ssm_mark_aborted(ssm, -EIO);
|
fpi_ssm_next_state(ssm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1073,13 +1083,12 @@ static void init_run_state(struct fpi_ssm *ssm)
|
||||||
fpi_ssm_mark_aborted(ssm, -ETIME);
|
fpi_ssm_mark_aborted(ssm, -ETIME);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
urudev->irq_cb_data = ssm;
|
|
||||||
urudev->irq_cb = init_scanpwr_irq_cb;
|
|
||||||
break;
|
break;
|
||||||
case INIT_DONE:
|
case INIT_DONE:
|
||||||
fpi_timeout_cancel(urudev->scanpwr_irq_timeout);
|
if (urudev->scanpwr_irq_timeout) {
|
||||||
urudev->scanpwr_irq_timeout = NULL;
|
fpi_timeout_cancel(urudev->scanpwr_irq_timeout);
|
||||||
|
urudev->scanpwr_irq_timeout = NULL;
|
||||||
|
}
|
||||||
urudev->irq_cb_data = NULL;
|
urudev->irq_cb_data = NULL;
|
||||||
urudev->irq_cb = NULL;
|
urudev->irq_cb = NULL;
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
|
Loading…
Reference in a new issue