浏览代码

cpm_uart: Add generic clock API support to set baudrates

This patch introduces baudrate setting support via the generic clock API.
When present the optional device tree clock property is used instead of
fsl-cpm-brg. Platforms can then define complex clock schemes, to output
the serial clock on an external pin for instance.

Signed-off-by: Laurent Pinchart <laurentp@cse-semaphore.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Laurent Pinchart 17 年之前
父节点
当前提交
80776554b6
共有 3 个文件被更改,包括 21 次插入7 次删除
  1. 1 0
      arch/powerpc/platforms/Kconfig
  2. 1 0
      drivers/serial/cpm_uart/cpm_uart.h
  3. 19 7
      drivers/serial/cpm_uart/cpm_uart_core.c

+ 1 - 0
arch/powerpc/platforms/Kconfig

@@ -283,6 +283,7 @@ config FSL_ULI1575
 
 config CPM
 	bool
+	select PPC_CLOCK
 
 config OF_RTC
 	bool

+ 1 - 0
drivers/serial/cpm_uart/cpm_uart.h

@@ -77,6 +77,7 @@ struct uart_cpm_port {
 	unsigned char		*rx_buf;
 	u32			flags;
 	void			(*set_lineif)(struct uart_cpm_port *);
+	struct clk		*clk;
 	u8			brg;
 	uint			 dp_addr;
 	void			*mem_addr;

+ 19 - 7
drivers/serial/cpm_uart/cpm_uart_core.c

@@ -45,6 +45,7 @@
 #include <linux/of_platform.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -596,7 +597,10 @@ static void cpm_uart_set_termios(struct uart_port *port,
 		out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
 	}
 
-	cpm_set_brg(pinfo->brg - 1, baud);
+	if (pinfo->clk)
+		clk_set_rate(pinfo->clk, baud);
+	else
+		cpm_set_brg(pinfo->brg - 1, baud);
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
@@ -1023,13 +1027,21 @@ static int cpm_uart_init_port(struct device_node *np,
 	int ret;
 	int i;
 
-	data = of_get_property(np, "fsl,cpm-brg", &len);
-	if (!data || len != 4) {
-		printk(KERN_ERR "CPM UART %s has no/invalid "
-		                "fsl,cpm-brg property.\n", np->name);
-		return -EINVAL;
+	data = of_get_property(np, "clock", NULL);
+	if (data) {
+		struct clk *clk = clk_get(NULL, (const char*)data);
+		if (!IS_ERR(clk))
+			pinfo->clk = clk;
+	}
+	if (!pinfo->clk) {
+		data = of_get_property(np, "fsl,cpm-brg", &len);
+		if (!data || len != 4) {
+			printk(KERN_ERR "CPM UART %s has no/invalid "
+			                "fsl,cpm-brg property.\n", np->name);
+			return -EINVAL;
+		}
+		pinfo->brg = *data;
 	}
-	pinfo->brg = *data;
 
 	data = of_get_property(np, "fsl,cpm-command", &len);
 	if (!data || len != 4) {