📄 au1xxx_pm.patch
字号:
diff -Naur linux26-cvs/arch/mips/au1000/common/power.c linux26-new/arch/mips/au1000/common/power.c--- linux26-cvs/arch/mips/au1000/common/power.c 2005-08-10 15:44:21.000000000 -0500+++ linux26-new/arch/mips/au1000/common/power.c 2005-08-10 15:47:37.000000000 -0500@@ -29,44 +29,120 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */-#include <linux/config.h>+ #include <linux/init.h>-#include <linux/pm.h> #include <linux/slab.h> #include <linux/sysctl.h>+#include <linux/proc_fs.h>+#include <linux/timer.h>+#include <linux/time.h>+#include <linux/jiffies.h> #include <asm/string.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/system.h> #include <asm/mach-au1x00/au1000.h>+#include <asm/mach-au1x00/au1xxx_pm.h>+#include <asm/mach-au1x00/au1xxx_psc.h>+#include <asm/mach-au1x00/au1xxx_dbdma.h>++#if defined(CONFIG_MIPS_PB1200)+#include <asm/mach-pb1x00/pb1200.h>+#elif defined (CONFIG_MIPS_DB1200)+#include <asm/mach-db1x00/db1200.h>+#endif -#ifdef CONFIG_PM--#define DEBUG 1-#ifdef DEBUG+#define DEBUG 0+#if DEBUG # define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) #else # define DPRINTK(fmt, args...) #endif -static void calibrate_delay(void);+#ifdef CONFIG_PM++#define AU1XXX_PM_VERSION "1.0"+#define TRUE 1+#define FALSE 0+#define MAX_POWER_CONF_LEN 64+/* set this to a non-zero value to enable a fake device for testing */+#define ENABLE_TEST_DEV 0++/* function definitions */+int remove_au1xxx_pm_error(au1xxx_pm_error_t *error);+static void au1xxx_pm_service_timer(unsigned long var);++static void au1xxx_pm_debug(void);++/* system settings */+static struct proc_dir_entry *power_dir;+static struct proc_dir_entry *timeout_dir;+static struct proc_dir_entry *pending_proc_entry;+static struct proc_dir_entry *error_proc_entry;++au1xxx_power_dev_t sys_power_array[MAX_SUPPORTED_DEVICES]; +au1xxx_power_dev_t *sys_power_pointers[MAX_SUPPORTED_DEVICES];+au1xxx_power_dev_t *system_dev = &sys_power_array[0];++u16 sleep_bcsr_int, sleep_bcsr_mask,sleep_bcsr_resets;+u16 sleep_bcsr_pcmcia, sleep_bcsr_boards;+++struct au1xxx_pm_settings { + int wakeup_mode;+ int sleep_time; /* in seconds */+ int feedback_mode;+ int valid;+ struct proc_dir_entry *proc_entry;+};+typedef struct au1xxx_pm_settings au1xxx_pm_settings_t; -extern void set_au1x00_speed(unsigned int new_freq);-extern unsigned int get_au1x00_speed(void);-extern unsigned long get_au1x00_uart_baud_base(void);-extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);-extern unsigned long save_local_and_disable(int controller);-extern void restore_local_and_enable(int controller, unsigned long mask);-extern void local_enable_irq(unsigned int irq_nr);--/* Quick acpi hack. This will have to change! */-#define CTL_ACPI 9999-#define ACPI_S1_SLP_TYP 19-#define ACPI_SLEEP 21+/* Definition PM Catch All */+struct pm_module+{+ char modname[64];+ char pmname[64];+ spinlock_t lock; /* Used to block on state transitions */+ au1xxx_power_dev_t *dev; /* Power Managers device structure */+}; +typedef struct pm_module pm_module; -static DEFINE_SPINLOCK(pm_lock);+char modprobe_path_pm[64] = "/sbin/modprobe";++/* Add entries for modules that need power Management support+ To add : .modname should be the name of the module when you do lsmod+ .pmname could be anything.+ For eg: Ethernet: + root@(none):~# lsmod+ Module Size Used by+ smc91111 25248 0+ + */+static pm_module pm_modules[] = {+ { .modname = "ehci-hcd", .pmname="ehci" },+ { .modname = "ohci-hcd", .pmname="ohci" },+ { .modname = "smc91111", .pmname="ethernet" }};++static int num_modules=sizeof(pm_modules)/sizeof(pm_module);++/* End PM Catch All definition*/+++au1xxx_pm_settings_t set;+au1xxx_pm_settings_t *au1xxx_pm_setup = &set;++static spinlock_t au1xxx_pm_lock = SPIN_LOCK_UNLOCKED;+unsigned long spin_lock_flags;++/* error related */+au1xxx_pm_error_t sys_error_array[MAX_SUPPORTED_ERRORS];+au1xxx_pm_error_t *sys_error_pointers[MAX_SUPPORTED_ERRORS];+au1xxx_pm_error_t *first_error = &sys_error_array[0];++/* timer related */+static struct timeval zero_timeval = {0, 0}; /* We need to save/restore a bunch of core registers that are * either volatile or reset to some state across a processor sleep.@@ -75,7 +151,7 @@ * register and save a copy. * * We only have to save/restore registers that aren't otherwise- * done as part of a driver pm_* function.+ * done as part of a driver au1xxx_pm_* function. */ static uint sleep_aux_pll_cntrl; static uint sleep_cpu_pll_cntrl;@@ -88,23 +164,26 @@ static uint sleep_usbhost_enable; static uint sleep_usbdev_enable; static uint sleep_static_memctlr[4][3];+static uint sleep_ddma[16][8];+static uint sleep_psc[1][12];+static uint sleep_sys_clksrc, sleep_sys_clksrc_temp;+static uint sleep_sys_freqctl0;+static uint sleep_sys_freqctl1;+static uint sleep_mae[60]; /* Define this to cause the value you write to /proc/sys/pm/sleep to * set the TOY timer for the amount of time you want to sleep.- * This is done mainly for testing, but may be useful in other cases.- * The value is number of 32KHz ticks to sleep.+ * The value is number of seconds to sleep. */-#define SLEEP_TEST_TIMEOUT 1-#ifdef SLEEP_TEST_TIMEOUT-static int sleep_ticks;-void wakeup_toym2_set(int ticks);-#endif--static void-save_core_regs(void)-{+extern void wakeup_toym2_set(int ticks);+ +/***********************************************************************+ * SLEEP FUNCTIONS+ ***********************************************************************/+static void save_core_regs(void) { extern void save_au1xxx_intctl(void); extern void pm_eth0_shutdown(void);+ unsigned int addr,i; /* Do the serial ports.....these really should be a pm_* * registered function by the driver......but of course the@@ -117,36 +196,32 @@ sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); - /* Shutdown USB host/device.- */+#ifndef CONFIG_SOC_AU1200+ /* Shutdown USB host/device. */ sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); - /* There appears to be some undocumented reset register....- */+ /* There appears to be some undocumented reset register.... */ au_writel(0, 0xb0100004); au_sync(); au_writel(0, USB_HOST_CONFIG); au_sync(); sleep_usbdev_enable = au_readl(USBD_ENABLE); au_writel(0, USBD_ENABLE); au_sync();+#endif - /* Save interrupt controller state.- */+ /* Save interrupt controller state. */ save_au1xxx_intctl(); - /* Clocks and PLLs.- */+ /* Clocks and PLLs. */ sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL); /* We don't really need to do this one, but unless we * write it again it won't have a valid value if we- * happen to read it.- */+ * happen to read it. */ sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL); sleep_pin_function = au_readl(SYS_PINFUNC); - /* Save the static memory controller configuration.- */+ /* Save the static memory controller configuration. */ sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);@@ -159,20 +234,131 @@ sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);+ + /* Save the DDMA gloabl regs */+ addr = DDMA_GLOBAL_BASE;+ sleep_ddma[0][0] = au_readl(addr);+ sleep_ddma[0][1] = au_readl(addr+4);+ sleep_ddma[0][2] = au_readl(addr+8);+ sleep_ddma[0][3] = au_readl(addr+0xC);++ for(i=1,addr=DDMA_CHANNEL_BASE; i<NUM_DBDMA_CHANS; i++, addr+=0x100 ) {+ sleep_ddma[i][0] = au_readl(addr);+ sleep_ddma[i][1] = au_readl(addr+4);+ sleep_ddma[i][2] = au_readl(addr+8);+ sleep_ddma[i][3] = au_readl(addr+0xC);+ sleep_ddma[i][4] = au_readl(addr+0x10);+ sleep_ddma[i][5] = au_readl(addr+0x14);+ sleep_ddma[i][6] = au_readl(addr+0x18); + }++ /* Save the Programable Serial Controller registers */+ for (i = 0, addr = PSC0_BASE_ADDR; addr < (PSC0_BASE_ADDR + 0x30); i++, addr += 0x04)+ sleep_psc[0][i] = au_readl(addr);+ for (i = 0, addr = PSC1_BASE_ADDR; addr < (PSC1_BASE_ADDR + 0x30); i++, addr += 0x04)+ sleep_psc[1][i] = au_readl(addr);+ + /* Save clock information */+ sleep_sys_clksrc = au_readl(SYS_CLKSRC);+ sleep_sys_freqctl0 = au_readl(SYS_FREQCTRL0);+ sleep_sys_freqctl1 = au_readl(SYS_FREQCTRL1);++ DPRINTK("Saving MAE FE regs\n");+ /* Save MAE front end registers */+ addr = 0xb4012000;+ sleep_mae[0] = au_readl(addr + 0x0000);+ sleep_mae[1] = au_readl(addr + 0x0004);+ sleep_mae[2] = au_readl(addr + 0x0008);+ sleep_mae[3] = au_readl(addr + 0x000C);+ sleep_mae[4] = au_readl(addr + 0x0010);+ sleep_mae[5] = au_readl(addr + 0x0014);+ sleep_mae[6] = au_readl(addr + 0x0018);+ sleep_mae[7] = au_readl(addr + 0x001C);+ sleep_mae[8] = au_readl(addr + 0x0020);+ sleep_mae[9] = au_readl(addr + 0x0024);+ sleep_mae[10] = au_readl(addr + 0x0028);+ sleep_mae[11] = au_readl(addr + 0x002C);+ sleep_mae[12] = au_readl(addr + 0x0038);+ sleep_mae[13] = au_readl(addr + 0x003C);+ sleep_mae[14] = au_readl(addr + 0x0040);+ sleep_mae[15] = au_readl(addr + 0x0044);+ sleep_mae[16] = au_readl(addr + 0x0048);+ sleep_mae[17] = au_readl(addr + 0x004C);+ sleep_mae[18] = au_readl(addr + 0x0050);+ sleep_mae[19] = au_readl(addr + 0x0054);+ sleep_mae[20] = au_readl(addr + 0x0058);+ sleep_mae[21] = au_readl(addr + 0x005C);+ sleep_mae[22] = au_readl(addr + 0x1004);+ sleep_mae[23] = au_readl(addr + 0x1008);+ DPRINTK("Saving MAE BE regs\n");+ /* Save MAE backend registers */+ addr = 0xb4010000;+ sleep_mae[24] = au_readl(addr + 0x0000);+ sleep_mae[25] = au_readl(addr + 0x0004);+ sleep_mae[26] = au_readl(addr + 0x0008);+ sleep_mae[27] = au_readl(addr + 0x0100);+ sleep_mae[28] = au_readl(addr + 0x0180);+ sleep_mae[29] = au_readl(addr + 0x0200);+ sleep_mae[30] = au_readl(addr + 0x0280);+ sleep_mae[31] = au_readl(addr + 0x0300);+ sleep_mae[32] = au_readl(addr + 0x0380);+ DPRINTK("Saving MAE CSC regs\n");+ /* CSC registers */+ sleep_mae[33] = au_readl(addr + 0x0400);+ sleep_mae[34] = au_readl(addr + 0x0404);+ sleep_mae[35] = au_readl(addr + 0x0408);+ sleep_mae[36] = au_readl(addr + 0x040C);+ sleep_mae[37] = au_readl(addr + 0x0410);+ sleep_mae[38] = au_readl(addr + 0x0414);+ sleep_mae[39] = au_readl(addr + 0x0418);+ sleep_mae[40] = au_readl(addr + 0x041C);+ sleep_mae[41] = au_readl(addr + 0x0420);+ sleep_mae[42] = au_readl(addr + 0x0424);+ sleep_mae[43] = au_readl(addr + 0x0428);+ sleep_mae[44] = au_readl(addr + 0x042C);+ sleep_mae[45] = au_readl(addr + 0x0430);+ DPRINTK("Saving MAE SRC regs\n");+ /* SRC registers */+ sleep_mae[46] = au_readl(addr + 0x0500);+ sleep_mae[47] = au_readl(addr + 0x0504);+ sleep_mae[48] = au_readl(addr + 0x0508);+ sleep_mae[49] = au_readl(addr + 0x050C);+ sleep_mae[50] = au_readl(addr + 0x0510);+ sleep_mae[51] = au_readl(addr + 0x0514);+ sleep_mae[52] = au_readl(addr + 0x0518);+ sleep_mae[53] = au_readl(addr + 0x051C);+ DPRINTK("Saving MAE DST regs\n");+ /* DST registers */+ sleep_mae[54] = au_readl(addr + 0x0600);+ sleep_mae[55] = au_readl(addr + 0x0604);+ sleep_mae[56] = au_readl(addr + 0x0608);+ sleep_mae[57] = au_readl(addr + 0x060C);+ DPRINTK("Saving MAE CTL regs\n");+ /* CTL registers */+ sleep_mae[58] = au_readl(addr + 0x0700);+ sleep_mae[59] = au_readl(addr + 0x070C);+ sleep_mae[60] = au_readl(addr + 0x0710);++#if defined(CONFIG_MIPS_PB1200) || defined(CONFIG_MIPS_DB1200)+ /* save board register */+ sleep_bcsr_int = bcsr->intset;+ sleep_bcsr_mask = bcsr->intset_mask;+ sleep_bcsr_resets = bcsr->resets;+ sleep_bcsr_pcmcia = bcsr->pcmcia;+ sleep_bcsr_boards = bcsr->board;+#endif } -static void-restore_core_regs(void)-{+static void restore_core_regs(void) { extern void restore_au1xxx_intctl(void); extern void wakeup_kernel_timer(void);+ unsigned int addr,i; au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync(); au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync(); au_writel(sleep_pin_function, SYS_PINFUNC); au_sync(); - /* Restore the static memory controller configuration.- */+ /* Restore the static memory controller configuration. */ au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);@@ -187,8 +373,7 @@ au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); /* Enable the UART if it was enabled before sleep.- * I guess I should define module control bits........- */+ * I guess I should define module control bits........ */ if (sleep_uart0_enable & 0x02) { au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync(); au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync();@@ -199,295 +384,1479 @@ au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); } + /* Save the DDMA gloabl regs */+ addr = DDMA_GLOBAL_BASE;+ au_writel(sleep_ddma[0][0],addr+0x0);+ au_writel(sleep_ddma[0][1],addr+0x4);+ au_writel(sleep_ddma[0][2],addr+0x8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -