@@ -186,6 +186,7 @@ struct spmi_pmic_arb {
186186 * struct pmic_arb_ver_ops - version dependent functionality.
187187 *
188188 * @ver_str: version string.
189+ * @init_apid: finds the apid base and count
189190 * @ppid_to_apid: finds the apid for a given ppid.
190191 * @non_data_cmd: on v1 issues an spmi non-data command.
191192 * on v2 no HW support, returns -EOPNOTSUPP.
@@ -205,6 +206,7 @@ struct spmi_pmic_arb {
205206 */
206207struct pmic_arb_ver_ops {
207208 const char * ver_str ;
209+ int (* init_apid )(struct spmi_pmic_arb * pmic_arb );
208210 int (* ppid_to_apid )(struct spmi_pmic_arb * pmic_arb , u16 ppid );
209211 /* spmi commands (read_cmd, write_cmd, cmd) functionality */
210212 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,
947949 return 0 ;
948950}
949951
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+
950978static int pmic_arb_ppid_to_apid_v1 (struct spmi_pmic_arb * pmic_arb , u16 ppid )
951979{
952980 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,
11491177 return 0x1000 * pmic_arb -> ee + 0x8000 * apid ;
11501178}
11511179
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+
11521208/*
11531209 * v5 offset per ee and per apid for observer channels and per apid for
11541210 * read/write channels.
@@ -1363,6 +1419,7 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb *pmic_arb, u16 n)
13631419
13641420static const struct pmic_arb_ver_ops pmic_arb_v1 = {
13651421 .ver_str = "v1" ,
1422+ .init_apid = pmic_arb_init_apid_v1 ,
13661423 .ppid_to_apid = pmic_arb_ppid_to_apid_v1 ,
13671424 .non_data_cmd = pmic_arb_non_data_cmd_v1 ,
13681425 .offset = pmic_arb_offset_v1 ,
@@ -1377,6 +1434,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v1 = {
13771434
13781435static const struct pmic_arb_ver_ops pmic_arb_v2 = {
13791436 .ver_str = "v2" ,
1437+ .init_apid = pmic_arb_init_apid_v1 ,
13801438 .ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
13811439 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
13821440 .offset = pmic_arb_offset_v2 ,
@@ -1391,6 +1449,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v2 = {
13911449
13921450static const struct pmic_arb_ver_ops pmic_arb_v3 = {
13931451 .ver_str = "v3" ,
1452+ .init_apid = pmic_arb_init_apid_v1 ,
13941453 .ppid_to_apid = pmic_arb_ppid_to_apid_v2 ,
13951454 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
13961455 .offset = pmic_arb_offset_v2 ,
@@ -1405,6 +1464,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v3 = {
14051464
14061465static const struct pmic_arb_ver_ops pmic_arb_v5 = {
14071466 .ver_str = "v5" ,
1467+ .init_apid = pmic_arb_init_apid_v5 ,
14081468 .ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
14091469 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
14101470 .offset = pmic_arb_offset_v5 ,
@@ -1419,6 +1479,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
14191479
14201480static const struct pmic_arb_ver_ops pmic_arb_v7 = {
14211481 .ver_str = "v7" ,
1482+ .init_apid = pmic_arb_init_apid_v5 ,
14221483 .ppid_to_apid = pmic_arb_ppid_to_apid_v5 ,
14231484 .non_data_cmd = pmic_arb_non_data_cmd_v2 ,
14241485 .offset = pmic_arb_offset_v7 ,
@@ -1444,7 +1505,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
14441505 struct spmi_controller * ctrl ;
14451506 struct resource * res ;
14461507 void __iomem * core ;
1447- u32 * mapping_table ;
14481508 u32 channel , ee , hw_ver ;
14491509 int err ;
14501510
@@ -1472,12 +1532,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
14721532
14731533 pmic_arb -> core_size = resource_size (res );
14741534
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-
14811535 hw_ver = readl_relaxed (core + PMIC_ARB_VERSION );
14821536
14831537 if (hw_ver < PMIC_ARB_VERSION_V2_MIN ) {
@@ -1511,58 +1565,17 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
15111565 return - ENOMEM ;
15121566 }
15131567
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 );
15151570
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
15171574 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- }
15261575
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 ;
15661579
15671580 res = platform_get_resource_byname (pdev , IORESOURCE_MEM , "intr" );
15681581 pmic_arb -> intr = devm_ioremap_resource (& ctrl -> dev , res );
@@ -1604,16 +1617,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
16041617 }
16051618
16061619 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 ;
16171620
16181621 platform_set_drvdata (pdev , ctrl );
16191622 raw_spin_lock_init (& pmic_arb -> lock );
@@ -1622,15 +1625,6 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
16221625 ctrl -> read_cmd = pmic_arb_read_cmd ;
16231626 ctrl -> write_cmd = pmic_arb_write_cmd ;
16241627
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-
16341628 dev_dbg (& pdev -> dev , "adding irq domain\n" );
16351629 pmic_arb -> domain = irq_domain_add_tree (pdev -> dev .of_node ,
16361630 & pmic_arb_irq_domain_ops , pmic_arb );
0 commit comments