diff options
author | Alex Gonzalez <alex.gonzalez@digi.com> | 2012-01-30 14:22:00 +0100 |
---|---|---|
committer | Alex Gonzalez <alex.gonzalez@digi.com> | 2012-01-31 10:08:55 +0100 |
commit | 59ded640f71244dba294741de6d5b9961b235f07 (patch) | |
tree | f742c60d41077b4068dc87f35fd0e4aeb44fb8bf | |
parent | 8a9575276d12a638bdd79ee112bed359e540751e (diff) |
ccxmx53: Assure safe PMIC access before reboot
The patch to the PMIC I2C accesses to make them safe does not completely
guarantee that a reboot can not happen and that interrupts cannot make
unsafe accesses to the PMIC.
This commit assures a last safe PMIC access on reboot.
Signed-off-by: Alex Gonzalez <alex.gonzalez@digi.com>
-rw-r--r-- | arch/arm/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/arm/plat-mxc/system.c | 6 | ||||
-rw-r--r-- | drivers/mfd/da9052-core.c | 20 |
3 files changed, 18 insertions, 15 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index a4a9cc88bec7..5ba5597ab8fc 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -48,6 +48,7 @@ static const char *isa_modes[] = { }; extern void setup_mm_for_reboot(char mode); +extern int da9053_last_access(void); static volatile int hlt_counter; @@ -84,6 +85,12 @@ __setup("hlt", hlt_setup); void arm_machine_restart(char mode, const char *cmd) { + +#if defined(CONFIG_MODULE_CCXMX53) + // Digi: Need to do this before disabling IRQs + da9053_last_access(); +#endif + /* * Clean and disable cache, and turn off interrupts */ diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c index 81c69e49424a..0ebb3fb8b1b8 100644 --- a/arch/arm/plat-mxc/system.c +++ b/arch/arm/plat-mxc/system.c @@ -37,7 +37,7 @@ static void __iomem *wdog_base; extern int dvfs_core_is_active; extern void stop_dvfs(void); -extern void da9053_last_read(void); + #define MX53_WDA_GPIO 9 /* * Reset the system. It is called by machine_restart(). @@ -84,10 +84,6 @@ void arch_reset(char mode, const char *cmd) wcr_enable = (1 << 2); } -#if defined(CONFIG_MODULE_CCXMX53) - da9053_last_read(); -#endif - /* Assert SRS signal */ __raw_writew(wcr_enable, wdog_base); diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 6ba73bb329a9..e24da112e728 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -555,16 +555,14 @@ void da9052_ssc_exit(struct da9052 *da9052) return; } -// A Dialog reported PMIC I2C bug needs to finish with an I2C read -// or the PMIC won't power up again in some cases. -void da9053_last_read( void) +/* A reported bug in Dialog's PMIC I2C access needs to guarantee the last + * PMIC access is to a safe register. */ +int da9053_last_access(void) { struct da9052_ssc_msg msg_test; + int ret = 0; - if (!da9052_data){ - printk("Can't apply da9053 I2C workaround\n"); - return; - } + BUG_ON( !da9052_data ); if( !mutex_is_locked(&da9052_data->ssc_lock) ) da9052_lock(da9052_data); @@ -574,9 +572,13 @@ void da9053_last_read( void) // Dummy read msg_test.addr = DA9052_GPIO0809_REG; msg_test.data = 0; - da9052_data->read(da9052_data, &msg_test); + ret = da9052_data->read(da9052_data, &msg_test); + if( ret < 0 ){ + da9052_unlock(da9052_data); + } // Do not unlock to disallow any other I2C access. + return ret; } void da9053_power_off(void) @@ -611,8 +613,6 @@ void da9053_power_off(void) if (ret != 0) printk(KERN_WARNING "DA9052: %s failure\n", __func__); - da9053_last_read(); - // No more accesses while(1); #else |