📄 pm.c
字号:
* we move jz support into the serial driver. * Restore the on-chip UART. */ /* FIFO control reg, write-only */ REG8(UART0_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; REG8(UART1_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; REG8(UART2_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; REG8(UART3_FCR) = UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS | UARTFCR_UUE; REG8(UART0_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ RESTORE(UART0_DLLR, 8); RESTORE(UART0_DLHR, 8); REG8(UART0_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ RESTORE(UART0_IER, 8); RESTORE(UART0_MCR, 8); RESTORE(UART0_SPR, 8); RESTORE(UART0_LCR, 8); REG8(UART1_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ RESTORE(UART1_DLLR, 8); RESTORE(UART1_DLHR, 8); REG8(UART1_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ RESTORE(UART1_IER, 8); RESTORE(UART1_MCR, 8); RESTORE(UART1_SPR, 8); RESTORE(UART1_LCR, 8); REG8(UART2_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ RESTORE(UART2_DLLR, 8); RESTORE(UART2_DLHR, 8); REG8(UART2_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ RESTORE(UART2_IER, 8); RESTORE(UART2_MCR, 8); RESTORE(UART2_SPR, 8); RESTORE(UART2_LCR, 8); REG8(UART3_LCR) |= UARTLCR_DLAB; /* Access to DLLR/DLHR */ RESTORE(UART3_DLLR, 8); RESTORE(UART3_DLHR, 8); REG8(UART3_LCR) &= ~UARTLCR_DLAB; /* Access to IER */ RESTORE(UART3_IER, 8); RESTORE(UART3_MCR, 8); RESTORE(UART3_SPR, 8); RESTORE(UART3_LCR, 8); /* Restore current time */ xtime.tv_sec = REG_RTC_RSR + delta; REG_CPM_OCR &= ~CPM_OCR_SUSPEND_PHY0; /* resume USB PHY 0 */ REG_CPM_OCR &= ~CPM_OCR_SUSPEND_PHY1; /* resume USB PHY 1 */ REG_CPM_OCR &= ~CPM_OCR_EXT_RTC_CLK; /* reuse internal RTC clock (3686400/128=28.8KHz) */ return 0;}/* * In order to save power most, all gpio pins should be put to their * proper states during low power mode. */static void board_pm_setup(void){ /* Clear all first */ REG_CPM_WER = 0;#ifdef CONFIG_MIPS_JZ_LIBRA /* Set the GPIO/CS/PCMCIA pins state in hibernate mode */ REG_CPM_GSR0 = 0xfffff00f; REG_CPM_GSR1 = 0xf0000fff; REG_CPM_GSR2 = ~0; REG_CPM_GSR3 = ~0; /* GPIO pin 96 */ __gpio_as_input(96); REG_CPM_WER |= 1 << 0; REG_CPM_WRER |= 1 << 0; REG_CPM_WFER |= 1 << 0; /* enable irq */ __intc_unmask_irq(IRQ_GPIO3);#endif#ifdef CONFIG_MIPS_JZ_PMP /* Set the GPIO/CS/PCMCIA pins state in hibernate mode */ /* Put next pins to there proper states during HIBERNATE * * GP66(PW_O) = high * GP94(PWM0) = low */ __cpm_set_pin(66); __cpm_clear_pin(94); /* GP97(PW_I) */ __gpio_as_input(97); REG_CPM_WER |= 1 << 1; REG_CPM_WRER |= 1 << 1; REG_CPM_WFER |= 1 << 1; __intc_unmask_irq(IRQ_GPIO3); /* enable INTC irq */ /* Enable RTC alarm */ REG_CPM_WER |= CPM_WER_WERTC; REG_RTC_RGR = 32767; REG_RTC_RCR &= ~RTC_RCR_AE; REG_RTC_RSR = 0; REG_RTC_RSAR = 30; REG_RTC_RCR = RTC_RCR_AE | RTC_RCR_AIE | RTC_RCR_START;#endif}static int jz_pm_do_sleep(void){ unsigned long delta; unsigned long imsr = REG_INTC_IMSR; /* Preserve current time */ delta = xtime.tv_sec - REG_RTC_RSR; REG_INTC_IMSR = 0xffffffff; /* Mask all intrs */ /* Setup wakeup sources */ __intc_unmask_irq(IRQ_PS2); /* PS2 */ __intc_unmask_irq(IRQ_UHC); /* USB Host */ REG_CPM_LPCR &= CPM_LPCR_LPM_MASK; REG_CPM_LPCR |= CPM_LPCR_LPM_SLEEP; /* Enter SLEEP mode */ __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); REG_CPM_LPCR &= CPM_LPCR_LPM_MASK; REG_CPM_LPCR |= CPM_LPCR_LPM_IDLE; REG_INTC_IMR = imsr; /* Restore current time */ xtime.tv_sec = REG_RTC_RSR + delta; return 0;}void jz_flush_cache_all(void){ unsigned long addr; /* Clear CP0 TagLo */ asm volatile ("mtc0 $0, $28\n\t"::); for (addr = K0BASE; addr < (K0BASE + 0x4000); addr += 32) { asm volatile ( ".set mips3\n\t" " cache %0, 0(%1)\n\t" ".set mips2\n\t" : : "I" (Index_Writeback_Inv_D), "r"(addr)); asm volatile ( ".set mips3\n\t" " cache %0, 0(%1)\n\t" ".set mips2\n\t" : : "I" (Index_Store_Tag_I), "r"(addr)); } asm volatile ("sync\n\t"::);}/* Put CPU to HIBERNATE mode */int jz_pm_suspend(void){ int retval; pm_send_all(PM_SUSPEND, (void *)3); retval = jz_pm_do_suspend(); pm_send_all(PM_RESUME, (void *)0); return retval;}/* Put CPU to SLEEP mode */int jz_pm_sleep(void){ int retval; pm_send_all(PM_SUSPEND, (void *)3); retval = jz_pm_do_sleep(); pm_send_all(PM_RESUME, (void *)0); return retval;}/* Put CPU to IDLE mode */void jz_pm_idle(void){ if (!current->need_resched) { cpu_wait(); }}#ifdef CONFIG_SYSCTL/* * ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than * linux/sysctl.h. */#define CTL_ACPI 9999 #define APM_S1_SLP_TYP 19/*---------------------------------------------------------------------------- * Power Management suspend sysctl proc interface * * A write to /proc/sys/pm/suspend invokes this function * which initiates a suspend. *--------------------------------------------------------------------------*/static int sysctl_jz_pm_suspend(void){ return jz_pm_suspend();}static struct ctl_table pm_table[] ={ {APM_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_jz_pm_suspend}, {0}};static struct ctl_table pm_dir_table[] ={ {CTL_ACPI, "pm", NULL, 0, 0555, pm_table}, {0}};/* * Initialize power interface */static int __init jz_pm_init(void){ register_sysctl_table(pm_dir_table, 1); //pm_idle = jz_pm_idle; //printk("initializing pm_idle at 0x%x\n", pm_idle); return 0;}__initcall(jz_pm_init);#endif /* CONFIG_SYSCTL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -