in masters/omap_hdq.c [238:306]
static int omap_hdq_break(struct hdq_data *hdq_data)
{
int ret = 0;
u8 tmp_status;
ret = mutex_lock_interruptible(&hdq_data->hdq_mutex);
if (ret < 0) {
dev_dbg(hdq_data->dev, "Could not acquire mutex\n");
ret = -EINTR;
goto rtn;
}
if (hdq_data->hdq_irqstatus)
dev_err(hdq_data->dev, "break irqstatus not cleared (%02x)\n",
hdq_data->hdq_irqstatus);
/* set the INIT and GO bit */
hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS,
OMAP_HDQ_CTRL_STATUS_INITIALIZATION | OMAP_HDQ_CTRL_STATUS_GO,
OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_INITIALIZATION |
OMAP_HDQ_CTRL_STATUS_GO);
/* wait for the TIMEOUT bit */
ret = wait_event_timeout(hdq_wait_queue,
(hdq_data->hdq_irqstatus & OMAP_HDQ_INT_STATUS_TIMEOUT),
OMAP_HDQ_TIMEOUT);
tmp_status = hdq_reset_irqstatus(hdq_data, OMAP_HDQ_INT_STATUS_TIMEOUT);
if (ret == 0) {
dev_dbg(hdq_data->dev, "break wait elapsed\n");
ret = -EINTR;
goto out;
}
/* check irqstatus */
if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) {
dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x\n",
tmp_status);
ret = -ETIMEDOUT;
goto out;
}
/*
* check for the presence detect bit to get
* set to show that the slave is responding
*/
if (!(hdq_reg_in(hdq_data, OMAP_HDQ_CTRL_STATUS) &
OMAP_HDQ_CTRL_STATUS_PRESENCE)) {
dev_dbg(hdq_data->dev, "Presence bit not set\n");
ret = -ETIMEDOUT;
goto out;
}
/*
* wait for both INIT and GO bits rerurn to zero.
* zero wait time expected for interrupt mode.
*/
ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS,
OMAP_HDQ_CTRL_STATUS_INITIALIZATION |
OMAP_HDQ_CTRL_STATUS_GO, OMAP_HDQ_FLAG_CLEAR,
&tmp_status);
if (ret)
dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits"
" return to zero, %x\n", tmp_status);
out:
mutex_unlock(&hdq_data->hdq_mutex);
rtn:
return ret;
}