diff options
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
| -rw-r--r-- | drivers/tty/serial/atmel_serial.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index fabbe76203bb..dcebb28ffbc4 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
| @@ -175,6 +175,17 @@ struct atmel_uart_port { | |||
| 175 | unsigned int pending_status; | 175 | unsigned int pending_status; |
| 176 | spinlock_t lock_suspended; | 176 | spinlock_t lock_suspended; |
| 177 | 177 | ||
| 178 | struct { | ||
| 179 | u32 cr; | ||
| 180 | u32 mr; | ||
| 181 | u32 imr; | ||
| 182 | u32 brgr; | ||
| 183 | u32 rtor; | ||
| 184 | u32 ttgr; | ||
| 185 | u32 fmr; | ||
| 186 | u32 fimr; | ||
| 187 | } cache; | ||
| 188 | |||
| 178 | int (*prepare_rx)(struct uart_port *port); | 189 | int (*prepare_rx)(struct uart_port *port); |
| 179 | int (*prepare_tx)(struct uart_port *port); | 190 | int (*prepare_tx)(struct uart_port *port); |
| 180 | void (*schedule_rx)(struct uart_port *port); | 191 | void (*schedule_rx)(struct uart_port *port); |
| @@ -1758,7 +1769,9 @@ static void atmel_get_ip_name(struct uart_port *port) | |||
| 1758 | 1769 | ||
| 1759 | /* | 1770 | /* |
| 1760 | * Only USART devices from at91sam9260 SOC implement fractional | 1771 | * Only USART devices from at91sam9260 SOC implement fractional |
| 1761 | * baudrate. | 1772 | * baudrate. It is available for all asynchronous modes, with the |
| 1773 | * following restriction: the sampling clock's duty cycle is not | ||
| 1774 | * constant. | ||
| 1762 | */ | 1775 | */ |
| 1763 | atmel_port->has_frac_baudrate = false; | 1776 | atmel_port->has_frac_baudrate = false; |
| 1764 | atmel_port->has_hw_timer = false; | 1777 | atmel_port->has_hw_timer = false; |
| @@ -2202,8 +2215,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 2202 | * then | 2215 | * then |
| 2203 | * 8 CD + FP = selected clock / (2 * baudrate) | 2216 | * 8 CD + FP = selected clock / (2 * baudrate) |
| 2204 | */ | 2217 | */ |
| 2205 | if (atmel_port->has_frac_baudrate && | 2218 | if (atmel_port->has_frac_baudrate) { |
| 2206 | (mode & ATMEL_US_USMODE) == ATMEL_US_USMODE_NORMAL) { | ||
| 2207 | div = DIV_ROUND_CLOSEST(port->uartclk, baud * 2); | 2219 | div = DIV_ROUND_CLOSEST(port->uartclk, baud * 2); |
| 2208 | cd = div >> 3; | 2220 | cd = div >> 3; |
| 2209 | fp = div & ATMEL_US_FP_MASK; | 2221 | fp = div & ATMEL_US_FP_MASK; |
| @@ -2659,6 +2671,20 @@ static int atmel_serial_suspend(struct platform_device *pdev, | |||
| 2659 | cpu_relax(); | 2671 | cpu_relax(); |
| 2660 | } | 2672 | } |
| 2661 | 2673 | ||
| 2674 | if (atmel_is_console_port(port) && !console_suspend_enabled) { | ||
| 2675 | /* Cache register values as we won't get a full shutdown/startup | ||
| 2676 | * cycle | ||
| 2677 | */ | ||
| 2678 | atmel_port->cache.mr = atmel_uart_readl(port, ATMEL_US_MR); | ||
| 2679 | atmel_port->cache.imr = atmel_uart_readl(port, ATMEL_US_IMR); | ||
| 2680 | atmel_port->cache.brgr = atmel_uart_readl(port, ATMEL_US_BRGR); | ||
| 2681 | atmel_port->cache.rtor = atmel_uart_readl(port, | ||
| 2682 | atmel_port->rtor); | ||
| 2683 | atmel_port->cache.ttgr = atmel_uart_readl(port, ATMEL_US_TTGR); | ||
| 2684 | atmel_port->cache.fmr = atmel_uart_readl(port, ATMEL_US_FMR); | ||
| 2685 | atmel_port->cache.fimr = atmel_uart_readl(port, ATMEL_US_FIMR); | ||
| 2686 | } | ||
| 2687 | |||
| 2662 | /* we can not wake up if we're running on slow clock */ | 2688 | /* we can not wake up if we're running on slow clock */ |
| 2663 | atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); | 2689 | atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); |
| 2664 | if (atmel_serial_clk_will_stop()) { | 2690 | if (atmel_serial_clk_will_stop()) { |
| @@ -2681,6 +2707,25 @@ static int atmel_serial_resume(struct platform_device *pdev) | |||
| 2681 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 2707 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
| 2682 | unsigned long flags; | 2708 | unsigned long flags; |
| 2683 | 2709 | ||
| 2710 | if (atmel_is_console_port(port) && !console_suspend_enabled) { | ||
| 2711 | atmel_uart_writel(port, ATMEL_US_MR, atmel_port->cache.mr); | ||
| 2712 | atmel_uart_writel(port, ATMEL_US_IER, atmel_port->cache.imr); | ||
| 2713 | atmel_uart_writel(port, ATMEL_US_BRGR, atmel_port->cache.brgr); | ||
| 2714 | atmel_uart_writel(port, atmel_port->rtor, | ||
| 2715 | atmel_port->cache.rtor); | ||
| 2716 | atmel_uart_writel(port, ATMEL_US_TTGR, atmel_port->cache.ttgr); | ||
| 2717 | |||
| 2718 | if (atmel_port->fifo_size) { | ||
| 2719 | atmel_uart_writel(port, ATMEL_US_CR, ATMEL_US_FIFOEN | | ||
| 2720 | ATMEL_US_RXFCLR | ATMEL_US_TXFLCLR); | ||
| 2721 | atmel_uart_writel(port, ATMEL_US_FMR, | ||
| 2722 | atmel_port->cache.fmr); | ||
| 2723 | atmel_uart_writel(port, ATMEL_US_FIER, | ||
| 2724 | atmel_port->cache.fimr); | ||
| 2725 | } | ||
| 2726 | atmel_start_rx(port); | ||
| 2727 | } | ||
| 2728 | |||
| 2684 | spin_lock_irqsave(&atmel_port->lock_suspended, flags); | 2729 | spin_lock_irqsave(&atmel_port->lock_suspended, flags); |
| 2685 | if (atmel_port->pending) { | 2730 | if (atmel_port->pending) { |
| 2686 | atmel_handle_receive(port, atmel_port->pending); | 2731 | atmel_handle_receive(port, atmel_port->pending); |
