aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/atmel_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r--drivers/tty/serial/atmel_serial.c51
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);