@@ -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
+ * @get_core_resources: initializes the core, observer and channels
189
190
* @init_apid: finds the apid base and count
190
191
* @ppid_to_apid: finds the apid for a given ppid.
191
192
* @non_data_cmd: on v1 issues an spmi non-data command.
@@ -206,6 +207,7 @@ struct spmi_pmic_arb {
206
207
*/
207
208
struct pmic_arb_ver_ops {
208
209
const char * ver_str ;
210
+ int (* get_core_resources )(struct platform_device * pdev , void __iomem * core );
209
211
int (* init_apid )(struct spmi_pmic_arb * pmic_arb );
210
212
int (* ppid_to_apid )(struct spmi_pmic_arb * pmic_arb , u16 ppid );
211
213
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
@@ -961,6 +963,19 @@ static int pmic_arb_init_apid_min_max(struct spmi_pmic_arb *pmic_arb)
961
963
return 0 ;
962
964
}
963
965
966
+ static int pmic_arb_get_core_resources_v1 (struct platform_device * pdev ,
967
+ void __iomem * core )
968
+ {
969
+ struct spmi_pmic_arb * pmic_arb = platform_get_drvdata (pdev );
970
+
971
+ pmic_arb -> wr_base = core ;
972
+ pmic_arb -> rd_base = core ;
973
+
974
+ pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS ;
975
+
976
+ return 0 ;
977
+ }
978
+
964
979
static int pmic_arb_init_apid_v1 (struct spmi_pmic_arb * pmic_arb )
965
980
{
966
981
u32 * mapping_table ;
@@ -1062,6 +1077,33 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
1062
1077
return apid ;
1063
1078
}
1064
1079
1080
+ static int pmic_arb_get_obsrvr_chnls_v2 (struct platform_device * pdev )
1081
+ {
1082
+ struct spmi_pmic_arb * pmic_arb = platform_get_drvdata (pdev );
1083
+
1084
+ pmic_arb -> rd_base = devm_platform_ioremap_resource_byname (pdev , "obsrvr" );
1085
+ if (IS_ERR (pmic_arb -> rd_base ))
1086
+ return PTR_ERR (pmic_arb -> rd_base );
1087
+
1088
+ pmic_arb -> wr_base = devm_platform_ioremap_resource_byname (pdev , "chnls" );
1089
+ if (IS_ERR (pmic_arb -> wr_base ))
1090
+ return PTR_ERR (pmic_arb -> wr_base );
1091
+
1092
+ return 0 ;
1093
+ }
1094
+
1095
+ static int pmic_arb_get_core_resources_v2 (struct platform_device * pdev ,
1096
+ void __iomem * core )
1097
+ {
1098
+ struct spmi_pmic_arb * pmic_arb = platform_get_drvdata (pdev );
1099
+
1100
+ pmic_arb -> core = core ;
1101
+
1102
+ pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS ;
1103
+
1104
+ return pmic_arb_get_obsrvr_chnls_v2 (pdev );
1105
+ }
1106
+
1065
1107
static int pmic_arb_ppid_to_apid_v2 (struct spmi_pmic_arb * pmic_arb , u16 ppid )
1066
1108
{
1067
1109
u16 apid_valid ;
@@ -1239,6 +1281,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
1239
1281
return offset ;
1240
1282
}
1241
1283
1284
+ static int pmic_arb_get_core_resources_v7 (struct platform_device * pdev ,
1285
+ void __iomem * core )
1286
+ {
1287
+ struct spmi_pmic_arb * pmic_arb = platform_get_drvdata (pdev );
1288
+
1289
+ pmic_arb -> core = core ;
1290
+
1291
+ pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS_V7 ;
1292
+
1293
+ return pmic_arb_get_obsrvr_chnls_v2 (pdev );
1294
+ }
1295
+
1242
1296
/*
1243
1297
* v7 offset per ee and per apid for observer channels and per apid for
1244
1298
* read/write channels.
@@ -1419,6 +1473,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
1419
1473
1420
1474
static const struct pmic_arb_ver_ops pmic_arb_v1 = {
1421
1475
.ver_str = "v1" ,
1476
+ .get_core_resources = pmic_arb_get_core_resources_v1 ,
1422
1477
.init_apid = pmic_arb_init_apid_v1 ,
1423
1478
.ppid_to_apid = pmic_arb_ppid_to_apid_v1 ,
1424
1479
.non_data_cmd = pmic_arb_non_data_cmd_v1 ,
@@ -1434,6 +1489,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
1434
1489
1435
1490
static const struct pmic_arb_ver_ops pmic_arb_v2 = {
1436
1491
.ver_str = "v2" ,
1492
+ .get_core_resources = pmic_arb_get_core_resources_v2 ,
1437
1493
.init_apid = pmic_arb_init_apid_v1 ,
1438
1494
.ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
1439
1495
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1449,6 +1505,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
1449
1505
1450
1506
static const struct pmic_arb_ver_ops pmic_arb_v3 = {
1451
1507
.ver_str = "v3" ,
1508
+ .get_core_resources = pmic_arb_get_core_resources_v2 ,
1452
1509
.init_apid = pmic_arb_init_apid_v1 ,
1453
1510
.ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
1454
1511
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1464,6 +1521,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
1464
1521
1465
1522
static const struct pmic_arb_ver_ops pmic_arb_v5 = {
1466
1523
.ver_str = "v5" ,
1524
+ .get_core_resources = pmic_arb_get_core_resources_v2 ,
1467
1525
.init_apid = pmic_arb_init_apid_v5 ,
1468
1526
.ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
1469
1527
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1479,6 +1537,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
1479
1537
1480
1538
static const struct pmic_arb_ver_ops pmic_arb_v7 = {
1481
1539
.ver_str = "v7" ,
1540
+ .get_core_resources = pmic_arb_get_core_resources_v7 ,
1482
1541
.init_apid = pmic_arb_init_apid_v5 ,
1483
1542
.ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
1484
1543
.non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1515,16 +1574,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1515
1574
pmic_arb = spmi_controller_get_drvdata (ctrl );
1516
1575
pmic_arb -> spmic = ctrl ;
1517
1576
1518
- /*
1519
- * Please don't replace this with devm_platform_ioremap_resource() or
1520
- * devm_ioremap_resource(). These both result in a call to
1521
- * devm_request_mem_region() which prevents multiple mappings of this
1522
- * register address range. SoCs with PMIC arbiter v7 may define two
1523
- * arbiter devices, for the two physical SPMI interfaces, which share
1524
- * some register address ranges (i.e. "core", "obsrvr", and "chnls").
1525
- * Ensure that both devices probe successfully by calling devm_ioremap()
1526
- * which does not result in a devm_request_mem_region() call.
1527
- */
1528
1577
res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "core" );
1529
1578
core = devm_ioremap (& ctrl -> dev , res -> start , resource_size (res ));
1530
1579
if (!core )
@@ -1534,44 +1583,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
1534
1583
1535
1584
hw_ver = readl_relaxed (core + PMIC_ARB_VERSION );
1536
1585
1537
- if (hw_ver < PMIC_ARB_VERSION_V2_MIN ) {
1586
+ if (hw_ver < PMIC_ARB_VERSION_V2_MIN )
1538
1587
pmic_arb -> ver_ops = & pmic_arb_v1 ;
1539
- pmic_arb -> wr_base = core ;
1540
- pmic_arb -> rd_base = core ;
1541
- } else {
1542
- pmic_arb -> core = core ;
1543
-
1544
- if (hw_ver < PMIC_ARB_VERSION_V3_MIN )
1545
- pmic_arb -> ver_ops = & pmic_arb_v2 ;
1546
- else if (hw_ver < PMIC_ARB_VERSION_V5_MIN )
1547
- pmic_arb -> ver_ops = & pmic_arb_v3 ;
1548
- else if (hw_ver < PMIC_ARB_VERSION_V7_MIN )
1549
- pmic_arb -> ver_ops = & pmic_arb_v5 ;
1550
- else
1551
- pmic_arb -> ver_ops = & pmic_arb_v7 ;
1552
-
1553
- res = platform_get_resource_byname (pdev , IORESOURCE_MEM ,
1554
- "obsrvr" );
1555
- pmic_arb -> rd_base = devm_ioremap (& ctrl -> dev , res -> start ,
1556
- resource_size (res ));
1557
- if (!pmic_arb -> rd_base )
1558
- return - ENOMEM ;
1559
-
1560
- res = platform_get_resource_byname (pdev , IORESOURCE_MEM ,
1561
- "chnls" );
1562
- pmic_arb -> wr_base = devm_ioremap (& ctrl -> dev , res -> start ,
1563
- resource_size (res ));
1564
- if (!pmic_arb -> wr_base )
1565
- return - ENOMEM ;
1566
- }
1588
+ else if (hw_ver < PMIC_ARB_VERSION_V3_MIN )
1589
+ pmic_arb -> ver_ops = & pmic_arb_v2 ;
1590
+ else if (hw_ver < PMIC_ARB_VERSION_V5_MIN )
1591
+ pmic_arb -> ver_ops = & pmic_arb_v3 ;
1592
+ else if (hw_ver < PMIC_ARB_VERSION_V7_MIN )
1593
+ pmic_arb -> ver_ops = & pmic_arb_v5 ;
1594
+ else
1595
+ pmic_arb -> ver_ops = & pmic_arb_v7 ;
1567
1596
1568
1597
dev_info (& ctrl -> dev , "PMIC arbiter version %s (0x%x)\n" ,
1569
1598
pmic_arb -> ver_ops -> ver_str , hw_ver );
1570
1599
1571
- if (hw_ver < PMIC_ARB_VERSION_V7_MIN )
1572
- pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS ;
1573
- else
1574
- pmic_arb -> max_periphs = PMIC_ARB_MAX_PERIPHS_V7 ;
1600
+ err = pmic_arb -> ver_ops -> get_core_resources (pdev , core );
1601
+ if (err )
1602
+ return err ;
1575
1603
1576
1604
err = pmic_arb -> ver_ops -> init_apid (pmic_arb );
1577
1605
if (err )
0 commit comments