Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: xilinx_uartps: Get clock rate info from dts

Add support for specifying clock information for the uart clk via the
device tree. This eliminates the need to hardcode rates in the device
tree.

Signed-off-by: Josh Cartwright <josh.cartwright@ni.com>
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Acked-by: Michal Simek <michal.simek@xilinx.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Josh Cartwright and committed by
Greg Kroah-Hartman
2326669c 1f9db092

+21 -17
+2 -2
arch/arm/boot/dts/zynq-7000.dtsi
··· 44 44 compatible = "xlnx,xuartps"; 45 45 reg = <0xE0000000 0x1000>; 46 46 interrupts = <0 27 4>; 47 - clock = <50000000>; 47 + clocks = <&uart_clk 0>; 48 48 }; 49 49 50 50 uart1: uart@e0001000 { 51 51 compatible = "xlnx,xuartps"; 52 52 reg = <0xE0001000 0x1000>; 53 53 interrupts = <0 50 4>; 54 - clock = <50000000>; 54 + clocks = <&uart_clk 1>; 55 55 }; 56 56 57 57 slcr: slcr@f8000000 {
+19 -15
drivers/tty/serial/xilinx_uartps.c
··· 17 17 #include <linux/tty.h> 18 18 #include <linux/tty_flip.h> 19 19 #include <linux/console.h> 20 + #include <linux/clk.h> 20 21 #include <linux/irq.h> 21 22 #include <linux/io.h> 22 23 #include <linux/of.h> ··· 937 936 int rc; 938 937 struct uart_port *port; 939 938 struct resource *res, *res2; 940 - int clk = 0; 939 + struct clk *clk; 941 940 942 - const unsigned int *prop; 943 - 944 - prop = of_get_property(pdev->dev.of_node, "clock", NULL); 945 - if (prop) 946 - clk = be32_to_cpup(prop); 947 - if (!clk) { 941 + clk = of_clk_get(pdev->dev.of_node, 0); 942 + if (IS_ERR(clk)) { 948 943 dev_err(&pdev->dev, "no clock specified\n"); 949 - return -ENODEV; 944 + return PTR_ERR(clk); 945 + } 946 + 947 + rc = clk_prepare_enable(clk); 948 + if (rc) { 949 + dev_err(&pdev->dev, "could not enable clock\n"); 950 + return -EBUSY; 950 951 } 951 952 952 953 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ··· 973 970 port->mapbase = res->start; 974 971 port->irq = res2->start; 975 972 port->dev = &pdev->dev; 976 - port->uartclk = clk; 973 + port->uartclk = clk_get_rate(clk); 974 + port->private_data = clk; 977 975 dev_set_drvdata(&pdev->dev, port); 978 976 rc = uart_add_one_port(&xuartps_uart_driver, port); 979 977 if (rc) { ··· 996 992 static int xuartps_remove(struct platform_device *pdev) 997 993 { 998 994 struct uart_port *port = dev_get_drvdata(&pdev->dev); 999 - int rc = 0; 995 + struct clk *clk = port->private_data; 996 + int rc; 1000 997 1001 998 /* Remove the xuartps port from the serial core */ 1002 - if (port) { 1003 - rc = uart_remove_one_port(&xuartps_uart_driver, port); 1004 - dev_set_drvdata(&pdev->dev, NULL); 1005 - port->mapbase = 0; 1006 - } 999 + rc = uart_remove_one_port(&xuartps_uart_driver, port); 1000 + dev_set_drvdata(&pdev->dev, NULL); 1001 + port->mapbase = 0; 1002 + clk_disable_unprepare(clk); 1007 1003 return rc; 1008 1004 } 1009 1005