au1x00 UARTs power management
Hello,
the attached patch adds support for power management for UART interfaces.
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
arch/mips/au1000/common/power.c +75 -15
@@ -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 ();