diff options
Diffstat (limited to 'drivers/mfd/m4sensorhub-core.c')
| -rw-r--r-- | drivers/mfd/m4sensorhub-core.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/drivers/mfd/m4sensorhub-core.c b/drivers/mfd/m4sensorhub-core.c index a1ae596bf4c..9053bfbba45 100644 --- a/drivers/mfd/m4sensorhub-core.c +++ b/drivers/mfd/m4sensorhub-core.c @@ -459,6 +459,8 @@ static void m4sensorhub_initialize(const struct firmware *firmware, int err = 0; struct init_call *inc, *prev; struct init_calldata arg; + int i; + uint16_t version; if (firmware == NULL) { KDEBUG(M4SH_ERROR, "%s: No firmware data recieved\n", @@ -467,27 +469,46 @@ static void m4sensorhub_initialize(const struct firmware *firmware, } /* initiate m4 firmware download */ - KDEBUG(M4SH_CRITICAL, "%s: Starting M4 download %s = %d\n", - __func__, "with force_upgrade", force_upgrade); - if (m4sensorhub_misc_data.i2c_client->addr == 0x39) - firmware_download_status = m4sensorhub_401_load_firmware( - &m4sensorhub_misc_data, - force_upgrade, - firmware); - else - firmware_download_status = m4sensorhub_load_firmware( - &m4sensorhub_misc_data, - force_upgrade, - firmware); + for (i = 0; i < 3; i++) { + KDEBUG(M4SH_CRITICAL, "%s: Starting M4 download %s = %d\n", + __func__, "with force_upgrade", force_upgrade); + if (m4sensorhub_misc_data.i2c_client->addr == 0x39) + firmware_download_status = + m4sensorhub_401_load_firmware( + &m4sensorhub_misc_data, + force_upgrade, firmware); + else + firmware_download_status = m4sensorhub_load_firmware( + &m4sensorhub_misc_data, + force_upgrade, firmware); - if (firmware_download_status < 0) { - KDEBUG(M4SH_ERROR, "%s: Failed to load M4 firmware = %d\n", - __func__, err); - /* Since firmware download failed, put m4 back into boot mode*/ - m4sensorhub_hw_reset(&m4sensorhub_misc_data); - return; + if (firmware_download_status < 0) { + KDEBUG(M4SH_ERROR, "%s: %s = %d\n", + __func__, "Failed to load M4 firmware", err); + /* Since download failed, return M4 to boot mode */ + m4sensorhub_hw_reset(&m4sensorhub_misc_data); + return; + } + + /* Wait progressively longer for M4 to become ready */ + if (i > 0) + msleep(i * 100); + + /* Read M4 register to test if M4 is ready */ + err = m4sensorhub_reg_read(&m4sensorhub_misc_data, + M4SH_REG_GENERAL_VERSION, (char *)&version); + if (err < 0) + KDEBUG(M4SH_ERROR, "%s: %s (retries=%d).\n", __func__, + "Failed initial I2C read", i); + else /* No failure */ + break; } + /* Check if we actually finished the loop */ + if (i >= 3) + panic("%s: M4 has failed--forcing panic...\n", + __func__); + err = m4sensorhub_irq_init(&m4sensorhub_misc_data); if (err < 0) { KDEBUG(M4SH_ERROR, "%s: m4sensorhub irq init failed (err=%d)\n", |