Skip to content

Commit

Permalink
serial: msm: Use OPP table for DVFS support
Browse files Browse the repository at this point in the history
Parse the OPP table from the device tree and use dev_pm_opp_set_rate()
instead of clk_set_rate() to allow making performance state votes
specified in the OPP table (e.g. for power domains and interconnects).

Without an OPP table in the device tree this will behave just as before
this patch.

Signed-off-by: Stephan Gerhold <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
stephan-gh authored and gregkh committed Dec 8, 2023
1 parent 692079b commit 173ebde
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions drivers/tty/serial/msm_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_device.h>
Expand Down Expand Up @@ -1131,7 +1132,7 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud,
uart_port_unlock_irqrestore(port, flags);

entry = msm_find_best_baud(port, baud, &rate);
clk_set_rate(msm_port->clk, rate);
dev_pm_opp_set_rate(port->dev, rate);
baud = rate / 16 / entry->divisor;

uart_port_lock_irqsave(port, &flags);
Expand Down Expand Up @@ -1186,6 +1187,7 @@ static void msm_init_clock(struct uart_port *port)
{
struct msm_port *msm_port = to_msm_port(port);

dev_pm_opp_set_rate(port->dev, port->uartclk);
clk_prepare_enable(msm_port->clk);
clk_prepare_enable(msm_port->pclk);
msm_serial_set_mnd_regs(port);
Expand Down Expand Up @@ -1239,6 +1241,7 @@ static int msm_startup(struct uart_port *port)

clk_disable_unprepare(msm_port->pclk);
clk_disable_unprepare(msm_port->clk);
dev_pm_opp_set_rate(port->dev, 0);

return ret;
}
Expand All @@ -1254,6 +1257,7 @@ static void msm_shutdown(struct uart_port *port)
msm_release_dma(msm_port);

clk_disable_unprepare(msm_port->clk);
dev_pm_opp_set_rate(port->dev, 0);

free_irq(port->irq, port);
}
Expand Down Expand Up @@ -1419,11 +1423,13 @@ static void msm_power(struct uart_port *port, unsigned int state,

switch (state) {
case 0:
dev_pm_opp_set_rate(port->dev, port->uartclk);
clk_prepare_enable(msm_port->clk);
clk_prepare_enable(msm_port->pclk);
break;
case 3:
clk_disable_unprepare(msm_port->clk);
dev_pm_opp_set_rate(port->dev, 0);
clk_disable_unprepare(msm_port->pclk);
break;
default:
Expand Down Expand Up @@ -1789,7 +1795,7 @@ static int msm_serial_probe(struct platform_device *pdev)
struct resource *resource;
struct uart_port *port;
const struct of_device_id *id;
int irq, line;
int irq, line, ret;

if (pdev->dev.of_node)
line = of_alias_get_id(pdev->dev.of_node, "serial");
Expand Down Expand Up @@ -1824,6 +1830,15 @@ static int msm_serial_probe(struct platform_device *pdev)
return PTR_ERR(msm_port->pclk);
}

ret = devm_pm_opp_set_clkname(&pdev->dev, "core");
if (ret)
return ret;

/* OPP table is optional */
ret = devm_pm_opp_of_add_table(&pdev->dev);
if (ret && ret != -ENODEV)
return dev_err_probe(&pdev->dev, ret, "invalid OPP table\n");

port->uartclk = clk_get_rate(msm_port->clk);
dev_info(&pdev->dev, "uartclk = %d\n", port->uartclk);

Expand Down

0 comments on commit 173ebde

Please sign in to comment.