@@ -186,6 +186,7 @@ struct spmi_pmic_arb {
186186 * struct pmic_arb_ver_ops - version dependent functionality.
187187 *
188188 * @ver_str: version string.
189+ * @get_core_resources: initializes the core, observer and channels
189190 * @init_apid: finds the apid base and count
190191 * @ppid_to_apid: finds the apid for a given ppid.
191192 * @non_data_cmd: on v1 issues an spmi non-data command.
@@ -206,6 +207,7 @@ struct spmi_pmic_arb {
206207 */
207208struct pmic_arb_ver_ops {
208209 const char * ver_str ;
210+ int (* get_core_resources )(struct platform_device * pdev , void __iomem * core );
209211 int (* init_apid )(struct spmi_pmic_arb * pmic_arb );
210212 int (* ppid_to_apid )(struct spmi_pmic_arb * pmic_arb , u16 ppid );
211213 /* 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)
961963 return 0 ;
962964}
963965
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+
964979static int pmic_arb_init_apid_v1 (struct spmi_pmic_arb * pmic_arb )
965980{
966981 u32 * mapping_table ;
@@ -1062,6 +1077,33 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
10621077 return apid ;
10631078}
10641079
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+
10651107static int pmic_arb_ppid_to_apid_v2 (struct spmi_pmic_arb * pmic_arb , u16 ppid )
10661108{
10671109 u16 apid_valid ;
@@ -1239,6 +1281,18 @@ static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
12391281 return offset ;
12401282}
12411283
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+
12421296/*
12431297 * v7 offset per ee and per apid for observer channels and per apid for
12441298 * read/write channels.
@@ -1419,6 +1473,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
14191473
14201474static const struct pmic_arb_ver_ops pmic_arb_v1 = {
14211475 .ver_str = "v1" ,
1476+ .get_core_resources = pmic_arb_get_core_resources_v1 ,
14221477 .init_apid = pmic_arb_init_apid_v1 ,
14231478 .ppid_to_apid = pmic_arb_ppid_to_apid_v1 ,
14241479 .non_data_cmd = pmic_arb_non_data_cmd_v1 ,
@@ -1434,6 +1489,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
14341489
14351490static const struct pmic_arb_ver_ops pmic_arb_v2 = {
14361491 .ver_str = "v2" ,
1492+ .get_core_resources = pmic_arb_get_core_resources_v2 ,
14371493 .init_apid = pmic_arb_init_apid_v1 ,
14381494 .ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
14391495 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1449,6 +1505,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
14491505
14501506static const struct pmic_arb_ver_ops pmic_arb_v3 = {
14511507 .ver_str = "v3" ,
1508+ .get_core_resources = pmic_arb_get_core_resources_v2 ,
14521509 .init_apid = pmic_arb_init_apid_v1 ,
14531510 .ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
14541511 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1464,6 +1521,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
14641521
14651522static const struct pmic_arb_ver_ops pmic_arb_v5 = {
14661523 .ver_str = "v5" ,
1524+ .get_core_resources = pmic_arb_get_core_resources_v2 ,
14671525 .init_apid = pmic_arb_init_apid_v5 ,
14681526 .ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
14691527 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1479,6 +1537,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
14791537
14801538static const struct pmic_arb_ver_ops pmic_arb_v7 = {
14811539 .ver_str = "v7" ,
1540+ .get_core_resources = pmic_arb_get_core_resources_v7 ,
14821541 .init_apid = pmic_arb_init_apid_v5 ,
14831542 .ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
14841543 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
@@ -1515,16 +1574,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
15151574 pmic_arb = spmi_controller_get_drvdata (ctrl );
15161575 pmic_arb -> spmic = ctrl ;
15171576
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- */
15281577 res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "core" );
15291578 core = devm_ioremap (& ctrl -> dev , res -> start , resource_size (res ));
15301579 if (!core )
@@ -1534,44 +1583,23 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
15341583
15351584 hw_ver = readl_relaxed (core + PMIC_ARB_VERSION );
15361585
1537- if (hw_ver < PMIC_ARB_VERSION_V2_MIN ) {
1586+ if (hw_ver < PMIC_ARB_VERSION_V2_MIN )
15381587 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 ;
15671596
15681597 dev_info (& ctrl -> dev , "PMIC arbiter version %s (0x%x)\n" ,
15691598 pmic_arb -> ver_ops -> ver_str , hw_ver );
15701599
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 ;
15751603
15761604 err = pmic_arb -> ver_ops -> init_apid (pmic_arb );
15771605 if (err )
0 commit comments