@@ -186,6 +186,7 @@ struct spmi_pmic_arb {
186
186
* struct pmic_arb_ver_ops - version dependent functionality.
187
187
*
188
188
* @ver_str: version string.
189
+ * @init_apid: finds the apid base and count
189
190
* @ppid_to_apid: finds the apid for a given ppid.
190
191
* @non_data_cmd: on v1 issues an spmi non-data command.
191
192
* on v2 no HW support, returns -EOPNOTSUPP.
@@ -205,6 +206,7 @@ struct spmi_pmic_arb {
205
206
*/
206
207
struct pmic_arb_ver_ops {
207
208
const char * ver_str ;
209
+ int (* init_apid )(struct spmi_pmic_arb * pmic_arb );
208
210
int (* ppid_to_apid )(struct spmi_pmic_arb * pmic_arb , u16 ppid );
209
211
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
210
212
int (* offset )(struct spmi_pmic_arb * pmic_arb , u8 sid , u16 addr ,
@@ -947,6 +949,32 @@ static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
947
949
return 0 ;
948
950
}
949
951
952
+ static int pmic_arb_init_apid_min_max (struct spmi_pmic_arb * pmic_arb )
953
+ {
954
+ /*
955
+ * Initialize max_apid/min_apid to the opposite bounds, during
956
+ * the irq domain translation, we are sure to update these
957
+ */
958
+ pmic_arb -> max_apid = 0 ;
959
+ pmic_arb -> min_apid = pmic_arb -> max_periphs - 1 ;
960
+
961
+ return 0 ;
962
+ }
963
+
964
+ static int pmic_arb_init_apid_v1 (struct spmi_pmic_arb * pmic_arb )
965
+ {
966
+ u32 * mapping_table ;
967
+
968
+ mapping_table = devm_kcalloc (& pmic_arb -> spmic -> dev , pmic_arb -> max_periphs ,
969
+ sizeof (* mapping_table ), GFP_KERNEL );
970
+ if (!mapping_table )
971
+ return - ENOMEM ;
972
+
973
+ pmic_arb -> mapping_table = mapping_table ;
974
+
975
+ return pmic_arb_init_apid_min_max (pmic_arb );
976
+ }
977
+
950
978
static int pmic_arb_ppid_to_apid_v1 (struct spmi_pmic_arb * pmic_arb , u16 ppid )
951
979
{
952
980
u32 * mapping_table = pmic_arb -> mapping_table ;
@@ -1149,6 +1177,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
1149
1177
return 0x1000 * pmic_arb -> ee + 0x8000 * apid ;
1150
1178
}
1151
1179
1180
+ static int pmic_arb_init_apid_v5 (struct spmi_pmic_arb * pmic_arb )
1181
+ {
1182
+ int ret ;
1183
+
1184
+ pmic_arb -> base_apid = 0 ;
1185
+ pmic_arb -> apid_count = readl_relaxed (pmic_arb -> core + PMIC_ARB_FEATURES ) &
1186
+ PMIC_ARB_FEATURES_PERIPH_MASK ;
1187
+
1188
+ if (pmic_arb -> base_apid + pmic_arb -> apid_count > pmic_arb -> max_periphs ) {
1189
+ dev_err (& pmic_arb -> spmic -> dev , "Unsupported APID count %d detected\n" ,
1190
+ pmic_arb -> base_apid + pmic_arb -> apid_count );
1191
+ return - EINVAL ;
1192
+ }
1193
+
1194
+ ret = pmic_arb_init_apid_min_max (pmic_arb );
1195
+ if (ret )
1196
+ return ret ;
1197
+
1198
+ ret = pmic_arb_read_apid_map_v5 (pmic_arb );
1199
+ if (ret ) {
1200
+ dev_err (& pmic_arb -> spmic -> dev , "could not read APID->PPID mapping table, rc= %d\n" ,
1201
+ ret );
1202
+ return ret ;
1203
+ }
1204
+
1205
+ return 0 ;
1206
+ }
1207
+
1152
1208
/*
1153
1209
* v5 offset per ee and per apid for observer channels and per apid for
1154
1210
* read/write channels.
@@ -1363,6 +1419,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
1363
1419
1364
1420
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
1365
1421
.ver_str = "v1" ,
1422
+ .init_apid = pmic_arb_init_apid_v1 ,
1366
1423
.ppid_to_apid = pmic_arb_ppid_to_apid_v1 ,
1367
1424
.non_data_cmd = pmic_arb_non_data_cmd_v1 ,
1368
1425
.offset = pmic_arb_offset_v1 ,
@@ -1377,6 +1434,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
1377
1434
1378
1435
static const struct pmic_arb_ver_ops pmic_arb_v2 = {
1379
1436
.ver_str = "v2" ,
1437
+ .init_apid = pmic_arb_init_apid_v1 ,
1380
1438
.ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
1381
1439
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
1382
1440
.offset = pmic_arb_offset_v2 ,
@@ -1391,6 +1449,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
1391
1449
1392
1450
static const struct pmic_arb_ver_ops pmic_arb_v3 = {
1393
1451
.ver_str = "v3" ,
1452
+ .init_apid = pmic_arb_init_apid_v1 ,
1394
1453
.ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
1395
1454
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
1396
1455
.offset = pmic_arb_offset_v2 ,
@@ -1405,6 +1464,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
1405
1464
1406
1465
static const struct pmic_arb_ver_ops pmic_arb_v5 = {
1407
1466
.ver_str = "v5" ,
1467
+ .init_apid = pmic_arb_init_apid_v5 ,
1408
1468
.ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
1409
1469
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
1410
1470
.offset = pmic_arb_offset_v5 ,
@@ -1419,6 +1479,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
1419
1479
1420
1480
static const struct pmic_arb_ver_ops pmic_arb_v7 = {
1421
1481
.ver_str = "v7" ,
1482
+ .init_apid = pmic_arb_init_apid_v5 ,
1422
1483
.ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
1423
1484
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
1424
1485
.offset = pmic_arb_offset_v7 ,
@@ -1444,7 +1505,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1444
1505
struct spmi_controller * ctrl ;
1445
1506
struct resource * res ;
1446
1507
void __iomem * core ;
1447
- u32 * mapping_table ;
1448
1508
u32 channel , ee , hw_ver ;
1449
1509
int err ;
1450
1510
@@ -1472,12 +1532,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1472
1532
1473
1533
pmic_arb -> core_size = resource_size (res );
1474
1534
1475
- pmic_arb -> ppid_to_apid = devm_kcalloc (& ctrl -> dev , PMIC_ARB_MAX_PPID ,
1476
- sizeof (* pmic_arb -> ppid_to_apid ),
1477
- GFP_KERNEL );
1478
- if (!pmic_arb -> ppid_to_apid )
1479
- return - ENOMEM ;
1480
-
1481
1535
hw_ver = readl_relaxed (core + PMIC_ARB_VERSION );
1482
1536
1483
1537
if (hw_ver < PMIC_ARB_VERSION_V2_MIN ) {
@@ -1511,58 +1565,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1511
1565
return - ENOMEM ;
1512
1566
}
1513
1567
1514
- pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS ;
1568
+ dev_info (& ctrl -> dev , "PMIC arbiter version %s (0x%x)\n" ,
1569
+ pmic_arb -> ver_ops -> ver_str , hw_ver );
1515
1570
1516
- if (hw_ver >= PMIC_ARB_VERSION_V7_MIN ) {
1571
+ if (hw_ver < PMIC_ARB_VERSION_V7_MIN )
1572
+ pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS ;
1573
+ else
1517
1574
pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS_V7 ;
1518
- /* Optional property for v7: */
1519
- of_property_read_u32 (pdev -> dev .of_node , "qcom,bus-id" ,
1520
- & pmic_arb -> bus_instance );
1521
- if (pmic_arb -> bus_instance > 1 ) {
1522
- dev_err (& pdev -> dev , "invalid bus instance (%u) specified\n" ,
1523
- pmic_arb -> bus_instance );
1524
- return - EINVAL ;
1525
- }
1526
1575
1527
- if (pmic_arb -> bus_instance == 0 ) {
1528
- pmic_arb -> base_apid = 0 ;
1529
- pmic_arb -> apid_count =
1530
- readl_relaxed (core + PMIC_ARB_FEATURES ) &
1531
- PMIC_ARB_FEATURES_PERIPH_MASK ;
1532
- } else {
1533
- pmic_arb -> base_apid =
1534
- readl_relaxed (core + PMIC_ARB_FEATURES ) &
1535
- PMIC_ARB_FEATURES_PERIPH_MASK ;
1536
- pmic_arb -> apid_count =
1537
- readl_relaxed (core + PMIC_ARB_FEATURES1 ) &
1538
- PMIC_ARB_FEATURES_PERIPH_MASK ;
1539
- }
1540
-
1541
- if (pmic_arb -> base_apid + pmic_arb -> apid_count > pmic_arb -> max_periphs ) {
1542
- dev_err (& pdev -> dev , "Unsupported APID count %d detected\n" ,
1543
- pmic_arb -> base_apid + pmic_arb -> apid_count );
1544
- return - EINVAL ;
1545
- }
1546
- } else if (hw_ver >= PMIC_ARB_VERSION_V5_MIN ) {
1547
- pmic_arb -> base_apid = 0 ;
1548
- pmic_arb -> apid_count = readl_relaxed (core + PMIC_ARB_FEATURES ) &
1549
- PMIC_ARB_FEATURES_PERIPH_MASK ;
1550
-
1551
- if (pmic_arb -> apid_count > pmic_arb -> max_periphs ) {
1552
- dev_err (& pdev -> dev , "Unsupported APID count %d detected\n" ,
1553
- pmic_arb -> apid_count );
1554
- return - EINVAL ;
1555
- }
1556
- }
1557
-
1558
- pmic_arb -> apid_data = devm_kcalloc (& ctrl -> dev , pmic_arb -> max_periphs ,
1559
- sizeof (* pmic_arb -> apid_data ),
1560
- GFP_KERNEL );
1561
- if (!pmic_arb -> apid_data )
1562
- return - ENOMEM ;
1563
-
1564
- dev_info (& ctrl -> dev , "PMIC arbiter version %s (0x%x)\n" ,
1565
- pmic_arb -> ver_ops -> ver_str , hw_ver );
1576
+ err = pmic_arb -> ver_ops -> init_apid (pmic_arb );
1577
+ if (err )
1578
+ return err ;
1566
1579
1567
1580
res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "intr" );
1568
1581
pmic_arb -> intr = devm_ioremap_resource (& ctrl -> dev , res );
@@ -1604,16 +1617,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1604
1617
}
1605
1618
1606
1619
pmic_arb -> ee = ee ;
1607
- mapping_table = devm_kcalloc (& ctrl -> dev , pmic_arb -> max_periphs ,
1608
- sizeof (* mapping_table ), GFP_KERNEL );
1609
- if (!mapping_table )
1610
- return - ENOMEM ;
1611
-
1612
- pmic_arb -> mapping_table = mapping_table ;
1613
- /* Initialize max_apid/min_apid to the opposite bounds, during
1614
- * the irq domain translation, we are sure to update these */
1615
- pmic_arb -> max_apid = 0 ;
1616
- pmic_arb -> min_apid = pmic_arb -> max_periphs - 1 ;
1617
1620
1618
1621
platform_set_drvdata (pdev , ctrl );
1619
1622
raw_spin_lock_init (& pmic_arb -> lock );
@@ -1622,15 +1625,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1622
1625
ctrl -> read_cmd = pmic_arb_read_cmd ;
1623
1626
ctrl -> write_cmd = pmic_arb_write_cmd ;
1624
1627
1625
- if (hw_ver >= PMIC_ARB_VERSION_V5_MIN ) {
1626
- err = pmic_arb_read_apid_map_v5 (pmic_arb );
1627
- if (err ) {
1628
- dev_err (& pdev -> dev , "could not read APID->PPID mapping table, rc= %d\n" ,
1629
- err );
1630
- return err ;
1631
- }
1632
- }
1633
-
1634
1628
dev_dbg (& pdev -> dev , "adding irq domain\n" );
1635
1629
pmic_arb -> domain = irq_domain_add_tree (pdev -> dev .of_node ,
1636
1630
& pmic_arb_irq_domain_ops , pmic_arb );
0 commit comments