⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm.c

📁 Linux 2.4 内核下动态电源管理(Dynamic Power Management)的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/arch/mips/jz47xx/common/pm.c * * Jz47xx Power Management Routines * * Copyright 2005 Ingenic Semiconductor *      Wei Jianli <jlwei@ingenic.cn> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include <linux/config.h>#include <linux/init.h>#include <linux/pm.h>#include <linux/slab.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/proc_fs.h>   #include <linux/sysctl.h>#include <linux/errno.h>#include <linux/pm.h>#include <linux/time.h>#include <asm/cacheops.h>#include <asm/jzsoc.h>extern void jz_cpu_suspend(void);extern void jz_cpu_resume(void);static void board_pm_setup(void);#define SAVE(x,s)	sleep_save[SLEEP_SAVE_##x] = REG##s(x)#define RESTORE(x,s)	REG##s(x) = sleep_save[SLEEP_SAVE_##x]/* * List of global jz47xx peripheral registers to preserve. * More ones like core register and general purpose register values  * are preserved with the stack pointer in sleep.S. */enum {	SLEEP_SAVE_START = 0,	/* OST */	SLEEP_SAVE_OST_TER,	SLEEP_SAVE_OST_TCSR0, SLEEP_SAVE_OST_TCSR1, SLEEP_SAVE_OST_TCSR2,	SLEEP_SAVE_OST_TRDR0, SLEEP_SAVE_OST_TRDR1, SLEEP_SAVE_OST_TRDR2,	SLEEP_SAVE_OST_TCNT0, SLEEP_SAVE_OST_TCNT1, SLEEP_SAVE_OST_TCNT2,	/* HARB */	SLEEP_SAVE_HARB_HAPOR, SLEEP_SAVE_HARB_HMCTR, SLEEP_SAVE_HARB_HMLTR,	/* GPIO */	SLEEP_SAVE_GPIO_GPDR0, SLEEP_SAVE_GPIO_GPDR1, SLEEP_SAVE_GPIO_GPDR2, SLEEP_SAVE_GPIO_GPDR3,	SLEEP_SAVE_GPIO_GPDIR0, SLEEP_SAVE_GPIO_GPDIR1, SLEEP_SAVE_GPIO_GPDIR2,	SLEEP_SAVE_GPIO_GPDIR3,	SLEEP_SAVE_GPIO_GPODR0, SLEEP_SAVE_GPIO_GPODR1, SLEEP_SAVE_GPIO_GPODR2,	SLEEP_SAVE_GPIO_GPODR3,	SLEEP_SAVE_GPIO_GPPUR0, SLEEP_SAVE_GPIO_GPPUR1, SLEEP_SAVE_GPIO_GPPUR2, SLEEP_SAVE_GPIO_GPPUR3,	SLEEP_SAVE_GPIO_GPALR0, SLEEP_SAVE_GPIO_GPALR1, SLEEP_SAVE_GPIO_GPALR2,	SLEEP_SAVE_GPIO_GPALR3,	SLEEP_SAVE_GPIO_GPAUR0, SLEEP_SAVE_GPIO_GPAUR1, SLEEP_SAVE_GPIO_GPAUR2,	SLEEP_SAVE_GPIO_GPAUR3,	SLEEP_SAVE_GPIO_GPIDLR0, SLEEP_SAVE_GPIO_GPIDLR1, SLEEP_SAVE_GPIO_GPIDLR2, SLEEP_SAVE_GPIO_GPIDLR3,	SLEEP_SAVE_GPIO_GPIDUR0, SLEEP_SAVE_GPIO_GPIDUR1, SLEEP_SAVE_GPIO_GPIDUR2, SLEEP_SAVE_GPIO_GPIDUR3,	SLEEP_SAVE_GPIO_GPIER0, SLEEP_SAVE_GPIO_GPIER1, SLEEP_SAVE_GPIO_GPIER2,	SLEEP_SAVE_GPIO_GPIER3,	SLEEP_SAVE_GPIO_GPIMR0, SLEEP_SAVE_GPIO_GPIMR1, SLEEP_SAVE_GPIO_GPIMR2, SLEEP_SAVE_GPIO_GPIMR3,	SLEEP_SAVE_GPIO_GPFR0, SLEEP_SAVE_GPIO_GPFR1, SLEEP_SAVE_GPIO_GPFR2, SLEEP_SAVE_GPIO_GPFR3,	/* UART(0-3) */	SLEEP_SAVE_UART0_IER, SLEEP_SAVE_UART0_LCR, SLEEP_SAVE_UART0_MCR, SLEEP_SAVE_UART0_SPR, SLEEP_SAVE_UART0_DLLR, SLEEP_SAVE_UART0_DLHR,	SLEEP_SAVE_UART1_IER, SLEEP_SAVE_UART1_LCR, SLEEP_SAVE_UART1_MCR, SLEEP_SAVE_UART1_SPR, SLEEP_SAVE_UART1_DLLR, SLEEP_SAVE_UART1_DLHR,	SLEEP_SAVE_UART2_IER, SLEEP_SAVE_UART2_LCR, SLEEP_SAVE_UART2_MCR, SLEEP_SAVE_UART2_SPR, SLEEP_SAVE_UART2_DLLR, SLEEP_SAVE_UART2_DLHR,	SLEEP_SAVE_UART3_IER, SLEEP_SAVE_UART3_LCR, SLEEP_SAVE_UART3_MCR, SLEEP_SAVE_UART3_SPR, SLEEP_SAVE_UART3_DLLR, SLEEP_SAVE_UART3_DLHR,	/* DMAC */	SLEEP_SAVE_DMAC_DMACR,	SLEEP_SAVE_DMAC_DSAR0, SLEEP_SAVE_DMAC_DSAR1, SLEEP_SAVE_DMAC_DSAR2, SLEEP_SAVE_DMAC_DSAR3, SLEEP_SAVE_DMAC_DSAR4, SLEEP_SAVE_DMAC_DSAR5, SLEEP_SAVE_DMAC_DSAR6, SLEEP_SAVE_DMAC_DSAR7,	SLEEP_SAVE_DMAC_DDAR0, SLEEP_SAVE_DMAC_DDAR1, SLEEP_SAVE_DMAC_DDAR2, SLEEP_SAVE_DMAC_DDAR3, SLEEP_SAVE_DMAC_DDAR4, SLEEP_SAVE_DMAC_DDAR5, SLEEP_SAVE_DMAC_DDAR6, SLEEP_SAVE_DMAC_DDAR7,	SLEEP_SAVE_DMAC_DTCR0, SLEEP_SAVE_DMAC_DTCR1, SLEEP_SAVE_DMAC_DTCR2, SLEEP_SAVE_DMAC_DTCR3, SLEEP_SAVE_DMAC_DTCR4, SLEEP_SAVE_DMAC_DTCR5, SLEEP_SAVE_DMAC_DTCR6, SLEEP_SAVE_DMAC_DTCR7,	SLEEP_SAVE_DMAC_DRSR0, SLEEP_SAVE_DMAC_DRSR1, SLEEP_SAVE_DMAC_DRSR2, SLEEP_SAVE_DMAC_DRSR3, SLEEP_SAVE_DMAC_DRSR4, SLEEP_SAVE_DMAC_DRSR5, SLEEP_SAVE_DMAC_DRSR6, SLEEP_SAVE_DMAC_DRSR7,	SLEEP_SAVE_DMAC_DCCSR0, SLEEP_SAVE_DMAC_DCCSR1, SLEEP_SAVE_DMAC_DCCSR2, SLEEP_SAVE_DMAC_DCCSR3, SLEEP_SAVE_DMAC_DCCSR4, SLEEP_SAVE_DMAC_DCCSR5, SLEEP_SAVE_DMAC_DCCSR6, SLEEP_SAVE_DMAC_DCCSR7,	/* INTC */	SLEEP_SAVE_INTC_IMR, 	/* Checksum */	SLEEP_SAVE_CKSUM,	SLEEP_SAVE_SIZE};static int jz_pm_do_suspend(void){	unsigned long sleep_save[SLEEP_SAVE_SIZE];	unsigned long delta;	unsigned long checksum = 0;	int i;	REG_CPM_OCR |= CPM_OCR_SUSPEND_PHY0; /* suspend USB PHY 0 */	REG_CPM_OCR |= CPM_OCR_SUSPEND_PHY1; /* suspend USB PHY 1 */	REG_CPM_OCR |= CPM_OCR_EXT_RTC_CLK;  /* select the external RTC clock (32.768KHz) */	/* Preserve current time */	delta = xtime.tv_sec - REG_RTC_RSR;	/*	 * Temporary solution.  This won't be necessary once	 * we move jz support into the serial driver.	 * Save the on-chip UART	 */	SAVE(UART0_LCR, 8); SAVE(UART0_MCR, 8); SAVE(UART0_SPR, 8);	REG8(UART0_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */	SAVE(UART0_DLLR, 8); SAVE(UART0_DLHR, 8);	REG8(UART0_LCR) &= ~UARTLCR_DLAB; /* Access to IER */	SAVE(UART0_IER, 8);	SAVE(UART1_LCR, 8); SAVE(UART1_MCR, 8); SAVE(UART1_SPR, 8);	REG8(UART1_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */	SAVE(UART1_DLLR, 8); SAVE(UART1_DLHR, 8);	REG8(UART1_LCR) &= ~UARTLCR_DLAB; /* Access to IER */	SAVE(UART1_IER, 8);	SAVE(UART2_LCR, 8); SAVE(UART2_MCR, 8); SAVE(UART2_SPR, 8);	REG8(UART2_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */	SAVE(UART2_DLLR, 8); SAVE(UART2_DLHR, 8);	REG8(UART2_LCR) &= ~UARTLCR_DLAB; /* Access to IER */	SAVE(UART2_IER, 8);	SAVE(UART3_LCR, 8); SAVE(UART3_MCR, 8); SAVE(UART3_SPR, 8);	REG8(UART3_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */	SAVE(UART3_DLLR, 8); SAVE(UART3_DLHR, 8);	REG8(UART3_LCR) &= ~UARTLCR_DLAB; /* Access to IER */	SAVE(UART3_IER, 8);	/* Save vital registers */	SAVE(OST_TER, 8);	SAVE(OST_TCSR0, 16); SAVE(OST_TCSR1, 16); SAVE(OST_TCSR2, 16);	SAVE(OST_TRDR0, 32); SAVE(OST_TRDR1, 32); SAVE(OST_TRDR2, 32);	SAVE(OST_TCNT0, 32); SAVE(OST_TCNT1, 32); SAVE(OST_TCNT2, 32);	SAVE(HARB_HAPOR, 32); SAVE(HARB_HMCTR, 32); SAVE(HARB_HMLTR, 32);	SAVE(GPIO_GPDR0, 32); SAVE(GPIO_GPDR1, 32); SAVE(GPIO_GPDR2, 32); 	SAVE(GPIO_GPDR3, 32);	SAVE(GPIO_GPDIR0, 32); SAVE(GPIO_GPDIR1, 32); SAVE(GPIO_GPDIR2, 32); 	SAVE(GPIO_GPDIR3, 32);	SAVE(GPIO_GPODR0, 32); SAVE(GPIO_GPODR1, 32); SAVE(GPIO_GPODR2, 32); 	SAVE(GPIO_GPODR3, 32);	SAVE(GPIO_GPPUR0, 32); SAVE(GPIO_GPPUR1, 32); SAVE(GPIO_GPPUR2, 32); 	SAVE(GPIO_GPPUR3, 32);	SAVE(GPIO_GPALR0, 32); SAVE(GPIO_GPALR1, 32); SAVE(GPIO_GPALR2, 32); 	SAVE(GPIO_GPALR3, 32);	SAVE(GPIO_GPAUR0, 32); SAVE(GPIO_GPAUR1, 32); SAVE(GPIO_GPAUR2, 32); 	SAVE(GPIO_GPAUR3, 32);	SAVE(GPIO_GPIDLR0, 32); SAVE(GPIO_GPIDLR1, 32);	SAVE(GPIO_GPIDLR2, 32); 	SAVE(GPIO_GPIDLR3, 32);	SAVE(GPIO_GPIDUR0, 32);	SAVE(GPIO_GPIDUR1, 32);	SAVE(GPIO_GPIDUR2, 32);		SAVE(GPIO_GPIDUR3, 32);	SAVE(GPIO_GPIER0, 32); SAVE(GPIO_GPIER1, 32); SAVE(GPIO_GPIER2, 32); 	SAVE(GPIO_GPIER3, 32);	SAVE(GPIO_GPIMR0, 32); SAVE(GPIO_GPIMR1, 32); SAVE(GPIO_GPIMR2, 32); 	SAVE(GPIO_GPIMR3, 32);	SAVE(GPIO_GPFR0, 32); SAVE(GPIO_GPFR1, 32); SAVE(GPIO_GPFR2, 32); 	SAVE(GPIO_GPFR3, 32);	SAVE(DMAC_DMACR, 32);	SAVE(DMAC_DSAR0, 32); SAVE(DMAC_DSAR1, 32); SAVE(DMAC_DSAR2, 32); SAVE(DMAC_DSAR3, 32); SAVE(DMAC_DSAR4, 32); SAVE(DMAC_DSAR5, 32); SAVE(DMAC_DSAR6, 32); SAVE(DMAC_DSAR7, 32); 	SAVE(DMAC_DDAR0, 32); SAVE(DMAC_DDAR1, 32); SAVE(DMAC_DDAR2, 32); SAVE(DMAC_DDAR3, 32); SAVE(DMAC_DDAR4, 32); SAVE(DMAC_DDAR5, 32); SAVE(DMAC_DDAR6, 32); SAVE(DMAC_DDAR7, 32); 	SAVE(DMAC_DTCR0, 32); SAVE(DMAC_DTCR1, 32); SAVE(DMAC_DTCR2, 32); SAVE(DMAC_DTCR3, 32); SAVE(DMAC_DTCR4, 32); SAVE(DMAC_DTCR5, 32); SAVE(DMAC_DTCR6, 32); SAVE(DMAC_DTCR7, 32); 	SAVE(DMAC_DRSR0, 32); SAVE(DMAC_DRSR1, 32); SAVE(DMAC_DRSR2, 32); SAVE(DMAC_DRSR3, 32); SAVE(DMAC_DRSR4, 32); SAVE(DMAC_DRSR5, 32); SAVE(DMAC_DRSR6, 32); SAVE(DMAC_DRSR7, 32); 	SAVE(DMAC_DCCSR0, 32); SAVE(DMAC_DCCSR1, 32); SAVE(DMAC_DCCSR2, 32); SAVE(DMAC_DCCSR3, 32); SAVE(DMAC_DCCSR4, 32); SAVE(DMAC_DCCSR5, 32); SAVE(DMAC_DCCSR6, 32); SAVE(DMAC_DCCSR7, 32);	SAVE(INTC_IMR, 32);	REG32(INTC_IMSR) = 0xffffffff; /* Mask all intrs */	board_pm_setup();	/* Clear previous reset status */	REG_CPM_RSTR &= ~(CPM_RSTR_HR | CPM_RSTR_WR | CPM_RSTR_SR);	/* Set resume return address */	REG_CPM_SPR = virt_to_phys(jz_cpu_resume);	/* Before sleeping, calculate and save a checksum */	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)		checksum += sleep_save[i];	sleep_save[SLEEP_SAVE_CKSUM] = checksum;	/* *** go zzz *** */	jz_cpu_suspend();	/* after sleeping, validate the checksum */	checksum = 0;	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)		checksum += sleep_save[i];	/* if invalid, display message and wait for a hardware reset */	if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) {		/** Add platform-specific message display codes here **/		while (1);	}	/* Ensure not to come back here if it wasn't intended */	REG_CPM_SPR = 0;	/* Restore registers */	RESTORE(GPIO_GPDR0, 32); RESTORE(GPIO_GPDR1, 32); RESTORE(GPIO_GPDR2, 32); 	RESTORE(GPIO_GPDR3, 32);	RESTORE(GPIO_GPDIR0, 32); RESTORE(GPIO_GPDIR1, 32); RESTORE(GPIO_GPDIR2, 32); 	RESTORE(GPIO_GPDIR3, 32);	RESTORE(GPIO_GPODR0, 32); RESTORE(GPIO_GPODR1, 32); RESTORE(GPIO_GPODR2, 32); 	RESTORE(GPIO_GPODR3, 32);	RESTORE(GPIO_GPPUR0, 32); RESTORE(GPIO_GPPUR1, 32); RESTORE(GPIO_GPPUR2, 32); 	RESTORE(GPIO_GPPUR3, 32);	RESTORE(GPIO_GPALR0, 32); RESTORE(GPIO_GPALR1, 32); RESTORE(GPIO_GPALR2, 32); 	RESTORE(GPIO_GPALR3, 32);	RESTORE(GPIO_GPAUR0, 32); RESTORE(GPIO_GPAUR1, 32); RESTORE(GPIO_GPAUR2, 32); 	RESTORE(GPIO_GPAUR3, 32);	RESTORE(GPIO_GPIDLR0, 32);RESTORE(GPIO_GPIDLR1, 32);RESTORE(GPIO_GPIDLR2, 32);	RESTORE(GPIO_GPIDLR3, 32);	RESTORE(GPIO_GPIDUR0, 32);RESTORE(GPIO_GPIDUR1, 32);RESTORE(GPIO_GPIDUR2, 32); 	RESTORE(GPIO_GPIDUR3, 32);	RESTORE(GPIO_GPIER0, 32); RESTORE(GPIO_GPIER1, 32); RESTORE(GPIO_GPIER2, 32);	RESTORE(GPIO_GPIER3, 32);	RESTORE(GPIO_GPIMR0, 32); RESTORE(GPIO_GPIMR1, 32); RESTORE(GPIO_GPIMR2, 32); 	RESTORE(GPIO_GPIMR3, 32);	RESTORE(GPIO_GPFR0, 32); RESTORE(GPIO_GPFR1, 32); RESTORE(GPIO_GPFR2, 32); 	RESTORE(GPIO_GPFR3, 32);	RESTORE(HARB_HAPOR, 32); RESTORE(HARB_HMCTR, 32); RESTORE(HARB_HMLTR, 32);	RESTORE(OST_TCNT0, 32);	RESTORE(OST_TCNT1, 32);	RESTORE(OST_TCNT2, 32);	RESTORE(OST_TRDR0, 32);	RESTORE(OST_TRDR1, 32);	RESTORE(OST_TRDR2, 32);	RESTORE(OST_TCSR0, 16);	RESTORE(OST_TCSR1, 16);	RESTORE(OST_TCSR2, 16);	RESTORE(OST_TER, 8);	RESTORE(DMAC_DMACR, 32);	RESTORE(DMAC_DSAR0, 32); RESTORE(DMAC_DSAR1, 32); RESTORE(DMAC_DSAR2, 32); RESTORE(DMAC_DSAR3, 32); RESTORE(DMAC_DSAR4, 32); RESTORE(DMAC_DSAR5, 32); RESTORE(DMAC_DSAR6, 32); RESTORE(DMAC_DSAR7, 32); 	RESTORE(DMAC_DDAR0, 32); RESTORE(DMAC_DDAR1, 32); RESTORE(DMAC_DDAR2, 32); RESTORE(DMAC_DDAR3, 32); RESTORE(DMAC_DDAR4, 32); RESTORE(DMAC_DDAR5, 32); RESTORE(DMAC_DDAR6, 32); RESTORE(DMAC_DDAR7, 32); 	RESTORE(DMAC_DTCR0, 32); RESTORE(DMAC_DTCR1, 32); RESTORE(DMAC_DTCR2, 32); RESTORE(DMAC_DTCR3, 32); RESTORE(DMAC_DTCR4, 32); RESTORE(DMAC_DTCR5, 32); RESTORE(DMAC_DTCR6, 32); RESTORE(DMAC_DTCR7, 32); 	RESTORE(DMAC_DRSR0, 32); RESTORE(DMAC_DRSR1, 32); RESTORE(DMAC_DRSR2, 32); RESTORE(DMAC_DRSR3, 32); RESTORE(DMAC_DRSR4, 32); RESTORE(DMAC_DRSR5, 32); RESTORE(DMAC_DRSR6, 32); RESTORE(DMAC_DRSR7, 32); 	RESTORE(DMAC_DCCSR0, 32); RESTORE(DMAC_DCCSR1, 32); RESTORE(DMAC_DCCSR2, 32); RESTORE(DMAC_DCCSR3, 32); RESTORE(DMAC_DCCSR4, 32); RESTORE(DMAC_DCCSR5, 32); RESTORE(DMAC_DCCSR6, 32); RESTORE(DMAC_DCCSR7, 32);	RESTORE(INTC_IMR, 32);	/*	 * Temporary solution.  This won't be necessary once

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -