diff options
| author | Eric Tashakkor <w36098@motorola.com> | 2014-07-07 16:13:44 -0500 |
|---|---|---|
| committer | Eric Tashakkor <w36098@motorola.com> | 2014-07-08 10:24:59 -0500 |
| commit | 649585cbe0bc50b36291576e79e90ba3072aa88d (patch) | |
| tree | c0011fed23a139fa162ca0dfa93c3a625ea9ea74 | |
| parent | 4781f57ed379549dbcddbb184297ec390927cfab (diff) | |
| download | olio-linux-3.10-649585cbe0bc50b36291576e79e90ba3072aa88d.tar.xz olio-linux-3.10-649585cbe0bc50b36291576e79e90ba3072aa88d.zip | |
IKXCLOCK-2760 mfd: M4: Add Retries for Initialization
Added M4 reset retries if the M4 I2C fails after booting the IC.
Added a kernel panic if we cannot recover M4.
In some cases, we cannot communicate with M4, which causes the
kernel never to suspend because the RTC is not available.
Change-Id: I7995e4ed27503f67e231eedb8ded8ad2ba105d55
Signed-off-by: Eric Tashakkor <w36098@motorola.com>
| -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", |