diff options
author | Arun Murthy <arun.murthy@stericsson.com> | 2012-05-21 04:58:21 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-07-08 18:16:10 -0400 |
commit | 5261e101198e7ef31a60d3aa97815a49c8b8fa20 (patch) | |
tree | 53e8157eaceb4c6448b8ca15c73368e5a04185d3 | |
parent | 19d57ed5a308472a02e773f33c03ad4cb2ec6a9d (diff) |
mfd: Update db8500-prmcu hostport_access enable
Force the Modem wakeup by asserting the CaWakeReq signal before the
hostaccess_req/ack ping-pong sequence. The Awake_req signal is de-asserted
asserted at the same time than the hostaccess_req. Return error on failure
case so that the client using this can take appropiate steps.
Signed-off-by: Arun Murthy <arun.murthy@stericsson.com>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/db8500-prcmu.c | 45 | ||||
-rw-r--r-- | drivers/mfd/dbx500-prcmu-regs.h | 1 | ||||
-rw-r--r-- | include/linux/mfd/db8500-prcmu.h | 7 | ||||
-rw-r--r-- | include/linux/mfd/dbx500-prcmu.h | 7 |
4 files changed, 30 insertions, 30 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index bf5a054a2b91..f4adcabb2a51 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -2269,10 +2269,10 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
2269 | /** | 2269 | /** |
2270 | * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem | 2270 | * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem |
2271 | */ | 2271 | */ |
2272 | void prcmu_ac_wake_req(void) | 2272 | int prcmu_ac_wake_req(void) |
2273 | { | 2273 | { |
2274 | u32 val; | 2274 | u32 val; |
2275 | u32 status; | 2275 | int ret = 0; |
2276 | 2276 | ||
2277 | mutex_lock(&mb0_transfer.ac_wake_lock); | 2277 | mutex_lock(&mb0_transfer.ac_wake_lock); |
2278 | 2278 | ||
@@ -2282,39 +2282,32 @@ void prcmu_ac_wake_req(void) | |||
2282 | 2282 | ||
2283 | atomic_set(&ac_wake_req_state, 1); | 2283 | atomic_set(&ac_wake_req_state, 1); |
2284 | 2284 | ||
2285 | retry: | 2285 | /* |
2286 | writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ); | 2286 | * Force Modem Wake-up before hostaccess_req ping-pong. |
2287 | * It prevents Modem to enter in Sleep while acking the hostaccess | ||
2288 | * request. The 31us delay has been calculated by HWI. | ||
2289 | */ | ||
2290 | val |= PRCM_HOSTACCESS_REQ_WAKE_REQ; | ||
2291 | writel(val, PRCM_HOSTACCESS_REQ); | ||
2292 | |||
2293 | udelay(31); | ||
2294 | |||
2295 | val |= PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ; | ||
2296 | writel(val, PRCM_HOSTACCESS_REQ); | ||
2287 | 2297 | ||
2288 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | 2298 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, |
2289 | msecs_to_jiffies(5000))) { | 2299 | msecs_to_jiffies(5000))) { |
2300 | #if defined(CONFIG_DBX500_PRCMU_DEBUG) | ||
2301 | db8500_prcmu_debug_dump(__func__, true, true); | ||
2302 | #endif | ||
2290 | pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", | 2303 | pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", |
2291 | __func__); | 2304 | __func__); |
2292 | goto unlock_and_return; | 2305 | ret = -EFAULT; |
2293 | } | ||
2294 | |||
2295 | /* | ||
2296 | * The modem can generate an AC_WAKE_ACK, and then still go to sleep. | ||
2297 | * As a workaround, we wait, and then check that the modem is indeed | ||
2298 | * awake (in terms of the value of the PRCM_MOD_AWAKE_STATUS | ||
2299 | * register, which may not be the whole truth). | ||
2300 | */ | ||
2301 | udelay(400); | ||
2302 | status = (readl(PRCM_MOD_AWAKE_STATUS) & BITS(0, 2)); | ||
2303 | if (status != (PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE | | ||
2304 | PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE)) { | ||
2305 | pr_err("prcmu: %s received ack, but modem not awake (0x%X).\n", | ||
2306 | __func__, status); | ||
2307 | udelay(1200); | ||
2308 | writel(val, PRCM_HOSTACCESS_REQ); | ||
2309 | if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | ||
2310 | msecs_to_jiffies(5000))) | ||
2311 | goto retry; | ||
2312 | pr_crit("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n", | ||
2313 | __func__); | ||
2314 | } | 2306 | } |
2315 | 2307 | ||
2316 | unlock_and_return: | 2308 | unlock_and_return: |
2317 | mutex_unlock(&mb0_transfer.ac_wake_lock); | 2309 | mutex_unlock(&mb0_transfer.ac_wake_lock); |
2310 | return ret; | ||
2318 | } | 2311 | } |
2319 | 2312 | ||
2320 | /** | 2313 | /** |
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h index 3a0bf91d7780..23108a6e3167 100644 --- a/drivers/mfd/dbx500-prcmu-regs.h +++ b/drivers/mfd/dbx500-prcmu-regs.h | |||
@@ -106,6 +106,7 @@ | |||
106 | 106 | ||
107 | #define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) | 107 | #define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) |
108 | #define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1 | 108 | #define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ 0x1 |
109 | #define PRCM_HOSTACCESS_REQ_WAKE_REQ BIT(16) | ||
109 | #define ARM_WAKEUP_MODEM 0x1 | 110 | #define ARM_WAKEUP_MODEM 0x1 |
110 | 111 | ||
111 | #define PRCM_ARM_IT1_CLR (_PRCMU_BASE + 0x48C) | 112 | #define PRCM_ARM_IT1_CLR (_PRCMU_BASE + 0x48C) |
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index b3a43b1263fe..b82f6ee66a0b 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h | |||
@@ -530,7 +530,7 @@ int db8500_prcmu_stop_temp_sense(void); | |||
530 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | 530 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); |
531 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | 531 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); |
532 | 532 | ||
533 | void prcmu_ac_wake_req(void); | 533 | int prcmu_ac_wake_req(void); |
534 | void prcmu_ac_sleep_req(void); | 534 | void prcmu_ac_sleep_req(void); |
535 | void db8500_prcmu_modem_reset(void); | 535 | void db8500_prcmu_modem_reset(void); |
536 | 536 | ||
@@ -680,7 +680,10 @@ static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
680 | return -ENOSYS; | 680 | return -ENOSYS; |
681 | } | 681 | } |
682 | 682 | ||
683 | static inline void prcmu_ac_wake_req(void) {} | 683 | static inline int prcmu_ac_wake_req(void) |
684 | { | ||
685 | return 0; | ||
686 | } | ||
684 | 687 | ||
685 | static inline void prcmu_ac_sleep_req(void) {} | 688 | static inline void prcmu_ac_sleep_req(void) {} |
686 | 689 | ||
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index 5a13f93d8f1c..5b90e94399e1 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h | |||
@@ -345,7 +345,7 @@ static inline u16 prcmu_get_reset_code(void) | |||
345 | return db8500_prcmu_get_reset_code(); | 345 | return db8500_prcmu_get_reset_code(); |
346 | } | 346 | } |
347 | 347 | ||
348 | void prcmu_ac_wake_req(void); | 348 | int prcmu_ac_wake_req(void); |
349 | void prcmu_ac_sleep_req(void); | 349 | void prcmu_ac_sleep_req(void); |
350 | static inline void prcmu_modem_reset(void) | 350 | static inline void prcmu_modem_reset(void) |
351 | { | 351 | { |
@@ -533,7 +533,10 @@ static inline u16 prcmu_get_reset_code(void) | |||
533 | return 0; | 533 | return 0; |
534 | } | 534 | } |
535 | 535 | ||
536 | static inline void prcmu_ac_wake_req(void) {} | 536 | static inline int prcmu_ac_wake_req(void) |
537 | { | ||
538 | return 0; | ||
539 | } | ||
537 | 540 | ||
538 | static inline void prcmu_ac_sleep_req(void) {} | 541 | static inline void prcmu_ac_sleep_req(void) {} |
539 | 542 | ||