9
9
#include <linux/module.h>
10
10
#include <linux/of.h>
11
11
#include <linux/of_device.h>
12
+ #include <linux/pm_opp.h>
12
13
#include <linux/platform_device.h>
13
14
#include <linux/pm_runtime.h>
14
15
#include <linux/pm_wakeirq.h>
@@ -963,7 +964,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
963
964
goto out_restart_rx ;
964
965
965
966
uport -> uartclk = clk_rate ;
966
- clk_set_rate ( port -> se . clk , clk_rate );
967
+ dev_pm_opp_set_rate ( uport -> dev , clk_rate );
967
968
ser_clk_cfg = SER_CLK_EN ;
968
969
ser_clk_cfg |= clk_div << CLK_DIV_SHFT ;
969
970
@@ -1383,21 +1384,33 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
1383
1384
if (of_property_read_bool (pdev -> dev .of_node , "cts-rts-swap" ))
1384
1385
port -> cts_rts_swap = true;
1385
1386
1387
+ port -> se .opp_table = dev_pm_opp_set_clkname (& pdev -> dev , "se" );
1388
+ if (IS_ERR (port -> se .opp_table ))
1389
+ return PTR_ERR (port -> se .opp_table );
1390
+ /* OPP table is optional */
1391
+ ret = dev_pm_opp_of_add_table (& pdev -> dev );
1392
+ if (!ret ) {
1393
+ port -> se .has_opp_table = true;
1394
+ } else if (ret != - ENODEV ) {
1395
+ dev_err (& pdev -> dev , "invalid OPP table in device tree\n" );
1396
+ return ret ;
1397
+ }
1398
+
1386
1399
uport -> private_data = drv ;
1387
1400
platform_set_drvdata (pdev , port );
1388
1401
port -> handle_rx = console ? handle_rx_console : handle_rx_uart ;
1389
1402
1390
1403
ret = uart_add_one_port (drv , uport );
1391
1404
if (ret )
1392
- return ret ;
1405
+ goto err ;
1393
1406
1394
1407
irq_set_status_flags (uport -> irq , IRQ_NOAUTOEN );
1395
1408
ret = devm_request_irq (uport -> dev , uport -> irq , qcom_geni_serial_isr ,
1396
1409
IRQF_TRIGGER_HIGH , port -> name , uport );
1397
1410
if (ret ) {
1398
1411
dev_err (uport -> dev , "Failed to get IRQ ret %d\n" , ret );
1399
1412
uart_remove_one_port (drv , uport );
1400
- return ret ;
1413
+ goto err ;
1401
1414
}
1402
1415
1403
1416
/*
@@ -1414,18 +1427,26 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
1414
1427
if (ret ) {
1415
1428
device_init_wakeup (& pdev -> dev , false);
1416
1429
uart_remove_one_port (drv , uport );
1417
- return ret ;
1430
+ goto err ;
1418
1431
}
1419
1432
}
1420
1433
1421
1434
return 0 ;
1435
+ err :
1436
+ if (port -> se .has_opp_table )
1437
+ dev_pm_opp_of_remove_table (& pdev -> dev );
1438
+ dev_pm_opp_put_clkname (port -> se .opp_table );
1439
+ return ret ;
1422
1440
}
1423
1441
1424
1442
static int qcom_geni_serial_remove (struct platform_device * pdev )
1425
1443
{
1426
1444
struct qcom_geni_serial_port * port = platform_get_drvdata (pdev );
1427
1445
struct uart_driver * drv = port -> uport .private_data ;
1428
1446
1447
+ if (port -> se .has_opp_table )
1448
+ dev_pm_opp_of_remove_table (& pdev -> dev );
1449
+ dev_pm_opp_put_clkname (port -> se .opp_table );
1429
1450
dev_pm_clear_wake_irq (& pdev -> dev );
1430
1451
device_init_wakeup (& pdev -> dev , false);
1431
1452
uart_remove_one_port (drv , & port -> uport );
0 commit comments