ltib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Ltib] anti-freeze imx27 pm patch


From: Peter Wurmsdobler
Subject: Re: [Ltib] anti-freeze imx27 pm patch
Date: Fri, 22 Feb 2008 12:32:55 +0000
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Hello Stuart,

thanks for the hint and link.

I downloaded the 2.6.22 kernel's mxc_keyb.c and had a look at the #ifdef CONFIG_PM clause for suspend and resume. I replaced the dummy implementation of these functions in the 2.6.19 shipped with bsp 20070522 with the implementation in the 2.6.22 version, then applied the patch freescale provided (both to the resume/suspend functions and the interrupt handler). The result is attached.

Eager to see it work, I recompiled the kernel, installed, deployed and rebooted. "echo mem > /sys/power/state" suspends the board, and pressing a key on the keypad wakes it up. However, if I press a key on the keypad a short time after the entering the echo command (presumingly while the system is suspending), the board freezes.

I wonder if something similar happens for other drivers, interrupts that is. Imagine, that you suspend the system with the exception of a wifi board that happens to be on the sdio, and while the system is supsending, an IP packet comes in causing an interrupt. The system woudl probably freeze as well?

Regards,
peter


static irqreturn_t mxc_kpp_interrupt(int irq, void *dev_id)
{
        unsigned short reg_val;

        /* Delete the polling timer */
        del_timer(&kpp_dev.poll_timer);
        reg_val = __raw_readw(KPSR);

        /* Check if it is key press interrupt */
        if (reg_val & KBD_STAT_KPKD) {
                /*
                 * Disable key press(KDIE status bit) interrupt
                 */
                reg_val &= ~KBD_STAT_KDIE;
                __raw_writew(reg_val, KPSR);
#ifdef CONFIG_PM
                 } else if (reg_val & KBD_STAT_KPKR) {
                                 reg_val &= ~KBD_STAT_KRIE;
                                 __raw_writew(reg_val, KPSR);
#endif
        } else {
                /* spurious interrupt */
                return IRQ_RETVAL(0);
        }
        /*
         * Check if any keys are pressed, if so start polling.
         */
        mxc_kpp_handle_timer(0);

        return IRQ_RETVAL(1);
}
                        

#ifdef CONFIG_PM
/*!
 * This function puts the Keypad controller in low-power mode/state.
 * If Keypad is enabled as a wake source(i.e. it can resume the system
 * from suspend mode), the Keypad controller doesn't enter low-power state.
 *
 * @param   pdev  the device structure used to give information on Keypad
 *                to suspend
 * @param   state the power state the device is entering
 *
 * @return  The function always returns 0.
 */
static int mxc_kpp_suspend(struct platform_device *pdev, pm_message_t state)
{
                 unsigned short reg_val;

        del_timer(&kpp_dev.poll_timer);

        if (device_may_wakeup(&pdev->dev)) {
                                 reg_val = __raw_readw(KPSR);
                                 if ((reg_val & KBD_STAT_KDIE) == 0) {
                                                 reg_val |= KBD_STAT_KRIE;
                                                 __raw_writew(reg_val, KPSR);
                                 }
                enable_irq_wake(keypad->irq);
        } else {
                disable_irq(keypad->irq);
                key_pad_enabled = 0;
                clk_disable(kpp_clk);
                gpio_keypad_inactive();
        }

        return 0;
}

/*!
 * This function brings the Keypad controller back from low-power state.
 * If Keypad is enabled as a wake source(i.e. it can resume the system
 * from suspend mode), the Keypad controller doesn't enter low-power state.
 *
 * @param   pdev  the device structure used to give information on Keypad
 *                to resume
 *
 * @return  The function always returns 0.
 */
static int mxc_kpp_resume(struct platform_device *pdev)
{
        if (device_may_wakeup(&pdev->dev)) {
                disable_irq_wake(keypad->irq);
        } else {
                gpio_keypad_active();
                clk_enable(kpp_clk);
                key_pad_enabled = 1;
                enable_irq(keypad->irq);
        }

        init_timer(&kpp_dev.poll_timer);

        return 0;
}

#else
#define mxc_kpp_suspend  NULL
#define mxc_kpp_resume   NULL
#endif                          /* CONFIG_PM */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]