summaryrefslogtreecommitdiff
path: root/drivers/mfd/m4sensorhub-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/m4sensorhub-core.c')
-rw-r--r--drivers/mfd/m4sensorhub-core.c57
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",