struct s3c24xx_uart_info {
        char                    *name;
        enum s3c24xx_port_type  type;
+       unsigned int            has_usi;
        unsigned int            port_type;
        unsigned int            fifosize;
        unsigned long           rx_fifomask;
        return ret;
 }
 
+static void exynos_usi_init(struct uart_port *port)
+{
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       struct s3c24xx_uart_info *info = ourport->info;
+       unsigned int val;
+
+       if (!info->has_usi)
+               return;
+
+       /* Clear the software reset of USI block (it's set at startup) */
+       val = rd_regl(port, USI_CON);
+       val &= ~USI_CON_RESET_MASK;
+       wr_regl(port, USI_CON, val);
+       udelay(1);
+
+       /* Continuously provide the clock to USI IP w/o gating (for Rx mode) */
+       val = rd_regl(port, USI_OPTION);
+       val &= ~USI_OPTION_HWACG_MASK;
+       val |= USI_OPTION_HWACG_CLKREQ_ON;
+       wr_regl(port, USI_OPTION, val);
+}
+
 /* power power management control */
 
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
                if (!IS_ERR(ourport->baudclk))
                        clk_prepare_enable(ourport->baudclk);
 
+               exynos_usi_init(port);
                break;
        default:
                dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level);
        if (ret)
                pr_warn("uart: failed to enable baudclk\n");
 
+       exynos_usi_init(port);
+
        /* Keep all interrupts masked and cleared */
        switch (ourport->info->type) {
        case TYPE_S3C6400:
 #endif
 
 #if defined(CONFIG_ARCH_EXYNOS)
-#define EXYNOS_COMMON_SERIAL_DRV_DATA                          \
+#define EXYNOS_COMMON_SERIAL_DRV_DATA_USI(_has_usi)            \
        .info = &(struct s3c24xx_uart_info) {                   \
                .name           = "Samsung Exynos UART",        \
                .type           = TYPE_S3C6400,                 \
+               .has_usi        = _has_usi,                     \
                .port_type      = PORT_S3C6400,                 \
                .has_divslot    = 1,                            \
                .rx_fifomask    = S5PV210_UFSTAT_RXMASK,        \
                .has_fracval    = 1,                            \
        }                                                       \
 
+#define EXYNOS_COMMON_SERIAL_DRV_DATA                          \
+       EXYNOS_COMMON_SERIAL_DRV_DATA_USI(0)
+
 static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
        EXYNOS_COMMON_SERIAL_DRV_DATA,
        .fifosize = { 256, 64, 16, 16 },
 
 #define S3C2410_UERSTAT          (0x14)
 #define S3C2410_UFSTAT   (0x18)
 #define S3C2410_UMSTAT   (0x1C)
+#define USI_CON                  (0xC4)
+#define USI_OPTION       (0xC8)
+
+#define USI_CON_RESET                  (1<<0)
+#define USI_CON_RESET_MASK             (1<<0)
+
+#define USI_OPTION_HWACG_CLKREQ_ON     (1<<1)
+#define USI_OPTION_HWACG_CLKSTOP_ON    (1<<2)
+#define USI_OPTION_HWACG_MASK          (3<<1)
 
 #define S3C2410_LCON_CFGMASK     ((0xF<<3)|(0x3))