[PORT FROM R2] mid_pmu: check completion flag after wait_for_completion timeout
authorIllyas Mansoor <illyas.mansoor@intel.com>
Wed, 25 Jan 2012 14:11:03 +0000 (19:41 +0530)
committerbuildbot <buildbot@intel.com>
Fri, 17 Feb 2012 23:42:50 +0000 (15:42 -0800)
BZ: 21156 23293

In S3 flow pci_pmu_set_power_state waits on d0ix command
completion interrupt, the interrupt is received but the
completion signal is not delivered since the threads are
frozen.

Hence pci_pmu_set_power_state timesout after 5secs and
calls BUG()

Fixed this by checking the completion flag that gets cleared
when d0ix completion interrupt is received.

<0>[ 7959.846890] ------------[ cut here ]------------
<2>[ 7959.846903] Kernel BUG at c1852942 [verbose debug info unavailable]
<0>[ 7959.846917] invalid opcode: 0000 [#1] PREEMPT SMP
<0>[ 7959.846933] last sysfs file: /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
<4>[ 7959.846944] Modules linked in: ipv6 atomisp lm3554 mt9m114 mt9e013 videobuf_vmalloc videobuf_dma_contig videobuf_core wl12xx_sdio wl12xx mac80211 cfg80211 compat btwilink st_drv
<4>[ 7959.846995]
<4>[ 7959.847010] Pid: 19, comm: suspend Not tainted 2.6.35.3-84696-gf486d97 #1 /
<4>[ 7959.847024] EIP: 0060:[<c1852942>] EFLAGS: 00010246 CPU: 1
<4>[ 7959.847046] EIP is at pmu_pci_set_power_state+0x322/0x6e0
<4>[ 7959.847059] EAX: 00000000 EBX: 0000001a ECX: c186dd96 EDX: 00000000
<4>[ 7959.847071] ESI: 00000000 EDI: 00000001 EBP: f78e3d74 ESP: f78e3cd0
<4>[ 7959.847083] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
<0>[ 7959.847097] Process suspend (pid: 19, ti=f78e2000 task=f7899b20 task.ti=f78e2000)
<0>[ 7959.847106] Stack:
<4>[ 7959.847114] c1bcee0b f78e3cf8 c14b502a 00000002 f78e3d4e c1b77d00 f78e3dcc c1bcf200
<4>[ 7959.847142] <0> 00000002 c1bcee0b f78e3d9c f78e3d48 00000008 00000000 00000000 0000011e
<4>[ 7959.847172] <0> 00018601 f78e3d38 c14b502a 00000008 f78e3d02 f78e3d44 c2603920 ffffffff
<0>[ 7959.847204] Call Trace:
<4>[ 7959.847227] [<c14b502a>] ? put_dec+0x2a/0xa0
<4>[ 7959.847249] [<c14b502a>] ? put_dec+0x2a/0xa0
<4>[ 7959.847276] [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7959.847295] [<c14cee6e>] ? pci_platform_power_transition+0x3e/0xa0
<4>[ 7959.847314] [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
<4>[ 7959.847333] [<c14cf5df>] ? pci_set_power_state+0x3f/0x2c0
<4>[ 7959.847353] [<c14ced7c>] ? pci_update_current_state+0x3c/0x50
<4>[ 7959.847372] [<c14d180e>] ? pci_pm_runtime_resume+0x5e/0xa0
<4>[ 7959.847390] [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7959.847406] [<c14d17b0>] ? pci_pm_runtime_resume+0x0/0xa0
<4>[ 7959.847425] [<c1554d7b>] ? rpm_callback+0x3b/0x70
<4>[ 7959.847442] [<c155577c>] ? rpm_resume+0x37c/0x5c0
<4>[ 7959.847460] [<c124923b>] ? release_console_sem+0x37b/0x3c0
<4>[ 7959.847482] [<c1238593>] ? add_preempt_count+0xb3/0xf0
<4>[ 7959.847500] [<c1556609>] ? __pm_runtime_resume+0x49/0xc0
<4>[ 7959.847519] [<c14d1b71>] ? pci_pm_prepare+0x21/0x60
<4>[ 7959.847536] [<c1553947>] ? dpm_suspend_start+0x137/0x7d0
<4>[ 7959.847554] [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7959.847572] [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
<4>[ 7959.847590] [<c126f548>] ? up+0x28/0x40
<4>[ 7959.847610] [<c1288f13>] ? suspend_devices_and_enter+0x73/0x1d0
<4>[ 7959.847628] [<c1289196>] ? enter_state+0x126/0x1e0
<4>[ 7959.847646] [<c1289277>] ? pm_suspend+0x27/0x70
<4>[ 7959.847662] [<c128acba>] ? suspend+0x8a/0x160
<4>[ 7959.847678] [<c186e445>] ? schedule+0x545/0x9e0
<4>[ 7959.847701] [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7959.847720] [<c1265833>] ? worker_thread+0x123/0x2c0
<4>[ 7959.847736] [<c186e445>] ? schedule+0x545/0x9e0
<4>[ 7959.847755] [<c128ac30>] ? suspend+0x0/0x160
<4>[ 7959.847772] [<c12690d0>] ? autoremove_wake_function+0x0/0x50
<4>[ 7959.847790] [<c1265710>] ? worker_thread+0x0/0x2c0
<4>[ 7959.847807] [<c1268c34>] ? kthread+0x74/0x80
<4>[ 7959.847825] [<c1268bc0>] ? kthread+0x0/0x80
<4>[ 7959.847843] [<c120357a>] ? kernel_thread_helper+0x6/0x10
<0>[ 7959.847852] Code: ff 33 00 00 e8 40 b3 9d ff 85 c0 89 c6 0f 85 aa 02 00 00 a1 c0 de b8 c1 ba f4 01 00 00 05 1c 19 00 00 e8 82 b5 01 00 85 c0 75 04 <0f> 0b eb fe a1 c0 de b8 c1 c7 80 14 0a 00 00 00 00 00 00 83 7c
<0>[ 7959.848033] EIP: [<c1852942>] pmu_pci_set_power_state+0x322/0x6e0 SS:ESP 0068:f78e3cd0
<4>[ 7959.848064] ---[ end trace f7884632b6bd02b8 ]---

Change-Id: I230427819b80875cc7da106f3339546c2a1ff2cb
Orig-Change-Id: I6774d29f74a66d413c2e8cb0514bcc6468ccdd20
Signed-off-by: Illyas Mansoor <illyas.mansoor@intel.com>
Reviewed-on: http://android.intel.com:8080/35158
Reviewed-by: Martin, LoicX <loicx.martin@intel.com>
Reviewed-by: Gross, Mark <mark.gross@intel.com>
Tested-by: Martin, LoicX <loicx.martin@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
arch/x86/platform/intel-mid/mfld-pmu.c
arch/x86/platform/intel-mid/mfld-pmu.h

index 502b9f9..ba8515f 100644 (file)
@@ -1186,7 +1186,7 @@ static irqreturn_t pmu_sc_irq(int irq, void *ignored)
         * release scu_ready_sem
         */
        if (mid_pmu_cxt->interactive_cmd_sent) {
-               mid_pmu_cxt->interactive_cmd_sent = 0;
+               mid_pmu_cxt->interactive_cmd_sent = false;
 
                /* unblock set_power_state() */
                complete(&mid_pmu_cxt->set_mode_complete);
@@ -1744,7 +1744,7 @@ int __ref pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
                BUG();
        }
 
-       mid_pmu_cxt->interactive_cmd_sent = 1;
+       mid_pmu_cxt->interactive_cmd_sent = true;
 
        status =
                pmu_pci_to_indexes(pdev, &i, &pmu_num,
@@ -1824,8 +1824,19 @@ int __ref pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
                 *
                 */
                if (!wait_for_completion_timeout(
-                           &mid_pmu_cxt->set_mode_complete, 5 * HZ))
-                       BUG();
+                           &mid_pmu_cxt->set_mode_complete, 5 * HZ)) {
+                       /* It is possible that in S3 we may miss
+                        * completion signal, so check if interactive_cmd_sent
+                        * cleared indicating completion interrupt received.
+                        */
+                       if (!mid_pmu_cxt->interactive_cmd_sent) {
+                               WARN(1,
+                               "%s: completion timed out.\n", __func__);
+                               init_completion
+                                       (&mid_pmu_cxt->set_mode_complete);
+                       } else
+                               BUG();
+               }
 
                pmu_set_s0ix_possible(state);
 
@@ -1835,8 +1846,9 @@ int __ref pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t state)
        }
 
 unlock:
-       mid_pmu_cxt->interactive_cmd_sent = 0;
+       mid_pmu_cxt->interactive_cmd_sent = false;
        up(&mid_pmu_cxt->scu_ready_sem);
+
        return status;
 }
 
@@ -2463,10 +2475,10 @@ static int pmu_init(void)
        update_all_lss_states(&pmu_config);
 
        /* send a interactive command to fw */
-       mid_pmu_cxt->interactive_cmd_sent = 1;
+       mid_pmu_cxt->interactive_cmd_sent = true;
        status = _pmu_issue_command(&pmu_config, SET_MODE, 1, PMU_NUM_2);
        if (status != PMU_SUCCESS) {
-               mid_pmu_cxt->interactive_cmd_sent = 0;
+               mid_pmu_cxt->interactive_cmd_sent = false;
                dev_dbg(&mid_pmu_cxt->pmu_dev->dev,\
                 "Failure from pmu mode change to interactive."
                " = %d\n", status);
index 849170d..c27b463 100644 (file)
@@ -793,6 +793,7 @@ struct mid_pmu_stats {
 struct mid_pmu_dev {
        bool suspend_started;
        bool shutdown_started;
+       bool interactive_cmd_sent;
 
        u32 apm_base;
        u32 ospm_base;
@@ -808,7 +809,6 @@ struct mid_pmu_dev {
        int camera_off;
        int display_off;
        int s0ix_possible;
-       int interactive_cmd_sent;
        int s0ix_entered;
 
        enum sys_state  pmu_current_state;