]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-omap2/serial.c
REMOVE OMAP LEGACY CODE: Reset clocks and PM code to mainline
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / serial.c
index fd5b9f83e0bc51ad361c2eaaf11a7b016ee65f7c..4dcf39c285b94bac5e1e6292469299c633fcd0bf 100644 (file)
@@ -6,8 +6,6 @@
  * Copyright (C) 2005-2008 Nokia Corporation
  * Author: Paul Mundt <paul.mundt@nokia.com>
  *
- * Major rework for PM support by Kevin Hilman
- *
  * Based off of arch/arm/mach-omap/omap1/serial.c
  *
  * This file is subject to the terms and conditions of the GNU General Public
 
 #include <mach/common.h>
 #include <mach/board.h>
-#include <mach/clock.h>
-#include <mach/control.h>
-
-#include "prm.h"
-#include "pm.h"
-#include "prm-regbits-34xx.h"
-
-#define DEFAULT_TIMEOUT (5 * HZ)
-
-struct omap_uart_state {
-       int num;
-       int can_sleep;
-       struct timer_list timer;
-       u32 timeout;
-
-       void __iomem *wk_st;
-       void __iomem *wk_en;
-       u32 wk_mask;
-       u32 padconf;
 
-       struct clk *ick;
-       struct clk *fck;
-       int clocked;
-
-       struct plat_serial8250_port *p;
-       struct list_head node;
-
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-       int context_valid;
-
-       /* Registers to be saved/restored for OFF-mode */
-       u16 dll;
-       u16 dlh;
-       u16 ier;
-       u16 sysc;
-       u16 scr;
-       u16 wer;
-#endif
-};
-
-static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS];
-static LIST_HEAD(uart_list);
+static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
+static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
 
 static struct plat_serial8250_port serial_platform_data[] = {
        {
@@ -115,356 +74,30 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
  * properly. Note that the TX watermark initialization may not be needed
  * once the 8250.c watermark handling code is merged.
  */
-static inline void __init omap_uart_reset(struct omap_uart_state *uart)
+static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
 {
-       struct plat_serial8250_port *p = uart->p;
-
        serial_write_reg(p, UART_OMAP_MDR1, 0x07);
        serial_write_reg(p, UART_OMAP_SCR, 0x08);
        serial_write_reg(p, UART_OMAP_MDR1, 0x00);
        serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
 }
 
-static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
-{
-       if (uart->clocked)
-               return;
-
-       clk_enable(uart->ick);
-       clk_enable(uart->fck);
-       uart->clocked = 1;
-}
-
-#ifdef CONFIG_PM
-#ifdef CONFIG_ARCH_OMAP3
-
-static int enable_off_mode; /* to be removed by full off-mode patches */
-
-static void omap_uart_save_context(struct omap_uart_state *uart)
-{
-       u16 lcr = 0;
-       struct plat_serial8250_port *p = uart->p;
-
-       if (!enable_off_mode)
-               return;
-
-       lcr = serial_read_reg(p, UART_LCR);
-       serial_write_reg(p, UART_LCR, 0xBF);
-       uart->dll = serial_read_reg(p, UART_DLL);
-       uart->dlh = serial_read_reg(p, UART_DLM);
-       serial_write_reg(p, UART_LCR, lcr);
-       uart->ier = serial_read_reg(p, UART_IER);
-       uart->sysc = serial_read_reg(p, UART_OMAP_SYSC);
-       uart->scr = serial_read_reg(p, UART_OMAP_SCR);
-       uart->wer = serial_read_reg(p, UART_OMAP_WER);
-
-       uart->context_valid = 1;
-}
-
-static void omap_uart_restore_context(struct omap_uart_state *uart)
-{
-       u16 efr = 0;
-       struct plat_serial8250_port *p = uart->p;
-
-       if (!enable_off_mode)
-               return;
-
-       if (!uart->context_valid)
-               return;
-
-       uart->context_valid = 0;
-
-       serial_write_reg(p, UART_OMAP_MDR1, 0x7);
-       serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
-       efr = serial_read_reg(p, UART_EFR);
-       serial_write_reg(p, UART_EFR, UART_EFR_ECB);
-       serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
-       serial_write_reg(p, UART_IER, 0x0);
-       serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
-       serial_write_reg(p, UART_DLL, uart->dll);
-       serial_write_reg(p, UART_DLM, uart->dlh);
-       serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
-       serial_write_reg(p, UART_IER, uart->ier);
-       serial_write_reg(p, UART_FCR, 0xA1);
-       serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
-       serial_write_reg(p, UART_EFR, efr);
-       serial_write_reg(p, UART_LCR, UART_LCR_WLEN8);
-       serial_write_reg(p, UART_OMAP_SCR, uart->scr);
-       serial_write_reg(p, UART_OMAP_WER, uart->wer);
-       serial_write_reg(p, UART_OMAP_SYSC, uart->sysc);
-       serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
-}
-#else
-static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
-static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
-#endif /* CONFIG_ARCH_OMAP3 */
-
-static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
-                                         int enable)
+void omap_serial_enable_clocks(int enable)
 {
-       struct plat_serial8250_port *p = uart->p;
-       u16 sysc;
-
-       sysc = serial_read_reg(p, UART_OMAP_SYSC) & 0x7;
-       if (enable)
-               sysc |= 0x2 << 3;
-       else
-               sysc |= 0x1 << 3;
-
-       serial_write_reg(p, UART_OMAP_SYSC, sysc);
-}
-
-static inline void omap_uart_restore(struct omap_uart_state *uart)
-{
-       omap_uart_enable_clocks(uart);
-       omap_uart_restore_context(uart);
-}
-
-static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
-{
-       if (!uart->clocked)
-               return;
-
-       omap_uart_save_context(uart);
-       uart->clocked = 0;
-       clk_disable(uart->ick);
-       clk_disable(uart->fck);
-}
-
-static void omap_uart_block_sleep(struct omap_uart_state *uart)
-{
-       omap_uart_restore(uart);
-
-       omap_uart_smart_idle_enable(uart, 0);
-       uart->can_sleep = 0;
-       mod_timer(&uart->timer, jiffies + uart->timeout);
-}
-
-static void omap_uart_allow_sleep(struct omap_uart_state *uart)
-{
-       if (!uart->clocked)
-               return;
-
-       omap_uart_smart_idle_enable(uart, 1);
-       uart->can_sleep = 1;
-       del_timer(&uart->timer);
-}
-
-static void omap_uart_idle_timer(unsigned long data)
-{
-       struct omap_uart_state *uart = (struct omap_uart_state *)data;
-
-       omap_uart_allow_sleep(uart);
-}
-
-void omap_uart_prepare_idle(int num)
-{
-       struct omap_uart_state *uart;
-
-       list_for_each_entry(uart, &uart_list, node) {
-               if (!clocks_off_while_idle)
-                       continue;
-
-               if (num == uart->num && uart->can_sleep) {
-                       omap_uart_disable_clocks(uart);
-                       return;
-               }
-       }
-}
-
-void omap_uart_resume_idle(int num)
-{
-       struct omap_uart_state *uart;
-
-       list_for_each_entry(uart, &uart_list, node) {
-               if (num == uart->num) {
-                       omap_uart_restore(uart);
-
-                       /* Check for IO pad wakeup */
-                       if (cpu_is_omap34xx() && uart->padconf) {
-                               u16 p = omap_ctrl_readw(uart->padconf);
-
-                               if (p & OMAP3_PADCONF_WAKEUPEVENT0)
-                                       omap_uart_block_sleep(uart);
+       int i;
+       for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+               if (uart_ick[i] && uart_fck[i]) {
+                       if (enable) {
+                               clk_enable(uart_ick[i]);
+                               clk_enable(uart_fck[i]);
+                       } else {
+                               clk_disable(uart_ick[i]);
+                               clk_disable(uart_fck[i]);
                        }
-
-                       /* Check for normal UART wakeup */
-                       if (__raw_readl(uart->wk_st) & uart->wk_mask)
-                               omap_uart_block_sleep(uart);
-
-                       return;
-               }
-       }
-}
-
-void omap_uart_prepare_suspend(void)
-{
-       struct omap_uart_state *uart;
-
-       list_for_each_entry(uart, &uart_list, node) {
-               omap_uart_allow_sleep(uart);
-       }
-}
-
-int omap_uart_can_sleep(void)
-{
-       struct omap_uart_state *uart;
-       int can_sleep = 1;
-
-       list_for_each_entry(uart, &uart_list, node) {
-               if (!uart->clocked)
-                       continue;
-
-               if (!uart->can_sleep) {
-                       can_sleep = 0;
-                       continue;
-               }
-
-               /* This UART can now safely sleep. */
-               omap_uart_allow_sleep(uart);
-       }
-
-       return can_sleep;
-}
-
-/**
- * omap_uart_interrupt()
- *
- * This handler is used only to detect that *any* UART interrupt has
- * occurred.  It does _nothing_ to handle the interrupt.  Rather,
- * any UART interrupt will trigger the inactivity timer so the
- * UART will not idle or sleep for its timeout period.
- *
- **/
-static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
-{
-       struct omap_uart_state *uart = dev_id;
-
-       omap_uart_block_sleep(uart);
-
-       return IRQ_NONE;
-}
-
-static u32 sleep_timeout = DEFAULT_TIMEOUT;
-
-static void omap_uart_idle_init(struct omap_uart_state *uart)
-{
-       u32 v;
-       struct plat_serial8250_port *p = uart->p;
-       int ret;
-
-       uart->can_sleep = 0;
-       uart->timeout = sleep_timeout;
-       setup_timer(&uart->timer, omap_uart_idle_timer,
-                   (unsigned long) uart);
-       mod_timer(&uart->timer, jiffies + uart->timeout);
-       omap_uart_smart_idle_enable(uart, 0);
-
-       if (cpu_is_omap34xx()) {
-               u32 mod = (uart->num == 2) ? OMAP3430_PER_MOD : CORE_MOD;
-               u32 wk_mask = 0;
-               u32 padconf = 0;
-
-               uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
-               uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
-               switch (uart->num) {
-               case 0:
-                       wk_mask = OMAP3430_ST_UART1_MASK;
-                       padconf = 0x182;
-                       break;
-               case 1:
-                       wk_mask = OMAP3430_ST_UART2_MASK;
-                       padconf = 0x17a;
-                       break;
-               case 2:
-                       wk_mask = OMAP3430_ST_UART3_MASK;
-                       padconf = 0x19e;
-                       break;
-               }
-               uart->wk_mask = wk_mask;
-               uart->padconf = padconf;
-       } else if (cpu_is_omap24xx()) {
-               u32 wk_mask = 0;
-
-               if (cpu_is_omap2430()) {
-                       uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKEN1);
-                       uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKST1);
-               } else if (cpu_is_omap2420()) {
-                       uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1);
-                       uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1);
                }
-               switch (uart->num) {
-               case 0:
-                       wk_mask = OMAP24XX_ST_UART1_MASK;
-                       break;
-               case 1:
-                       wk_mask = OMAP24XX_ST_UART2_MASK;
-                       break;
-               case 2:
-                       wk_mask = OMAP24XX_ST_UART3_MASK;
-                       break;
-               }
-               uart->wk_mask = wk_mask;
-       } else {
-               uart->wk_en = 0;
-               uart->wk_st = 0;
-               uart->wk_mask = 0;
-               uart->padconf = 0;
-       }
-
-       /* Set wake-enable bit */
-       if (uart->wk_en && uart->wk_mask) {
-               v = __raw_readl(uart->wk_en);
-               v |= uart->wk_mask;
-               __raw_writel(v, uart->wk_en);
-       }
-
-       /* Ensure IOPAD wake-enables are set */
-       if (cpu_is_omap34xx() && uart->padconf) {
-               u16 v;
-
-               v = omap_ctrl_readw(uart->padconf);
-               v |= OMAP3_PADCONF_WAKEUPENABLE0;
-               omap_ctrl_writew(v, uart->padconf);
        }
-
-       p->flags |= UPF_SHARE_IRQ;
-       ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
-                         "serial idle", (void *)uart);
-       WARN_ON(ret);
 }
 
-static ssize_t sleep_timeout_show(struct kobject *kobj,
-                                 struct kobj_attribute *attr,
-                                 char *buf)
-{
-       return sprintf(buf, "%u\n", sleep_timeout / HZ);
-}
-
-static ssize_t sleep_timeout_store(struct kobject *kobj,
-                                  struct kobj_attribute *attr,
-                                  const char *buf, size_t n)
-{
-       struct omap_uart_state *uart;
-       unsigned int value;
-
-       if (sscanf(buf, "%u", &value) != 1) {
-               printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
-               return -EINVAL;
-       }
-       sleep_timeout = value * HZ;
-       list_for_each_entry(uart, &uart_list, node)
-               uart->timeout = sleep_timeout;
-       return n;
-}
-
-static struct kobj_attribute sleep_timeout_attr =
-       __ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store);
-
-#else
-static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
-#endif /* CONFIG_PM */
-
 void __init omap_serial_init(void)
 {
        int i;
@@ -484,7 +117,6 @@ void __init omap_serial_init(void)
 
        for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
                struct plat_serial8250_port *p = serial_platform_data + i;
-               struct omap_uart_state *uart = &omap_uart[i];
 
                if (!(info->enabled_uarts & (1 << i))) {
                        p->membase = NULL;
@@ -493,30 +125,22 @@ void __init omap_serial_init(void)
                }
 
                sprintf(name, "uart%d_ick", i+1);
-               uart->ick = clk_get(NULL, name);
-               if (IS_ERR(uart->ick)) {
+               uart_ick[i] = clk_get(NULL, name);
+               if (IS_ERR(uart_ick[i])) {
                        printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
-                       uart->ick = NULL;
-               }
+                       uart_ick[i] = NULL;
+               } else
+                       clk_enable(uart_ick[i]);
 
                sprintf(name, "uart%d_fck", i+1);
-               uart->fck = clk_get(NULL, name);
-               if (IS_ERR(uart->fck)) {
+               uart_fck[i] = clk_get(NULL, name);
+               if (IS_ERR(uart_fck[i])) {
                        printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
-                       uart->fck = NULL;
-               }
-
-               if (!uart->ick || !uart->fck)
-                       continue;
-
-               uart->num = i;
-               p->private_data = uart;
-               uart->p = p;
-               list_add(&uart->node, &uart_list);
+                       uart_fck[i] = NULL;
+               } else
+                       clk_enable(uart_fck[i]);
 
-               omap_uart_enable_clocks(uart);
-               omap_uart_reset(uart);
-               omap_uart_idle_init(uart);
+               omap_serial_reset(p);
        }
 }
 
@@ -530,15 +154,6 @@ static struct platform_device serial_device = {
 
 static int __init omap_init(void)
 {
-       int ret;
-
-       ret = platform_device_register(&serial_device);
-
-#ifdef CONFIG_PM
-       if (!ret)
-               ret = sysfs_create_file(&serial_device.dev.kobj,
-                                       &sleep_timeout_attr.attr);
-#endif
-       return ret;
+       return platform_device_register(&serial_device);
 }
 arch_initcall(omap_init);