Commit a9ec81f4 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Geert Uytterhoeven

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: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: default avatarSimon Horman <horms+renesas@verge.net.au>
[geert: Handle EPROBE_DEFER, reformat description, break long comment line]
Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Acked-by: default avatarRob Herring <robh@kernel.org>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8005c49d
...@@ -42,7 +42,7 @@ Required properties: ...@@ -42,7 +42,7 @@ Required properties:
- clocks: Must contain a phandle and clock-specifier pair for each entry - clocks: Must contain a phandle and clock-specifier pair for each entry
in clock-names. in clock-names.
- clock-names: Must contain "sci_ick" for the SCIx UART interface clock. - clock-names: Must contain "fck" for the SCIx UART functional clock.
Note: Each enabled SCIx UART should have an alias correctly numbered in the Note: Each enabled SCIx UART should have an alias correctly numbered in the
"aliases" node. "aliases" node.
...@@ -63,7 +63,7 @@ Example: ...@@ -63,7 +63,7 @@ Example:
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>;
clock-names = "sci_ick"; clock-names = "fck";
dmas = <&dmac0 0x21>, <&dmac0 0x22>; dmas = <&dmac0 0x21>, <&dmac0 0x22>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
}; };
...@@ -92,8 +92,6 @@ struct sci_port { ...@@ -92,8 +92,6 @@ struct sci_port {
struct timer_list break_timer; struct timer_list break_timer;
int break_flag; int break_flag;
/* Interface clock */
struct clk *iclk;
/* Function clock */ /* Function clock */
struct clk *fclk; struct clk *fclk;
...@@ -457,9 +455,8 @@ static void sci_port_enable(struct sci_port *sci_port) ...@@ -457,9 +455,8 @@ static void sci_port_enable(struct sci_port *sci_port)
pm_runtime_get_sync(sci_port->port.dev); pm_runtime_get_sync(sci_port->port.dev);
clk_prepare_enable(sci_port->iclk);
sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
clk_prepare_enable(sci_port->fclk); clk_prepare_enable(sci_port->fclk);
sci_port->port.uartclk = clk_get_rate(sci_port->fclk);
} }
static void sci_port_disable(struct sci_port *sci_port) 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,7 +473,6 @@ static void sci_port_disable(struct sci_port *sci_port)
sci_port->break_flag = 0; sci_port->break_flag = 0;
clk_disable_unprepare(sci_port->fclk); clk_disable_unprepare(sci_port->fclk);
clk_disable_unprepare(sci_port->iclk);
pm_runtime_put_sync(sci_port->port.dev); pm_runtime_put_sync(sci_port->port.dev);
} }
...@@ -1622,7 +1618,7 @@ static int sci_notifier(struct notifier_block *self, ...@@ -1622,7 +1618,7 @@ static int sci_notifier(struct notifier_block *self,
struct uart_port *port = &sci_port->port; struct uart_port *port = &sci_port->port;
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
port->uartclk = clk_get_rate(sci_port->iclk); port->uartclk = clk_get_rate(sci_port->fclk);
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
} }
...@@ -2241,6 +2237,42 @@ static struct uart_ops sci_uart_ops = { ...@@ -2241,6 +2237,42 @@ static struct uart_ops sci_uart_ops = {
#endif #endif
}; };
static int sci_init_clocks(struct sci_port *sci_port, struct device *dev)
{
/* Get the SCI functional clock. It's called "fck" on ARM. */
sci_port->fclk = clk_get(dev, "fck");
if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!IS_ERR(sci_port->fclk))
return 0;
/*
* But it used to be called "sci_ick", and we need to maintain DT
* backward compatibility.
*/
sci_port->fclk = clk_get(dev, "sci_ick");
if (PTR_ERR(sci_port->fclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!IS_ERR(sci_port->fclk))
return 0;
/* SH has historically named the clock "sci_fck". */
sci_port->fclk = clk_get(dev, "sci_fck");
if (!IS_ERR(sci_port->fclk))
return 0;
/*
* Not all SH platforms declare a clock lookup entry for SCI devices,
* in which case we need to get the global "peripheral_clk" clock.
*/
sci_port->fclk = clk_get(dev, "peripheral_clk");
if (!IS_ERR(sci_port->fclk))
return 0;
dev_err(dev, "failed to get functional clock\n");
return PTR_ERR(sci_port->fclk);
}
static int sci_init_single(struct platform_device *dev, static int sci_init_single(struct platform_device *dev,
struct sci_port *sci_port, unsigned int index, struct sci_port *sci_port, unsigned int index,
struct plat_sci_port *p, bool early) struct plat_sci_port *p, bool early)
...@@ -2333,22 +2365,9 @@ static int sci_init_single(struct platform_device *dev, ...@@ -2333,22 +2365,9 @@ static int sci_init_single(struct platform_device *dev,
sci_port->sampling_rate = p->sampling_rate; sci_port->sampling_rate = p->sampling_rate;
if (!early) { if (!early) {
sci_port->iclk = clk_get(&dev->dev, "sci_ick"); ret = sci_init_clocks(sci_port, &dev->dev);
if (IS_ERR(sci_port->iclk)) { if (ret < 0)
sci_port->iclk = clk_get(&dev->dev, "peripheral_clk"); return ret;
if (IS_ERR(sci_port->iclk)) {
dev_err(&dev->dev, "can't get iclk\n");
return PTR_ERR(sci_port->iclk);
}
}
/*
* The function clock is optional, ignore it if we can't
* find it.
*/
sci_port->fclk = clk_get(&dev->dev, "sci_fck");
if (IS_ERR(sci_port->fclk))
sci_port->fclk = NULL;
port->dev = &dev->dev; port->dev = &dev->dev;
...@@ -2405,7 +2424,6 @@ static int sci_init_single(struct platform_device *dev, ...@@ -2405,7 +2424,6 @@ static int sci_init_single(struct platform_device *dev,
static void sci_cleanup_single(struct sci_port *port) static void sci_cleanup_single(struct sci_port *port)
{ {
clk_put(port->iclk);
clk_put(port->fclk); clk_put(port->fclk);
pm_runtime_disable(port->port.dev); pm_runtime_disable(port->port.dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment