From 3e4e9a48c8057d76bc5d45a2337c0406c2a77b90 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Mon, 19 Mar 2012 20:15:53 -0500 Subject: mfd : ux500 - check if the other core is in WFI This patch allows to check if the other core is in WFI mode. It is the last check the idle routine has to do before entering into the retention state. Signed-off-by: Daniel Lezcano --- drivers/mfd/db8500-prcmu.c | 12 ++++++++++++ drivers/mfd/dbx500-prcmu-regs.h | 2 ++ include/linux/mfd/db8500-prcmu.h | 1 + include/linux/mfd/dbx500-prcmu.h | 8 ++++++++ 4 files changed, 23 insertions(+) diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index dd3fb0568d2..e1ad6c79ccc 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -869,6 +869,18 @@ bool db8500_prcmu_pending_irq(void) return false; } +/* + * This function checks if the specified cpu is in in WFI. It's usage + * makes sense only if the gic is decoupled with the db8500_prcmu_gic_decouple + * function. Of course passing smp_processor_id() to this function will + * always return false... + */ +bool db8500_prcmu_is_cpu_in_wfi(int cpu) +{ + return readl(PRCM_ARM_WFI_STANDBY) & cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : + PRCM_ARM_WFI_STANDBY_WFI0; +} + /* * This function copies the gic SPI settings to the prcmu in order to * monitor them and abort/finish the retention/off sequence or state. diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h index ec22e9f15d3..78bb628068f 100644 --- a/drivers/mfd/dbx500-prcmu-regs.h +++ b/drivers/mfd/dbx500-prcmu-regs.h @@ -79,6 +79,8 @@ /* ARM WFI Standby signal register */ #define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) +#define PRCM_ARM_WFI_STANDBY_WFI0 0x08 +#define PRCM_ARM_WFI_STANDBY_WFI1 0x10 #define PRCM_IOCR (_PRCMU_BASE + 0x310) #define PRCM_IOCR_IOFORCE 0x1 diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index 026d93e8cef..488cd401d10 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -541,6 +541,7 @@ int db8500_prcmu_gic_recouple(void); int db8500_prcmu_copy_gic_settings(void); bool db8500_prcmu_gic_pending_irq(void); bool db8500_prcmu_pending_irq(void); +bool db8500_prcmu_is_cpu_in_wfi(int cpu); void db8500_prcmu_enable_wakeups(u32 wakeups); int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state); int db8500_prcmu_request_clock(u8 clock, bool enable); diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index 69848f8e652..b74a474f97f 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -269,6 +269,14 @@ static inline bool prcmu_pending_irq(void) return db8500_prcmu_pending_irq(); } +static inline bool prcmu_is_cpu_in_wfi(int cpu) +{ + if (cpu_is_u5500()) + return -EINVAL; + else + return db8500_prcmu_is_cpu_in_wfi(cpu); +} + static inline int prcmu_copy_gic_settings(void) { if (machine_is_u5500()) -- cgit v1.2.3