serial: vt8500: UART uses gated clock rather than 24Mhz reference
authorTony Prisk <linux@prisktech.co.nz>
Fri, 18 Jan 2013 02:05:31 +0000 (15:05 +1300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 18 Jan 2013 02:54:32 +0000 (18:54 -0800)
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>
arch/arm/boot/dts/vt8500.dtsi
arch/arm/boot/dts/wm8505.dtsi
arch/arm/boot/dts/wm8650.dtsi
drivers/tty/serial/vt8500_serial.c

index d8645e990b21a023c1535c43c656f5b1250d6dec..cf31ced46602e1ef8c24bf8a1fed2634488e8845 100644 (file)
                                        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>;
+                               };
                        };
                };
 
                        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 {
index 330f833ac3b03e97b376bbcdcf418770b3431a23..e74a1c0fb9a2998ef91dbf58019850644711465f 100644 (file)
                                        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>;
+                               };
                        };
                };
 
                        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 {
index 83b9467559bba0552fc6ec0ddb7c63a1a4f7cc6e..db3c0a12e052782641bd23731bf58aa4f4d4cc62 100644 (file)
                                        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";
                        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 {
index ff391db0a22041c543e7dd261a066f16cf008fff..798bf944a2e56134ec6ac626b1fa9910838b8fad 100644 (file)
@@ -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;
@@ -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);
@@ -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);