Skip to content

Commit

Permalink
serial: vt8500: UART uses gated clock rather than 24Mhz reference
Browse files Browse the repository at this point in the history
UART modules on Wondermedia SoCs are connected via a gated clock
source, rather than directly to the 24Mhz reference clock. While
uboot enables UART0 for debugging, other UART ports are unavailable
until the clock is enabled.

This patch checks that a valid clock is actually passed from devicetree,
enables the clock in probe. This change removes the fallback when a
clock was not specified as it doesn't apply any longer (and would only
work if the UART clock was already enabled).

DTSI files are updated for VT8500, WM8505 and WM8650.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Tony Prisk authored and Greg Kroah-Hartman committed Jan 18, 2013
1 parent 962963e commit 12faa35
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 27 deletions.
40 changes: 36 additions & 4 deletions arch/arm/boot/dts/vt8500.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,38 @@
compatible = "fixed-clock";
clock-frequency = <24000000>;
};

clkuart0: uart0 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <1>;
};

clkuart1: uart1 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <2>;
};

clkuart2: uart2 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <3>;
};

clkuart3: uart3 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <4>;
};
};
};

Expand Down Expand Up @@ -83,28 +115,28 @@
compatible = "via,vt8500-uart";
reg = <0xd8200000 0x1040>;
interrupts = <32>;
clocks = <&ref24>;
clocks = <&clkuart0>;
};

uart@d82b0000 {
compatible = "via,vt8500-uart";
reg = <0xd82b0000 0x1040>;
interrupts = <33>;
clocks = <&ref24>;
clocks = <&clkuart1>;
};

uart@d8210000 {
compatible = "via,vt8500-uart";
reg = <0xd8210000 0x1040>;
interrupts = <47>;
clocks = <&ref24>;
clocks = <&clkuart2>;
};

uart@d82c0000 {
compatible = "via,vt8500-uart";
reg = <0xd82c0000 0x1040>;
interrupts = <50>;
clocks = <&ref24>;
clocks = <&clkuart3>;
};

rtc@d8100000 {
Expand Down
60 changes: 54 additions & 6 deletions arch/arm/boot/dts/wm8505.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,54 @@
compatible = "fixed-clock";
clock-frequency = <24000000>;
};

clkuart0: uart0 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <1>;
};

clkuart1: uart1 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <2>;
};

clkuart2: uart2 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <3>;
};

clkuart3: uart3 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <4>;
};

clkuart4: uart4 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <22>;
};

clkuart5: uart5 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <23>;
};
};
};

Expand Down Expand Up @@ -96,42 +144,42 @@
compatible = "via,vt8500-uart";
reg = <0xd8200000 0x1040>;
interrupts = <32>;
clocks = <&ref24>;
clocks = <&clkuart0>;
};

uart@d82b0000 {
compatible = "via,vt8500-uart";
reg = <0xd82b0000 0x1040>;
interrupts = <33>;
clocks = <&ref24>;
clocks = <&clkuart1>;
};

uart@d8210000 {
compatible = "via,vt8500-uart";
reg = <0xd8210000 0x1040>;
interrupts = <47>;
clocks = <&ref24>;
clocks = <&clkuart2>;
};

uart@d82c0000 {
compatible = "via,vt8500-uart";
reg = <0xd82c0000 0x1040>;
interrupts = <50>;
clocks = <&ref24>;
clocks = <&clkuart3>;
};

uart@d8370000 {
compatible = "via,vt8500-uart";
reg = <0xd8370000 0x1040>;
interrupts = <31>;
clocks = <&ref24>;
clocks = <&clkuart4>;
};

uart@d8380000 {
compatible = "via,vt8500-uart";
reg = <0xd8380000 0x1040>;
interrupts = <30>;
clocks = <&ref24>;
clocks = <&clkuart5>;
};

rtc@d8100000 {
Expand Down
20 changes: 18 additions & 2 deletions arch/arm/boot/dts/wm8650.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@
reg = <0x204>;
};

clkuart0: uart0 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <1>;
};

clkuart1: uart1 {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
clocks = <&ref24>;
enable-reg = <0x250>;
enable-bit = <2>;
};

arm: arm {
#clock-cells = <0>;
compatible = "via,vt8500-device-clock";
Expand Down Expand Up @@ -128,14 +144,14 @@
compatible = "via,vt8500-uart";
reg = <0xd8200000 0x1040>;
interrupts = <32>;
clocks = <&ref24>;
clocks = <&clkuart0>;
};

uart@d82b0000 {
compatible = "via,vt8500-uart";
reg = <0xd82b0000 0x1040>;
interrupts = <33>;
clocks = <&ref24>;
clocks = <&clkuart1>;
};

rtc@d8100000 {
Expand Down
34 changes: 19 additions & 15 deletions drivers/tty/serial/vt8500_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,23 @@ static int vt8500_serial_probe(struct platform_device *pdev)
if (!vt8500_port)
return -ENOMEM;

vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres);
if (!vt8500_port->uart.membase)
return -EADDRNOTAVAIL;

vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
if (IS_ERR(vt8500_port->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
ret = -EINVAL;
goto err;
}

ret = clk_prepare_enable(vt8500_port->clk);
if (ret) {
dev_err(&pdev->dev, "failed to enable clock\n");
goto err;
}

vt8500_port->uart.type = PORT_VT8500;
vt8500_port->uart.iotype = UPIO_MEM;
vt8500_port->uart.mapbase = mmres->start;
Expand All @@ -593,25 +610,11 @@ static int vt8500_serial_probe(struct platform_device *pdev)
vt8500_port->uart.line = port;
vt8500_port->uart.dev = &pdev->dev;
vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;

vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
if (vt8500_port->clk) {
vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
} else {
/* use the default of 24Mhz if not specified and warn */
pr_warn("%s: serial clock source not specified\n", __func__);
vt8500_port->uart.uartclk = 24000000;
}
vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);

snprintf(vt8500_port->name, sizeof(vt8500_port->name),
"VT8500 UART%d", pdev->id);

vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres);
if (!vt8500_port->uart.membase) {
ret = -EADDRNOTAVAIL;
goto err;
}

vt8500_uart_ports[port] = vt8500_port;

uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
Expand All @@ -630,6 +633,7 @@ static int vt8500_serial_remove(struct platform_device *pdev)
struct vt8500_port *vt8500_port = platform_get_drvdata(pdev);

platform_set_drvdata(pdev, NULL);
clk_disable_unprepare(vt8500_port->clk);
uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart);
kfree(vt8500_port);

Expand Down

0 comments on commit 12faa35

Please sign in to comment.