Merge branch 'for_3.3/uart/runtime-pm' of git://git.kernel.org/pub/scm/linux/kernel...
authorTony Lindgren <tony@atomide.com>
Fri, 16 Dec 2011 22:01:03 +0000 (14:01 -0800)
committerTony Lindgren <tony@atomide.com>
Fri, 16 Dec 2011 22:01:03 +0000 (14:01 -0800)
Conflicts:
arch/arm/mach-omap2/pm34xx.c

34 files changed:
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-n8x0.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-ti8168evm.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/common.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/control.h
arch/arm/mach-omap2/cpuidle34xx.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/include/mach/debug-macro.S
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/irq.c
arch/arm/mach-omap2/opp2xxx.h
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/serial.c
arch/arm/plat-omap/Makefile
arch/arm/plat-omap/include/plat/am33xx.h [new file with mode: 0644]
arch/arm/plat-omap/include/plat/clock.h
arch/arm/plat-omap/include/plat/cpu.h
arch/arm/plat-omap/include/plat/hardware.h
arch/arm/plat-omap/include/plat/io.h
arch/arm/plat-omap/include/plat/omap-serial.h
arch/arm/plat-omap/include/plat/omap34xx.h
arch/arm/plat-omap/include/plat/serial.h
arch/arm/plat-omap/include/plat/ti816x.h [deleted file]
arch/arm/plat-omap/include/plat/ti81xx.h [new file with mode: 0644]
arch/arm/plat-omap/include/plat/uncompress.h
drivers/tty/serial/omap-serial.c

index 50f43942c1aa8f5091b16c8a11669505f0aed1a8..a34d0f7d1bfaea554a9cf577ae807a76d656c692 100644 (file)
@@ -76,8 +76,13 @@ config SOC_OMAP3430
        default y
        select ARCH_OMAP_OTG
 
-config SOC_OMAPTI816X
-       bool "TI816X support"
+config SOC_OMAPTI81XX
+       bool "TI81XX support"
+       depends on ARCH_OMAP3
+       default y
+
+config SOC_OMAPAM33XX
+       bool "AM33XX support"
        depends on ARCH_OMAP3
        default y
 
@@ -314,7 +319,7 @@ config MACH_OMAP_3630SDP
 
 config MACH_TI8168EVM
        bool "TI8168 Evaluation Module"
-       depends on SOC_OMAPTI816X
+       depends on SOC_OMAPTI81XX
        default y
 
 config MACH_OMAP_4430SDP
index 83126368ed99f2bf0d32679c0ec1e2cb265a5516..109b434159f566ef7856d135ba342cc6a7fa8267 100644 (file)
@@ -475,106 +475,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 static struct omap_board_mux board_mux[] __initdata = {
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
-
-static struct omap_device_pad serial1_pads[] __initdata = {
-       /*
-        * Note that off output enable is an active low
-        * signal. So setting this means pin is a
-        * input enabled in off mode
-        */
-       OMAP_MUX_STATIC("uart1_cts.uart1_cts",
-                        OMAP_PIN_INPUT |
-                        OMAP_PIN_OFF_INPUT_PULLDOWN |
-                        OMAP_OFFOUT_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart1_rts.uart1_rts",
-                        OMAP_PIN_OUTPUT |
-                        OMAP_OFF_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart1_rx.uart1_rx",
-                        OMAP_PIN_INPUT |
-                        OMAP_PIN_OFF_INPUT_PULLDOWN |
-                        OMAP_OFFOUT_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart1_tx.uart1_tx",
-                        OMAP_PIN_OUTPUT |
-                        OMAP_OFF_EN |
-                        OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial2_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-                        OMAP_PIN_INPUT_PULLUP |
-                        OMAP_PIN_OFF_INPUT_PULLDOWN |
-                        OMAP_OFFOUT_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-                        OMAP_PIN_OUTPUT |
-                        OMAP_OFF_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-                        OMAP_PIN_INPUT |
-                        OMAP_PIN_OFF_INPUT_PULLDOWN |
-                        OMAP_OFFOUT_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-                        OMAP_PIN_OUTPUT |
-                        OMAP_OFF_EN |
-                        OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-                        OMAP_PIN_INPUT_PULLDOWN |
-                        OMAP_PIN_OFF_INPUT_PULLDOWN |
-                        OMAP_OFFOUT_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-                        OMAP_PIN_OUTPUT |
-                        OMAP_OFF_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-                        OMAP_PIN_INPUT |
-                        OMAP_PIN_OFF_INPUT_PULLDOWN |
-                        OMAP_OFFOUT_EN |
-                        OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-                        OMAP_PIN_OUTPUT |
-                        OMAP_OFF_EN |
-                        OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial1_data __initdata = {
-       .id             = 0,
-       .pads           = serial1_pads,
-       .pads_cnt       = ARRAY_SIZE(serial1_pads),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-       .id             = 1,
-       .pads           = serial2_pads,
-       .pads_cnt       = ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-       .id             = 2,
-       .pads           = serial3_pads,
-       .pads_cnt       = ARRAY_SIZE(serial3_pads),
-};
-
-static inline void board_serial_init(void)
-{
-       omap_serial_init_port(&serial1_data);
-       omap_serial_init_port(&serial2_data);
-       omap_serial_init_port(&serial3_data);
-}
 #else
 #define board_mux      NULL
-
-static inline void board_serial_init(void)
-{
-       omap_serial_init();
-}
 #endif
 
 /*
@@ -711,7 +613,7 @@ static void __init omap_3430sdp_init(void)
        else
                gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
        omap_ads7846_init(1, gpio_pendown, 310, NULL);
-       board_serial_init();
+       omap_serial_init();
        omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
        usb_musb_init(NULL);
        board_smc91x_init();
index ef2bbc09428a2e29b2786bbeb623ac307e1d1ed8..5f264fad69bc3197f22739af5ab6fc0bd387244b 100644 (file)
@@ -837,74 +837,8 @@ static struct omap_board_mux board_mux[] __initdata = {
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
-static struct omap_device_pad serial2_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-                        OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial4_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart4_rx.uart4_rx",
-                        OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart4_tx.uart4_tx",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-       .id             = 1,
-       .pads           = serial2_pads,
-       .pads_cnt       = ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-       .id             = 2,
-       .pads           = serial3_pads,
-       .pads_cnt       = ARRAY_SIZE(serial3_pads),
-};
-
-static struct omap_board_data serial4_data __initdata = {
-       .id             = 3,
-       .pads           = serial4_pads,
-       .pads_cnt       = ARRAY_SIZE(serial4_pads),
-};
-
-static inline void board_serial_init(void)
-{
-       struct omap_board_data bdata;
-       bdata.flags     = 0;
-       bdata.pads      = NULL;
-       bdata.pads_cnt  = 0;
-       bdata.id        = 0;
-       /* pass dummy data for UART1 */
-       omap_serial_init_port(&bdata);
-
-       omap_serial_init_port(&serial2_data);
-       omap_serial_init_port(&serial3_data);
-       omap_serial_init_port(&serial4_data);
-}
 #else
 #define board_mux      NULL
-
-static inline void board_serial_init(void)
-{
-       omap_serial_init();
-}
  #endif
 
 static void omap4_sdp4430_wifi_mux_init(void)
@@ -954,7 +888,7 @@ static void __init omap_4430sdp_init(void)
        omap4_i2c_init();
        omap_sfh7741prox_init();
        platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
-       board_serial_init();
+       omap_serial_init();
        omap_sdrc_init(NULL, NULL);
        omap4_sdp4430_wifi_init();
        omap4_twl6030_hsmmc_init(mmc);
index bebd3d84365eec43e34eb5f786b1956c27e0a15b..118f38c4b37d1be9cf7dbc58722c2c560fdfd032 100644 (file)
@@ -644,15 +644,15 @@ static inline void board_serial_init(void)
        bdata.pads_cnt = 0;
 
        bdata.id = 0;
-       omap_serial_init_port(&bdata);
+       omap_serial_init_port(&bdata, NULL);
 
        bdata.id = 1;
-       omap_serial_init_port(&bdata);
+       omap_serial_init_port(&bdata, NULL);
 
        bdata.id = 2;
        bdata.pads = serial2_pads;
        bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
-       omap_serial_init_port(&bdata);
+       omap_serial_init_port(&bdata, NULL);
 }
 
 #else
index b6f114436dbc74bb93d09300deef50db59b57c52..ea45f5835103395a2825134e5406c73448ec1bd3 100644 (file)
@@ -364,74 +364,8 @@ static struct omap_board_mux board_mux[] __initdata = {
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
-static struct omap_device_pad serial2_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-                        OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-                        OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial4_pads[] __initdata = {
-       OMAP_MUX_STATIC("uart4_rx.uart4_rx",
-                        OMAP_PIN_INPUT | OMAP_MUX_MODE0),
-       OMAP_MUX_STATIC("uart4_tx.uart4_tx",
-                        OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-       .id             = 1,
-       .pads           = serial2_pads,
-       .pads_cnt       = ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-       .id             = 2,
-       .pads           = serial3_pads,
-       .pads_cnt       = ARRAY_SIZE(serial3_pads),
-};
-
-static struct omap_board_data serial4_data __initdata = {
-       .id             = 3,
-       .pads           = serial4_pads,
-       .pads_cnt       = ARRAY_SIZE(serial4_pads),
-};
-
-static inline void board_serial_init(void)
-{
-       struct omap_board_data bdata;
-       bdata.flags     = 0;
-       bdata.pads      = NULL;
-       bdata.pads_cnt  = 0;
-       bdata.id        = 0;
-       /* pass dummy data for UART1 */
-       omap_serial_init_port(&bdata);
-
-       omap_serial_init_port(&serial2_data);
-       omap_serial_init_port(&serial3_data);
-       omap_serial_init_port(&serial4_data);
-}
 #else
 #define board_mux      NULL
-
-static inline void board_serial_init(void)
-{
-       omap_serial_init();
-}
 #endif
 
 /* Display DVI */
@@ -562,7 +496,7 @@ static void __init omap4_panda_init(void)
        omap4_panda_i2c_init();
        platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
        platform_device_register(&omap_vwlan_device);
-       board_serial_init();
+       omap_serial_init();
        omap_sdrc_init(NULL, NULL);
        omap4_twl6030_hsmmc_init(mmc);
        omap4_ehci_init();
index 8402b39b28405bb86f5ceceb2177c4c3874ef2c4..b236fcc023ac0f9efbb59a3d7fb358c658e4c2f8 100644 (file)
@@ -35,17 +35,12 @@ static void __init ti8168_evm_init(void)
        omap_board_config_size = ARRAY_SIZE(ti8168_evm_config);
 }
 
-static void __init ti8168_evm_map_io(void)
-{
-       omapti816x_map_common_io();
-}
-
 MACHINE_START(TI8168EVM, "ti8168evm")
        /* Maintainer: Texas Instruments */
        .atag_offset    = 0x100,
-       .map_io         = ti8168_evm_map_io,
-       .init_early     = ti816x_init_early,
-       .init_irq       = ti816x_init_irq,
+       .map_io         = ti81xx_map_io,
+       .init_early     = ti81xx_init_early,
+       .init_irq       = ti81xx_init_irq,
        .timer          = &omap3_timer,
        .init_machine   = ti8168_evm_init,
 MACHINE_END
index 1f3481f8d695f73a71bf8725eba18ca4c702a58e..f57ed5baeccf78f93c6b7f0a012a7b0da083c193 100644 (file)
@@ -35,7 +35,7 @@
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 
-u8 cpu_mask;
+u16 cpu_mask;
 
 /*
  * clkdm_control: if true, then when a clock is enabled in the
index 2311bc2172264248aa181f75fb579c6e6b218fbd..b8c2a686481ca313298253246e789e1ce844feea 100644 (file)
@@ -132,7 +132,7 @@ void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
                               const char *core_ck_name,
                               const char *mpu_ck_name);
 
-extern u8 cpu_mask;
+extern u16 cpu_mask;
 
 extern const struct clkops clkops_omap2_dflt_wait;
 extern const struct clkops clkops_dummy;
index 5d0064a4fb5a638bb1141489354244e95899c1a1..60424f41156b0ff147a5e4b489399adfbaf359e1 100644 (file)
@@ -3517,6 +3517,10 @@ int __init omap3xxx_clk_init(void)
        } else if (cpu_is_ti816x()) {
                cpu_mask = RATE_IN_TI816X;
                cpu_clkflg = CK_TI816X;
+       } else if (cpu_is_am33xx()) {
+               cpu_mask = RATE_IN_AM33XX;
+       } else if (cpu_is_ti814x()) {
+               cpu_mask = RATE_IN_TI814X;
        } else if (cpu_is_omap34xx()) {
                if (omap_rev() == OMAP3430_REV_ES1_0) {
                        cpu_mask = RATE_IN_3430ES1;
@@ -3600,7 +3604,7 @@ int __init omap3xxx_clk_init(void)
         * Lock DPLL5 -- here only until other device init code can
         * handle this
         */
-       if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0))
+       if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0))
                omap3_clk_lock_dpll5();
 
        /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
index 684b8a7cd401adcd034b7ab23a4f7852680eff34..aaf421178c919ad0c4b77fda64f18fe446c509a8 100644 (file)
@@ -110,23 +110,49 @@ void __init omap3_map_io(void)
 
 /*
  * Adjust TAP register base such that omap3_check_revision accesses the correct
- * TI816X register for checking device ID (it adds 0x204 to tap base while
- * TI816X DEVICE ID register is at offset 0x600 from control base).
+ * TI81XX register for checking device ID (it adds 0x204 to tap base while
+ * TI81XX DEVICE ID register is at offset 0x600 from control base).
  */
-#define TI816X_TAP_BASE                (TI816X_CTRL_BASE + \
-                               TI816X_CONTROL_DEVICE_ID - 0x204)
+#define TI81XX_TAP_BASE                (TI81XX_CTRL_BASE + \
+                               TI81XX_CONTROL_DEVICE_ID - 0x204)
 
-static struct omap_globals ti816x_globals = {
+static struct omap_globals ti81xx_globals = {
        .class  = OMAP343X_CLASS,
-       .tap    = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE),
-       .ctrl   = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE),
-       .prm    = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE),
-       .cm     = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE),
+       .tap    = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE),
+       .ctrl   = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
+       .prm    = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
+       .cm     = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
 };
 
-void __init omap2_set_globals_ti816x(void)
+void __init omap2_set_globals_ti81xx(void)
 {
-       __omap2_set_globals(&ti816x_globals);
+       __omap2_set_globals(&ti81xx_globals);
+}
+
+void __init ti81xx_map_io(void)
+{
+       omapti81xx_map_common_io();
+}
+
+#define AM33XX_TAP_BASE                (AM33XX_CTRL_BASE + \
+                               TI81XX_CONTROL_DEVICE_ID - 0x204)
+
+static struct omap_globals am33xx_globals = {
+       .class  = AM335X_CLASS,
+       .tap    = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE),
+       .ctrl   = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
+       .prm    = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
+       .cm     = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
+};
+
+void __init omap2_set_globals_am33xx(void)
+{
+       __omap2_set_globals(&am33xx_globals);
+}
+
+void __init am33xx_map_io(void)
+{
+       omapam33xx_map_common_io();
 }
 #endif
 
index 0911e843f079ae256859fcf3fff01364b02657fe..90bd2ae8559638144fa6d1e569dc191aafe9c22a 100644 (file)
@@ -54,10 +54,18 @@ static inline void omap34xx_map_common_io(void)
 }
 #endif
 
-#ifdef CONFIG_SOC_OMAPTI816X
-extern void omapti816x_map_common_io(void);
+#ifdef CONFIG_SOC_OMAPTI81XX
+extern void omapti81xx_map_common_io(void);
 #else
-static inline void omapti816x_map_common_io(void)
+static inline void omapti81xx_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAPAM33XX
+extern void omapam33xx_map_common_io(void);
+#else
+static inline void omapam33xx_map_common_io(void)
 {
 }
 #endif
@@ -84,7 +92,7 @@ void omap35xx_init_early(void);
 void omap3630_init_early(void);
 void omap3_init_early(void);   /* Do not use this one */
 void am35xx_init_early(void);
-void ti816x_init_early(void);
+void ti81xx_init_early(void);
 void omap4430_init_early(void);
 
 /*
@@ -108,7 +116,8 @@ void omap2_set_globals_242x(void);
 void omap2_set_globals_243x(void);
 void omap2_set_globals_3xxx(void);
 void omap2_set_globals_443x(void);
-void omap2_set_globals_ti816x(void);
+void omap2_set_globals_ti81xx(void);
+void omap2_set_globals_am33xx(void);
 
 /* These get called from omap2_set_globals_xxxx(), do not call these */
 void omap2_set_globals_tap(struct omap_globals *);
@@ -119,7 +128,9 @@ void omap2_set_globals_prcm(struct omap_globals *);
 void omap242x_map_io(void);
 void omap243x_map_io(void);
 void omap3_map_io(void);
+void am33xx_map_io(void);
 void omap4_map_io(void);
+void ti81xx_map_io(void);
 
 /**
  * omap_test_timeout - busy-loop, testing a condition
@@ -148,7 +159,7 @@ extern struct device *omap4_get_dsp_device(void);
 
 void omap2_init_irq(void);
 void omap3_init_irq(void);
-void ti816x_init_irq(void);
+void ti81xx_init_irq(void);
 extern int omap_irq_pending(void);
 void omap_intc_save_context(void);
 void omap_intc_restore_context(void);
index d4ef75d5a3823d0f85336e8f416e8d861553f83a..0ba68d3764bc932b3ff85091203559b5f0d323be 100644 (file)
@@ -52,8 +52,8 @@
 #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00
 #define OMAP343X_CONTROL_GENERAL_WKUP  0xa60
 
-/* TI816X spefic control submodules */
-#define TI816X_CONTROL_DEVCONF         0x600
+/* TI81XX spefic control submodules */
+#define TI81XX_CONTROL_DEVCONF         0x600
 
 /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
 
 #define OMAP3_PADCONF_SAD2D_MSTANDBY   0x250
 #define OMAP3_PADCONF_SAD2D_IDLEACK    0x254
 
-/* TI816X CONTROL_DEVCONF register offsets */
-#define TI816X_CONTROL_DEVICE_ID       (TI816X_CONTROL_DEVCONF + 0x000)
+/* TI81XX CONTROL_DEVCONF register offsets */
+#define TI81XX_CONTROL_DEVICE_ID       (TI81XX_CONTROL_DEVCONF + 0x000)
 
 /*
  * REVISIT: This list of registers is not comprehensive - there are more
index 1f71ebb6c12cc649a7243d07780ddb962bb20ae7..464cffde58fe9ecb5c6b26af3f4409b9d34506f3 100644 (file)
@@ -31,7 +31,6 @@
 #include <plat/irqs.h>
 #include "powerdomain.h"
 #include "clockdomain.h"
-#include <plat/serial.h>
 
 #include "pm.h"
 #include "control.h"
@@ -260,11 +259,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
        struct omap3_idle_statedata *cx;
        int ret;
 
-       if (!omap3_can_sleep()) {
-               new_state_idx = drv->safe_state_index;
-               goto select_state;
-       }
-
        /*
         * Prevent idle completely if CAM is active.
         * CAM does not have wakeup capability in OMAP3.
index 27ad722df637d29b33634a2586e21df55addcda1..6c5826605eaec5792b5f93c137fc9e32c2bc9f9f 100644 (file)
@@ -226,7 +226,7 @@ static void __init omap4_check_features(void)
        }
 }
 
-static void __init ti816x_check_features(void)
+static void __init ti81xx_check_features(void)
 {
        omap_features = OMAP3_HAS_NEON;
 }
@@ -340,6 +340,29 @@ static void __init omap3_check_revision(const char **cpu_rev)
                        break;
                }
                break;
+       case 0xb944:
+               omap_revision = AM335X_REV_ES1_0;
+               *cpu_rev = "1.0";
+       case 0xb8f2:
+               switch (rev) {
+               case 0:
+               /* FALLTHROUGH */
+               case 1:
+                       omap_revision = TI8148_REV_ES1_0;
+                       *cpu_rev = "1.0";
+                       break;
+               case 2:
+                       omap_revision = TI8148_REV_ES2_0;
+                       *cpu_rev = "2.0";
+                       break;
+               case 3:
+               /* FALLTHROUGH */
+               default:
+                       omap_revision = TI8148_REV_ES2_1;
+                       *cpu_rev = "2.1";
+                       break;
+               }
+               break;
        default:
                /* Unknown default to latest silicon rev as default */
                omap_revision = OMAP3630_REV_ES1_2;
@@ -367,7 +390,7 @@ static void __init omap4_check_revision(void)
         * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
         * Use ARM register to detect the correct ES version
         */
-       if (!rev && (hawkeye != 0xb94e)) {
+       if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
                idcode = read_cpuid(CPUID_ID);
                rev = (idcode & 0xf) - 1;
        }
@@ -389,8 +412,11 @@ static void __init omap4_check_revision(void)
                        omap_revision = OMAP4430_REV_ES2_1;
                        break;
                case 4:
-               default:
                        omap_revision = OMAP4430_REV_ES2_2;
+                       break;
+               case 6:
+               default:
+                       omap_revision = OMAP4430_REV_ES2_3;
                }
                break;
        case 0xb94e:
@@ -401,9 +427,17 @@ static void __init omap4_check_revision(void)
                        break;
                }
                break;
+       case 0xb975:
+               switch (rev) {
+               case 0:
+               default:
+                       omap_revision = OMAP4470_REV_ES1_0;
+                       break;
+               }
+               break;
        default:
                /* Unknown default to latest silicon rev as default */
-               omap_revision = OMAP4430_REV_ES2_2;
+               omap_revision = OMAP4430_REV_ES2_3;
        }
 
        pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16,
@@ -432,6 +466,10 @@ static void __init omap3_cpuinfo(const char *cpu_rev)
                cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
        } else if (cpu_is_ti816x()) {
                cpu_name = "TI816X";
+       } else if (cpu_is_am335x()) {
+               cpu_name =  "AM335X";
+       } else if (cpu_is_ti814x()) {
+               cpu_name = "TI814X";
        } else if (omap3_has_iva() && omap3_has_sgx()) {
                /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
                cpu_name = "OMAP3430/3530";
@@ -472,11 +510,11 @@ void __init omap2_check_revision(void)
        } else if (cpu_is_omap34xx()) {
                omap3_check_revision(&cpu_rev);
 
-               /* TI816X doesn't have feature register */
-               if (!cpu_is_ti816x())
+               /* TI81XX doesn't have feature register */
+               if (!cpu_is_ti81xx())
                        omap3_check_features();
                else
-                       ti816x_check_features();
+                       ti81xx_check_features();
 
                omap3_cpuinfo(cpu_rev);
                return;
index 13f98e59cfef87ebb44379f42ce2a965345c8a47..cdfc2a1f0e75778bcbe549b8b86dae212bed25ba 100644 (file)
@@ -66,11 +66,11 @@ omap_uart_lsr:      .word   0
                beq     34f                     @ configure OMAP3UART4
                cmp     \rp, #OMAP4UART4        @ only on 44xx
                beq     44f                     @ configure OMAP4UART4
-               cmp     \rp, #TI816XUART1       @ ti816x UART offsets different
+               cmp     \rp, #TI81XXUART1       @ ti81Xx UART offsets different
                beq     81f                     @ configure UART1
-               cmp     \rp, #TI816XUART2       @ ti816x UART offsets different
+               cmp     \rp, #TI81XXUART2       @ ti81Xx UART offsets different
                beq     82f                     @ configure UART2
-               cmp     \rp, #TI816XUART3       @ ti816x UART offsets different
+               cmp     \rp, #TI81XXUART3       @ ti81Xx UART offsets different
                beq     83f                     @ configure UART3
                cmp     \rp, #ZOOM_UART         @ only on zoom2/3
                beq     95f                     @ configure ZOOM_UART
@@ -94,11 +94,11 @@ omap_uart_lsr:      .word   0
                b       98f
 44:            mov     \rp, #UART_OFFSET(OMAP4_UART4_BASE)
                b       98f
-81:            mov     \rp, #UART_OFFSET(TI816X_UART1_BASE)
+81:            mov     \rp, #UART_OFFSET(TI81XX_UART1_BASE)
                b       98f
-82:            mov     \rp, #UART_OFFSET(TI816X_UART2_BASE)
+82:            mov     \rp, #UART_OFFSET(TI81XX_UART2_BASE)
                b       98f
-83:            mov     \rp, #UART_OFFSET(TI816X_UART3_BASE)
+83:            mov     \rp, #UART_OFFSET(TI81XX_UART3_BASE)
                b       98f
 
 95:            ldr     \rp, =ZOOM_UART_BASE
index 65843390e7f00f3c3f751a64c5e5e0d5621b650f..3f174d51f67fb8e4f41f01ebbbe577c892999449 100644 (file)
@@ -176,14 +176,31 @@ static struct map_desc omap34xx_io_desc[] __initdata = {
 };
 #endif
 
-#ifdef CONFIG_SOC_OMAPTI816X
-static struct map_desc omapti816x_io_desc[] __initdata = {
+#ifdef CONFIG_SOC_OMAPTI81XX
+static struct map_desc omapti81xx_io_desc[] __initdata = {
+       {
+               .virtual        = L4_34XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_34XX_PHYS),
+               .length         = L4_34XX_SIZE,
+               .type           = MT_DEVICE
+       }
+};
+#endif
+
+#ifdef CONFIG_SOC_OMAPAM33XX
+static struct map_desc omapam33xx_io_desc[] __initdata = {
        {
                .virtual        = L4_34XX_VIRT,
                .pfn            = __phys_to_pfn(L4_34XX_PHYS),
                .length         = L4_34XX_SIZE,
                .type           = MT_DEVICE
        },
+       {
+               .virtual        = L4_WK_AM33XX_VIRT,
+               .pfn            = __phys_to_pfn(L4_WK_AM33XX_PHYS),
+               .length         = L4_WK_AM33XX_SIZE,
+               .type           = MT_DEVICE
+       }
 };
 #endif
 
@@ -272,10 +289,17 @@ void __init omap34xx_map_common_io(void)
 }
 #endif
 
-#ifdef CONFIG_SOC_OMAPTI816X
-void __init omapti816x_map_common_io(void)
+#ifdef CONFIG_SOC_OMAPTI81XX
+void __init omapti81xx_map_common_io(void)
+{
+       iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAPAM33XX
+void __init omapam33xx_map_common_io(void)
 {
-       iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc));
+       iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
 }
 #endif
 
@@ -427,9 +451,9 @@ void __init am35xx_init_early(void)
        omap3_init_early();
 }
 
-void __init ti816x_init_early(void)
+void __init ti81xx_init_early(void)
 {
-       omap2_set_globals_ti816x();
+       omap2_set_globals_ti81xx();
        omap_common_init_early();
        omap3xxx_voltagedomains_init();
        omap3xxx_powerdomains_init();
index 42b1d659191215582f1288893a919881ee0dd13d..1fef061f7927929be28987d7ca10b270f05f04d3 100644 (file)
@@ -193,7 +193,7 @@ void __init omap3_init_irq(void)
        omap_init_irq(OMAP34XX_IC_BASE, 96);
 }
 
-void __init ti816x_init_irq(void)
+void __init ti81xx_init_irq(void)
 {
        omap_init_irq(OMAP34XX_IC_BASE, 128);
 }
index 8affc66a92c2c51745b2e380bdfb11e903741ed3..8fae534eb15711fe81d5f203821b5cf4823c8ab6 100644 (file)
@@ -51,7 +51,7 @@ struct prcm_config {
        unsigned long cm_clksel2_pll;   /* dpllx1 or x2 out */
        unsigned long cm_clksel_mdm;    /* modem dividers 2430 only */
        unsigned long base_sdrc_rfr;    /* base refresh timing for a set */
-       unsigned char flags;
+       unsigned short flags;
 };
 
 
index ef8595c802966e53993103fcbecaeed33318e1fe..b8822f8b289184c46332732bc20ebe2ea5605cb3 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
-#include <linux/console.h>
 
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
@@ -127,27 +126,11 @@ static void omap2_enter_full_retention(void)
        if (omap_irq_pending())
                goto no_sleep;
 
-       /* Block console output in case it is on one of the OMAP UARTs */
-       if (!is_suspending())
-               if (!console_trylock())
-                       goto no_sleep;
-
-       omap_uart_prepare_idle(0);
-       omap_uart_prepare_idle(1);
-       omap_uart_prepare_idle(2);
-
        /* Jump to SRAM suspend code */
        omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
                           OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
                           OMAP_SDRC_REGADDR(SDRC_POWER));
 
-       omap_uart_resume_idle(2);
-       omap_uart_resume_idle(1);
-       omap_uart_resume_idle(0);
-
-       if (!is_suspending())
-               console_unlock();
-
 no_sleep:
        omap2_gpio_resume_after_idle();
 
@@ -239,8 +222,6 @@ static int omap2_can_sleep(void)
 {
        if (omap2_fclks_active())
                return 0;
-       if (!omap_uart_can_sleep())
-               return 0;
        if (osc_ck->usecount > 1)
                return 0;
        if (omap_dma_running())
@@ -291,7 +272,6 @@ static int omap2_pm_suspend(void)
        mir1 = omap_readl(0x480fe0a4);
        omap_writel(1 << 5, 0x480fe0ac);
 
-       omap_uart_prepare_suspend();
        omap2_enter_full_retention();
 
        omap_writel(mir1, 0x480fe0a4);
index 53b5b1a71e0e90ce289a68f2df6780cdbd2d3bc9..fc6987578920c942ef66fd9f4dfb806f40bde8c1 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/console.h>
 #include <trace/events/power.h>
 
 #include <asm/suspend.h>
@@ -36,7 +35,6 @@
 #include <plat/sram.h>
 #include "clockdomain.h"
 #include "powerdomain.h"
-#include <plat/serial.h>
 #include <plat/sdrc.h>
 #include <plat/prcm.h>
 #include <plat/gpmc.h>
 
 #ifdef CONFIG_SUSPEND
 static suspend_state_t suspend_state = PM_SUSPEND_ON;
-static inline bool is_suspending(void)
-{
-       return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled;
-}
-#else
-static inline bool is_suspending(void)
-{
-       return false;
-}
 #endif
 
 /* pm34xx errata defined in pm.h */
@@ -337,20 +326,11 @@ void omap_sram_idle(void)
                        omap3_enable_io_chain();
        }
 
-       /* Block console output in case it is on one of the OMAP UARTs */
-       if (!is_suspending())
-               if (per_next_state < PWRDM_POWER_ON ||
-                   core_next_state < PWRDM_POWER_ON)
-                       if (!console_trylock())
-                               goto console_still_active;
-
        pwrdm_pre_transition();
 
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
                per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
-               omap_uart_prepare_idle(2);
-               omap_uart_prepare_idle(3);
                omap2_gpio_prepare_for_idle(per_going_off);
                if (per_next_state == PWRDM_POWER_OFF)
                                omap3_per_save_context();
@@ -358,8 +338,6 @@ void omap_sram_idle(void)
 
        /* CORE */
        if (core_next_state < PWRDM_POWER_ON) {
-               omap_uart_prepare_idle(0);
-               omap_uart_prepare_idle(1);
                if (core_next_state == PWRDM_POWER_OFF) {
                        omap3_core_save_context();
                        omap3_cm_save_context();
@@ -408,8 +386,6 @@ void omap_sram_idle(void)
                        omap3_sram_restore_context();
                        omap2_sms_restore_context();
                }
-               omap_uart_resume_idle(0);
-               omap_uart_resume_idle(1);
                if (core_next_state == PWRDM_POWER_OFF)
                        omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
                                               OMAP3430_GR_MOD,
@@ -425,14 +401,8 @@ void omap_sram_idle(void)
                omap2_gpio_resume_after_idle();
                if (per_prev_state == PWRDM_POWER_OFF)
                        omap3_per_restore_context();
-               omap_uart_resume_idle(2);
-               omap_uart_resume_idle(3);
        }
 
-       if (!is_suspending())
-               console_unlock();
-
-console_still_active:
        /* Disable IO-PAD and IO-CHAIN wakeup */
        if (omap3_has_io_wakeup() &&
            (per_next_state < PWRDM_POWER_ON ||
@@ -446,21 +416,11 @@ console_still_active:
        clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
 }
 
-int omap3_can_sleep(void)
-{
-       if (!omap_uart_can_sleep())
-               return 0;
-       return 1;
-}
-
 static void omap3_pm_idle(void)
 {
        local_irq_disable();
        local_fiq_disable();
 
-       if (!omap3_can_sleep())
-               goto out;
-
        if (omap_irq_pending() || need_resched())
                goto out;
 
@@ -494,7 +454,6 @@ static int omap3_pm_suspend(void)
                        goto restore;
        }
 
-       omap_uart_prepare_suspend();
        omap3_intc_suspend();
 
        omap_sram_idle();
@@ -541,7 +500,6 @@ static int omap3_pm_begin(suspend_state_t state)
 {
        disable_hlt();
        suspend_state = state;
-       omap_uart_enable_irqs(0);
        omap_prcm_irq_prepare();
        return 0;
 }
@@ -549,7 +507,6 @@ static int omap3_pm_begin(suspend_state_t state)
 static void omap3_pm_end(void)
 {
        suspend_state = PM_SUSPEND_ON;
-       omap_uart_enable_irqs(1);
        enable_hlt();
        return;
 }
index 42c326732a29a078f93f2a1874dadcfe5fd6c16c..247d89478f2439010c741045518d455e78e73d17 100644 (file)
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/serial_reg.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/serial_8250.h>
 #include <linux/pm_runtime.h>
 #include <linux/console.h>
 
-#ifdef CONFIG_SERIAL_OMAP
 #include <plat/omap-serial.h>
-#endif
-
 #include "common.h"
 #include <plat/board.h>
-#include <plat/clock.h>
 #include <plat/dma.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
+#include <plat/omap-pm.h>
 
 #include "prm2xxx_3xxx.h"
 #include "pm.h"
 #include "control.h"
 #include "mux.h"
 
-#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV    0x52
-#define UART_OMAP_WER          0x17    /* Wake-up enable register */
-
-#define UART_ERRATA_FIFO_FULL_ABORT    (0x1 << 0)
-#define UART_ERRATA_i202_MDR1_ACCESS   (0x1 << 1)
-
 /*
- * NOTE: By default the serial timeout is disabled as it causes lost characters
- * over the serial ports. This means that the UART clocks will stay on until
- * disabled via sysfs. This also causes that any deeper omap sleep states are
- * blocked. 
+ * NOTE: By default the serial auto_suspend timeout is disabled as it causes
+ * lost characters over the serial ports. This means that the UART clocks will
+ * stay on until power/autosuspend_delay is set for the uart from sysfs.
+ * This also causes that any deeper omap sleep states are blocked.
  */
-#define DEFAULT_TIMEOUT 0
+#define DEFAULT_AUTOSUSPEND_DELAY      -1
 
 #define MAX_UART_HWMOD_NAME_LEN                16
 
 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;
-       u32 dma_enabled;
-
-       struct clk *ick;
-       struct clk *fck;
-       int clocked;
-
-       int irq;
-       int regshift;
-       int irqflags;
-       void __iomem *membase;
-       resource_size_t mapbase;
 
        struct list_head node;
        struct omap_hwmod *oh;
        struct platform_device *pdev;
-
-       u32 errata;
-#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;
-       u16 mcr;
-#endif
 };
 
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
+static u8 console_uart_id = -1;
+static u8 no_console_suspend;
+static u8 uart_debug;
+
+#define DEFAULT_RXDMA_POLLRATE         1       /* RX DMA polling rate (us) */
+#define DEFAULT_RXDMA_BUFSIZE          4096    /* RX DMA buffer size */
+#define DEFAULT_RXDMA_TIMEOUT          (3 * HZ)/* RX DMA timeout (jiffies) */
+
+static struct omap_uart_port_info omap_serial_default_info[] __initdata = {
+       {
+               .dma_enabled    = false,
+               .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
+               .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
+               .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
+               .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY,
+       },
+};
 
-static inline unsigned int __serial_read_reg(struct uart_port *up,
-                                            int offset)
-{
-       offset <<= up->regshift;
-       return (unsigned int)__raw_readb(up->membase + offset);
-}
-
-static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
-                                          int offset)
+#ifdef CONFIG_PM
+static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
 {
-       offset <<= uart->regshift;
-       return (unsigned int)__raw_readb(uart->membase + offset);
-}
+       struct omap_device *od = to_omap_device(pdev);
 
-static inline void __serial_write_reg(struct uart_port *up, int offset,
-               int value)
-{
-       offset <<= up->regshift;
-       __raw_writeb(value, up->membase + offset);
-}
+       if (!od)
+               return;
 
-static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
-                                   int value)
-{
-       offset <<= uart->regshift;
-       __raw_writeb(value, uart->membase + offset);
+       if (enable)
+               omap_hwmod_enable_wakeup(od->hwmods[0]);
+       else
+               omap_hwmod_disable_wakeup(od->hwmods[0]);
 }
 
 /*
- * Internal UARTs need to be initialized for the 8250 autoconfig to work
- * properly. Note that the TX watermark initialization may not be needed
- * once the 8250.c watermark handling code is merged.
+ * Errata i291: [UART]:Cannot Acknowledge Idle Requests
+ * in Smartidle Mode When Configured for DMA Operations.
+ * WA: configure uart in force idle mode.
  */
-
-static inline void __init omap_uart_reset(struct omap_uart_state *uart)
+static void omap_uart_set_noidle(struct platform_device *pdev)
 {
-       serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
-       serial_write_reg(uart, UART_OMAP_SCR, 0x08);
-       serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
-}
-
-#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+       struct omap_device *od = to_omap_device(pdev);
 
-/*
- * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
- * The access to uart register after MDR1 Access
- * causes UART to corrupt data.
- *
- * Need a delay =
- * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
- * give 10 times as much
- */
-static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
-               u8 fcr_val)
-{
-       u8 timeout = 255;
-
-       serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
-       udelay(2);
-       serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
-                       UART_FCR_CLEAR_RCVR);
-       /*
-        * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
-        * TX_FIFO_E bit is 1.
-        */
-       while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
-                               (UART_LSR_THRE | UART_LSR_DR))) {
-               timeout--;
-               if (!timeout) {
-                       /* Should *never* happen. we warn and carry on */
-                       dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
-                       serial_read_reg(uart, UART_LSR));
-                       break;
-               }
-               udelay(1);
-       }
+       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
 }
 
-static void omap_uart_save_context(struct omap_uart_state *uart)
+static void omap_uart_set_forceidle(struct platform_device *pdev)
 {
-       u16 lcr = 0;
+       struct omap_device *od = to_omap_device(pdev);
 
-       if (!enable_off_mode)
-               return;
-
-       lcr = serial_read_reg(uart, UART_LCR);
-       serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-       uart->dll = serial_read_reg(uart, UART_DLL);
-       uart->dlh = serial_read_reg(uart, UART_DLM);
-       serial_write_reg(uart, UART_LCR, lcr);
-       uart->ier = serial_read_reg(uart, UART_IER);
-       uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
-       uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
-       uart->wer = serial_read_reg(uart, UART_OMAP_WER);
-       serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
-       uart->mcr = serial_read_reg(uart, UART_MCR);
-       serial_write_reg(uart, UART_LCR, lcr);
-
-       uart->context_valid = 1;
+       omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
 }
 
-static void omap_uart_restore_context(struct omap_uart_state *uart)
-{
-       u16 efr = 0;
-
-       if (!enable_off_mode)
-               return;
-
-       if (!uart->context_valid)
-               return;
-
-       uart->context_valid = 0;
-
-       if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
-               omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
-       else
-               serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
-
-       serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-       efr = serial_read_reg(uart, UART_EFR);
-       serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
-       serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
-       serial_write_reg(uart, UART_IER, 0x0);
-       serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-       serial_write_reg(uart, UART_DLL, uart->dll);
-       serial_write_reg(uart, UART_DLM, uart->dlh);
-       serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
-       serial_write_reg(uart, UART_IER, uart->ier);
-       serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
-       serial_write_reg(uart, UART_MCR, uart->mcr);
-       serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-       serial_write_reg(uart, UART_EFR, efr);
-       serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
-       serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
-       serial_write_reg(uart, UART_OMAP_WER, uart->wer);
-       serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
-
-       if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
-               omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
-       else
-               /* UART 16x mode */
-               serial_write_reg(uart, UART_OMAP_MDR1,
-                               UART_OMAP_MDR1_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_PM && CONFIG_ARCH_OMAP3 */
-
-static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
-{
-       if (uart->clocked)
-               return;
-
-       omap_device_enable(uart->pdev);
-       uart->clocked = 1;
-       omap_uart_restore_context(uart);
-}
-
-#ifdef CONFIG_PM
-
-static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
-{
-       if (!uart->clocked)
-               return;
-
-       omap_uart_save_context(uart);
-       uart->clocked = 0;
-       omap_device_idle(uart->pdev);
-}
-
-static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
-{
-       /* Set wake-enable bit */
-       if (uart->wk_en && uart->wk_mask) {
-               u32 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 = omap_ctrl_readw(uart->padconf);
-               v |= OMAP3_PADCONF_WAKEUPENABLE0;
-               omap_ctrl_writew(v, uart->padconf);
-       }
-}
-
-static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
-{
-       /* Clear wake-enable bit */
-       if (uart->wk_en && uart->wk_mask) {
-               u32 v = __raw_readl(uart->wk_en);
-               v &= ~uart->wk_mask;
-               __raw_writel(v, uart->wk_en);
-       }
-
-       /* Ensure IOPAD wake-enables are cleared */
-       if (cpu_is_omap34xx() && uart->padconf) {
-               u16 v = omap_ctrl_readw(uart->padconf);
-               v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
-               omap_ctrl_writew(v, uart->padconf);
-       }
-}
-
-static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
-                                              int enable)
-{
-       u8 idlemode;
-
-       if (enable) {
-               /**
-                * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
-                * in Smartidle Mode When Configured for DMA Operations.
-                */
-               if (uart->dma_enabled)
-                       idlemode = HWMOD_IDLEMODE_FORCE;
-               else
-                       idlemode = HWMOD_IDLEMODE_SMART;
-       } else {
-               idlemode = HWMOD_IDLEMODE_NO;
-       }
-
-       omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
-}
-
-static void omap_uart_block_sleep(struct omap_uart_state *uart)
-{
-       omap_uart_enable_clocks(uart);
-
-       omap_uart_smart_idle_enable(uart, 0);
-       uart->can_sleep = 0;
-       if (uart->timeout)
-               mod_timer(&uart->timer, jiffies + uart->timeout);
-       else
-               del_timer(&uart->timer);
-}
-
-static void omap_uart_allow_sleep(struct omap_uart_state *uart)
-{
-       if (device_may_wakeup(&uart->pdev->dev))
-               omap_uart_enable_wakeup(uart);
-       else
-               omap_uart_disable_wakeup(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 (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 && uart->can_sleep) {
-                       omap_uart_enable_clocks(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);
-                       }
-
-                       /* 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;
-}
+static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable)
+{}
+static void omap_uart_set_noidle(struct platform_device *pdev) {}
+static void omap_uart_set_forceidle(struct platform_device *pdev) {}
+#endif /* CONFIG_PM */
 
-/**
- * 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 int first_interrupt; */
-static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
-{
-       struct omap_uart_state *uart = dev_id;
+#ifdef CONFIG_OMAP_MUX
+static struct omap_device_pad default_uart1_pads[] __initdata = {
+       {
+               .name   = "uart1_cts.uart1_cts",
+               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart1_rts.uart1_rts",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart1_tx.uart1_tx",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart1_rx.uart1_rx",
+               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+               .idle   = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+       },
+};
 
-       omap_uart_block_sleep(uart);
+static struct omap_device_pad default_uart2_pads[] __initdata = {
+       {
+               .name   = "uart2_cts.uart2_cts",
+               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart2_rts.uart2_rts",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart2_tx.uart2_tx",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart2_rx.uart2_rx",
+               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+               .idle   = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+       },
+};
 
-       return IRQ_NONE;
-}
+static struct omap_device_pad default_uart3_pads[] __initdata = {
+       {
+               .name   = "uart3_cts_rctx.uart3_cts_rctx",
+               .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart3_rts_sd.uart3_rts_sd",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart3_tx_irtx.uart3_tx_irtx",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart3_rx_irrx.uart3_rx_irrx",
+               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
+               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
+       },
+};
 
-static void omap_uart_idle_init(struct omap_uart_state *uart)
-{
-       int ret;
-
-       uart->can_sleep = 0;
-       uart->timeout = DEFAULT_TIMEOUT;
-       setup_timer(&uart->timer, omap_uart_idle_timer,
-                   (unsigned long) uart);
-       if (uart->timeout)
-               mod_timer(&uart->timer, jiffies + uart->timeout);
-       omap_uart_smart_idle_enable(uart, 0);
-
-       if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
-               u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
-               u32 wk_mask = 0;
-               u32 padconf = 0;
-
-               /* XXX These PRM accesses do not belong here */
-               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;
-               case 3:
-                       wk_mask = OMAP3630_ST_UART4_MASK;
-                       padconf = 0x0d2;
-                       break;
-               }
-               uart->wk_mask = wk_mask;
-               uart->padconf = padconf;
-       } else if (cpu_is_omap24xx()) {
-               u32 wk_mask = 0;
-               u32 wk_en = PM_WKEN1, wk_st = 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_en = OMAP24XX_PM_WKEN2;
-                       wk_st = OMAP24XX_PM_WKST2;
-                       wk_mask = OMAP24XX_ST_UART3_MASK;
-                       break;
-               }
-               uart->wk_mask = wk_mask;
-               if (cpu_is_omap2430()) {
-                       uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en);
-                       uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st);
-               } else if (cpu_is_omap2420()) {
-                       uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en);
-                       uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st);
-               }
-       } else {
-               uart->wk_en = NULL;
-               uart->wk_st = NULL;
-               uart->wk_mask = 0;
-               uart->padconf = 0;
-       }
+static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = {
+       {
+               .name   = "gpmc_wait2.uart4_tx",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "gpmc_wait3.uart4_rx",
+               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
+               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE2,
+       },
+};
 
-       uart->irqflags |= IRQF_SHARED;
-       ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
-                                  IRQF_SHARED, "serial idle", (void *)uart);
-       WARN_ON(ret);
-}
+static struct omap_device_pad default_omap4_uart4_pads[] __initdata = {
+       {
+               .name   = "uart4_tx.uart4_tx",
+               .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
+       },
+       {
+               .name   = "uart4_rx.uart4_rx",
+               .flags  = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+               .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
+               .idle   = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
+       },
+};
 
-void omap_uart_enable_irqs(int enable)
+static void omap_serial_fill_default_pads(struct omap_board_data *bdata)
 {
-       int ret;
-       struct omap_uart_state *uart;
-
-       list_for_each_entry(uart, &uart_list, node) {
-               if (enable) {
-                       pm_runtime_put_sync(&uart->pdev->dev);
-                       ret = request_threaded_irq(uart->irq, NULL,
-                                                  omap_uart_interrupt,
-                                                  IRQF_SHARED,
-                                                  "serial idle",
-                                                  (void *)uart);
-               } else {
-                       pm_runtime_get_noresume(&uart->pdev->dev);
-                       free_irq(uart->irq, (void *)uart);
+       switch (bdata->id) {
+       case 0:
+               bdata->pads = default_uart1_pads;
+               bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads);
+               break;
+       case 1:
+               bdata->pads = default_uart2_pads;
+               bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads);
+               break;
+       case 2:
+               bdata->pads = default_uart3_pads;
+               bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads);
+               break;
+       case 3:
+               if (cpu_is_omap44xx()) {
+                       bdata->pads = default_omap4_uart4_pads;
+                       bdata->pads_cnt =
+                               ARRAY_SIZE(default_omap4_uart4_pads);
+               } else if (cpu_is_omap3630()) {
+                       bdata->pads = default_omap36xx_uart4_pads;
+                       bdata->pads_cnt =
+                               ARRAY_SIZE(default_omap36xx_uart4_pads);
                }
+               break;
+       default:
+               break;
        }
 }
-
-static ssize_t sleep_timeout_show(struct device *dev,
-                                 struct device_attribute *attr,
-                                 char *buf)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct omap_device *odev = to_omap_device(pdev);
-       struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
-
-       return sprintf(buf, "%u\n", uart->timeout / HZ);
-}
-
-static ssize_t sleep_timeout_store(struct device *dev,
-                                  struct device_attribute *attr,
-                                  const char *buf, size_t n)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct omap_device *odev = to_omap_device(pdev);
-       struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
-       unsigned int value;
-
-       if (sscanf(buf, "%u", &value) != 1) {
-               dev_err(dev, "sleep_timeout_store: Invalid value\n");
-               return -EINVAL;
-       }
-
-       uart->timeout = value * HZ;
-       if (uart->timeout)
-               mod_timer(&uart->timer, jiffies + uart->timeout);
-       else
-               /* A zero value means disable timeout feature */
-               omap_uart_block_sleep(uart);
-
-       return n;
-}
-
-static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
-               sleep_timeout_store);
-#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
 #else
-static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
-static void omap_uart_block_sleep(struct omap_uart_state *uart)
-{
-       /* Needed to enable UART clocks when built without CONFIG_PM */
-       omap_uart_enable_clocks(uart);
-}
-#define DEV_CREATE_FILE(dev, attr)
-#endif /* CONFIG_PM */
-
-#ifndef CONFIG_SERIAL_OMAP
-/*
- * Override the default 8250 read handler: mem_serial_in()
- * Empty RX fifo read causes an abort on omap3630 and omap4
- * This function makes sure that an empty rx fifo is not read on these silicons
- * (OMAP1/2/3430 are not affected)
- */
-static unsigned int serial_in_override(struct uart_port *up, int offset)
-{
-       if (UART_RX == offset) {
-               unsigned int lsr;
-               lsr = __serial_read_reg(up, UART_LSR);
-               if (!(lsr & UART_LSR_DR))
-                       return -EPERM;
-       }
-
-       return __serial_read_reg(up, offset);
-}
+static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {}
+#endif
 
-static void serial_out_override(struct uart_port *up, int offset, int value)
+char *cmdline_find_option(char *str)
 {
-       unsigned int status, tmout = 10000;
+       extern char *saved_command_line;
 
-       status = __serial_read_reg(up, UART_LSR);
-       while (!(status & UART_LSR_THRE)) {
-               /* Wait up to 10ms for the character(s) to be sent. */
-               if (--tmout == 0)
-                       break;
-               udelay(1);
-               status = __serial_read_reg(up, UART_LSR);
-       }
-       __serial_write_reg(up, offset, value);
+       return strstr(saved_command_line, str);
 }
-#endif
 
 static int __init omap_serial_early_init(void)
 {
-       int i = 0;
-
        do {
                char oh_name[MAX_UART_HWMOD_NAME_LEN];
                struct omap_hwmod *oh;
                struct omap_uart_state *uart;
+               char uart_name[MAX_UART_HWMOD_NAME_LEN];
 
                snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
-                        "uart%d", i + 1);
+                        "uart%d", num_uarts + 1);
                oh = omap_hwmod_lookup(oh_name);
                if (!oh)
                        break;
@@ -653,21 +271,35 @@ static int __init omap_serial_early_init(void)
                        return -ENODEV;
 
                uart->oh = oh;
-               uart->num = i++;
+               uart->num = num_uarts++;
                list_add_tail(&uart->node, &uart_list);
-               num_uarts++;
-
-               /*
-                * NOTE: omap_hwmod_setup*() has not yet been called,
-                *       so no hwmod functions will work yet.
-                */
-
-               /*
-                * During UART early init, device need to be probed
-                * to determine SoC specific init before omap_device
-                * is ready.  Therefore, don't allow idle here
-                */
-               uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
+               snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN,
+                               "%s%d", OMAP_SERIAL_NAME, uart->num);
+
+               if (cmdline_find_option(uart_name)) {
+                       console_uart_id = uart->num;
+
+                       if (console_loglevel >= 10) {
+                               uart_debug = true;
+                               pr_info("%s used as console in debug mode"
+                                               " uart%d clocks will not be"
+                                               " gated", uart_name, uart->num);
+                       }
+
+                       if (cmdline_find_option("no_console_suspend"))
+                               no_console_suspend = true;
+
+                       /*
+                        * omap-uart can be used for earlyprintk logs
+                        * So if omap-uart is used as console then prevent
+                        * uart reset and idle to get logs from omap-uart
+                        * until uart console driver is available to take
+                        * care for console messages.
+                        * Idling or resetting omap-uart while printing logs
+                        * early boot logs can stall the boot-up.
+                        */
+                       oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
+               }
        } while (1);
 
        return 0;
@@ -677,6 +309,7 @@ core_initcall(omap_serial_early_init);
 /**
  * omap_serial_init_port() - initialize single serial port
  * @bdata: port specific board data pointer
+ * @info: platform specific data pointer
  *
  * This function initialies serial driver for given port only.
  * Platforms can call this function instead of omap_serial_init()
@@ -685,7 +318,8 @@ core_initcall(omap_serial_early_init);
  * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
  * use only one of the two.
  */
-void __init omap_serial_init_port(struct omap_board_data *bdata)
+void __init omap_serial_init_port(struct omap_board_data *bdata,
+                       struct omap_uart_port_info *info)
 {
        struct omap_uart_state *uart;
        struct omap_hwmod *oh;
@@ -693,15 +327,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
        void *pdata = NULL;
        u32 pdata_size = 0;
        char *name;
-#ifndef CONFIG_SERIAL_OMAP
-       struct plat_serial8250_port ports[2] = {
-               {},
-               {.flags = 0},
-       };
-       struct plat_serial8250_port *p = &ports[0];
-#else
        struct omap_uart_port_info omap_up;
-#endif
 
        if (WARN_ON(!bdata))
                return;
@@ -713,66 +339,34 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
        list_for_each_entry(uart, &uart_list, node)
                if (bdata->id == uart->num)
                        break;
+       if (!info)
+               info = omap_serial_default_info;
 
        oh = uart->oh;
-       uart->dma_enabled = 0;
-#ifndef CONFIG_SERIAL_OMAP
-       name = "serial8250";
-
-       /*
-        * !! 8250 driver does not use standard IORESOURCE* It
-        * has it's own custom pdata that can be taken from
-        * the hwmod resource data.  But, this needs to be
-        * done after the build.
-        *
-        * ?? does it have to be done before the register ??
-        * YES, because platform_device_data_add() copies
-        * pdata, it does not use a pointer.
-        */
-       p->flags = UPF_BOOT_AUTOCONF;
-       p->iotype = UPIO_MEM;
-       p->regshift = 2;
-       p->uartclk = OMAP24XX_BASE_BAUD * 16;
-       p->irq = oh->mpu_irqs[0].irq;
-       p->mapbase = oh->slaves[0]->addr->pa_start;
-       p->membase = omap_hwmod_get_mpu_rt_va(oh);
-       p->irqflags = IRQF_SHARED;
-       p->private_data = uart;
-
-       /*
-        * omap44xx, ti816x: Never read empty UART fifo
-        * omap3xxx: Never read empty UART fifo on UARTs
-        * with IP rev >=0x52
-        */
-       uart->regshift = p->regshift;
-       uart->membase = p->membase;
-       if (cpu_is_omap44xx() || cpu_is_ti816x())
-               uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
-       else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
-                       >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
-               uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
-
-       if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
-               p->serial_in = serial_in_override;
-               p->serial_out = serial_out_override;
-       }
-
-       pdata = &ports[0];
-       pdata_size = 2 * sizeof(struct plat_serial8250_port);
-#else
-
        name = DRIVER_NAME;
 
-       omap_up.dma_enabled = uart->dma_enabled;
+       omap_up.dma_enabled = info->dma_enabled;
        omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
-       omap_up.mapbase = oh->slaves[0]->addr->pa_start;
-       omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
-       omap_up.irqflags = IRQF_SHARED;
-       omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       omap_up.flags = UPF_BOOT_AUTOCONF;
+       omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
+       omap_up.set_forceidle = omap_uart_set_forceidle;
+       omap_up.set_noidle = omap_uart_set_noidle;
+       omap_up.enable_wakeup = omap_uart_enable_wakeup;
+       omap_up.dma_rx_buf_size = info->dma_rx_buf_size;
+       omap_up.dma_rx_timeout = info->dma_rx_timeout;
+       omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate;
+       omap_up.autosuspend_timeout = info->autosuspend_timeout;
+
+       /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */
+       if (!cpu_is_omap2420() && !cpu_is_ti816x())
+               omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS;
+
+       /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */
+       if (cpu_is_omap34xx() || cpu_is_omap3630())
+               omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE;
 
        pdata = &omap_up;
        pdata_size = sizeof(struct omap_uart_port_info);
-#endif
 
        if (WARN_ON(!oh))
                return;
@@ -782,64 +376,29 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
        WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
             name, oh->name);
 
-       omap_device_disable_idle_on_suspend(pdev);
+       if ((console_uart_id == bdata->id) && no_console_suspend)
+               omap_device_disable_idle_on_suspend(pdev);
+
        oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
-       uart->irq = oh->mpu_irqs[0].irq;
-       uart->regshift = 2;
-       uart->mapbase = oh->slaves[0]->addr->pa_start;
-       uart->membase = omap_hwmod_get_mpu_rt_va(oh);
        uart->pdev = pdev;
 
        oh->dev_attr = uart;
 
-       console_lock(); /* in case the earlycon is on the UART */
-
-       /*
-        * Because of early UART probing, UART did not get idled
-        * on init.  Now that omap_device is ready, ensure full idle
-        * before doing omap_device_enable().
-        */
-       omap_hwmod_idle(uart->oh);
-
-       omap_device_enable(uart->pdev);
-       omap_uart_idle_init(uart);
-       omap_uart_reset(uart);
-       omap_hwmod_enable_wakeup(uart->oh);
-       omap_device_idle(uart->pdev);
-
-       /*
-        * Need to block sleep long enough for interrupt driven
-        * driver to start.  Console driver is in polling mode
-        * so device needs to be kept enabled while polling driver
-        * is in use.
-        */
-       if (uart->timeout)
-               uart->timeout = (30 * HZ);
-       omap_uart_block_sleep(uart);
-       uart->timeout = DEFAULT_TIMEOUT;
-
-       console_unlock();
-
-       if ((cpu_is_omap34xx() && uart->padconf) ||
-           (uart->wk_en && uart->wk_mask)) {
+       if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads)
+                       && !uart_debug)
                device_init_wakeup(&pdev->dev, true);
-               DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
-       }
-
-       /* Enable the MDR1 errata for OMAP3 */
-       if (cpu_is_omap34xx() && !cpu_is_ti816x())
-               uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
 }
 
 /**
- * omap_serial_init() - initialize all supported serial ports
+ * omap_serial_board_init() - initialize all supported serial ports
+ * @info: platform specific data pointer
  *
  * Initializes all available UARTs as serial ports. Platforms
  * can call this function when they want to have default behaviour
  * for serial ports (e.g initialize them all as serial ports).
  */
-void __init omap_serial_init(void)
+void __init omap_serial_board_init(struct omap_uart_port_info *info)
 {
        struct omap_uart_state *uart;
        struct omap_board_data bdata;
@@ -849,7 +408,25 @@ void __init omap_serial_init(void)
                bdata.flags = 0;
                bdata.pads = NULL;
                bdata.pads_cnt = 0;
-               omap_serial_init_port(&bdata);
 
+               if (cpu_is_omap44xx() || cpu_is_omap34xx())
+                       omap_serial_fill_default_pads(&bdata);
+
+               if (!info)
+                       omap_serial_init_port(&bdata, NULL);
+               else
+                       omap_serial_init_port(&bdata, &info[uart->num]);
        }
 }
+
+/**
+ * omap_serial_init() - initialize all supported serial ports
+ *
+ * Initializes all available UARTs.
+ * Platforms can call this function when they want to have default behaviour
+ * for serial ports (e.g initialize them all as serial ports).
+ */
+void __init omap_serial_init(void)
+{
+       omap_serial_board_init(NULL);
+}
index 3df04d944e4d1497f4e74475acac603e163af24c..9a584614e7e66feb051ddde13f61545f94632290 100644 (file)
@@ -19,7 +19,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/include/plat/am33xx.h b/arch/arm/plat-omap/include/plat/am33xx.h
new file mode 100644 (file)
index 0000000..06c19bb
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * This file contains the address info for various AM33XX modules.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc. - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_AM33XX_H
+#define __ASM_ARCH_AM33XX_H
+
+#define L4_SLOW_AM33XX_BASE    0x48000000
+
+#define AM33XX_SCM_BASE                0x44E10000
+#define AM33XX_CTRL_BASE       AM33XX_SCM_BASE
+#define AM33XX_PRCM_BASE       0x44E00000
+
+#endif /* __ASM_ARCH_AM33XX_H */
index eb73ab40e9556ee03f36e63fa7c06b9e77b4b1d3..240a7b9fd946ed95de93fd8b1685e4207acada20 100644 (file)
@@ -59,6 +59,8 @@ struct clkops {
 #define RATE_IN_4430           (1 << 5)
 #define RATE_IN_TI816X         (1 << 6)
 #define RATE_IN_4460           (1 << 7)
+#define RATE_IN_AM33XX         (1 << 8)
+#define RATE_IN_TI814X         (1 << 9)
 
 #define RATE_IN_24XX           (RATE_IN_242X | RATE_IN_243X)
 #define RATE_IN_34XX           (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
@@ -84,7 +86,7 @@ struct clkops {
 struct clksel_rate {
        u32                     val;
        u8                      div;
-       u                     flags;
+       u16                     flags;
 };
 
 /**
index 408a12f792051865c9adf21b0760b9b6871fe899..6b51086fce18c9360fda3fb0bbc396422e3973ff 100644 (file)
@@ -69,6 +69,7 @@ unsigned int omap_rev(void);
  * cpu_is_omap343x():  True for OMAP3430
  * cpu_is_omap443x():  True for OMAP4430
  * cpu_is_omap446x():  True for OMAP4460
+ * cpu_is_omap447x():  True for OMAP4470
  */
 #define GET_OMAP_CLASS (omap_rev() & 0xff)
 
@@ -78,6 +79,22 @@ static inline int is_omap ##class (void)             \
        return (GET_OMAP_CLASS == (id)) ? 1 : 0;        \
 }
 
+#define GET_AM_CLASS   ((omap_rev() >> 24) & 0xff)
+
+#define IS_AM_CLASS(class, id)                         \
+static inline int is_am ##class (void)                 \
+{                                                      \
+       return (GET_AM_CLASS == (id)) ? 1 : 0;          \
+}
+
+#define GET_TI_CLASS   ((omap_rev() >> 24) & 0xff)
+
+#define IS_TI_CLASS(class, id)                 \
+static inline int is_ti ##class (void)         \
+{                                                      \
+       return (GET_TI_CLASS == (id)) ? 1 : 0;  \
+}
+
 #define GET_OMAP_SUBCLASS      ((omap_rev() >> 20) & 0x0fff)
 
 #define IS_OMAP_SUBCLASS(subclass, id)                 \
@@ -92,12 +109,21 @@ static inline int is_ti ##subclass (void)          \
        return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0;     \
 }
 
+#define IS_AM_SUBCLASS(subclass, id)                   \
+static inline int is_am ##subclass (void)              \
+{                                                      \
+       return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0;     \
+}
+
 IS_OMAP_CLASS(7xx, 0x07)
 IS_OMAP_CLASS(15xx, 0x15)
 IS_OMAP_CLASS(16xx, 0x16)
 IS_OMAP_CLASS(24xx, 0x24)
 IS_OMAP_CLASS(34xx, 0x34)
 IS_OMAP_CLASS(44xx, 0x44)
+IS_AM_CLASS(33xx, 0x33)
+
+IS_TI_CLASS(81xx, 0x81)
 
 IS_OMAP_SUBCLASS(242x, 0x242)
 IS_OMAP_SUBCLASS(243x, 0x243)
@@ -105,8 +131,11 @@ IS_OMAP_SUBCLASS(343x, 0x343)
 IS_OMAP_SUBCLASS(363x, 0x363)
 IS_OMAP_SUBCLASS(443x, 0x443)
 IS_OMAP_SUBCLASS(446x, 0x446)
+IS_OMAP_SUBCLASS(447x, 0x447)
 
 IS_TI_SUBCLASS(816x, 0x816)
+IS_TI_SUBCLASS(814x, 0x814)
+IS_AM_SUBCLASS(335x, 0x335)
 
 #define cpu_is_omap7xx()               0
 #define cpu_is_omap15xx()              0
@@ -116,10 +145,15 @@ IS_TI_SUBCLASS(816x, 0x816)
 #define cpu_is_omap243x()              0
 #define cpu_is_omap34xx()              0
 #define cpu_is_omap343x()              0
+#define cpu_is_ti81xx()                        0
 #define cpu_is_ti816x()                        0
+#define cpu_is_ti814x()                        0
+#define cpu_is_am33xx()                        0
+#define cpu_is_am335x()                        0
 #define cpu_is_omap44xx()              0
 #define cpu_is_omap443x()              0
 #define cpu_is_omap446x()              0
+#define cpu_is_omap447x()              0
 
 #if defined(MULTI_OMAP1)
 # if defined(CONFIG_ARCH_OMAP730)
@@ -322,7 +356,11 @@ IS_OMAP_TYPE(3517, 0x3517)
 # undef cpu_is_omap3530
 # undef cpu_is_omap3505
 # undef cpu_is_omap3517
+# undef cpu_is_ti81xx
 # undef cpu_is_ti816x
+# undef cpu_is_ti814x
+# undef cpu_is_am33xx
+# undef cpu_is_am335x
 # define cpu_is_omap3430()             is_omap3430()
 # define cpu_is_omap3503()             (cpu_is_omap3430() &&           \
                                                (!omap3_has_iva()) &&   \
@@ -339,16 +377,22 @@ IS_OMAP_TYPE(3517, 0x3517)
                                                !omap3_has_sgx())
 # undef cpu_is_omap3630
 # define cpu_is_omap3630()             is_omap363x()
+# define cpu_is_ti81xx()               is_ti81xx()
 # define cpu_is_ti816x()               is_ti816x()
+# define cpu_is_ti814x()               is_ti814x()
+# define cpu_is_am33xx()               is_am33xx()
+# define cpu_is_am335x()               is_am335x()
 #endif
 
 # if defined(CONFIG_ARCH_OMAP4)
 # undef cpu_is_omap44xx
 # undef cpu_is_omap443x
 # undef cpu_is_omap446x
+# undef cpu_is_omap447x
 # define cpu_is_omap44xx()             is_omap44xx()
 # define cpu_is_omap443x()             is_omap443x()
 # define cpu_is_omap446x()             is_omap446x()
+# define cpu_is_omap447x()             is_omap447x()
 # endif
 
 /* Macros to detect if we have OMAP1 or OMAP2 */
@@ -386,15 +430,27 @@ IS_OMAP_TYPE(3517, 0x3517)
 #define TI8168_REV_ES1_0       TI816X_CLASS
 #define TI8168_REV_ES1_1       (TI816X_CLASS | (0x1 << 8))
 
+#define TI814X_CLASS           0x81400034
+#define TI8148_REV_ES1_0       TI814X_CLASS
+#define TI8148_REV_ES2_0       (TI814X_CLASS | (0x1 << 8))
+#define TI8148_REV_ES2_1       (TI814X_CLASS | (0x2 << 8))
+
+#define AM335X_CLASS           0x33500034
+#define AM335X_REV_ES1_0       AM335X_CLASS
+
 #define OMAP443X_CLASS         0x44300044
 #define OMAP4430_REV_ES1_0     (OMAP443X_CLASS | (0x10 << 8))
 #define OMAP4430_REV_ES2_0     (OMAP443X_CLASS | (0x20 << 8))
 #define OMAP4430_REV_ES2_1     (OMAP443X_CLASS | (0x21 << 8))
 #define OMAP4430_REV_ES2_2     (OMAP443X_CLASS | (0x22 << 8))
+#define OMAP4430_REV_ES2_3     (OMAP443X_CLASS | (0x23 << 8))
 
 #define OMAP446X_CLASS         0x44600044
 #define OMAP4460_REV_ES1_0     (OMAP446X_CLASS | (0x10 << 8))
 
+#define OMAP447X_CLASS         0x44700044
+#define OMAP4470_REV_ES1_0     (OMAP447X_CLASS | (0x10 << 8))
+
 void omap2_check_revision(void);
 
 /*
index e87efe1499b8c5ba06874ead21fd5c52de64f2fc..e897978371c2719167eb7bfbe2625dc5d7bc6fdf 100644 (file)
 #include <plat/omap24xx.h>
 #include <plat/omap34xx.h>
 #include <plat/omap44xx.h>
-#include <plat/ti816x.h>
+#include <plat/ti81xx.h>
+#include <plat/am33xx.h>
 
 #endif /* __ASM_ARCH_OMAP_HARDWARE_H */
index 1234944a4da06870fbd11cf9bb2725f05c876f4a..0696bae1818bc9104d06a931606f628c06549b65 100644 (file)
@@ -73,6 +73,9 @@
 #define OMAP4_L3_IO_OFFSET     0xb4000000
 #define OMAP4_L3_IO_ADDRESS(pa)        IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
 
+#define AM33XX_L4_WK_IO_OFFSET 0xb5000000
+#define AM33XX_L4_WK_IO_ADDRESS(pa)    IOMEM((pa) + AM33XX_L4_WK_IO_OFFSET)
+
 #define OMAP4_L3_PER_IO_OFFSET 0xb1100000
 #define OMAP4_L3_PER_IO_ADDRESS(pa)    IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
 
 #define L4_34XX_VIRT           (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET)
 #define L4_34XX_SIZE           SZ_4M   /* 1MB of 128MB used, want 1MB sect */
 
+/*
+ * ----------------------------------------------------------------------------
+ * AM33XX specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+#define L4_WK_AM33XX_PHYS      L4_WK_AM33XX_BASE
+#define L4_WK_AM33XX_VIRT      (L4_WK_AM33XX_PHYS + AM33XX_L4_WK_IO_OFFSET)
+#define L4_WK_AM33XX_SIZE      SZ_4M   /* 1MB of 128MB used, want 1MB sect */
+
 /*
  * Need to look at the Size 4M for L4.
  * VPOM3430 was not working for Int controller
index 2682043f5a5bacc86376012f86598b8ba907bab3..9ff444469f3d9a1add04cda94c4b7d9247b5ea4a 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
+#include <linux/pm_qos.h>
 
 #include <plat/mux.h>
 
@@ -33,6 +34,8 @@
 
 #define OMAP_MODE13X_SPEED     230400
 
+#define OMAP_UART_SCR_TX_EMPTY 0x08
+
 /* WER = 0x7F
  * Enable module level wakeup in WER reg
  */
 
 #define OMAP_UART_DMA_CH_FREE  -1
 
-#define RX_TIMEOUT             (3 * HZ)
 #define OMAP_MAX_HSUART_PORTS  4
 
 #define MSR_SAVE_FLAGS         UART_MSR_ANY_DELTA
 
+#define UART_ERRATA_i202_MDR1_ACCESS   BIT(0)
+#define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1)
+
 struct omap_uart_port_info {
        bool                    dma_enabled;    /* To specify DMA Mode */
        unsigned int            uartclk;        /* UART clock rate */
-       void __iomem            *membase;       /* ioremap cookie or NULL */
-       resource_size_t         mapbase;        /* resource base */
-       unsigned long           irqflags;       /* request_irq flags */
        upf_t                   flags;          /* UPF_* flags */
+       u32                     errata;
+       unsigned int            dma_rx_buf_size;
+       unsigned int            dma_rx_timeout;
+       unsigned int            autosuspend_timeout;
+       unsigned int            dma_rx_poll_rate;
+
+       int (*get_context_loss_count)(struct device *);
+       void (*set_forceidle)(struct platform_device *);
+       void (*set_noidle)(struct platform_device *);
+       void (*enable_wakeup)(struct platform_device *, bool);
 };
 
 struct uart_omap_dma {
@@ -86,8 +98,9 @@ struct uart_omap_dma {
        spinlock_t              rx_lock;
        /* timer to poll activity on rx dma */
        struct timer_list       rx_timer;
-       int                     rx_buf_size;
-       int                     rx_timeout;
+       unsigned int            rx_buf_size;
+       unsigned int            rx_poll_rate;
+       unsigned int            rx_timeout;
 };
 
 struct uart_omap_port {
@@ -100,6 +113,10 @@ struct uart_omap_port {
        unsigned char           mcr;
        unsigned char           fcr;
        unsigned char           efr;
+       unsigned char           dll;
+       unsigned char           dlh;
+       unsigned char           mdr1;
+       unsigned char           scr;
 
        int                     use_dma;
        /*
@@ -111,6 +128,14 @@ struct uart_omap_port {
        unsigned char           msr_saved_flags;
        char                    name[20];
        unsigned long           port_activity;
+       u32                     context_loss_cnt;
+       u32                     errata;
+       u8                      wakeups_enabled;
+
+       struct pm_qos_request   pm_qos_request;
+       u32                     latency;
+       u32                     calc_latency;
+       struct work_struct      qos_work;
 };
 
 #endif /* __OMAP_SERIAL_H__ */
index b9e85886b9d641964267361041a70e3fa7741467..0d818acf39178f1053f13263b87dc550af0710de 100644 (file)
@@ -35,6 +35,8 @@
 #define L4_EMU_34XX_BASE       0x54000000
 #define L3_34XX_BASE           0x68000000
 
+#define L4_WK_AM33XX_BASE      0x44C00000
+
 #define OMAP3430_32KSYNCT_BASE 0x48320000
 #define OMAP3430_CM_BASE       0x48004800
 #define OMAP3430_PRM_BASE      0x48306800
index 1ab9fd6abe6de8e837e06260fbb58ff03f6b4d6f..38b3e38df2a059edee7b0a7a34a52d0b020cc5fb 100644 (file)
 #define OMAP4_UART3_BASE       0x48020000
 #define OMAP4_UART4_BASE       0x4806e000
 
-/* TI816X serial ports */
-#define TI816X_UART1_BASE      0x48020000
-#define TI816X_UART2_BASE      0x48022000
-#define TI816X_UART3_BASE      0x48024000
+/* TI81XX serial ports */
+#define TI81XX_UART1_BASE      0x48020000
+#define TI81XX_UART2_BASE      0x48022000
+#define TI81XX_UART3_BASE      0x48024000
 
 /* AM3505/3517 UART4 */
 #define AM35XX_UART4_BASE      0x4809E000      /* Only on AM3505/3517 */
@@ -89,9 +89,9 @@
 #define OMAP4UART2             OMAP2UART2
 #define OMAP4UART3             43
 #define OMAP4UART4             44
-#define TI816XUART1            81
-#define TI816XUART2            82
-#define TI816XUART3            83
+#define TI81XXUART1            81
+#define TI81XXUART2            82
+#define TI81XXUART3            83
 #define ZOOM_UART              95              /* Only on zoom2/3 */
 
 /* This is only used by 8250.c for omap1510 */
 #ifndef __ASSEMBLER__
 
 struct omap_board_data;
+struct omap_uart_port_info;
 
 extern void omap_serial_init(void);
-extern void omap_serial_init_port(struct omap_board_data *bdata);
 extern int omap_uart_can_sleep(void);
-extern void omap_uart_check_wakeup(void);
-extern void omap_uart_prepare_suspend(void);
-extern void omap_uart_prepare_idle(int num);
-extern void omap_uart_resume_idle(int num);
-extern void omap_uart_enable_irqs(int enable);
+extern void omap_serial_board_init(struct omap_uart_port_info *platform_data);
+extern void omap_serial_init_port(struct omap_board_data *bdata,
+               struct omap_uart_port_info *platform_data);
 #endif
 
 #endif
diff --git a/arch/arm/plat-omap/include/plat/ti816x.h b/arch/arm/plat-omap/include/plat/ti816x.h
deleted file mode 100644 (file)
index 50510f5..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * This file contains the address data for various TI816X modules.
- *
- * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_TI816X_H
-#define __ASM_ARCH_TI816X_H
-
-#define L4_SLOW_TI816X_BASE    0x48000000
-
-#define TI816X_SCM_BASE                0x48140000
-#define TI816X_CTRL_BASE       TI816X_SCM_BASE
-#define TI816X_PRCM_BASE       0x48180000
-
-#define TI816X_ARM_INTC_BASE   0x48200000
-
-#endif /* __ASM_ARCH_TI816X_H */
diff --git a/arch/arm/plat-omap/include/plat/ti81xx.h b/arch/arm/plat-omap/include/plat/ti81xx.h
new file mode 100644 (file)
index 0000000..8f9843f
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * This file contains the address data for various TI81XX modules.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_TI81XX_H
+#define __ASM_ARCH_TI81XX_H
+
+#define L4_SLOW_TI81XX_BASE    0x48000000
+
+#define TI81XX_SCM_BASE                0x48140000
+#define TI81XX_CTRL_BASE       TI81XX_SCM_BASE
+#define TI81XX_PRCM_BASE       0x48180000
+
+#define TI81XX_ARM_INTC_BASE   0x48200000
+
+#endif /* __ASM_ARCH_TI81XX_H */
index 2f472e989ec6b9ee66e592c0d314a696a578c829..7fbc361946b5fcce7c2f638b11c38b379fbbf219 100644 (file)
@@ -99,9 +99,9 @@ static inline void flush(void)
 #define DEBUG_LL_ZOOM(mach)                                            \
        _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART)
 
-#define DEBUG_LL_TI816X(p, mach)                                       \
-       _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT,   \
-               TI816XUART##p)
+#define DEBUG_LL_TI81XX(p, mach)                                       \
+       _DEBUG_LL_ENTRY(mach, TI81XX_UART##p##_BASE, OMAP_PORT_SHIFT,   \
+               TI81XXUART##p)
 
 static inline void __arch_decomp_setup(unsigned long arch_id)
 {
@@ -177,7 +177,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id)
                DEBUG_LL_ZOOM(omap_zoom3);
 
                /* TI8168 base boards using UART3 */
-               DEBUG_LL_TI816X(3, ti8168evm);
+               DEBUG_LL_TI81XX(3, ti8168evm);
 
        } while (0);
 }
index 5e713d3ef1f47c49eaa93f8d4ced09ce87b89c1e..7b0303d3402136d7faf4beb40a5e904f84884a12 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/clk.h>
 #include <linux/serial_core.h>
 #include <linux/irq.h>
+#include <linux/pm_runtime.h>
 
 #include <plat/dma.h>
 #include <plat/dmtimer.h>
@@ -46,8 +47,11 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
 static void uart_tx_dma_callback(int lch, u16 ch_status, void *data);
-static void serial_omap_rx_timeout(unsigned long uart_no);
+static void serial_omap_rxdma_poll(unsigned long uart_no);
 static int serial_omap_start_rxdma(struct uart_omap_port *up);
+static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1);
+
+static struct workqueue_struct *serial_omap_uart_wq;
 
 static inline unsigned int serial_in(struct uart_omap_port *up, int offset)
 {
@@ -102,6 +106,8 @@ static void serial_omap_stop_rxdma(struct uart_omap_port *up)
                omap_free_dma(up->uart_dma.rx_dma_channel);
                up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
                up->uart_dma.rx_dma_used = false;
+               pm_runtime_mark_last_busy(&up->pdev->dev);
+               pm_runtime_put_autosuspend(&up->pdev->dev);
        }
 }
 
@@ -110,8 +116,11 @@ static void serial_omap_enable_ms(struct uart_port *port)
        struct uart_omap_port *up = (struct uart_omap_port *)port;
 
        dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id);
+
+       pm_runtime_get_sync(&up->pdev->dev);
        up->ier |= UART_IER_MSI;
        serial_out(up, UART_IER, up->ier);
+       pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_stop_tx(struct uart_port *port)
@@ -129,30 +138,40 @@ static void serial_omap_stop_tx(struct uart_port *port)
                omap_stop_dma(up->uart_dma.tx_dma_channel);
                omap_free_dma(up->uart_dma.tx_dma_channel);
                up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
+               pm_runtime_mark_last_busy(&up->pdev->dev);
+               pm_runtime_put_autosuspend(&up->pdev->dev);
        }
 
+       pm_runtime_get_sync(&up->pdev->dev);
        if (up->ier & UART_IER_THRI) {
                up->ier &= ~UART_IER_THRI;
                serial_out(up, UART_IER, up->ier);
        }
+
+       pm_runtime_mark_last_busy(&up->pdev->dev);
+       pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
 static void serial_omap_stop_rx(struct uart_port *port)
 {
        struct uart_omap_port *up = (struct uart_omap_port *)port;
 
+       pm_runtime_get_sync(&up->pdev->dev);
        if (up->use_dma)
                serial_omap_stop_rxdma(up);
        up->ier &= ~UART_IER_RLSI;
        up->port.read_status_mask &= ~UART_LSR_DR;
        serial_out(up, UART_IER, up->ier);
+       pm_runtime_mark_last_busy(&up->pdev->dev);
+       pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
-static inline void receive_chars(struct uart_omap_port *up, int *status)
+static inline void receive_chars(struct uart_omap_port *up,
+               unsigned int *status)
 {
        struct tty_struct *tty = up->port.state->port.tty;
-       unsigned int flag;
-       unsigned char ch, lsr = *status;
+       unsigned int flag, lsr = *status;
+       unsigned char ch = 0;
        int max_count = 256;
 
        do {
@@ -262,7 +281,10 @@ static void serial_omap_start_tx(struct uart_port *port)
        int ret = 0;
 
        if (!up->use_dma) {
+               pm_runtime_get_sync(&up->pdev->dev);
                serial_omap_enable_ier_thri(up);
+               pm_runtime_mark_last_busy(&up->pdev->dev);
+               pm_runtime_put_autosuspend(&up->pdev->dev);
                return;
        }
 
@@ -272,6 +294,7 @@ static void serial_omap_start_tx(struct uart_port *port)
        xmit = &up->port.state->xmit;
 
        if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) {
+               pm_runtime_get_sync(&up->pdev->dev);
                ret = omap_request_dma(up->uart_dma.uart_dma_tx,
                                "UART Tx DMA",
                                (void *)uart_tx_dma_callback, up,
@@ -354,9 +377,13 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
        unsigned int iir, lsr;
        unsigned long flags;
 
+       pm_runtime_get_sync(&up->pdev->dev);
        iir = serial_in(up, UART_IIR);
-       if (iir & UART_IIR_NO_INT)
+       if (iir & UART_IIR_NO_INT) {
+               pm_runtime_mark_last_busy(&up->pdev->dev);
+               pm_runtime_put_autosuspend(&up->pdev->dev);
                return IRQ_NONE;
+       }
 
        spin_lock_irqsave(&up->port.lock, flags);
        lsr = serial_in(up, UART_LSR);
@@ -378,6 +405,9 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
                transmit_chars(up);
 
        spin_unlock_irqrestore(&up->port.lock, flags);
+       pm_runtime_mark_last_busy(&up->pdev->dev);
+       pm_runtime_put_autosuspend(&up->pdev->dev);
+
        up->port_activity = jiffies;
        return IRQ_HANDLED;
 }
@@ -388,11 +418,12 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)
        unsigned long flags = 0;
        unsigned int ret = 0;
 
+       pm_runtime_get_sync(&up->pdev->dev);
        dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id);
        spin_lock_irqsave(&up->port.lock, flags);
        ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
        spin_unlock_irqrestore(&up->port.lock, flags);
-
+       pm_runtime_put(&up->pdev->dev);
        return ret;
 }
 
@@ -402,7 +433,10 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port)
        unsigned char status;
        unsigned int ret = 0;
 
+       pm_runtime_get_sync(&up->pdev->dev);
        status = check_modem_status(up);
+       pm_runtime_put(&up->pdev->dev);
+
        dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id);
 
        if (status & UART_MSR_DCD)
@@ -433,8 +467,11 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
        if (mctrl & TIOCM_LOOP)
                mcr |= UART_MCR_LOOP;
 
-       mcr |= up->mcr;
-       serial_out(up, UART_MCR, mcr);
+       pm_runtime_get_sync(&up->pdev->dev);
+       up->mcr = serial_in(up, UART_MCR);
+       up->mcr |= mcr;
+       serial_out(up, UART_MCR, up->mcr);
+       pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_break_ctl(struct uart_port *port, int break_state)
@@ -443,6 +480,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
        unsigned long flags = 0;
 
        dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id);
+       pm_runtime_get_sync(&up->pdev->dev);
        spin_lock_irqsave(&up->port.lock, flags);
        if (break_state == -1)
                up->lcr |= UART_LCR_SBC;
@@ -450,6 +488,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
                up->lcr &= ~UART_LCR_SBC;
        serial_out(up, UART_LCR, up->lcr);
        spin_unlock_irqrestore(&up->port.lock, flags);
+       pm_runtime_put(&up->pdev->dev);
 }
 
 static int serial_omap_startup(struct uart_port *port)
@@ -468,6 +507,7 @@ static int serial_omap_startup(struct uart_port *port)
 
        dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id);
 
+       pm_runtime_get_sync(&up->pdev->dev);
        /*
         * Clear the FIFO buffers and disable them.
         * (they will be reenabled in set_termios())
@@ -505,7 +545,7 @@ static int serial_omap_startup(struct uart_port *port)
                        (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys),
                        0);
                init_timer(&(up->uart_dma.rx_timer));
-               up->uart_dma.rx_timer.function = serial_omap_rx_timeout;
+               up->uart_dma.rx_timer.function = serial_omap_rxdma_poll;
                up->uart_dma.rx_timer.data = up->pdev->id;
                /* Currently the buffer size is 4KB. Can increase it */
                up->uart_dma.rx_buf = dma_alloc_coherent(NULL,
@@ -523,6 +563,8 @@ static int serial_omap_startup(struct uart_port *port)
        /* Enable module level wake up */
        serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP);
 
+       pm_runtime_mark_last_busy(&up->pdev->dev);
+       pm_runtime_put_autosuspend(&up->pdev->dev);
        up->port_activity = jiffies;
        return 0;
 }
@@ -533,6 +575,8 @@ static void serial_omap_shutdown(struct uart_port *port)
        unsigned long flags = 0;
 
        dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id);
+
+       pm_runtime_get_sync(&up->pdev->dev);
        /*
         * Disable interrupts from this port
         */
@@ -566,6 +610,8 @@ static void serial_omap_shutdown(struct uart_port *port)
                        up->uart_dma.rx_buf_dma_phys);
                up->uart_dma.rx_buf = NULL;
        }
+
+       pm_runtime_put(&up->pdev->dev);
        free_irq(up->port.irq, up);
 }
 
@@ -573,8 +619,6 @@ static inline void
 serial_omap_configure_xonxoff
                (struct uart_omap_port *up, struct ktermios *termios)
 {
-       unsigned char efr = 0;
-
        up->lcr = serial_in(up, UART_LCR);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        up->efr = serial_in(up, UART_EFR);
@@ -584,8 +628,7 @@ serial_omap_configure_xonxoff
        serial_out(up, UART_XOFF1, termios->c_cc[VSTOP]);
 
        /* clear SW control mode bits */
-       efr = up->efr;
-       efr &= OMAP_UART_SW_CLR;
+       up->efr &= OMAP_UART_SW_CLR;
 
        /*
         * IXON Flag:
@@ -593,7 +636,7 @@ serial_omap_configure_xonxoff
         * Transmit XON1, XOFF1
         */
        if (termios->c_iflag & IXON)
-               efr |= OMAP_UART_SW_TX;
+               up->efr |= OMAP_UART_SW_TX;
 
        /*
         * IXOFF Flag:
@@ -601,7 +644,7 @@ serial_omap_configure_xonxoff
         * Receiver compares XON1, XOFF1.
         */
        if (termios->c_iflag & IXOFF)
-               efr |= OMAP_UART_SW_RX;
+               up->efr |= OMAP_UART_SW_RX;
 
        serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
@@ -624,13 +667,21 @@ serial_omap_configure_xonxoff
         * load the new software flow control mode IXON or IXOFF
         * and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
         */
-       serial_out(up, UART_EFR, efr | UART_EFR_SCD);
+       serial_out(up, UART_EFR, up->efr | UART_EFR_SCD);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 
        serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
        serial_out(up, UART_LCR, up->lcr);
 }
 
+static void serial_omap_uart_qos_work(struct work_struct *work)
+{
+       struct uart_omap_port *up = container_of(work, struct uart_omap_port,
+                                               qos_work);
+
+       pm_qos_update_request(&up->pm_qos_request, up->latency);
+}
+
 static void
 serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
                        struct ktermios *old)
@@ -671,6 +722,16 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13);
        quot = serial_omap_get_divisor(port, baud);
 
+       /* calculate wakeup latency constraint */
+       up->calc_latency = (1000000 * up->port.fifosize) /
+                               (1000 * baud / 8);
+       up->latency = up->calc_latency;
+       schedule_work(&up->qos_work);
+
+       up->dll = quot & 0xff;
+       up->dlh = quot >> 8;
+       up->mdr1 = UART_OMAP_MDR1_DISABLE;
+
        up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 |
                        UART_FCR_ENABLE_FIFO;
        if (up->use_dma)
@@ -680,6 +741,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
         * Ok, we're now changing the port state. Do it with
         * interrupts disabled.
         */
+       pm_runtime_get_sync(&up->pdev->dev);
        spin_lock_irqsave(&up->port.lock, flags);
 
        /*
@@ -723,6 +785,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
                up->ier |= UART_IER_MSI;
        serial_out(up, UART_IER, up->ier);
        serial_out(up, UART_LCR, cval);         /* reset DLAB */
+       up->lcr = cval;
+       up->scr = OMAP_UART_SCR_TX_EMPTY;
 
        /* FIFOs and DMA Settings */
 
@@ -749,17 +813,22 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (up->use_dma) {
                serial_out(up, UART_TI752_TLR, 0);
-               serial_out(up, UART_OMAP_SCR,
-                       (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8));
+               up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8);
        }
 
+       serial_out(up, UART_OMAP_SCR, up->scr);
+
        serial_out(up, UART_EFR, up->efr);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_out(up, UART_MCR, up->mcr);
 
        /* Protocol, Baud Rate, and Interrupt Settings */
 
-       serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+       if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+               serial_omap_mdr1_errataset(up, up->mdr1);
+       else
+               serial_out(up, UART_OMAP_MDR1, up->mdr1);
+
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
        up->efr = serial_in(up, UART_EFR);
@@ -769,8 +838,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        serial_out(up, UART_IER, 0);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 
-       serial_out(up, UART_DLL, quot & 0xff);          /* LS of divisor */
-       serial_out(up, UART_DLM, quot >> 8);            /* MS of divisor */
+       serial_out(up, UART_DLL, up->dll);      /* LS of divisor */
+       serial_out(up, UART_DLM, up->dlh);      /* MS of divisor */
 
        serial_out(up, UART_LCR, 0);
        serial_out(up, UART_IER, up->ier);
@@ -780,9 +849,14 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        serial_out(up, UART_LCR, cval);
 
        if (baud > 230400 && baud != 3000000)
-               serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE);
+               up->mdr1 = UART_OMAP_MDR1_13X_MODE;
+       else
+               up->mdr1 = UART_OMAP_MDR1_16X_MODE;
+
+       if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+               serial_omap_mdr1_errataset(up, up->mdr1);
        else
-               serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
+               serial_out(up, UART_OMAP_MDR1, up->mdr1);
 
        /* Hardware Flow Control Configuration */
 
@@ -809,6 +883,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
        serial_omap_configure_xonxoff(up, termios);
 
        spin_unlock_irqrestore(&up->port.lock, flags);
+       pm_runtime_put(&up->pdev->dev);
        dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id);
 }
 
@@ -820,6 +895,8 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
        unsigned char efr;
 
        dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id);
+
+       pm_runtime_get_sync(&up->pdev->dev);
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        efr = serial_in(up, UART_EFR);
        serial_out(up, UART_EFR, efr | UART_EFR_ECB);
@@ -829,6 +906,15 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
        serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_out(up, UART_EFR, efr);
        serial_out(up, UART_LCR, 0);
+
+       if (!device_may_wakeup(&up->pdev->dev)) {
+               if (!state)
+                       pm_runtime_forbid(&up->pdev->dev);
+               else
+                       pm_runtime_allow(&up->pdev->dev);
+       }
+
+       pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_release_port(struct uart_port *port)
@@ -906,19 +992,26 @@ static inline void wait_for_xmitr(struct uart_omap_port *up)
 static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch)
 {
        struct uart_omap_port *up = (struct uart_omap_port *)port;
+
+       pm_runtime_get_sync(&up->pdev->dev);
        wait_for_xmitr(up);
        serial_out(up, UART_TX, ch);
+       pm_runtime_put(&up->pdev->dev);
 }
 
 static int serial_omap_poll_get_char(struct uart_port *port)
 {
        struct uart_omap_port *up = (struct uart_omap_port *)port;
-       unsigned int status = serial_in(up, UART_LSR);
+       unsigned int status;
 
+       pm_runtime_get_sync(&up->pdev->dev);
+       status = serial_in(up, UART_LSR);
        if (!(status & UART_LSR_DR))
                return NO_POLL_CHAR;
 
-       return serial_in(up, UART_RX);
+       status = serial_in(up, UART_RX);
+       pm_runtime_put(&up->pdev->dev);
+       return status;
 }
 
 #endif /* CONFIG_CONSOLE_POLL */
@@ -946,6 +1039,8 @@ serial_omap_console_write(struct console *co, const char *s,
        unsigned int ier;
        int locked = 1;
 
+       pm_runtime_get_sync(&up->pdev->dev);
+
        local_irq_save(flags);
        if (up->port.sysrq)
                locked = 0;
@@ -978,6 +1073,8 @@ serial_omap_console_write(struct console *co, const char *s,
        if (up->msr_saved_flags)
                check_modem_status(up);
 
+       pm_runtime_mark_last_busy(&up->pdev->dev);
+       pm_runtime_put_autosuspend(&up->pdev->dev);
        if (locked)
                spin_unlock(&up->port.lock);
        local_irq_restore(flags);
@@ -1060,26 +1157,30 @@ static struct uart_driver serial_omap_reg = {
        .cons           = OMAP_CONSOLE,
 };
 
-static int
-serial_omap_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_SUSPEND
+static int serial_omap_suspend(struct device *dev)
 {
-       struct uart_omap_port *up = platform_get_drvdata(pdev);
+       struct uart_omap_port *up = dev_get_drvdata(dev);
 
-       if (up)
+       if (up) {
                uart_suspend_port(&serial_omap_reg, &up->port);
+               flush_work_sync(&up->qos_work);
+       }
+
        return 0;
 }
 
-static int serial_omap_resume(struct platform_device *dev)
+static int serial_omap_resume(struct device *dev)
 {
-       struct uart_omap_port *up = platform_get_drvdata(dev);
+       struct uart_omap_port *up = dev_get_drvdata(dev);
 
        if (up)
                uart_resume_port(&serial_omap_reg, &up->port);
        return 0;
 }
+#endif
 
-static void serial_omap_rx_timeout(unsigned long uart_no)
+static void serial_omap_rxdma_poll(unsigned long uart_no)
 {
        struct uart_omap_port *up = ui[uart_no];
        unsigned int curr_dma_pos, curr_transmitted_size;
@@ -1089,9 +1190,9 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
        if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) ||
                             (curr_dma_pos == 0)) {
                if (jiffies_to_msecs(jiffies - up->port_activity) <
-                                                       RX_TIMEOUT) {
+                                               up->uart_dma.rx_timeout) {
                        mod_timer(&up->uart_dma.rx_timer, jiffies +
-                               usecs_to_jiffies(up->uart_dma.rx_timeout));
+                               usecs_to_jiffies(up->uart_dma.rx_poll_rate));
                } else {
                        serial_omap_stop_rxdma(up);
                        up->ier |= (UART_IER_RDI | UART_IER_RLSI);
@@ -1120,7 +1221,7 @@ static void serial_omap_rx_timeout(unsigned long uart_no)
                }
        } else  {
                mod_timer(&up->uart_dma.rx_timer, jiffies +
-                       usecs_to_jiffies(up->uart_dma.rx_timeout));
+                       usecs_to_jiffies(up->uart_dma.rx_poll_rate));
        }
        up->port_activity = jiffies;
 }
@@ -1135,6 +1236,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
        int ret = 0;
 
        if (up->uart_dma.rx_dma_channel == -1) {
+               pm_runtime_get_sync(&up->pdev->dev);
                ret = omap_request_dma(up->uart_dma.uart_dma_rx,
                                "UART Rx DMA",
                                (void *)uart_rx_dma_callback, up,
@@ -1158,7 +1260,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
        /* FIXME: Cache maintenance needed here? */
        omap_start_dma(up->uart_dma.rx_dma_channel);
        mod_timer(&up->uart_dma.rx_timer, jiffies +
-                               usecs_to_jiffies(up->uart_dma.rx_timeout));
+                               usecs_to_jiffies(up->uart_dma.rx_poll_rate));
        up->uart_dma.rx_dma_used = true;
        return ret;
 }
@@ -1275,25 +1377,47 @@ static int serial_omap_probe(struct platform_device *pdev)
        up->port.ops = &serial_omap_pops;
        up->port.line = pdev->id;
 
-       up->port.membase = omap_up_info->membase;
-       up->port.mapbase = omap_up_info->mapbase;
+       up->port.mapbase = mem->start;
+       up->port.membase = ioremap(mem->start, resource_size(mem));
+       if (!up->port.membase) {
+               dev_err(&pdev->dev, "can't ioremap UART\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
        up->port.flags = omap_up_info->flags;
-       up->port.irqflags = omap_up_info->irqflags;
        up->port.uartclk = omap_up_info->uartclk;
        up->uart_dma.uart_base = mem->start;
+       up->errata = omap_up_info->errata;
 
        if (omap_up_info->dma_enabled) {
                up->uart_dma.uart_dma_tx = dma_tx->start;
                up->uart_dma.uart_dma_rx = dma_rx->start;
                up->use_dma = 1;
-               up->uart_dma.rx_buf_size = 4096;
-               up->uart_dma.rx_timeout = 2;
+               up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size;
+               up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout;
+               up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate;
                spin_lock_init(&(up->uart_dma.tx_lock));
                spin_lock_init(&(up->uart_dma.rx_lock));
                up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
                up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
        }
 
+       up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
+       up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
+       pm_qos_add_request(&up->pm_qos_request,
+               PM_QOS_CPU_DMA_LATENCY, up->latency);
+       serial_omap_uart_wq = create_singlethread_workqueue(up->name);
+       INIT_WORK(&up->qos_work, serial_omap_uart_qos_work);
+
+       pm_runtime_use_autosuspend(&pdev->dev);
+       pm_runtime_set_autosuspend_delay(&pdev->dev,
+                       omap_up_info->autosuspend_timeout);
+
+       pm_runtime_irq_safe(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+
        ui[pdev->id] = up;
        serial_omap_add_console_port(up);
 
@@ -1301,6 +1425,7 @@ static int serial_omap_probe(struct platform_device *pdev)
        if (ret != 0)
                goto do_release_region;
 
+       pm_runtime_put(&pdev->dev);
        platform_set_drvdata(pdev, up);
        return 0;
 err:
@@ -1315,22 +1440,157 @@ static int serial_omap_remove(struct platform_device *dev)
 {
        struct uart_omap_port *up = platform_get_drvdata(dev);
 
-       platform_set_drvdata(dev, NULL);
        if (up) {
+               pm_runtime_disable(&up->pdev->dev);
                uart_remove_one_port(&serial_omap_reg, &up->port);
+               pm_qos_remove_request(&up->pm_qos_request);
+
                kfree(up);
        }
+
+       platform_set_drvdata(dev, NULL);
        return 0;
 }
 
+/*
+ * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460)
+ * The access to uart register after MDR1 Access
+ * causes UART to corrupt data.
+ *
+ * Need a delay =
+ * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
+ * give 10 times as much
+ */
+static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1)
+{
+       u8 timeout = 255;
+
+       serial_out(up, UART_OMAP_MDR1, mdr1);
+       udelay(2);
+       serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
+                       UART_FCR_CLEAR_RCVR);
+       /*
+        * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
+        * TX_FIFO_E bit is 1.
+        */
+       while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
+                               (UART_LSR_THRE | UART_LSR_DR))) {
+               timeout--;
+               if (!timeout) {
+                       /* Should *never* happen. we warn and carry on */
+                       dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n",
+                                               serial_in(up, UART_LSR));
+                       break;
+               }
+               udelay(1);
+       }
+}
+
+static void serial_omap_restore_context(struct uart_omap_port *up)
+{
+       if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+               serial_omap_mdr1_errataset(up, UART_OMAP_MDR1_DISABLE);
+       else
+               serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+       serial_out(up, UART_EFR, UART_EFR_ECB);
+       serial_out(up, UART_LCR, 0x0); /* Operational mode */
+       serial_out(up, UART_IER, 0x0);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+       serial_out(up, UART_DLL, up->dll);
+       serial_out(up, UART_DLM, up->dlh);
+       serial_out(up, UART_LCR, 0x0); /* Operational mode */
+       serial_out(up, UART_IER, up->ier);
+       serial_out(up, UART_FCR, up->fcr);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       serial_out(up, UART_MCR, up->mcr);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+       serial_out(up, UART_OMAP_SCR, up->scr);
+       serial_out(up, UART_EFR, up->efr);
+       serial_out(up, UART_LCR, up->lcr);
+       if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
+               serial_omap_mdr1_errataset(up, up->mdr1);
+       else
+               serial_out(up, UART_OMAP_MDR1, up->mdr1);
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int serial_omap_runtime_suspend(struct device *dev)
+{
+       struct uart_omap_port *up = dev_get_drvdata(dev);
+       struct omap_uart_port_info *pdata = dev->platform_data;
+
+       if (!up)
+               return -EINVAL;
+
+       if (!pdata->enable_wakeup)
+               return 0;
+
+       if (pdata->get_context_loss_count)
+               up->context_loss_cnt = pdata->get_context_loss_count(dev);
+
+       if (device_may_wakeup(dev)) {
+               if (!up->wakeups_enabled) {
+                       pdata->enable_wakeup(up->pdev, true);
+                       up->wakeups_enabled = true;
+               }
+       } else {
+               if (up->wakeups_enabled) {
+                       pdata->enable_wakeup(up->pdev, false);
+                       up->wakeups_enabled = false;
+               }
+       }
+
+       /* Errata i291 */
+       if (up->use_dma && pdata->set_forceidle &&
+                       (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
+               pdata->set_forceidle(up->pdev);
+
+       up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
+       schedule_work(&up->qos_work);
+
+       return 0;
+}
+
+static int serial_omap_runtime_resume(struct device *dev)
+{
+       struct uart_omap_port *up = dev_get_drvdata(dev);
+       struct omap_uart_port_info *pdata = dev->platform_data;
+
+       if (up) {
+               if (pdata->get_context_loss_count) {
+                       u32 loss_cnt = pdata->get_context_loss_count(dev);
+
+                       if (up->context_loss_cnt != loss_cnt)
+                               serial_omap_restore_context(up);
+               }
+
+               /* Errata i291 */
+               if (up->use_dma && pdata->set_noidle &&
+                               (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
+                       pdata->set_noidle(up->pdev);
+
+               up->latency = up->calc_latency;
+               schedule_work(&up->qos_work);
+       }
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops serial_omap_dev_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume)
+       SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend,
+                               serial_omap_runtime_resume, NULL)
+};
+
 static struct platform_driver serial_omap_driver = {
        .probe          = serial_omap_probe,
        .remove         = serial_omap_remove,
-
-       .suspend        = serial_omap_suspend,
-       .resume         = serial_omap_resume,
        .driver         = {
                .name   = DRIVER_NAME,
+               .pm     = &serial_omap_dev_pm_ops,
        },
 };