diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2015-09-14 08:14:23 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert+renesas@glider.be> | 2015-12-17 05:17:51 -0500 |
commit | a9ec81f4ed5c05dbbc671e5fa39de0540eb0495f (patch) | |
tree | 11e942cb0d395d7dacaefecfe23725404a5a9c85 /drivers/tty | |
parent | 8005c49d9aea74d382f474ce11afbbc7d7130bec (diff) |
serial: sh-sci: Drop the interface clock
As no platform defines an interface clock the SCI driver always falls
back to a clock named "peripheral_clk".
- On SH platforms that clock is the base clock for the SCI functional
clock and has the same frequency,
- On ARM platforms that clock doesn't exist, and clk_get() will return
the default clock for the device.
We can thus make the functional clock mandatory and drop the interface
clock.
EPROBE_DEFER is handled for clocks that may be referenced from DT (i.e.
"fck", and the deprecated "sci_ick").
Cc: devicetree@vger.kernel.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
[geert: Handle EPROBE_DEFER, reformat description, break long comment line]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 960e50a97558..cc6fa55231ba 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -92,8 +92,6 @@ struct sci_port { | |||
92 | struct timer_list break_timer; | 92 | struct timer_list break_timer; |
93 | int break_flag; | 93 | int break_flag; |
94 | 94 | ||
95 | /* Interface clock */ | ||
96 | struct clk *iclk; | ||
97 | /* Function clock */ | 95 | /* Function clock */ |
98 | struct clk *fclk; | 96 | struct clk *fclk; |
99 | 97 | ||
@@ -457,9 +455,8 @@ static void sci_port_enable(struct sci_port *sci_port) | |||
457 | 455 | ||
458 | pm_runtime_get_sync(sci_port->port.dev); | 456 | pm_runtime_get_sync(sci_port->port.dev); |
459 | 457 | ||
460 | clk_prepare_enable(sci_port->iclk); | ||
461 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | ||
462 | clk_prepare_enable(sci_port->fclk); | 458 | clk_prepare_enable(sci_port->fclk); |
459 | sci_port->port.uartclk = clk_get_rate(sci_port->fclk); | ||
463 | } | 460 | } |
464 | 461 | ||
465 | static void sci_port_disable(struct sci_port *sci_port) | 462 | static void sci_port_disable(struct sci_port *sci_port) |
@@ -476,7 +473,6 @@ static void sci_port_disable(struct sci_port *sci_port) | |||
476 | sci_port->break_flag = 0; | 473 | sci_port->break_flag = 0; |
477 | 474 | ||
478 | clk_disable_unprepare(sci_port->fclk); | 475 | clk_disable_unprepare(sci_port->fclk); |
479 | clk_disable_unprepare(sci_port->iclk); | ||
480 | 476 | ||
481 | pm_runtime_put_sync(sci_port->port.dev); | 477 | pm_runtime_put_sync(sci_port->port.dev); |
482 | } | 478 | } |
@@ -1622,7 +1618,7 @@ static int sci_notifier(struct notifier_block *self, | |||
1622 | struct uart_port *port = &sci_port->port; | 1618 | struct uart_port *port = &sci_port->port; |
1623 | 1619 | ||
1624 | spin_lock_irqsave(&port->lock, flags); | 1620 | spin_lock_irqsave(&port->lock, flags); |
1625 | port->uartclk = clk_get_rate(sci_port->iclk); | 1621 | port->uartclk = clk_get_rate(sci_port->fclk); |
1626 | spin_unlock_irqrestore(&port->lock, flags); | 1622 | spin_unlock_irqrestore(&port->lock, flags); |
1627 | } | 1623 | } |
1628 | 1624 | ||
@@ -2241,6 +2237,42 @@ static struct uart_ops sci_uart_ops = { | |||
2241 | #endif | 2237 | #endif |
2242 | }; | 2238 | }; |
2243 | 2239 | ||
2240 | static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) | ||
2241 | { | ||
2242 | /* Get the SCI functional clock. It's called "fck" on ARM. */ | ||
2243 | sci_port->fclk = clk_get(dev, "fck"); | ||
2244 | if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) | ||
2245 | return -EPROBE_DEFER; | ||
2246 | if (!IS_ERR(sci_port->fclk)) | ||
2247 | return 0; | ||
2248 | |||
2249 | /* | ||
2250 | * But it used to be called "sci_ick", and we need to maintain DT | ||
2251 | * backward compatibility. | ||
2252 | */ | ||
2253 | sci_port->fclk = clk_get(dev, "sci_ick"); | ||
2254 | if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER) | ||
2255 | return -EPROBE_DEFER; | ||
2256 | if (!IS_ERR(sci_port->fclk)) | ||
2257 | return 0; | ||
2258 | |||
2259 | /* SH has historically named the clock "sci_fck". */ | ||
2260 | sci_port->fclk = clk_get(dev, "sci_fck"); | ||
2261 | if (!IS_ERR(sci_port->fclk)) | ||
2262 | return 0; | ||
2263 | |||
2264 | /* | ||
2265 | * Not all SH platforms declare a clock lookup entry for SCI devices, | ||
2266 | * in which case we need to get the global "peripheral_clk" clock. | ||
2267 | */ | ||
2268 | sci_port->fclk = clk_get(dev, "peripheral_clk"); | ||
2269 | if (!IS_ERR(sci_port->fclk)) | ||
2270 | return 0; | ||
2271 | |||
2272 | dev_err(dev, "failed to get functional clock\n"); | ||
2273 | return PTR_ERR(sci_port->fclk); | ||
2274 | } | ||
2275 | |||
2244 | static int sci_init_single(struct platform_device *dev, | 2276 | static int sci_init_single(struct platform_device *dev, |
2245 | struct sci_port *sci_port, unsigned int index, | 2277 | struct sci_port *sci_port, unsigned int index, |
2246 | struct plat_sci_port *p, bool early) | 2278 | struct plat_sci_port *p, bool early) |
@@ -2333,22 +2365,9 @@ static int sci_init_single(struct platform_device *dev, | |||
2333 | sci_port->sampling_rate = p->sampling_rate; | 2365 | sci_port->sampling_rate = p->sampling_rate; |
2334 | 2366 | ||
2335 | if (!early) { | 2367 | if (!early) { |
2336 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | 2368 | ret = sci_init_clocks(sci_port, &dev->dev); |
2337 | if (IS_ERR(sci_port->iclk)) { | 2369 | if (ret < 0) |
2338 | sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); | 2370 | return ret; |
2339 | if (IS_ERR(sci_port->iclk)) { | ||
2340 | dev_err(&dev->dev, "can't get iclk\n"); | ||
2341 | return PTR_ERR(sci_port->iclk); | ||
2342 | } | ||
2343 | } | ||
2344 | |||
2345 | /* | ||
2346 | * The function clock is optional, ignore it if we can't | ||
2347 | * find it. | ||
2348 | */ | ||
2349 | sci_port->fclk = clk_get(&dev->dev, "sci_fck"); | ||
2350 | if (IS_ERR(sci_port->fclk)) | ||
2351 | sci_port->fclk = NULL; | ||
2352 | 2371 | ||
2353 | port->dev = &dev->dev; | 2372 | port->dev = &dev->dev; |
2354 | 2373 | ||
@@ -2405,7 +2424,6 @@ static int sci_init_single(struct platform_device *dev, | |||
2405 | 2424 | ||
2406 | static void sci_cleanup_single(struct sci_port *port) | 2425 | static void sci_cleanup_single(struct sci_port *port) |
2407 | { | 2426 | { |
2408 | clk_put(port->iclk); | ||
2409 | clk_put(port->fclk); | 2427 | clk_put(port->fclk); |
2410 | 2428 | ||
2411 | pm_runtime_disable(port->port.dev); | 2429 | pm_runtime_disable(port->port.dev); |