提交 06a7f058 编写于 作者: D David Brownell 提交者: Linus Torvalds

atmel_serial: keep clock off when it's not needed

The atmel_serial driver is mismanaging its clock by leaving it on at all
times ...  the whole point of clock management is to leave it off unless
it's actively needed, which conserves power!!

Although the kernel doesn't actually hang without my fix, it does
discard quite a lot of early console output.

The result still looks correct:

          usart        users= 1 on   35000000 Hz, for atmel_usart.0
          usart        users= 0 off  35000000 Hz, for atmel_usart.2

when using ttyS0 as serial console.

[haavard.skinnemoen@atmel.com: Make sure clock is enabled early for console]
Signed-off-by: NDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: NHaavard Skinnemoen <haavard.skinnemoen@atmel.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 b225d44e
...@@ -1258,6 +1258,8 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, ...@@ -1258,6 +1258,8 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
atmel_port->clk = clk_get(&pdev->dev, "usart"); atmel_port->clk = clk_get(&pdev->dev, "usart");
clk_enable(atmel_port->clk); clk_enable(atmel_port->clk);
port->uartclk = clk_get_rate(atmel_port->clk); port->uartclk = clk_get_rate(atmel_port->clk);
clk_disable(atmel_port->clk);
/* only enable clock when USART is in use */
} }
atmel_port->use_dma_rx = data->use_dma_rx; atmel_port->use_dma_rx = data->use_dma_rx;
...@@ -1379,6 +1381,8 @@ static int __init atmel_console_setup(struct console *co, char *options) ...@@ -1379,6 +1381,8 @@ static int __init atmel_console_setup(struct console *co, char *options)
return -ENODEV; return -ENODEV;
} }
clk_enable(atmel_ports[co->index].clk);
UART_PUT_IDR(port, -1); UART_PUT_IDR(port, -1);
UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX);
UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN);
...@@ -1403,7 +1407,7 @@ static struct console atmel_console = { ...@@ -1403,7 +1407,7 @@ static struct console atmel_console = {
.data = &atmel_uart, .data = &atmel_uart,
}; };
#define ATMEL_CONSOLE_DEVICE &atmel_console #define ATMEL_CONSOLE_DEVICE (&atmel_console)
/* /*
* Early console initialization (before VM subsystem initialized). * Early console initialization (before VM subsystem initialized).
...@@ -1534,6 +1538,15 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) ...@@ -1534,6 +1538,15 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_add_port; goto err_add_port;
if (atmel_is_console_port(&port->uart)
&& ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) {
/*
* The serial core enabled the clock for us, so undo
* the clk_enable() in atmel_console_setup()
*/
clk_disable(port->clk);
}
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
platform_set_drvdata(pdev, port); platform_set_drvdata(pdev, port);
...@@ -1544,7 +1557,6 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) ...@@ -1544,7 +1557,6 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
port->rx_ring.buf = NULL; port->rx_ring.buf = NULL;
err_alloc_ring: err_alloc_ring:
if (!atmel_is_console_port(&port->uart)) { if (!atmel_is_console_port(&port->uart)) {
clk_disable(port->clk);
clk_put(port->clk); clk_put(port->clk);
port->clk = NULL; port->clk = NULL;
} }
...@@ -1568,7 +1580,6 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev) ...@@ -1568,7 +1580,6 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev)
/* "port" is allocated statically, so we shouldn't free it */ /* "port" is allocated statically, so we shouldn't free it */
clk_disable(atmel_port->clk);
clk_put(atmel_port->clk); clk_put(atmel_port->clk);
return ret; return ret;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册