Hello, the attached patch adds support for power management for UART interfaces. Ciao, Rodolfo -- GNU/Linux Solutions e-mail: giometti@xxxxxxxxxxxx Linux Device Driver giometti@xxxxxxxxx Embedded Systems giometti@xxxxxxxx UNIX programming phone: +39 349 2432127
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c index 482de93..30bfccf 100644 --- a/arch/mips/au1000/common/power.c +++ b/arch/mips/au1000/common/power.c @@ -92,11 +92,13 @@ static uint sleep_gpio2_dir; static uint sleep_gpio2_output; static uint sleep_gpio2_enable; static uint sleep_gpio2_inten; -static uint sleep_uart0_inten; -static uint sleep_uart0_fifoctl; -static uint sleep_uart0_linectl; -static uint sleep_uart0_clkdiv; -static uint sleep_uart0_enable; +static struct sleep_uart_s { + uint inten; + uint fifoctl; + uint linectl; + uint clkdiv; + uint enable; +} sleep_uart[4]; static uint sleep_usbhost_enable; static uint sleep_usbdev_enable; static uint sleep_static_memctlr[4][3]; @@ -152,11 +154,34 @@ save_core_regs(void) * standard serial driver doesn't understand our Au1xxx * unique registers. */ - sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER); - sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR); - sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); - sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); - sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); +#ifdef UART0_ADDR + sleep_uart[0].inten = au_readl(UART0_ADDR + UART_IER); + sleep_uart[0].fifoctl = au_readl(UART0_ADDR + UART_FCR); + sleep_uart[0].linectl = au_readl(UART0_ADDR + UART_LCR); + sleep_uart[0].clkdiv = au_readl(UART0_ADDR + UART_CLK); + sleep_uart[0].enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); +#endif +#ifdef UART1_ADDR + sleep_uart[1].inten = au_readl(UART1_ADDR + UART_IER); + sleep_uart[1].fifoctl = au_readl(UART1_ADDR + UART_FCR); + sleep_uart[1].linectl = au_readl(UART1_ADDR + UART_LCR); + sleep_uart[1].clkdiv = au_readl(UART1_ADDR + UART_CLK); + sleep_uart[1].enable = au_readl(UART1_ADDR + UART_MOD_CNTRL); +#endif +#ifdef UART2_ADDR + sleep_uart[2].inten = au_readl(UART2_ADDR + UART_IER); + sleep_uart[2].fifoctl = au_readl(UART2_ADDR + UART_FCR); + sleep_uart[2].linectl = au_readl(UART2_ADDR + UART_LCR); + sleep_uart[2].clkdiv = au_readl(UART2_ADDR + UART_CLK); + sleep_uart[2].enable = au_readl(UART2_ADDR + UART_MOD_CNTRL); +#endif +#ifdef UART3_ADDR + sleep_uart[3].inten = au_readl(UART3_ADDR + UART_IER); + sleep_uart[3].fifoctl = au_readl(UART3_ADDR + UART_FCR); + sleep_uart[3].linectl = au_readl(UART3_ADDR + UART_LCR); + sleep_uart[3].clkdiv = au_readl(UART3_ADDR + UART_CLK); + sleep_uart[3].enable = au_readl(UART3_ADDR + UART_MOD_CNTRL); +#endif /* Shutdown USB host/device. */ @@ -240,15 +265,50 @@ restore_core_regs(void) /* Enable the UART if it was enabled before sleep. * I guess I should define module control bits........ */ - if (sleep_uart0_enable & 0x02) { +#ifdef UART0_ADDR + if (sleep_uart[0].enable & 0x02) { au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync(); au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync(); au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync(); - au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync(); - au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync(); - au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); - au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); + au_writel(sleep_uart[0].inten, UART0_ADDR + UART_IER); au_sync(); + au_writel(sleep_uart[0].fifoctl, UART0_ADDR + UART_FCR); au_sync(); + au_writel(sleep_uart[0].linectl, UART0_ADDR + UART_LCR); au_sync(); + au_writel(sleep_uart[0].clkdiv, UART0_ADDR + UART_CLK); au_sync(); + } +#endif +#ifdef UART1_ADDR + if (sleep_uart[1].enable & 0x02) { + au_writel(0, UART1_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(1, UART1_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(3, UART1_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(sleep_uart[1].inten, UART1_ADDR + UART_IER); au_sync(); + au_writel(sleep_uart[1].fifoctl, UART1_ADDR + UART_FCR); au_sync(); + au_writel(sleep_uart[1].linectl, UART1_ADDR + UART_LCR); au_sync(); + au_writel(sleep_uart[1].clkdiv, UART1_ADDR + UART_CLK); au_sync(); } +#endif +#ifdef UART2_ADDR + if (sleep_uart[2].enable & 0x02) { + au_writel(0, UART2_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(1, UART2_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(3, UART2_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(sleep_uart[2].inten, UART2_ADDR + UART_IER); au_sync(); + au_writel(sleep_uart[2].fifoctl, UART2_ADDR + UART_FCR); au_sync(); + au_writel(sleep_uart[2].linectl, UART2_ADDR + UART_LCR); au_sync(); + au_writel(sleep_uart[2].clkdiv, UART2_ADDR + UART_CLK); au_sync(); + } +#endif +#ifdef UART3_ADDR + if (sleep_uart[3].enable & 0x02) { + au_writel(0, UART3_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(1, UART3_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(3, UART3_ADDR + UART_MOD_CNTRL); au_sync(); + au_writel(sleep_uart[3].inten, UART3_ADDR + UART_IER); au_sync(); + au_writel(sleep_uart[3].fifoctl, UART3_ADDR + UART_FCR); au_sync(); + au_writel(sleep_uart[3].linectl, UART3_ADDR + UART_LCR); au_sync(); + au_writel(sleep_uart[3].clkdiv, UART3_ADDR + UART_CLK); au_sync(); + } +#endif restore_au1xxx_intctl(); wakeup_counter0_adjust();