Skip to content

Commit 9799873

Browse files
abelvesagregkh
authored andcommitted
spmi: pmic-arb: Add multi bus support
Starting with HW version 7, there are actually two separate buses (with two separate sets of wires). So add support for the second bus. The first platform that needs this support for the second bus is the Qualcomm X1 Elite, so add the compatible for it as well. 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 02922cc commit 9799873

File tree

1 file changed

+120
-18
lines changed

1 file changed

+120
-18
lines changed

drivers/spmi/spmi-pmic-arb.c

Lines changed: 120 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/kernel.h>
1414
#include <linux/module.h>
1515
#include <linux/of.h>
16+
#include <linux/of_address.h>
1617
#include <linux/of_irq.h>
1718
#include <linux/platform_device.h>
1819
#include <linux/slab.h>
@@ -95,6 +96,8 @@ enum pmic_arb_channel {
9596
PMIC_ARB_CHANNEL_OBS,
9697
};
9798

99+
#define PMIC_ARB_MAX_BUSES 2
100+
98101
/* Maximum number of support PMIC peripherals */
99102
#define PMIC_ARB_MAX_PERIPHS 512
100103
#define PMIC_ARB_MAX_PERIPHS_V7 1024
@@ -149,6 +152,7 @@ struct spmi_pmic_arb;
149152
* @min_apid: minimum APID (used for bounding IRQ search)
150153
* @max_apid: maximum APID
151154
* @irq: PMIC ARB interrupt.
155+
* @id: unique ID of the bus
152156
*/
153157
struct spmi_pmic_arb_bus {
154158
struct spmi_pmic_arb *pmic_arb;
@@ -167,6 +171,7 @@ struct spmi_pmic_arb_bus {
167171
u16 min_apid;
168172
u16 max_apid;
169173
int irq;
174+
u8 id;
170175
};
171176

172177
/**
@@ -180,7 +185,8 @@ struct spmi_pmic_arb_bus {
180185
* @ee: the current Execution Environment
181186
* @ver_ops: version dependent operations.
182187
* @max_periphs: Number of elements in apid_data[]
183-
* @bus: per arbiter bus instance
188+
* @buses: per arbiter buses instances
189+
* @buses_available: number of buses registered
184190
*/
185191
struct spmi_pmic_arb {
186192
void __iomem *rd_base;
@@ -191,7 +197,8 @@ struct spmi_pmic_arb {
191197
u8 ee;
192198
const struct pmic_arb_ver_ops *ver_ops;
193199
int max_periphs;
194-
struct spmi_pmic_arb_bus *bus;
200+
struct spmi_pmic_arb_bus *buses[PMIC_ARB_MAX_BUSES];
201+
int buses_available;
195202
};
196203

197204
/**
@@ -220,7 +227,7 @@ struct spmi_pmic_arb {
220227
struct pmic_arb_ver_ops {
221228
const char *ver_str;
222229
int (*get_core_resources)(struct platform_device *pdev, void __iomem *core);
223-
int (*init_apid)(struct spmi_pmic_arb_bus *bus);
230+
int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index);
224231
int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid);
225232
/* spmi commands (read_cmd, write_cmd, cmd) functionality */
226233
int (*offset)(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
@@ -309,8 +316,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
309316
}
310317

311318
if (status & PMIC_ARB_STATUS_FAILURE) {
312-
dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n",
313-
__func__, sid, addr, status);
319+
dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n",
320+
__func__, sid, addr, status, offset);
314321
WARN_ON(1);
315322
return -EIO;
316323
}
@@ -326,8 +333,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
326333
udelay(1);
327334
}
328335

329-
dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n",
330-
__func__, sid, addr, status);
336+
dev_err(&ctrl->dev, "%s: %#x %#x %#x: timeout, status %#x\n",
337+
__func__, bus->id, sid, addr, status);
331338
return -ETIMEDOUT;
332339
}
333340

@@ -1003,11 +1010,17 @@ static int pmic_arb_get_core_resources_v1(struct platform_device *pdev,
10031010
return 0;
10041011
}
10051012

1006-
static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus)
1013+
static int pmic_arb_init_apid_v1(struct spmi_pmic_arb_bus *bus, int index)
10071014
{
10081015
struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
10091016
u32 *mapping_table;
10101017

1018+
if (index) {
1019+
dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
1020+
index);
1021+
return -EINVAL;
1022+
}
1023+
10111024
mapping_table = devm_kcalloc(&bus->spmic->dev, pmic_arb->max_periphs,
10121025
sizeof(*mapping_table), GFP_KERNEL);
10131026
if (!mapping_table)
@@ -1250,11 +1263,17 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr,
12501263
return 0x1000 * pmic_arb->ee + 0x8000 * apid;
12511264
}
12521265

1253-
static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus)
1266+
static int pmic_arb_init_apid_v5(struct spmi_pmic_arb_bus *bus, int index)
12541267
{
12551268
struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
12561269
int ret;
12571270

1271+
if (index) {
1272+
dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
1273+
index);
1274+
return -EINVAL;
1275+
}
1276+
12581277
bus->base_apid = 0;
12591278
bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
12601279
PMIC_ARB_FEATURES_PERIPH_MASK;
@@ -1326,6 +1345,50 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev,
13261345
return pmic_arb_get_obsrvr_chnls_v2(pdev);
13271346
}
13281347

1348+
/*
1349+
* Only v7 supports 2 buses. Each bus will get a different apid count, read
1350+
* from different registers.
1351+
*/
1352+
static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index)
1353+
{
1354+
struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
1355+
int ret;
1356+
1357+
if (index == 0) {
1358+
bus->base_apid = 0;
1359+
bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
1360+
PMIC_ARB_FEATURES_PERIPH_MASK;
1361+
} else if (index == 1) {
1362+
bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) &
1363+
PMIC_ARB_FEATURES_PERIPH_MASK;
1364+
bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) &
1365+
PMIC_ARB_FEATURES_PERIPH_MASK;
1366+
} else {
1367+
dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n",
1368+
bus->id);
1369+
return -EINVAL;
1370+
}
1371+
1372+
if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) {
1373+
dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n",
1374+
bus->base_apid + bus->apid_count);
1375+
return -EINVAL;
1376+
}
1377+
1378+
ret = pmic_arb_init_apid_min_max(bus);
1379+
if (ret)
1380+
return ret;
1381+
1382+
ret = pmic_arb_read_apid_map_v5(bus);
1383+
if (ret) {
1384+
dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n",
1385+
ret);
1386+
return ret;
1387+
}
1388+
1389+
return 0;
1390+
}
1391+
13291392
/*
13301393
* v7 offset per ee and per apid for observer channels and per apid for
13311394
* read/write channels.
@@ -1578,7 +1641,7 @@ static const struct pmic_arb_ver_ops pmic_arb_v5 = {
15781641
static const struct pmic_arb_ver_ops pmic_arb_v7 = {
15791642
.ver_str = "v7",
15801643
.get_core_resources = pmic_arb_get_core_resources_v7,
1581-
.init_apid = pmic_arb_init_apid_v5,
1644+
.init_apid = pmic_arb_init_apid_v7,
15821645
.ppid_to_apid = pmic_arb_ppid_to_apid_v5,
15831646
.non_data_cmd = pmic_arb_non_data_cmd_v2,
15841647
.offset = pmic_arb_offset_v7,
@@ -1602,6 +1665,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16021665
struct device_node *node,
16031666
struct spmi_pmic_arb *pmic_arb)
16041667
{
1668+
int bus_index = pmic_arb->buses_available;
16051669
struct spmi_pmic_arb_bus *bus;
16061670
struct device *dev = &pdev->dev;
16071671
struct spmi_controller *ctrl;
@@ -1620,7 +1684,7 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16201684

16211685
bus = spmi_controller_get_drvdata(ctrl);
16221686

1623-
pmic_arb->bus = bus;
1687+
pmic_arb->buses[bus_index] = bus;
16241688

16251689
raw_spin_lock_init(&bus->lock);
16261690

@@ -1665,12 +1729,13 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16651729
bus->cnfg = cnfg;
16661730
bus->irq = irq;
16671731
bus->spmic = ctrl;
1732+
bus->id = bus_index;
16681733

1669-
ret = pmic_arb->ver_ops->init_apid(bus);
1734+
ret = pmic_arb->ver_ops->init_apid(bus, bus_index);
16701735
if (ret)
16711736
return ret;
16721737

1673-
dev_dbg(&pdev->dev, "adding irq domain\n");
1738+
dev_dbg(&pdev->dev, "adding irq domain for bus %d\n", bus_index);
16741739

16751740
bus->domain = irq_domain_add_tree(dev->of_node,
16761741
&pmic_arb_irq_domain_ops, bus);
@@ -1683,14 +1748,53 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev,
16831748
pmic_arb_chained_irq, bus);
16841749

16851750
ctrl->dev.of_node = node;
1751+
dev_set_name(&ctrl->dev, "spmi-%d", bus_index);
16861752

16871753
ret = devm_spmi_controller_add(dev, ctrl);
16881754
if (ret)
16891755
return ret;
16901756

1757+
pmic_arb->buses_available++;
1758+
16911759
return 0;
16921760
}
16931761

1762+
static int spmi_pmic_arb_register_buses(struct spmi_pmic_arb *pmic_arb,
1763+
struct platform_device *pdev)
1764+
{
1765+
struct device *dev = &pdev->dev;
1766+
struct device_node *node = dev->of_node;
1767+
struct device_node *child;
1768+
int ret;
1769+
1770+
/* legacy mode doesn't provide child node for the bus */
1771+
if (of_device_is_compatible(node, "qcom,spmi-pmic-arb"))
1772+
return spmi_pmic_arb_bus_init(pdev, node, pmic_arb);
1773+
1774+
for_each_available_child_of_node(node, child) {
1775+
if (of_node_name_eq(child, "spmi")) {
1776+
ret = spmi_pmic_arb_bus_init(pdev, child, pmic_arb);
1777+
if (ret)
1778+
return ret;
1779+
}
1780+
}
1781+
1782+
return ret;
1783+
}
1784+
1785+
static void spmi_pmic_arb_deregister_buses(struct spmi_pmic_arb *pmic_arb)
1786+
{
1787+
int i;
1788+
1789+
for (i = 0; i < pmic_arb->buses_available; i++) {
1790+
struct spmi_pmic_arb_bus *bus = pmic_arb->buses[i];
1791+
1792+
irq_set_chained_handler_and_data(bus->irq,
1793+
NULL, NULL);
1794+
irq_domain_remove(bus->domain);
1795+
}
1796+
}
1797+
16941798
static int spmi_pmic_arb_probe(struct platform_device *pdev)
16951799
{
16961800
struct spmi_pmic_arb *pmic_arb;
@@ -1760,21 +1864,19 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
17601864

17611865
pmic_arb->ee = ee;
17621866

1763-
return spmi_pmic_arb_bus_init(pdev, dev->of_node, pmic_arb);
1867+
return spmi_pmic_arb_register_buses(pmic_arb, pdev);
17641868
}
17651869

17661870
static void spmi_pmic_arb_remove(struct platform_device *pdev)
17671871
{
17681872
struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev);
1769-
struct spmi_pmic_arb_bus *bus = pmic_arb->bus;
17701873

1771-
irq_set_chained_handler_and_data(bus->irq,
1772-
NULL, NULL);
1773-
irq_domain_remove(bus->domain);
1874+
spmi_pmic_arb_deregister_buses(pmic_arb);
17741875
}
17751876

17761877
static const struct of_device_id spmi_pmic_arb_match_table[] = {
17771878
{ .compatible = "qcom,spmi-pmic-arb", },
1879+
{ .compatible = "qcom,x1e80100-spmi-pmic-arb", },
17781880
{},
17791881
};
17801882
MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);

0 commit comments

Comments
 (0)