Skip to content

Commit 8bc0376

Browse files
abelvesagregkh
authored andcommitted
spmi: pmic-arb: Make the APID init a version operation
Rather than using conditionals in probe function, add the APID init as a version specific operation. Due to v7, which supports multiple buses, pass on the bus index to be used for sorting out the apid base and count. Reviewed-by: Neil Armstrong <[email protected]> Signed-off-by: Abel Vesa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 83bfd7a commit 8bc0376

File tree

1 file changed

+69
-75
lines changed

1 file changed

+69
-75
lines changed

drivers/spmi/spmi-pmic-arb.c

Lines changed: 69 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
206207
struct 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+
950978
static 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

13641420
static 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

13781435
static 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

13921450
static 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

14061465
static 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

14201480
static 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

Comments
 (0)