Commit 7d78cbef authored by Heiko Stübner's avatar Heiko Stübner Committed by Greg Kroah-Hartman

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

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: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d8782c74
...@@ -4,7 +4,15 @@ Required properties: ...@@ -4,7 +4,15 @@ Required properties:
- compatible : "snps,dw-apb-uart" - compatible : "snps,dw-apb-uart"
- reg : offset and length of the register set for the device. - reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt. - 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. - 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: Optional properties:
- reg-shift : quantity to shift the register offsets by. If this property is - reg-shift : quantity to shift the register offsets by. If this property is
...@@ -23,3 +31,26 @@ Example: ...@@ -23,3 +31,26 @@ Example:
reg-shift = <2>; reg-shift = <2>;
reg-io-width = <4>; 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>;
};
...@@ -59,6 +59,7 @@ struct dw8250_data { ...@@ -59,6 +59,7 @@ struct dw8250_data {
int last_mcr; int last_mcr;
int line; int line;
struct clk *clk; struct clk *clk;
struct clk *pclk;
struct uart_8250_dma dma; struct uart_8250_dma dma;
}; };
...@@ -359,10 +360,25 @@ static int dw8250_probe(struct platform_device *pdev) ...@@ -359,10 +360,25 @@ static int dw8250_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
data->usr_reg = DW_UART_USR; 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)) { if (!IS_ERR(data->clk)) {
clk_prepare_enable(data->clk); err = clk_prepare_enable(data->clk);
uart.port.uartclk = clk_get_rate(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; data->dma.rx_chan_id = -1;
...@@ -408,6 +424,9 @@ static int dw8250_remove(struct platform_device *pdev) ...@@ -408,6 +424,9 @@ static int dw8250_remove(struct platform_device *pdev)
serial8250_unregister_port(data->line); serial8250_unregister_port(data->line);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
if (!IS_ERR(data->clk)) if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk); clk_disable_unprepare(data->clk);
...@@ -445,6 +464,9 @@ static int dw8250_runtime_suspend(struct device *dev) ...@@ -445,6 +464,9 @@ static int dw8250_runtime_suspend(struct device *dev)
if (!IS_ERR(data->clk)) if (!IS_ERR(data->clk))
clk_disable_unprepare(data->clk); clk_disable_unprepare(data->clk);
if (!IS_ERR(data->pclk))
clk_disable_unprepare(data->pclk);
return 0; return 0;
} }
...@@ -452,6 +474,9 @@ static int dw8250_runtime_resume(struct device *dev) ...@@ -452,6 +474,9 @@ static int dw8250_runtime_resume(struct device *dev)
{ {
struct dw8250_data *data = dev_get_drvdata(dev); struct dw8250_data *data = dev_get_drvdata(dev);
if (!IS_ERR(data->pclk))
clk_prepare_enable(data->pclk);
if (!IS_ERR(data->clk)) if (!IS_ERR(data->clk))
clk_prepare_enable(data->clk); clk_prepare_enable(data->clk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment