serial: 8250_dw: add ability to handle the peripheral clock

A patch from »serial: 8250_dw: add ability to handle the peripheral clock« in state Mainline for linux-kernel

From: Heiko Stuebner <heiko@...> Date: Mon, 16 Jun 2014 15:14:49 +0200

Commit-Message

First try to find the named clock variants then fall back to the already existing handling of a nameless declared baudclk. This also adds the missing documentation for this already existing variant. Signed-off-by: Heiko Stuebner <heiko@...>

Patch-Comment

.../bindings/serial/snps-dw-apb-uart.txt | 31 ++++++++++++++++++++++ drivers/tty/serial/8250/8250_dw.c | 31 +++++++++++++++++++--- 2 files changed, 59 insertions(+), 3 deletions(-)

Statistics

  • 59 lines added
  • 3 lines removed

Changes

-------- Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt ---------
index f13f1c5..3601399 100644
@@ -4,7 +4,15 @@ Required properties:
- compatible : "snps,dw-apb-uart"
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.
+
+Clock handling:
+The clock rate of the input clock needs to be supplied by one of
- clock-frequency : the input clock frequency for the UART.
+- clocks : phandle to the input clock
+
+The supplying peripheral clock can also be handled, needing a second property
+- clock-names: tuple listing input clock names.
+ Required elements: "baudclk", "apb_pclk"
Optional properties:
- reg-shift : quantity to shift the register offsets by. If this property is
@@ -23,3 +31,26 @@ Example:
reg-shift = <2>;
reg-io-width = <4>;
};
+
+Example with one clock:
+
+ uart@80230000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x80230000 0x100>;
+ clocks = <&baudclk>;
+ interrupts = <10>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
+
+Example with two clocks:
+
+ uart@80230000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x80230000 0x100>;
+ clocks = <&baudclk>, <&apb_pclk>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <10>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
---------------------- drivers/tty/serial/8250/8250_dw.c -----------------------
index 51b307a..024cd58 100644
@@ -59,6 +59,7 @@ struct dw8250_data {
int last_mcr;
int line;
struct clk *clk;
+ struct clk *pclk;
struct uart_8250_dma dma;
};
@@ -402,10 +403,25 @@ static int dw8250_probe(struct platform_device *pdev)
return -ENOMEM;
data->usr_reg = DW_UART_USR;
- data->clk = devm_clk_get(&pdev->dev, NULL);
+ data->clk = devm_clk_get(&pdev->dev, "baudclk");
+ if (IS_ERR(data->clk))
+ data->clk = devm_clk_get(&pdev->dev, NULL);
if (!IS_ERR(data->clk)) {
- clk_prepare_enable(data->clk);
- uart.port.uartclk = clk_get_rate(data->clk);
+ err = clk_prepare_enable(data->clk);
+ if (err)
+ dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n",
+ err);
+ else
+ uart.port.uartclk = clk_get_rate(data->clk);
+ }
+
+ data->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
+ if (!IS_ERR(data->pclk)) {
+ err = clk_prepare_enable(data->pclk);
+ if (err) {
+ dev_err(&pdev->dev, "could not enable apb_pclk\n");
+ return err;
+ }
}
data->dma.rx_chan_id = -1;
@@ -451,6 +467,9 @@ static int dw8250_remove(struct platform_device *pdev)
serial8250_unregister_port(data->line);
+ if (!IS_ERR(data->pclk))
+ clk_disable_unprepare(data->pclk);
+
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
@@ -488,6 +507,9 @@ static int dw8250_runtime_suspend(struct device *dev)
if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk);
+ if (!IS_ERR(data->pclk))
+ clk_disable_unprepare(data->pclk);
+
return 0;
}
@@ -495,6 +517,9 @@ static int dw8250_runtime_resume(struct device *dev)
{
struct dw8250_data *data = dev_get_drvdata(dev);
+ if (!IS_ERR(data->pclk))
+ clk_prepare_enable(data->pclk);
+
if (!IS_ERR(data->clk))
clk_prepare_enable(data->clk);
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...