diff options
Diffstat (limited to 'drivers/tty/serial/samsung.c')
-rw-r--r-- | drivers/tty/serial/samsung.c | 90 |
1 files changed, 38 insertions, 52 deletions
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index c78f43a481ce..7ed76773c274 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -199,12 +199,14 @@ static void s3c24xx_serial_stop_rx(struct uart_port *port) } } -static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *port) +static inline struct s3c24xx_uart_info + *s3c24xx_port_to_info(struct uart_port *port) { return to_ourport(port)->info; } -static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port) +static inline struct s3c2410_uartcfg + *s3c24xx_port_to_cfg(struct uart_port *port) { struct s3c24xx_uart_port *ourport; @@ -237,7 +239,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) struct uart_port *port = &ourport->port; unsigned int ufcon, ch, flag, ufstat, uerstat; unsigned long flags; - int max_count = 64; + int max_count = port->fifosize; spin_lock_irqsave(&port->lock, flags); @@ -311,14 +313,14 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag); - ignore_char: +ignore_char: continue; } spin_unlock_irqrestore(&port->lock, flags); tty_flip_buffer_push(&port->state->port); - out: +out: return IRQ_HANDLED; } @@ -328,7 +330,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) struct uart_port *port = &ourport->port; struct circ_buf *xmit = &port->state->xmit; unsigned long flags; - int count = 256; + int count = port->fifosize; spin_lock_irqsave(&port->lock, flags); @@ -368,7 +370,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) if (uart_circ_empty(xmit)) s3c24xx_serial_stop_tx(port); - out: +out: spin_unlock_irqrestore(&port->lock, flags); return IRQ_HANDLED; } @@ -519,7 +521,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) return ret; - err: +err: s3c24xx_serial_shutdown(port); return ret; } @@ -559,11 +561,15 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, unsigned int old) { struct s3c24xx_uart_port *ourport = to_ourport(port); + int timeout = 10000; ourport->pm_level = level; switch (level) { case 3: + while (--timeout && !s3c24xx_serial_txempty_nofifo(port)) + udelay(100); + if (!IS_ERR(ourport->baudclk)) clk_disable_unprepare(ourport->baudclk); @@ -841,8 +847,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, */ port->read_status_mask = S3C2410_UERSTAT_OVERRUN; if (termios->c_iflag & INPCK) - port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY; - + port->read_status_mask |= S3C2410_UERSTAT_FRAME | + S3C2410_UERSTAT_PARITY; /* * Which character status flags should we ignore? */ @@ -969,10 +975,13 @@ static struct uart_driver s3c24xx_uart_drv = { .minor = S3C24XX_SERIAL_MINOR, }; -static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { +#define __PORT_LOCK_UNLOCKED(i) \ + __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[i].port.lock) +static struct s3c24xx_uart_port +s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = { [0] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), + .lock = __PORT_LOCK_UNLOCKED(0), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -983,7 +992,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS }, [1] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), + .lock = __PORT_LOCK_UNLOCKED(1), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -996,7 +1005,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS [2] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), + .lock = __PORT_LOCK_UNLOCKED(2), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -1009,7 +1018,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS #if CONFIG_SERIAL_SAMSUNG_UARTS > 3 [3] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[3].port.lock), + .lock = __PORT_LOCK_UNLOCKED(3), .iotype = UPIO_MEM, .uartclk = 0, .fifosize = 16, @@ -1020,6 +1029,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS } #endif }; +#undef __PORT_LOCK_UNLOCKED /* s3c24xx_serial_resetport * @@ -1102,11 +1112,12 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, s3c24xx_serial_set_termios(uport, termios, NULL); } - exit: +exit: return 0; } -static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) +static inline int +s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { port->freq_transition.notifier_call = s3c24xx_serial_cpufreq_transition; @@ -1114,19 +1125,22 @@ static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port CPUFREQ_TRANSITION_NOTIFIER); } -static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) +static inline void +s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { cpufreq_unregister_notifier(&port->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } #else -static inline int s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) +static inline int +s3c24xx_serial_cpufreq_register(struct s3c24xx_uart_port *port) { return 0; } -static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) +static inline void +s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *port) { } #endif @@ -1226,24 +1240,6 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, return 0; } -#ifdef CONFIG_SAMSUNG_CLOCK -static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - 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 ?: "(null)"); -} - -static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); -#endif - /* Device driver serial port probe */ static const struct of_device_id s3c24xx_uart_dt_match[]; @@ -1296,11 +1292,10 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize); - if (!ourport->port.fifosize) { - ourport->port.fifosize = (ourport->info->fifosize) ? - ourport->info->fifosize : - ourport->drv_data->fifosize[index]; - } + if (ourport->drv_data->fifosize[index]) + ourport->port.fifosize = ourport->drv_data->fifosize[index]; + else if (ourport->info->fifosize) + ourport->port.fifosize = ourport->info->fifosize; probe_index++; @@ -1329,12 +1324,6 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) */ clk_disable_unprepare(ourport->clk); -#ifdef CONFIG_SAMSUNG_CLOCK - ret = device_create_file(&pdev->dev, &dev_attr_clock_source); - if (ret < 0) - dev_err(&pdev->dev, "failed to add clock source attr.\n"); -#endif - ret = s3c24xx_serial_cpufreq_register(ourport); if (ret < 0) dev_err(&pdev->dev, "failed to add cpufreq notifier\n"); @@ -1348,9 +1337,6 @@ static int s3c24xx_serial_remove(struct platform_device *dev) if (port) { s3c24xx_serial_cpufreq_deregister(to_ourport(port)); -#ifdef CONFIG_SAMSUNG_CLOCK - device_remove_file(&dev->dev, &dev_attr_clock_source); -#endif uart_remove_one_port(&s3c24xx_uart_drv, port); } |