6410 休眠喚醒實現小結

來源:互聯網
上載者:User

 前一段時間調試了6410的休眠和喚醒,一直沒有時間自己總結一下,下面把具體的實現貼出來,供大家參考,又不對的地方,請幫忙糾正,謝謝。
1,在/driver/char中修改Makefile,添加以下語句:

obj-$(CONFIG_APM_EMULATION)+= apm-emulation.o

2,在/driver/char中修改Kconfig,添加以下語句:

config APM_EMULATION
bool "S3C64XX Power Management support"
help
Power Management of Linux Arm for S3C64XX support

3,進入menuconfig介面,執行以下操作:

選中選項“Power management options --->”  

內部選為:“[*] Power Management support  
  [ ] Power Management Debug Support
  [*] Suspend to RAM and standby 
  <*> Advanced Power Management Emulation ”

4,修改檔案/driver/char/apm-emulation.c,將函數apm_ioctl改為以下代碼,實現rtc定時喚醒功能:

/*
 * apm_ioctl - handle APM ioctl
 *
 * APM_IOC_SUSPEND
 * This IOCTL is overloaded, and performs two functions. It is used to:
 * - initiate a suspend
 * - acknowledge a suspend read from /dev/apm_bios.
 * Only when everyone who has opened /dev/apm_bios with write permission
 * has acknowledge does the actual suspend happen.
 */
static int
apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
{
struct apm_user *as = filp->private_data;
int err = -EINVAL;

if (!as->suser || !as->writer)
return -EPERM;

switch (cmd) {
case APM_IOC_SUSPEND:
mutex_lock(&state_lock);

as->suspend_result = -EINTR;

/* added by byc for test */
printk(KERN_INFO "/nioctl of suspend is entered!/n");
printk(KERN_INFO "/nsuspend_state is %d %s/n", as->suspend_state, as->suspend_state);
/* end */

switch (as->suspend_state) {
case SUSPEND_READ:
/*
* If we read a suspend command from /dev/apm_bios,
* then the corresponding APM_IOC_SUSPEND ioctl is
* interpreted as an acknowledge.
*/
as->suspend_state = SUSPEND_ACKED;
atomic_dec(&suspend_acks_pending);
mutex_unlock(&state_lock);

/*
* suspend_acks_pending changed, the notifier needs to
* be woken up for this
*/
wake_up(&apm_suspend_waitqueue);

/*
* Wait for the suspend/resume to complete. If there
* are pending acknowledges, we wait here for them.
*/
freezer_do_not_count();

wait_event(apm_suspend_waitqueue,
as->suspend_state == SUSPEND_DONE);

/*
* Since we are waiting until the suspend is done, the
* try_to_freeze() in freezer_count() will not trigger
*/
freezer_count();
break;
case SUSPEND_ACKTO:
as->suspend_result = -ETIMEDOUT;
mutex_unlock(&state_lock);
break;
default:
as->suspend_state = SUSPEND_WAIT;
mutex_unlock(&state_lock);

/*
* Otherwise it is a request to suspend the system.
* Just invoke pm_suspend(), we'll handle it from
* there via the notifier.
*/
/* added by byc for test */
static void __iomem *base_addr_pwrcfg;
static void __iomem *base_addr_rtccon;

printk(KERN_INFO "/nsystem is suspended/n");

base_addr_pwrcfg = ioremap(0x7E00F804, 0x04);
base_addr_rtccon = ioremap(0x7E005050, 0x04);

printk(KERN_INFO " pwrcfg value is: %x/n", readl(base_addr_pwrcfg));
printk(KERN_INFO " rtccon value is: %x/n", readl(base_addr_rtccon));

writel(readl(base_addr_pwrcfg) & 0xfffffbff, base_addr_pwrcfg);
writel(readl(base_addr_rtccon) | 0x47, base_addr_rtccon);

printk(KERN_INFO " pwrcfg value is: %x/n", readl(base_addr_pwrcfg));
printk(KERN_INFO " rtccon value is: %x/n", readl(base_addr_rtccon));
/* end */

as->suspend_result = pm_suspend(PM_SUSPEND_MEM);
}
/* added by byc for test */
//platform_driver_register(&sdhci_s3c_driver);
/* end */
mutex_lock(&state_lock);
err = as->suspend_result;
as->suspend_state = SUSPEND_NONE;
mutex_unlock(&state_lock);
break;
}

return err;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.