in fsi-core.c [285:343]
static int fsi_slave_handle_error(struct fsi_slave *slave, bool write,
uint32_t addr, size_t size)
{
struct fsi_master *master = slave->master;
int rc, link;
uint32_t reg;
uint8_t id, send_delay, echo_delay;
if (discard_errors)
return -1;
link = slave->link;
id = slave->id;
dev_dbg(&slave->dev, "handling error on %s to 0x%08x[%zd]",
write ? "write" : "read", addr, size);
/* try a simple clear of error conditions, which may fail if we've lost
* communication with the slave
*/
rc = fsi_slave_report_and_clear_errors(slave);
if (!rc)
return 0;
/* send a TERM and retry */
if (master->term) {
rc = master->term(master, link, id);
if (!rc) {
rc = fsi_master_read(master, link, id, 0,
®, sizeof(reg));
if (!rc)
rc = fsi_slave_report_and_clear_errors(slave);
if (!rc)
return 0;
}
}
send_delay = slave->t_send_delay;
echo_delay = slave->t_echo_delay;
/* getting serious, reset the slave via BREAK */
rc = fsi_master_break(master, link);
if (rc)
return rc;
slave->t_send_delay = send_delay;
slave->t_echo_delay = echo_delay;
rc = fsi_slave_set_smode(slave);
if (rc)
return rc;
if (master->link_config)
master->link_config(master, link,
slave->t_send_delay,
slave->t_echo_delay);
return fsi_slave_report_and_clear_errors(slave);
}