瀏覽代碼

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>
Josh Cartwright 13 年之前
父節點
當前提交
2326669ccb
共有 2 個文件被更改,包括 21 次插入17 次删除
  1. 2 2
      arch/arm/boot/dts/zynq-7000.dtsi
  2. 19 15
      drivers/tty/serial/xilinx_uartps.c

+ 2 - 2
arch/arm/boot/dts/zynq-7000.dtsi

@@ -44,14 +44,14 @@
 			compatible = "xlnx,xuartps";
 			compatible = "xlnx,xuartps";
 			reg = <0xE0000000 0x1000>;
 			reg = <0xE0000000 0x1000>;
 			interrupts = <0 27 4>;
 			interrupts = <0 27 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;
 		};
 		};
 
 
 		uart1: uart@e0001000 {
 		uart1: uart@e0001000 {
 			compatible = "xlnx,xuartps";
 			compatible = "xlnx,xuartps";
 			reg = <0xE0001000 0x1000>;
 			reg = <0xE0001000 0x1000>;
 			interrupts = <0 50 4>;
 			interrupts = <0 50 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 1>;
 		};
 		};
 
 
 		slcr: slcr@f8000000 {
 		slcr: slcr@f8000000 {

+ 19 - 15
drivers/tty/serial/xilinx_uartps.c

@@ -17,6 +17,7 @@
 #include <linux/tty.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/tty_flip.h>
 #include <linux/console.h>
 #include <linux/console.h>
+#include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of.h>
@@ -936,16 +937,18 @@ static int xuartps_probe(struct platform_device *pdev)
 	int rc;
 	int rc;
 	struct uart_port *port;
 	struct uart_port *port;
 	struct resource *res, *res2;
 	struct resource *res, *res2;
-	int clk = 0;
+	struct clk *clk;
 
 
-	const unsigned int *prop;
-
-	prop = of_get_property(pdev->dev.of_node, "clock", NULL);
-	if (prop)
-		clk = be32_to_cpup(prop);
-	if (!clk) {
+	clk = of_clk_get(pdev->dev.of_node, 0);
+	if (IS_ERR(clk)) {
 		dev_err(&pdev->dev, "no clock specified\n");
 		dev_err(&pdev->dev, "no clock specified\n");
-		return -ENODEV;
+		return PTR_ERR(clk);
+	}
+
+	rc = clk_prepare_enable(clk);
+	if (rc) {
+		dev_err(&pdev->dev, "could not enable clock\n");
+		return -EBUSY;
 	}
 	}
 
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -970,7 +973,8 @@ static int xuartps_probe(struct platform_device *pdev)
 		port->mapbase = res->start;
 		port->mapbase = res->start;
 		port->irq = res2->start;
 		port->irq = res2->start;
 		port->dev = &pdev->dev;
 		port->dev = &pdev->dev;
-		port->uartclk = clk;
+		port->uartclk = clk_get_rate(clk);
+		port->private_data = clk;
 		dev_set_drvdata(&pdev->dev, port);
 		dev_set_drvdata(&pdev->dev, port);
 		rc = uart_add_one_port(&xuartps_uart_driver, port);
 		rc = uart_add_one_port(&xuartps_uart_driver, port);
 		if (rc) {
 		if (rc) {
@@ -992,14 +996,14 @@ static int xuartps_probe(struct platform_device *pdev)
 static int xuartps_remove(struct platform_device *pdev)
 static int xuartps_remove(struct platform_device *pdev)
 {
 {
 	struct uart_port *port = dev_get_drvdata(&pdev->dev);
 	struct uart_port *port = dev_get_drvdata(&pdev->dev);
-	int rc = 0;
+	struct clk *clk = port->private_data;
+	int rc;
 
 
 	/* Remove the xuartps port from the serial core */
 	/* Remove the xuartps port from the serial core */
-	if (port) {
-		rc = uart_remove_one_port(&xuartps_uart_driver, port);
-		dev_set_drvdata(&pdev->dev, NULL);
-		port->mapbase = 0;
-	}
+	rc = uart_remove_one_port(&xuartps_uart_driver, port);
+	dev_set_drvdata(&pdev->dev, NULL);
+	port->mapbase = 0;
+	clk_disable_unprepare(clk);
 	return rc;
 	return rc;
 }
 }