Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spmi: spmi-pmic-arb: add support for PMIC arbiter v8

PMIC arbiter v8 supports up to 4 SPMI buses and up to 8192 PMIC
peripherals. Its register map differs from v7 as several fields
increased in size. Add support for PMIC arbiter version 8.

Signed-off-by: David Collins <david.collins@oss.qualcomm.com>
Signed-off-by: Kamal Wadhwa <kamal.wadhwa@oss.qualcomm.com>
Signed-off-by: Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://patch.msgid.link/20260123182039.224314-10-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

David Collins and committed by
Greg Kroah-Hartman
815be38a 09144981

+256 -50
+256 -50
drivers/spmi/spmi-pmic-arb.c
··· 2 2 /* 3 3 * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved. 4 4 */ 5 + 6 + #include <linux/bitfield.h> 5 7 #include <linux/bitmap.h> 6 8 #include <linux/delay.h> 7 9 #include <linux/err.h> ··· 27 25 #define PMIC_ARB_VERSION_V3_MIN 0x30000000 28 26 #define PMIC_ARB_VERSION_V5_MIN 0x50000000 29 27 #define PMIC_ARB_VERSION_V7_MIN 0x70000000 28 + #define PMIC_ARB_VERSION_V8_MIN 0x80000000 30 29 #define PMIC_ARB_INT_EN 0x0004 31 30 32 31 #define PMIC_ARB_FEATURES 0x0004 33 32 #define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0) 34 - 35 - #define PMIC_ARB_FEATURES1 0x0008 33 + #define PMIC_ARB_FEATURES_V8_PERIPH_MASK GENMASK(12, 0) 36 34 37 35 /* PMIC Arbiter channel registers offsets */ 38 36 #define PMIC_ARB_CMD 0x00 ··· 52 50 #define SPMI_MAPPING_BIT_IS_1_RESULT(X) (((X) >> 0) & 0xFF) 53 51 54 52 #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */ 55 - #define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */ 53 + #define PMIC_ARB_MAX_PPID BIT(13) 56 54 #define PMIC_ARB_APID_VALID BIT(15) 57 - #define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24)) 55 + #define PMIC_ARB_CHAN_IS_IRQ_OWNER_MASK BIT(24) 56 + #define PMIC_ARB_V8_CHAN_IS_IRQ_OWNER_MASK BIT(31) 57 + 58 58 #define INVALID_EE 0xFF 59 59 60 60 /* Ownership Table */ ··· 100 96 PMIC_ARB_CHANNEL_OBS, 101 97 }; 102 98 103 - #define PMIC_ARB_MAX_BUSES 2 99 + #define PMIC_ARB_MAX_BUSES 4 104 100 105 101 /* Maximum number of support PMIC peripherals */ 106 102 #define PMIC_ARB_MAX_PERIPHS 512 107 103 #define PMIC_ARB_MAX_PERIPHS_V7 1024 104 + #define PMIC_ARB_MAX_PERIPHS_V8 8192 108 105 #define PMIC_ARB_TIMEOUT_US 1000 109 106 #define PMIC_ARB_MAX_TRANS_BYTES (8) 110 107 111 108 #define PMIC_ARB_APID_MASK 0xFF 112 - #define PMIC_ARB_PPID_MASK 0xFFF 109 + #define PMIC_ARB_PPID_MASK GENMASK(11, 0) 110 + #define PMIC_ARB_V8_PPID_MASK GENMASK(12, 0) 113 111 114 112 /* interrupt enable bit */ 115 113 #define SPMI_PIC_ACC_ENABLE_BIT BIT(0) 116 114 117 - #define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \ 118 - ((((slave_id) & 0xF) << 28) | \ 119 - (((periph_id) & 0xFF) << 20) | \ 120 - (((irq_id) & 0x7) << 16) | \ 121 - (((apid) & 0x3FF) << 0)) 115 + #define HWIRQ_SID_MASK GENMASK(28, 24) 116 + #define HWIRQ_PID_MASK GENMASK(23, 16) 117 + #define HWIRQ_IRQID_MASK GENMASK(15, 13) 118 + #define HWIRQ_APID_MASK GENMASK(12, 0) 122 119 123 - #define hwirq_to_sid(hwirq) (((hwirq) >> 28) & 0xF) 124 - #define hwirq_to_per(hwirq) (((hwirq) >> 20) & 0xFF) 125 - #define hwirq_to_irq(hwirq) (((hwirq) >> 16) & 0x7) 126 - #define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x3FF) 120 + #define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \ 121 + (FIELD_PREP(HWIRQ_SID_MASK, (slave_id)) | \ 122 + FIELD_PREP(HWIRQ_PID_MASK, (periph_id)) | \ 123 + FIELD_PREP(HWIRQ_IRQID_MASK, (irq_id)) | \ 124 + FIELD_PREP(HWIRQ_APID_MASK, (apid))) 125 + 126 + #define hwirq_to_sid(hwirq) FIELD_GET(HWIRQ_SID_MASK, (hwirq)) 127 + #define hwirq_to_per(hwirq) FIELD_GET(HWIRQ_PID_MASK, (hwirq)) 128 + #define hwirq_to_irq(hwirq) FIELD_GET(HWIRQ_IRQID_MASK, (hwirq)) 129 + #define hwirq_to_apid(hwirq) FIELD_GET(HWIRQ_APID_MASK, (hwirq)) 127 130 128 131 struct pmic_arb_ver_ops; 129 132 ··· 149 138 * @domain: irq domain object for PMIC IRQ domain 150 139 * @intr: address of the SPMI interrupt control registers. 151 140 * @cnfg: address of the PMIC Arbiter configuration registers. 141 + * @apid_owner: on v8: address of APID owner mapping table registers 152 142 * @spmic: spmi controller registered for this bus 153 143 * @lock: lock to synchronize accesses. 154 - * @base_apid: on v7: minimum APID associated with the particular SPMI 155 - * bus instance 156 - * @apid_count: on v5 and v7: number of APIDs associated with the 144 + * @base_apid: on v7 and v8: minimum APID associated with the 145 + * particular SPMI bus instance 146 + * @apid_count: on v5, v7 and v8: number of APIDs associated with the 157 147 * particular SPMI bus instance 158 148 * @mapping_table: in-memory copy of PPID -> APID mapping table. 159 149 * @mapping_table_valid:bitmap containing valid-only periphs ··· 171 159 struct irq_domain *domain; 172 160 void __iomem *intr; 173 161 void __iomem *cnfg; 162 + void __iomem *apid_owner; 174 163 struct spmi_controller *spmic; 175 164 raw_spinlock_t lock; 176 165 u16 base_apid; ··· 194 181 * @wr_base: on v1 "core", on v2 "chnls" register base off DT. 195 182 * @core: core register base for v2 and above only (see above) 196 183 * @core_size: core register base size 184 + * @apid_map: on v8, APID mapping table register base 197 185 * @channel: execution environment channel to use for accesses. 198 186 * @ee: the current Execution Environment 199 187 * @ver_ops: version dependent operations. ··· 207 193 void __iomem *wr_base; 208 194 void __iomem *core; 209 195 resource_size_t core_size; 196 + void __iomem *apid_map; 210 197 u8 channel; 211 198 u8 ee; 212 199 const struct pmic_arb_ver_ops *ver_ops; ··· 221 206 * 222 207 * @ver_str: version string. 223 208 * @get_core_resources: initializes the core, observer and channels 209 + * @get_bus_resources: requests per-SPMI bus register resources 224 210 * @init_apid: finds the apid base and count 225 211 * @ppid_to_apid: finds the apid for a given ppid. 226 212 * @non_data_cmd: on v1 issues an spmi non-data command. ··· 243 227 struct pmic_arb_ver_ops { 244 228 const char *ver_str; 245 229 int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); 230 + int (*get_bus_resources)(struct platform_device *pdev, 231 + struct device_node *node, 232 + struct spmi_pmic_arb_bus *bus); 246 233 int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index); 247 234 int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid); 248 235 /* spmi commands (read_cmd, write_cmd, cmd) functionality */ ··· 675 656 unsigned int irq; 676 657 u32 status, id; 677 658 int handled = 0; 678 - u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF; 659 + u8 sid = (bus->apid_data[apid].ppid >> 8) & 0x1F; 679 660 u8 per = bus->apid_data[apid].ppid & 0xFF; 680 661 681 662 status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid)); ··· 705 686 int last = bus->max_apid; 706 687 /* 707 688 * acc_offset will be non-zero for the secondary SPMI bus instance on 708 - * v7 controllers. 689 + * v7 and v8 controllers. 709 690 */ 710 691 int acc_offset = bus->base_apid >> 5; 711 692 u8 ee = pmic_arb->ee; ··· 932 913 return -EINVAL; 933 914 if (fwspec->param_count != 4) 934 915 return -EINVAL; 935 - if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7) 916 + if (intspec[0] > FIELD_MAX(HWIRQ_SID_MASK) || intspec[1] > FIELD_MAX(HWIRQ_PID_MASK) || 917 + intspec[2] > FIELD_MAX(HWIRQ_IRQID_MASK)) 936 918 return -EINVAL; 937 919 938 920 ppid = intspec[0] << 8 | intspec[1]; ··· 1180 1160 return apid_valid & ~PMIC_ARB_APID_VALID; 1181 1161 } 1182 1162 1183 - static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) 1163 + static int _pmic_arb_read_apid_map(struct spmi_pmic_arb_bus *bus, 1164 + void __iomem *ppid_base, unsigned long ppid_mask, 1165 + u8 ppid_shift, unsigned long irq_owner_mask) 1184 1166 { 1185 1167 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1186 1168 struct apid_data *apidd; ··· 1193 1171 1194 1172 /* 1195 1173 * In order to allow multiple EEs to write to a single PPID in arbiter 1196 - * version 5 and 7, there is more than one APID mapped to each PPID. 1174 + * version 5,7 and 8, there can be more than one APID mapped to each PPID. 1197 1175 * The owner field for each of these mappings specifies the EE which is 1198 1176 * allowed to write to the APID. The owner of the last (highest) APID 1199 1177 * which has the IRQ owner bit set for a given PPID will receive ··· 1205 1183 * APID = N to N+M-1 are assigned to the secondary bus 1206 1184 * where N = number of APIDs supported by the primary bus and 1207 1185 * M = number of APIDs supported by the secondary bus 1186 + * 1187 + * In arbiter version 8, the APID numbering space is divided between 1188 + * the SPMI buses according to this mapping: 1189 + * APID = 0 to N-1 --> bus 0 1190 + * APID = N to N+M-1 --> bus 1 1191 + * APID = N+M to N+M+P-1 --> bus 2 1192 + * APID = N+M+P to N+M+P+Q-1 --> bus 3 1193 + * where N = number of APIDs supported by bus 0 1194 + * M = number of APIDs supported by bus 1 1195 + * P = number of APIDs supported by bus 2 1196 + * Q = number of APIDs supported by bus 3 1208 1197 */ 1198 + 1209 1199 apidd = &bus->apid_data[bus->base_apid]; 1210 1200 apid_max = bus->base_apid + bus->apid_count; 1211 1201 for (i = bus->base_apid; i < apid_max; i++, apidd++) { 1212 1202 offset = pmic_arb->ver_ops->apid_map_offset(i); 1213 1203 if (offset >= pmic_arb->core_size) 1214 1204 break; 1215 - 1216 - regval = readl_relaxed(pmic_arb->core + offset); 1205 + regval = readl_relaxed(ppid_base + offset); 1217 1206 if (!regval) 1218 1207 continue; 1219 - ppid = (regval >> 8) & PMIC_ARB_PPID_MASK; 1220 - is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval); 1208 + ppid = (regval >> ppid_shift) & ppid_mask; 1209 + is_irq_ee = regval & irq_owner_mask; 1221 1210 1222 1211 regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i)); 1223 1212 apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); ··· 1268 1235 } 1269 1236 1270 1237 return 0; 1238 + } 1239 + 1240 + static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) 1241 + { 1242 + return _pmic_arb_read_apid_map(bus, bus->pmic_arb->core, PMIC_ARB_PPID_MASK, 1243 + 8, PMIC_ARB_CHAN_IS_IRQ_OWNER_MASK); 1271 1244 } 1272 1245 1273 1246 static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid) ··· 1384 1345 return pmic_arb_get_obsrvr_chnls_v2(pdev); 1385 1346 } 1386 1347 1387 - /* 1388 - * Only v7 supports 2 buses. Each bus will get a different apid count, read 1389 - * from different registers. 1390 - */ 1391 - static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) 1348 + static int _pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index, 1349 + int max_buses, unsigned long periph_mask) 1392 1350 { 1393 1351 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1394 - int ret; 1352 + int i; 1395 1353 1396 - if (index == 0) { 1397 - bus->base_apid = 0; 1398 - bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & 1399 - PMIC_ARB_FEATURES_PERIPH_MASK; 1400 - } else if (index == 1) { 1401 - bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & 1402 - PMIC_ARB_FEATURES_PERIPH_MASK; 1403 - bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & 1404 - PMIC_ARB_FEATURES_PERIPH_MASK; 1405 - } else { 1406 - dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", 1407 - bus->id); 1354 + if (index < 0 || index >= max_buses) { 1355 + dev_err(&bus->spmic->dev, "Unsupported bus index %d detected\n", 1356 + index); 1408 1357 return -EINVAL; 1409 1358 } 1410 1359 1411 - if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { 1412 - dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", 1360 + bus->base_apid = 0; 1361 + bus->apid_count = 0; 1362 + for (i = 0; i <= index; i++) { 1363 + bus->base_apid += bus->apid_count; 1364 + bus->apid_count = readl_relaxed(pmic_arb->core + 1365 + PMIC_ARB_FEATURES + i * 4) & 1366 + periph_mask; 1367 + } 1368 + 1369 + if (bus->apid_count == 0) { 1370 + dev_err(&bus->spmic->dev, "Bus %d not implemented\n", index); 1371 + return -EINVAL; 1372 + } else if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { 1373 + dev_err(&bus->spmic->dev, "Unsupported max APID %d detected\n", 1413 1374 bus->base_apid + bus->apid_count); 1414 1375 return -EINVAL; 1415 1376 } 1416 1377 1417 - ret = pmic_arb_init_apid_min_max(bus); 1378 + return pmic_arb_init_apid_min_max(bus); 1379 + } 1380 + 1381 + /* 1382 + * Arbiter v7 supports 2 buses. Each bus will get a different apid count, read 1383 + * from different registers. 1384 + */ 1385 + static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) 1386 + { 1387 + int ret = _pmic_arb_init_apid_v7(bus, index, 2, PMIC_ARB_FEATURES_PERIPH_MASK); 1418 1388 if (ret) 1419 1389 return ret; 1420 1390 ··· 1466 1418 return -EPERM; 1467 1419 } 1468 1420 offset = 0x1000 * apid; 1421 + break; 1422 + } 1423 + 1424 + return offset; 1425 + } 1426 + 1427 + static int pmic_arb_get_core_resources_v8(struct platform_device *pdev, 1428 + void __iomem *core) 1429 + { 1430 + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); 1431 + 1432 + pmic_arb->apid_map = devm_platform_ioremap_resource_byname(pdev, "chnl_map"); 1433 + if (IS_ERR(pmic_arb->apid_map)) 1434 + return PTR_ERR(pmic_arb->apid_map); 1435 + 1436 + pmic_arb->core = core; 1437 + 1438 + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V8; 1439 + 1440 + return pmic_arb_get_obsrvr_chnls_v2(pdev); 1441 + } 1442 + 1443 + static int pmic_arb_get_bus_resources_v8(struct platform_device *pdev, 1444 + struct device_node *node, 1445 + struct spmi_pmic_arb_bus *bus) 1446 + { 1447 + int index; 1448 + 1449 + index = of_property_match_string(node, "reg-names", "chnl_owner"); 1450 + if (index < 0) { 1451 + dev_err(&pdev->dev, "chnl_owner reg region missing\n"); 1452 + return -EINVAL; 1453 + } 1454 + 1455 + bus->apid_owner = devm_of_iomap(&pdev->dev, node, index, NULL); 1456 + 1457 + return PTR_ERR_OR_ZERO(bus->apid_owner); 1458 + } 1459 + 1460 + static int pmic_arb_read_apid_map_v8(struct spmi_pmic_arb_bus *bus) 1461 + { 1462 + return _pmic_arb_read_apid_map(bus, bus->pmic_arb->apid_map, 1463 + PMIC_ARB_V8_PPID_MASK, 0, 1464 + PMIC_ARB_V8_CHAN_IS_IRQ_OWNER_MASK); 1465 + } 1466 + 1467 + /* 1468 + * Arbiter v8 supports up to 4 buses. Each bus will get a different apid count, read 1469 + * from different registers. 1470 + */ 1471 + static int pmic_arb_init_apid_v8(struct spmi_pmic_arb_bus *bus, int index) 1472 + { 1473 + int ret = _pmic_arb_init_apid_v7(bus, index, 4, 1474 + PMIC_ARB_FEATURES_V8_PERIPH_MASK); 1475 + if (ret) 1476 + return ret; 1477 + 1478 + ret = pmic_arb_read_apid_map_v8(bus); 1479 + if (ret) { 1480 + dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", 1481 + ret); 1482 + return ret; 1483 + } 1484 + 1485 + return 0; 1486 + } 1487 + 1488 + /* 1489 + * v8 offset per ee and per apid for observer channels and per apid for 1490 + * read/write channels. 1491 + */ 1492 + static int pmic_arb_offset_v8(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, 1493 + enum pmic_arb_channel ch_type) 1494 + { 1495 + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1496 + u16 apid; 1497 + int rc; 1498 + u32 offset = 0; 1499 + u16 ppid = (sid << 8) | (addr >> 8); 1500 + 1501 + rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); 1502 + if (rc < 0) 1503 + return rc; 1504 + 1505 + apid = rc; 1506 + switch (ch_type) { 1507 + case PMIC_ARB_CHANNEL_OBS: 1508 + offset = 0x40000 * pmic_arb->ee + 0x20 * apid; 1509 + break; 1510 + case PMIC_ARB_CHANNEL_RW: 1511 + if (bus->apid_data[apid].write_ee != pmic_arb->ee) { 1512 + dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", 1513 + sid, addr); 1514 + return -EPERM; 1515 + } 1516 + offset = 0x200 * apid; 1469 1517 break; 1470 1518 } 1471 1519 ··· 1635 1491 } 1636 1492 1637 1493 static void __iomem * 1494 + pmic_arb_acc_enable_v8(struct spmi_pmic_arb_bus *bus, u16 n) 1495 + { 1496 + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1497 + 1498 + return pmic_arb->wr_base + 0x100 + 0x200 * n; 1499 + } 1500 + 1501 + static void __iomem * 1638 1502 pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n) 1639 1503 { 1640 1504 return bus->intr + 0x600 + 0x4 * n; ··· 1666 1514 { 1667 1515 struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1668 1516 return pmic_arb->wr_base + 0x104 + 0x1000 * n; 1517 + } 1518 + 1519 + static void __iomem * 1520 + pmic_arb_irq_status_v8(struct spmi_pmic_arb_bus *bus, u16 n) 1521 + { 1522 + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1523 + 1524 + return pmic_arb->wr_base + 0x104 + 0x200 * n; 1669 1525 } 1670 1526 1671 1527 static void __iomem * ··· 1702 1542 return pmic_arb->wr_base + 0x108 + 0x1000 * n; 1703 1543 } 1704 1544 1545 + static void __iomem * 1546 + pmic_arb_irq_clear_v8(struct spmi_pmic_arb_bus *bus, u16 n) 1547 + { 1548 + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; 1549 + 1550 + return pmic_arb->wr_base + 0x108 + 0x200 * n; 1551 + } 1552 + 1705 1553 static u32 pmic_arb_apid_map_offset_v2(u16 n) 1706 1554 { 1707 1555 return 0x800 + 0x4 * n; ··· 1725 1557 return 0x2000 + 0x4 * n; 1726 1558 } 1727 1559 1560 + static u32 pmic_arb_apid_map_offset_v8(u16 n) 1561 + { 1562 + /* For v8, offset is from "chnl_map" base register, not "core". */ 1563 + return 0x4 * n; 1564 + } 1565 + 1728 1566 static void __iomem * 1729 1567 pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n) 1730 1568 { ··· 1738 1564 } 1739 1565 1740 1566 /* 1741 - * For arbiter version 7, APID ownership table registers have independent 1567 + * For arbiter version 7 and 8, APID ownership table registers have independent 1742 1568 * numbering space for each SPMI bus instance, so each is indexed starting from 1743 1569 * 0. 1744 1570 */ ··· 1746 1572 pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n) 1747 1573 { 1748 1574 return bus->cnfg + 0x4 * (n - bus->base_apid); 1575 + } 1576 + 1577 + static void __iomem * 1578 + pmic_arb_apid_owner_v8(struct spmi_pmic_arb_bus *bus, u16 n) 1579 + { 1580 + return bus->apid_owner + 0x4 * (n - bus->base_apid); 1749 1581 } 1750 1582 1751 1583 static const struct pmic_arb_ver_ops pmic_arb_v1 = { ··· 1834 1654 .apid_owner = pmic_arb_apid_owner_v7, 1835 1655 }; 1836 1656 1657 + static const struct pmic_arb_ver_ops pmic_arb_v8 = { 1658 + .ver_str = "v8", 1659 + .get_core_resources = pmic_arb_get_core_resources_v8, 1660 + .get_bus_resources = pmic_arb_get_bus_resources_v8, 1661 + .init_apid = pmic_arb_init_apid_v8, 1662 + .ppid_to_apid = pmic_arb_ppid_to_apid_v5, 1663 + .non_data_cmd = pmic_arb_non_data_cmd_v2, 1664 + .offset = pmic_arb_offset_v8, 1665 + .fmt_cmd = pmic_arb_fmt_cmd_v2, 1666 + .owner_acc_status = pmic_arb_owner_acc_status_v7, 1667 + .acc_enable = pmic_arb_acc_enable_v8, 1668 + .irq_status = pmic_arb_irq_status_v8, 1669 + .irq_clear = pmic_arb_irq_clear_v8, 1670 + .apid_map_offset = pmic_arb_apid_map_offset_v8, 1671 + .apid_owner = pmic_arb_apid_owner_v8, 1672 + }; 1673 + 1837 1674 static const struct irq_domain_ops pmic_arb_irq_domain_ops = { 1838 1675 .activate = qpnpint_irq_domain_activate, 1839 1676 .alloc = qpnpint_irq_domain_alloc, ··· 1927 1730 bus->irq = irq; 1928 1731 bus->spmic = ctrl; 1929 1732 bus->id = bus_index; 1733 + 1734 + if (pmic_arb->ver_ops->get_bus_resources) { 1735 + ret = pmic_arb->ver_ops->get_bus_resources(pdev, node, bus); 1736 + if (ret) 1737 + return ret; 1738 + } 1930 1739 1931 1740 ret = pmic_arb->ver_ops->init_apid(bus, bus_index); 1932 1741 if (ret) ··· 2028 1825 pmic_arb->ver_ops = &pmic_arb_v3; 2029 1826 else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) 2030 1827 pmic_arb->ver_ops = &pmic_arb_v5; 2031 - else 1828 + else if (hw_ver < PMIC_ARB_VERSION_V8_MIN) 2032 1829 pmic_arb->ver_ops = &pmic_arb_v7; 1830 + else 1831 + pmic_arb->ver_ops = &pmic_arb_v8; 2033 1832 2034 1833 err = pmic_arb->ver_ops->get_core_resources(pdev, core); 2035 1834 if (err) ··· 2080 1875 static const struct of_device_id spmi_pmic_arb_match_table[] = { 2081 1876 { .compatible = "qcom,spmi-pmic-arb", }, 2082 1877 { .compatible = "qcom,x1e80100-spmi-pmic-arb", }, 1878 + { .compatible = "qcom,glymur-spmi-pmic-arb", }, 2083 1879 {}, 2084 1880 }; 2085 1881 MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);