From 2b7d3e2cd1a9414e85851879506b5bdf69b0a42c Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Mon, 22 Oct 2012 11:58:01 -0400 Subject: [PATCH] --- yaml --- r: 338389 b: refs/heads/master c: 0bbeb3c3e84bc963d1c66661e082d207023b0e5c h: refs/heads/master i: 338387: 0f8b7a3812d75998b264f42161a51b6237ce9100 v: v3 --- [refs] | 2 +- trunk/drivers/tty/serial/of_serial.c | 32 ++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 40c64fa25426..cb494c26ae31 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cadf74869013dc309bde50ed446f56d33a6a9806 +refs/heads/master: 0bbeb3c3e84bc963d1c66661e082d207023b0e5c diff --git a/trunk/drivers/tty/serial/of_serial.c b/trunk/drivers/tty/serial/of_serial.c index df443b908ca3..533ccfe77094 100644 --- a/trunk/drivers/tty/serial/of_serial.c +++ b/trunk/drivers/tty/serial/of_serial.c @@ -21,8 +21,10 @@ #include #include #include +#include struct of_serial_info { + struct clk *clk; int type; int line; }; @@ -51,7 +53,8 @@ EXPORT_SYMBOL_GPL(tegra_serial_handle_break); * Fill a struct uart_port for a given device node */ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, - int type, struct uart_port *port) + int type, struct uart_port *port, + struct of_serial_info *info) { struct resource resource; struct device_node *np = ofdev->dev.of_node; @@ -60,8 +63,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, memset(port, 0, sizeof *port); if (of_property_read_u32(np, "clock-frequency", &clk)) { - dev_warn(&ofdev->dev, "no clock-frequency property set\n"); - return -ENODEV; + + /* Get clk rate through clk driver if present */ + info->clk = clk_get(&ofdev->dev, NULL); + if (info->clk == NULL) { + dev_warn(&ofdev->dev, + "clk or clock-frequency not defined\n"); + return -ENODEV; + } + + clk_prepare_enable(info->clk); + clk = clk_get_rate(info->clk); } /* If current-speed was set, then try not to change it. */ if (of_property_read_u32(np, "current-speed", &spd) == 0) @@ -70,7 +82,7 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, ret = of_address_to_resource(np, 0, &resource); if (ret) { dev_warn(&ofdev->dev, "invalid address\n"); - return ret; + goto out; } spin_lock_init(&port->lock); @@ -97,7 +109,8 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, default: dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", prop); - return -EINVAL; + ret = -EINVAL; + goto out; } } @@ -115,6 +128,10 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, port->handle_break = tegra_serial_handle_break; return 0; +out: + if (info->clk) + clk_disable_unprepare(info->clk); + return ret; } /* @@ -141,7 +158,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) return -ENOMEM; port_type = (unsigned long)match->data; - ret = of_platform_serial_setup(ofdev, port_type, &port); + ret = of_platform_serial_setup(ofdev, port_type, &port, info); if (ret) goto out; @@ -204,6 +221,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev) /* need to add code for these */ break; } + + if (info->clk) + clk_disable_unprepare(info->clk); kfree(info); return 0; }