aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Nilsson <mattias.i.nilsson@stericsson.com>2011-08-12 04:28:43 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-10-24 08:09:19 -0400
commitd6e3002e493e43aa40473935e1803849cf37b6bb (patch)
tree639212ef87a8ddf1babad64a678c502ab0386cb0
parent84165b805972320050892e34fa28d09fe86a25eb (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.c32
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)
1745void prcmu_ac_wake_req(void) 1745void 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
1758retry:
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