Skip to content

Commit

Permalink
serial: 8250_dw: add ability to handle the peripheral clock
Browse files Browse the repository at this point in the history
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@sntech.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Heiko Stübner authored and Greg Kroah-Hartman committed Jul 10, 2014
1 parent d8782c7 commit 7d78cbe
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
31 changes: 31 additions & 0 deletions Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>;
};
31 changes: 28 additions & 3 deletions drivers/tty/serial/8250/8250_dw.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct dw8250_data {
int last_mcr;
int line;
struct clk *clk;
struct clk *pclk;
struct uart_8250_dma dma;
};

Expand Down Expand Up @@ -359,10 +360,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;
Expand Down Expand Up @@ -408,6 +424,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);

Expand Down Expand Up @@ -445,13 +464,19 @@ 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;
}

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);

Expand Down

0 comments on commit 7d78cbe

Please sign in to comment.