From 7cd88831feb03cadb355d5fb2b18ebe284c1f1e3 Mon Sep 17 00:00:00 2001 From: Kyoungil Kim Date: Sun, 20 May 2012 17:45:54 +0900 Subject: serial: samsung: Remove NULL checking for baud clock Signed-off-by: Kyoungil Kim Suggested-by: Russell King Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index d8b0aee35632..56685387f8eb 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -529,7 +529,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, switch (level) { case 3: - if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) + if (!IS_ERR(ourport->baudclk)) clk_disable(ourport->baudclk); clk_disable(ourport->clk); @@ -538,7 +538,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, case 0: clk_enable(ourport->clk); - if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) + if (!IS_ERR(ourport->baudclk)) clk_enable(ourport->baudclk); break; @@ -604,7 +604,6 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, char clkname[MAX_CLK_NAME_LENGTH]; int calc_deviation, deviation = (1 << 30) - 1; - *best_clk = NULL; clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : ourport->info->def_clk_sel; for (cnt = 0; cnt < info->num_clks; cnt++) { @@ -613,7 +612,7 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, sprintf(clkname, "clk_uart_baud%d", cnt); clk = clk_get(ourport->port.dev, clkname); - if (IS_ERR_OR_NULL(clk)) + if (IS_ERR(clk)) continue; rate = clk_get_rate(clk); @@ -684,7 +683,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, { struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); struct s3c24xx_uart_port *ourport = to_ourport(port); - struct clk *clk = NULL; + struct clk *clk = ERR_PTR(-EINVAL); unsigned long flags; unsigned int baud, quot, clk_sel = 0; unsigned int ulcon; @@ -705,7 +704,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) quot = port->custom_divisor; - if (!clk) + if (IS_ERR(clk)) return; /* check to see if we need to change clock source */ @@ -713,9 +712,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, if (ourport->baudclk != clk) { s3c24xx_serial_setsource(port, clk_sel); - if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { + if (!IS_ERR(ourport->baudclk)) { clk_disable(ourport->baudclk); - ourport->baudclk = NULL; + ourport->baudclk = ERR_PTR(-EINVAL); } clk_enable(clk); @@ -1160,6 +1159,9 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, struct uart_port *port = s3c24xx_dev_to_port(dev); struct s3c24xx_uart_port *ourport = to_ourport(port); + if (IS_ERR(ourport->baudclk)) + return -EINVAL; + return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name); } @@ -1200,6 +1202,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) return -ENODEV; } + ourport->baudclk = ERR_PTR(-EINVAL); ourport->info = ourport->drv_data->info; ourport->cfg = (pdev->dev.platform_data) ? (struct s3c2410_uartcfg *)pdev->dev.platform_data : @@ -1387,7 +1390,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, sprintf(clk_name, "clk_uart_baud%d", clk_sel); clk = clk_get(port->dev, clk_name); - if (!IS_ERR(clk) && clk != NULL) + if (!IS_ERR(clk)) rate = clk_get_rate(clk); else rate = 1; -- cgit v1.2.1 From 25f04ad423e5eb40c33a904db5a0d2c7e3bf08f5 Mon Sep 17 00:00:00 2001 From: Kyoungil Kim Date: Sun, 20 May 2012 17:49:31 +0900 Subject: serial: samsung: Fixed wrong comparison for baudclk_rate port->baudclk_rate should be compared to the rate of port->baudclk, because port->baudclk_rate was assigned as the rate of port->baudclk previously. So to check that the current baudclk rate is same as previous rate, the target of comparison sholud be the rate of port->baudclk. Signed-off-by: Jun-Ho, Yoon Signed-off-by: Kyoungil Kim Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 56685387f8eb..cefdd2d7c58c 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1013,10 +1013,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, * a disturbance in the clock-rate over the change. */ - if (IS_ERR(port->clk)) + if (IS_ERR(port->baudclk)) goto exit; - if (port->baudclk_rate == clk_get_rate(port->clk)) + if (port->baudclk_rate == clk_get_rate(port->baudclk)) goto exit; if (val == CPUFREQ_PRECHANGE) { -- cgit v1.2.1 From 7b15e1d9e342aca6c65f4824f1957f5245fcd87a Mon Sep 17 00:00:00 2001 From: KeyYoung Park Date: Wed, 30 May 2012 17:29:55 +0900 Subject: serial: samsung: protect NULL dereference of clock name When priting the serial clock source, if clock source name is null, kernel reference NULL point. Signed-off-by: KeyYoung Park Signed-off-by: Huisung Kang Signed-off-by: Kyoungil Kim Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index cefdd2d7c58c..d57f165d6be8 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1162,7 +1162,8 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, if (IS_ERR(ourport->baudclk)) return -EINVAL; - return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name); + return snprintf(buf, PAGE_SIZE, "* %s\n", + ourport->baudclk->name ?: "(null)"); } static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); -- cgit v1.2.1 From adc8d746caa67fff4b53ba3e5163a6cbacc3b523 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 14 Jul 2012 15:31:47 +0100 Subject: tty: move the termios object into the tty This will let us sort out a whole pile of tty related races. The alternative would be to keep points and refcount the termios objects. However 1. They are tiny anyway 2. Many devices don't use the stored copies 3. We can remove a pty special case Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index d57f165d6be8..5c5e7e09f23e 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1035,7 +1035,7 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, if (tty == NULL) goto exit; - termios = tty->termios; + termios = &tty->termios; if (termios == NULL) { printk(KERN_WARNING "%s: no termios?\n", __func__); -- cgit v1.2.1 From d20925e1e4fbd501754efad5401040d700fae4d6 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 5 Sep 2012 10:30:10 +0530 Subject: serial: Samsung: Replace printk with dev_* functions Silences checkpatch warnings regarding use of printks. Signed-off-by: Sachin Kamat Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 5c5e7e09f23e..8749a07dbea4 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -459,7 +459,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) s3c24xx_serial_portname(port), ourport); if (ret != 0) { - printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq); + dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); return ret; } @@ -473,7 +473,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) s3c24xx_serial_portname(port), ourport); if (ret) { - printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq); + dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); goto err; } @@ -502,7 +502,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, s3c24xx_serial_portname(port), ourport); if (ret) { - printk(KERN_ERR "cannot get irq %d\n", port->irq); + dev_err(port->dev, "cannot get irq %d\n", port->irq); return ret; } @@ -543,7 +543,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, break; default: - printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level); + dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level); } } @@ -1038,7 +1038,7 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, termios = &tty->termios; if (termios == NULL) { - printk(KERN_WARNING "%s: no termios?\n", __func__); + dev_warn(uport->dev, "%s: no termios?\n", __func__); goto exit; } @@ -1113,7 +1113,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, res = platform_get_resource(platdev, IORESOURCE_MEM, 0); if (res == NULL) { - printk(KERN_ERR "failed to find memory resource for uart\n"); + dev_err(port->dev, "failed to find memory resource for uart\n"); return -EINVAL; } @@ -1683,7 +1683,7 @@ static int __init s3c24xx_serial_modinit(void) ret = uart_register_driver(&s3c24xx_uart_drv); if (ret < 0) { - printk(KERN_ERR "failed to register UART driver\n"); + pr_err("Failed to register Samsung UART driver\n"); return -1; } -- cgit v1.2.1 From 9303ac158fcd5f69c032e06391a9a12d3ccb343e Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 5 Sep 2012 10:30:11 +0530 Subject: serial: Samsung: Silence some checkpatch errors and warnings Fixes the following errors and warnings: ERROR: trailing whitespace ERROR: return is not a function, parentheses are not required WARNING: suspect code indent for conditional statements (32, 36) Signed-off-by: Sachin Kamat Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 8749a07dbea4..bdaa06f3ab69 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -82,7 +82,7 @@ static inline const char *s3c24xx_serial_portname(struct uart_port *port) static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) { - return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE); + return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE; } /* @@ -268,7 +268,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) dbg("break!\n"); port->icount.brk++; if (uart_handle_break(port)) - goto ignore_char; + goto ignore_char; } if (uerstat & S3C2410_UERSTAT_FRAME) @@ -1129,7 +1129,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ourport->rx_irq = ret; ourport->tx_irq = ret + 1; } - + ret = platform_get_irq(platdev, 1); if (ret > 0) ourport->tx_irq = ret; -- cgit v1.2.1 From e740d8f1a0a23a8fea8fbc5a02013c7410283665 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 12 Sep 2012 12:00:01 +0530 Subject: tty: serial: Samsung: Fix return value Return the value returned by the failing function instead of -1 (which does not convey the right error information). Fixes the following smatch warning: drivers/tty/serial/samsung.c:1687 s3c24xx_serial_modinit() info: why not propagate 'ret' from uart_register_driver() instead of -1? Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index bdaa06f3ab69..8eef1141b81d 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1684,7 +1684,7 @@ static int __init s3c24xx_serial_modinit(void) ret = uart_register_driver(&s3c24xx_uart_drv); if (ret < 0) { pr_err("Failed to register Samsung UART driver\n"); - return -1; + return ret; } return platform_driver_register(&samsung_serial_driver); -- cgit v1.2.1 From 93b5c032d95e032691e627526b364cd463834347 Mon Sep 17 00:00:00 2001 From: Julien Pichon Date: Fri, 21 Sep 2012 23:22:31 -0700 Subject: serial: samsung: Add poll_get_char & poll_put_char The following patch allows users to use KGDB over serial console on board based on Samsung SOC. It has been tested on a board using exynos5. [dianders: changed poll to return NO_POLL_CHAR, which appears to fix 'help' in kgdb; also updated commit message] Signed-off-by: Julien Pichon Signed-off-by: Doug Anderson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'drivers/tty/serial/samsung.c') diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 8eef1141b81d..7f04717176aa 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -876,11 +876,24 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) static struct console s3c24xx_serial_console; +static int __init s3c24xx_serial_console_init(void) +{ + register_console(&s3c24xx_serial_console); + return 0; +} +console_initcall(s3c24xx_serial_console_init); + #define S3C24XX_SERIAL_CONSOLE &s3c24xx_serial_console #else #define S3C24XX_SERIAL_CONSOLE NULL #endif +#ifdef CONFIG_CONSOLE_POLL +static int s3c24xx_serial_get_poll_char(struct uart_port *port); +static void s3c24xx_serial_put_poll_char(struct uart_port *port, + unsigned char c); +#endif + static struct uart_ops s3c24xx_serial_ops = { .pm = s3c24xx_serial_pm, .tx_empty = s3c24xx_serial_tx_empty, @@ -899,6 +912,10 @@ static struct uart_ops s3c24xx_serial_ops = { .request_port = s3c24xx_serial_request_port, .config_port = s3c24xx_serial_config_port, .verify_port = s3c24xx_serial_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = s3c24xx_serial_get_poll_char, + .poll_put_char = s3c24xx_serial_put_poll_char, +#endif }; static struct uart_driver s3c24xx_uart_drv = { @@ -1316,6 +1333,36 @@ s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon) return (utrstat & S3C2410_UTRSTAT_TXE) ? 1 : 0; } +#ifdef CONFIG_CONSOLE_POLL +/* + * Console polling routines for writing and reading from the uart while + * in an interrupt or debug context. + */ + +static int s3c24xx_serial_get_poll_char(struct uart_port *port) +{ + struct s3c24xx_uart_port *ourport = to_ourport(port); + unsigned int ufstat; + + ufstat = rd_regl(port, S3C2410_UFSTAT); + if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) + return NO_POLL_CHAR; + + return rd_regb(port, S3C2410_URXH); +} + +static void s3c24xx_serial_put_poll_char(struct uart_port *port, + unsigned char c) +{ + unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); + + while (!s3c24xx_serial_console_txrdy(port, ufcon)) + cpu_relax(); + wr_regb(cons_uart, S3C2410_UTXH, c); +} + +#endif /* CONFIG_CONSOLE_POLL */ + static void s3c24xx_serial_console_putchar(struct uart_port *port, int ch) { -- cgit v1.2.1