[COMMON] serial: samsung: set USI_RESET before channel setting
authorYoungmin Nam <youngmin.nam@samsung.com>
Tue, 17 Jan 2017 02:54:05 +0000 (11:54 +0900)
committermyung-su.cha <myung-su.cha@samsung.com>
Wed, 9 May 2018 12:14:45 +0000 (21:14 +0900)
Change-Id: I222a1939d82041202ec999d14ef797bdf08b3776
Signed-off-by: Youngmin Nam <youngmin.nam@samsung.com>
drivers/tty/serial/samsung.c
include/linux/serial_s3c.h

index 99ed08ccde8011631697178d5d71ac255cbbc8c5..23eef13349cc5b1f5dea182a7c6ecabe7f23d5cd 100644 (file)
@@ -202,6 +202,7 @@ uart_dbg_store(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(uart_dbg, 0640, uart_dbg_show, uart_dbg_store);
 
+static void exynos_usi_init(struct uart_port *port);
 static void s3c24xx_serial_resetport(struct uart_port *port,
                                   struct s3c2410_uartcfg *cfg);
 static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
@@ -769,6 +770,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
        case S3C24XX_UART_PORT_RESUME:
                uart_clock_enable(ourport);
 
+               exynos_usi_init(port);
                s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
                break;
        default:
@@ -1248,6 +1250,21 @@ static struct s3c24xx_uart_port *exynos_serial_default_port(int port_index)
 }
 #undef __PORT_LOCK_UNLOCKED
 
+static void exynos_usi_init(struct uart_port *port)
+{
+       /* USI_RESET is active High signal.
+        * Reset value of USI_RESET is 'h1 to drive stable value to PAD.
+        * Due to this feature, the USI_RESET must be cleared (set as '0')
+        * before transaction starts.
+        */
+       wr_regl(port, USI_CON, USI_RESET);
+
+       /* set the HWACG option bit in case of UART Rx mode.
+        * CLKREQ_ON = 1, CLKSTOP_ON = 0 (set USI_OPTION[2:1] = 2'h1)
+        */
+       wr_regl(port, USI_OPTION, USI_HWACG_CLKREQ_ON);
+}
+
 /* s3c24xx_serial_resetport
  *
  * reset the fifos and other the settings.
@@ -1273,13 +1290,6 @@ static void s3c24xx_serial_resetport(struct uart_port *port,
 
        wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
 
-#ifdef CONFIG_SERIAL_SAMSUNG_HWACG
-       /* set the HWACG option bit in case of UART Rx mode.
-        * CLKREQ_ON = 1, CLKSTOP_ON = 0 (set USI_OPTION[2:1] = 2'h1)
-        */
-       wr_regl(port, USI_HWACG, USI_HWACG_CLKREQ_ON);
-#endif
-
        /* reset both fifos */
        wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
        wr_regl(port, S3C2410_UFCON, cfg->ufcon);
@@ -1391,6 +1401,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
                return ret;
        }
 
+       exynos_usi_init(port);
+
        /* Keep all interrupts masked and cleared */
        if (s3c24xx_serial_has_interrupt_mask(port)) {
                wr_regl(port, S3C64XX_UINTM, 0xf);
@@ -1732,6 +1744,7 @@ static int s3c24xx_serial_resume(struct device *dev)
 
        if (port) {
                uart_clock_enable(ourport);
+               exynos_usi_init(port);
                s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
                uart_clock_disable(ourport);
 
index a68ceb21d019bef9379225ee43697be1f7a9d44e..12d686edf43e00faa1c0ca51e72cdf8f2334798c 100644 (file)
 #define S3C2410_UERSTAT          (0x14)
 #define S3C2410_UFSTAT   (0x18)
 #define S3C2410_UMSTAT   (0x1C)
-#define USI_HWACG        (0xC8)
 
+#define USI_CON                        (0xC4)
+#define USI_OPTION             (0xC8)
+
+#define USI_RESET                      (0<<0)
 #define USI_HWACG_CLKREQ_ON            (1<<1)
 #define USI_HWACG_CLKSTOP_ON           (1<<2)