17
17
#include <linux/list.h>
18
18
#include <linux/module.h>
19
19
#include <linux/of.h>
20
+ #include <linux/pinctrl/consumer.h>
20
21
#include <linux/platform_device.h>
22
+ #include <linux/pm_runtime.h>
21
23
22
24
/* Master Mode Registers */
23
25
#define SVC_I3C_MCONFIG 0x000
119
121
#define SVC_MDYNADDR_ADDR (x ) FIELD_PREP(GENMASK(7, 1), (x))
120
122
121
123
#define SVC_I3C_MAX_DEVS 32
124
+ #define SVC_I3C_PM_TIMEOUT_MS 1000
122
125
123
126
/* This parameter depends on the implementation and may be tuned */
124
127
#define SVC_I3C_FIFO_SIZE 16
@@ -480,10 +483,20 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
480
483
u32 ppbaud , pplow , odhpp , odbaud , odstop , i2cbaud , reg ;
481
484
int ret ;
482
485
486
+ ret = pm_runtime_resume_and_get (master -> dev );
487
+ if (ret < 0 ) {
488
+ dev_err (master -> dev ,
489
+ "<%s> cannot resume i3c bus master, err: %d\n" ,
490
+ __func__ , ret );
491
+ return ret ;
492
+ }
493
+
483
494
/* Timings derivation */
484
495
fclk_rate = clk_get_rate (master -> fclk );
485
- if (!fclk_rate )
486
- return - EINVAL ;
496
+ if (!fclk_rate ) {
497
+ ret = - EINVAL ;
498
+ goto rpm_out ;
499
+ }
487
500
488
501
fclk_period_ns = DIV_ROUND_UP (1000000000 , fclk_rate );
489
502
@@ -527,7 +540,7 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
527
540
odstop = 1 ;
528
541
break ;
529
542
default :
530
- return - EINVAL ;
543
+ goto rpm_out ;
531
544
}
532
545
533
546
reg = SVC_I3C_MCONFIG_MASTER_EN |
@@ -545,7 +558,7 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
545
558
/* Master core's registration */
546
559
ret = i3c_master_get_free_addr (m , 0 );
547
560
if (ret < 0 )
548
- return ret ;
561
+ goto rpm_out ;
549
562
550
563
info .dyn_addr = ret ;
551
564
@@ -554,21 +567,35 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
554
567
555
568
ret = i3c_master_set_info (& master -> base , & info );
556
569
if (ret )
557
- return ret ;
570
+ goto rpm_out ;
558
571
559
572
svc_i3c_master_enable_interrupts (master , SVC_I3C_MINT_SLVSTART );
560
573
561
- return 0 ;
574
+ rpm_out :
575
+ pm_runtime_mark_last_busy (master -> dev );
576
+ pm_runtime_put_autosuspend (master -> dev );
577
+
578
+ return ret ;
562
579
}
563
580
564
581
static void svc_i3c_master_bus_cleanup (struct i3c_master_controller * m )
565
582
{
566
583
struct svc_i3c_master * master = to_svc_i3c_master (m );
584
+ int ret ;
585
+
586
+ ret = pm_runtime_resume_and_get (master -> dev );
587
+ if (ret < 0 ) {
588
+ dev_err (master -> dev , "<%s> Cannot get runtime PM.\n" , __func__ );
589
+ return ;
590
+ }
567
591
568
592
svc_i3c_master_disable_interrupts (master );
569
593
570
594
/* Disable master */
571
595
writel (0 , master -> regs + SVC_I3C_MCONFIG );
596
+
597
+ pm_runtime_mark_last_busy (master -> dev );
598
+ pm_runtime_put_autosuspend (master -> dev );
572
599
}
573
600
574
601
static int svc_i3c_master_reserve_slot (struct svc_i3c_master * master )
@@ -867,31 +894,36 @@ static int svc_i3c_master_do_daa(struct i3c_master_controller *m)
867
894
unsigned int dev_nb ;
868
895
int ret , i ;
869
896
897
+ ret = pm_runtime_resume_and_get (master -> dev );
898
+ if (ret < 0 ) {
899
+ dev_err (master -> dev , "<%s> Cannot get runtime PM.\n" , __func__ );
900
+ return ret ;
901
+ }
902
+
870
903
spin_lock_irqsave (& master -> xferqueue .lock , flags );
871
904
ret = svc_i3c_master_do_daa_locked (master , addrs , & dev_nb );
872
905
spin_unlock_irqrestore (& master -> xferqueue .lock , flags );
873
- if (ret )
874
- goto emit_stop ;
906
+ if (ret ) {
907
+ svc_i3c_master_emit_stop (master );
908
+ svc_i3c_master_clear_merrwarn (master );
909
+ goto rpm_out ;
910
+ }
875
911
876
912
/* Register all devices who participated to the core */
877
913
for (i = 0 ; i < dev_nb ; i ++ ) {
878
914
ret = i3c_master_add_i3c_dev_locked (m , addrs [i ]);
879
915
if (ret )
880
- return ret ;
916
+ goto rpm_out ;
881
917
}
882
918
883
919
/* Configure IBI auto-rules */
884
920
ret = svc_i3c_update_ibirules (master );
885
- if (ret ) {
921
+ if (ret )
886
922
dev_err (master -> dev , "Cannot handle such a list of devices" );
887
- return ret ;
888
- }
889
-
890
- return 0 ;
891
923
892
- emit_stop :
893
- svc_i3c_master_emit_stop (master );
894
- svc_i3c_master_clear_merrwarn (master );
924
+ rpm_out :
925
+ pm_runtime_mark_last_busy (master -> dev );
926
+ pm_runtime_put_autosuspend (master -> dev );
895
927
896
928
return ret ;
897
929
}
@@ -1060,6 +1092,12 @@ static void svc_i3c_master_start_xfer_locked(struct svc_i3c_master *master)
1060
1092
if (!xfer )
1061
1093
return ;
1062
1094
1095
+ ret = pm_runtime_resume_and_get (master -> dev );
1096
+ if (ret < 0 ) {
1097
+ dev_err (master -> dev , "<%s> Cannot get runtime PM.\n" , __func__ );
1098
+ return ;
1099
+ }
1100
+
1063
1101
svc_i3c_master_clear_merrwarn (master );
1064
1102
svc_i3c_master_flush_fifo (master );
1065
1103
@@ -1074,6 +1112,9 @@ static void svc_i3c_master_start_xfer_locked(struct svc_i3c_master *master)
1074
1112
break ;
1075
1113
}
1076
1114
1115
+ pm_runtime_mark_last_busy (master -> dev );
1116
+ pm_runtime_put_autosuspend (master -> dev );
1117
+
1077
1118
xfer -> ret = ret ;
1078
1119
complete (& xfer -> comp );
1079
1120
@@ -1350,15 +1391,30 @@ static void svc_i3c_master_free_ibi(struct i3c_dev_desc *dev)
1350
1391
static int svc_i3c_master_enable_ibi (struct i3c_dev_desc * dev )
1351
1392
{
1352
1393
struct i3c_master_controller * m = i3c_dev_get_master (dev );
1394
+ struct svc_i3c_master * master = to_svc_i3c_master (m );
1395
+ int ret ;
1396
+
1397
+ ret = pm_runtime_resume_and_get (master -> dev );
1398
+ if (ret < 0 ) {
1399
+ dev_err (master -> dev , "<%s> Cannot get runtime PM.\n" , __func__ );
1400
+ return ret ;
1401
+ }
1353
1402
1354
1403
return i3c_master_enec_locked (m , dev -> info .dyn_addr , I3C_CCC_EVENT_SIR );
1355
1404
}
1356
1405
1357
1406
static int svc_i3c_master_disable_ibi (struct i3c_dev_desc * dev )
1358
1407
{
1359
1408
struct i3c_master_controller * m = i3c_dev_get_master (dev );
1409
+ struct svc_i3c_master * master = to_svc_i3c_master (m );
1410
+ int ret ;
1411
+
1412
+ ret = i3c_master_disec_locked (m , dev -> info .dyn_addr , I3C_CCC_EVENT_SIR );
1360
1413
1361
- return i3c_master_disec_locked (m , dev -> info .dyn_addr , I3C_CCC_EVENT_SIR );
1414
+ pm_runtime_mark_last_busy (master -> dev );
1415
+ pm_runtime_put_autosuspend (master -> dev );
1416
+
1417
+ return ret ;
1362
1418
}
1363
1419
1364
1420
static void svc_i3c_master_recycle_ibi_slot (struct i3c_dev_desc * dev ,
@@ -1389,6 +1445,37 @@ static const struct i3c_master_controller_ops svc_i3c_master_ops = {
1389
1445
.disable_ibi = svc_i3c_master_disable_ibi ,
1390
1446
};
1391
1447
1448
+ static int svc_i3c_master_prepare_clks (struct svc_i3c_master * master )
1449
+ {
1450
+ int ret = 0 ;
1451
+
1452
+ ret = clk_prepare_enable (master -> pclk );
1453
+ if (ret )
1454
+ return ret ;
1455
+
1456
+ ret = clk_prepare_enable (master -> fclk );
1457
+ if (ret ) {
1458
+ clk_disable_unprepare (master -> pclk );
1459
+ return ret ;
1460
+ }
1461
+
1462
+ ret = clk_prepare_enable (master -> sclk );
1463
+ if (ret ) {
1464
+ clk_disable_unprepare (master -> pclk );
1465
+ clk_disable_unprepare (master -> fclk );
1466
+ return ret ;
1467
+ }
1468
+
1469
+ return 0 ;
1470
+ }
1471
+
1472
+ static void svc_i3c_master_unprepare_clks (struct svc_i3c_master * master )
1473
+ {
1474
+ clk_disable_unprepare (master -> pclk );
1475
+ clk_disable_unprepare (master -> fclk );
1476
+ clk_disable_unprepare (master -> sclk );
1477
+ }
1478
+
1392
1479
static int svc_i3c_master_probe (struct platform_device * pdev )
1393
1480
{
1394
1481
struct device * dev = & pdev -> dev ;
@@ -1421,24 +1508,16 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
1421
1508
1422
1509
master -> dev = dev ;
1423
1510
1424
- ret = clk_prepare_enable (master -> pclk );
1511
+ ret = svc_i3c_master_prepare_clks (master );
1425
1512
if (ret )
1426
1513
return ret ;
1427
1514
1428
- ret = clk_prepare_enable (master -> fclk );
1429
- if (ret )
1430
- goto err_disable_pclk ;
1431
-
1432
- ret = clk_prepare_enable (master -> sclk );
1433
- if (ret )
1434
- goto err_disable_fclk ;
1435
-
1436
1515
INIT_WORK (& master -> hj_work , svc_i3c_master_hj_work );
1437
1516
INIT_WORK (& master -> ibi_work , svc_i3c_master_ibi_work );
1438
1517
ret = devm_request_irq (dev , master -> irq , svc_i3c_master_irq_handler ,
1439
1518
IRQF_NO_SUSPEND , "svc-i3c-irq" , master );
1440
1519
if (ret )
1441
- goto err_disable_sclk ;
1520
+ goto err_disable_clks ;
1442
1521
1443
1522
master -> free_slots = GENMASK (SVC_I3C_MAX_DEVS - 1 , 0 );
1444
1523
@@ -1452,29 +1531,38 @@ static int svc_i3c_master_probe(struct platform_device *pdev)
1452
1531
GFP_KERNEL );
1453
1532
if (!master -> ibi .slots ) {
1454
1533
ret = - ENOMEM ;
1455
- goto err_disable_sclk ;
1534
+ goto err_disable_clks ;
1456
1535
}
1457
1536
1458
1537
platform_set_drvdata (pdev , master );
1459
1538
1539
+ pm_runtime_set_autosuspend_delay (& pdev -> dev , SVC_I3C_PM_TIMEOUT_MS );
1540
+ pm_runtime_use_autosuspend (& pdev -> dev );
1541
+ pm_runtime_get_noresume (& pdev -> dev );
1542
+ pm_runtime_set_active (& pdev -> dev );
1543
+ pm_runtime_enable (& pdev -> dev );
1544
+
1460
1545
svc_i3c_master_reset (master );
1461
1546
1462
1547
/* Register the master */
1463
1548
ret = i3c_master_register (& master -> base , & pdev -> dev ,
1464
1549
& svc_i3c_master_ops , false);
1465
1550
if (ret )
1466
- goto err_disable_sclk ;
1551
+ goto rpm_disable ;
1552
+
1553
+ pm_runtime_mark_last_busy (& pdev -> dev );
1554
+ pm_runtime_put_autosuspend (& pdev -> dev );
1467
1555
1468
1556
return 0 ;
1469
1557
1470
- err_disable_sclk :
1471
- clk_disable_unprepare (master -> sclk );
1558
+ rpm_disable :
1559
+ pm_runtime_dont_use_autosuspend (& pdev -> dev );
1560
+ pm_runtime_put_noidle (& pdev -> dev );
1561
+ pm_runtime_set_suspended (& pdev -> dev );
1562
+ pm_runtime_disable (& pdev -> dev );
1472
1563
1473
- err_disable_fclk :
1474
- clk_disable_unprepare (master -> fclk );
1475
-
1476
- err_disable_pclk :
1477
- clk_disable_unprepare (master -> pclk );
1564
+ err_disable_clks :
1565
+ svc_i3c_master_unprepare_clks (master );
1478
1566
1479
1567
return ret ;
1480
1568
}
@@ -1488,13 +1576,40 @@ static int svc_i3c_master_remove(struct platform_device *pdev)
1488
1576
if (ret )
1489
1577
return ret ;
1490
1578
1491
- clk_disable_unprepare (master -> pclk );
1492
- clk_disable_unprepare (master -> fclk );
1493
- clk_disable_unprepare (master -> sclk );
1579
+ pm_runtime_dont_use_autosuspend (& pdev -> dev );
1580
+ pm_runtime_disable (& pdev -> dev );
1494
1581
1495
1582
return 0 ;
1496
1583
}
1497
1584
1585
+ static int __maybe_unused svc_i3c_runtime_suspend (struct device * dev )
1586
+ {
1587
+ struct svc_i3c_master * master = dev_get_drvdata (dev );
1588
+
1589
+ svc_i3c_master_unprepare_clks (master );
1590
+ pinctrl_pm_select_sleep_state (dev );
1591
+
1592
+ return 0 ;
1593
+ }
1594
+
1595
+ static int __maybe_unused svc_i3c_runtime_resume (struct device * dev )
1596
+ {
1597
+ struct svc_i3c_master * master = dev_get_drvdata (dev );
1598
+ int ret = 0 ;
1599
+
1600
+ pinctrl_pm_select_default_state (dev );
1601
+ svc_i3c_master_prepare_clks (master );
1602
+
1603
+ return ret ;
1604
+ }
1605
+
1606
+ static const struct dev_pm_ops svc_i3c_pm_ops = {
1607
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS (pm_runtime_force_suspend ,
1608
+ pm_runtime_force_resume )
1609
+ SET_RUNTIME_PM_OPS (svc_i3c_runtime_suspend ,
1610
+ svc_i3c_runtime_resume , NULL )
1611
+ };
1612
+
1498
1613
static const struct of_device_id svc_i3c_master_of_match_tbl [] = {
1499
1614
{ .compatible = "silvaco,i3c-master" },
1500
1615
{ /* sentinel */ },
@@ -1506,6 +1621,7 @@ static struct platform_driver svc_i3c_master = {
1506
1621
.driver = {
1507
1622
.name = "silvaco-i3c-master" ,
1508
1623
.of_match_table = svc_i3c_master_of_match_tbl ,
1624
+ .pm = & svc_i3c_pm_ops ,
1509
1625
},
1510
1626
};
1511
1627
module_platform_driver (svc_i3c_master );
0 commit comments