aboutsummaryrefslogtreecommitdiffstats
path: root/tty/alchemy-add-uart-pm-methods.patch
diff options
Diffstat (limited to 'tty/alchemy-add-uart-pm-methods.patch')
-rw-r--r--tty/alchemy-add-uart-pm-methods.patch128
1 files changed, 128 insertions, 0 deletions
diff --git a/tty/alchemy-add-uart-pm-methods.patch b/tty/alchemy-add-uart-pm-methods.patch
new file mode 100644
index 00000000000000..8a46a9c1670331
--- /dev/null
+++ b/tty/alchemy-add-uart-pm-methods.patch
@@ -0,0 +1,128 @@
+From manuel.lauss@googlemail.com Wed Oct 6 13:38:47 2010
+From: Manuel Lauss <manuel.lauss@googlemail.com>
+To: linux-serial@vger.kernel.org
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>,
+ Andrew Morton <akpm@linux-foundation.org>,
+ Greg KH <greg@kroah.com>,
+ Manuel Lauss <manuel.lauss@googlemail.com>
+Subject: Alchemy: Add UART PM methods.
+Date: Sat, 25 Sep 2010 15:13:46 +0200
+Message-Id: <1285420426-8510-2-git-send-email-manuel.lauss@googlemail.com>
+
+Custom UART PM hook for Alchemy chips: do standard UART pm and
+additionally en/disable uart block clocks as needed.
+This allows to get rid of a debug port PM hack in the Alchemy pm code.
+
+Tested on Db1200.
+
+Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/mips/alchemy/common/platform.c | 28 ++++++++++++++++++++++++++++
+ arch/mips/alchemy/common/power.c | 35 -----------------------------------
+ 2 files changed, 28 insertions(+), 35 deletions(-)
+
+--- a/arch/mips/alchemy/common/platform.c
++++ b/arch/mips/alchemy/common/platform.c
+@@ -24,6 +24,33 @@
+
+ #include <prom.h>
+
++static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
++ unsigned int old_state)
++{
++ switch (state) {
++ case 0:
++ if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
++ /* power-on sequence as suggested in the databooks */
++ __raw_writel(0, port->membase + UART_MOD_CNTRL);
++ wmb();
++ __raw_writel(1, port->membase + UART_MOD_CNTRL);
++ wmb();
++ }
++ __raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */
++ wmb();
++ serial8250_do_pm(port, state, old_state);
++ break;
++ case 3: /* power off */
++ serial8250_do_pm(port, state, old_state);
++ __raw_writel(0, port->membase + UART_MOD_CNTRL);
++ wmb();
++ break;
++ default:
++ serial8250_do_pm(port, state, old_state);
++ break;
++ }
++}
++
+ #define PORT(_base, _irq) \
+ { \
+ .mapbase = _base, \
+@@ -33,6 +60,7 @@
+ .flags = UPF_SKIP_TEST | UPF_IOREMAP | \
+ UPF_FIXED_TYPE, \
+ .type = PORT_16550A, \
++ .pm = alchemy_8250_pm, \
+ }
+
+ static struct plat_serial8250_port au1x00_uart_data[] = {
+--- a/arch/mips/alchemy/common/power.c
++++ b/arch/mips/alchemy/common/power.c
+@@ -49,11 +49,6 @@
+ * We only have to save/restore registers that aren't otherwise
+ * done as part of a driver pm_* function.
+ */
+-static unsigned int sleep_uart0_inten;
+-static unsigned int sleep_uart0_fifoctl;
+-static unsigned int sleep_uart0_linectl;
+-static unsigned int sleep_uart0_clkdiv;
+-static unsigned int sleep_uart0_enable;
+ static unsigned int sleep_usb[2];
+ static unsigned int sleep_sys_clocks[5];
+ static unsigned int sleep_sys_pinfunc;
+@@ -62,22 +57,6 @@ static unsigned int sleep_static_memctlr
+
+ static void save_core_regs(void)
+ {
+- extern void save_au1xxx_intctl(void);
+- extern void pm_eth0_shutdown(void);
+-
+- /*
+- * Do the serial ports.....these really should be a pm_*
+- * registered function by the driver......but of course the
+- * 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);
+- au_sync();
+-
+ #ifndef CONFIG_SOC_AU1200
+ /* Shutdown USB host/device. */
+ sleep_usb[0] = au_readl(USB_HOST_CONFIG);
+@@ -175,20 +154,6 @@ static void restore_core_regs(void)
+ au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
+ au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
+ 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........
+- */
+- 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();
+- 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();
+- }
+ }
+
+ void au_sleep(void)