diff options
author | Mattias Nilsson <mattias.i.nilsson@stericsson.com> | 2011-08-12 04:28:43 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-10-24 08:09:19 -0400 |
commit | d6e3002e493e43aa40473935e1803849cf37b6bb (patch) | |
tree | 639212ef87a8ddf1babad64a678c502ab0386cb0 | |
parent | 84165b805972320050892e34fa28d09fe86a25eb (diff) |
mfd: db8500-prcmu tweak for modem wakeup
This is a tweak for the case where the modem goes to sleep while
emitting the AC_WAKE_ACK anyway. Also print the modem errors as
critical, since they jeopardize the entire platform when they
occur.
Signed-off-by: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/db8500-prcmu.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 95498f80c905..cb58e44b1e45 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -1745,6 +1745,7 @@ int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | |||
1745 | void prcmu_ac_wake_req(void) | 1745 | void prcmu_ac_wake_req(void) |
1746 | { | 1746 | { |
1747 | u32 val; | 1747 | u32 val; |
1748 | u32 status; | ||
1748 | 1749 | ||
1749 | mutex_lock(&mb0_transfer.ac_wake_lock); | 1750 | mutex_lock(&mb0_transfer.ac_wake_lock); |
1750 | 1751 | ||
@@ -1754,11 +1755,34 @@ void prcmu_ac_wake_req(void) | |||
1754 | 1755 | ||
1755 | atomic_set(&ac_wake_req_state, 1); | 1756 | atomic_set(&ac_wake_req_state, 1); |
1756 | 1757 | ||
1758 | retry: | ||
1757 | writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ); | 1759 | writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), PRCM_HOSTACCESS_REQ); |
1758 | 1760 | ||
1759 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | 1761 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, |
1760 | msecs_to_jiffies(20000))) { | 1762 | msecs_to_jiffies(5000))) { |
1761 | pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", | 1763 | panic("prcmu: %s timed out (5 s) waiting for a reply.\n", |
1764 | __func__); | ||
1765 | goto unlock_and_return; | ||
1766 | } | ||
1767 | |||
1768 | /* | ||
1769 | * The modem can generate an AC_WAKE_ACK, and then still go to sleep. | ||
1770 | * As a workaround, we wait, and then check that the modem is indeed | ||
1771 | * awake (in terms of the value of the PRCM_MOD_AWAKE_STATUS | ||
1772 | * register, which may not be the whole truth). | ||
1773 | */ | ||
1774 | udelay(400); | ||
1775 | status = (readl(PRCM_MOD_AWAKE_STATUS) & BITS(0, 2)); | ||
1776 | if (status != (PRCM_MOD_AWAKE_STATUS_PRCM_MOD_AAPD_AWAKE | | ||
1777 | PRCM_MOD_AWAKE_STATUS_PRCM_MOD_COREPD_AWAKE)) { | ||
1778 | pr_err("prcmu: %s received ack, but modem not awake (0x%X).\n", | ||
1779 | __func__, status); | ||
1780 | udelay(1200); | ||
1781 | writel(val, PRCM_HOSTACCESS_REQ); | ||
1782 | if (wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | ||
1783 | msecs_to_jiffies(5000))) | ||
1784 | goto retry; | ||
1785 | panic("prcmu: %s timed out (5 s) waiting for AC_SLEEP_ACK.\n", | ||
1762 | __func__); | 1786 | __func__); |
1763 | } | 1787 | } |
1764 | 1788 | ||
@@ -1783,8 +1807,8 @@ void prcmu_ac_sleep_req() | |||
1783 | PRCM_HOSTACCESS_REQ); | 1807 | PRCM_HOSTACCESS_REQ); |
1784 | 1808 | ||
1785 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | 1809 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, |
1786 | msecs_to_jiffies(20000))) { | 1810 | msecs_to_jiffies(5000))) { |
1787 | pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", | 1811 | panic("prcmu: %s timed out (5 s) waiting for a reply.\n", |
1788 | __func__); | 1812 | __func__); |
1789 | } | 1813 | } |
1790 | 1814 | ||