]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - sitara-epos/sitara-epos-kernel.git/commitdiff
ARM: OMAP: AM33XX: PM: Wait for M3 state machine reset in suspend failure
authorVaibhav Bedia <vaibhav.bedia@ti.com>
Mon, 12 Mar 2012 14:10:41 +0000 (19:40 +0530)
committerVaibhav Bedia <vaibhav.bedia@ti.com>
Mon, 12 Mar 2012 14:29:41 +0000 (19:59 +0530)
In case something goes wrong in the suspend sequence, A8 sends a command
to M3 to reset its state machine. After this A8 continues with its
resume process and eventually enters idle loop. The command for reset
depends on the mailbox interrupt being generated and M3 responding it.
However, in case A8 enters the idle loop before M3 has responded to the
command for reset, M3 might cut the power to A8 thereby causing a "hang"
in the A8 world. Although the chances of the above happening is very
rare, it can and should be fixed. This is currently done by waiting for
the command posted to M3 to complete and then continuing with the resume
process.

Note: This also enforced a minor change in the M3 code and it is
recommended that the firmware binary is updated to the latest one
available on Arago.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
arch/arm/mach-omap2/pm33xx.c

index e3f01c0a067e3e07afbd77b468d95a83ff3f46ea..1649b5f00abc500a47effc9e9eb9c81767411045 100644 (file)
@@ -255,6 +255,8 @@ static void am33xx_m3_state_machine_reset(void)
        ret = omap_mbox_msg_send(m3_mbox, 0xABCDABCD);
        if (!ret) {
                pr_debug("Message sent for resetting M3 state machine\n");
+               if (!wait_for_completion_timeout(&a8_m3_sync, msecs_to_jiffies(5000)))
+                       pr_err("A8<->CM3 sync failure\n");
        } else {
                pr_debug("Could not reset M3 state machine!!!\n");
                m3_state = M3_STATE_UNKNOWN;
@@ -320,7 +322,7 @@ static int am33xx_verify_lp_state(void)
                ret = -1;
                goto clear_old_status;
        } else {
-               pr_info("Status = %0x\n", status);
+               pr_info("Something went wrong :(\nStatus = %0x\n", status);
                ret = -1;
        }
 
@@ -359,6 +361,7 @@ static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
                omap_mbox_msg_rx_flush(m3_mbox);
                if (m3_mbox->ops->ack_irq)
                        m3_mbox->ops->ack_irq(m3_mbox, IRQ_RX);
+               complete(&a8_m3_sync);
        } else if (m3_state == M3_STATE_MSG_FOR_LP) {
                /* Read back the MBOX and disable the interrupt to M3 since we are going down */
                omap_mbox_msg_rx_flush(m3_mbox);