Lines Matching +full:pmic +full:- +full:arbiter

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved.
20 /* PMIC Arbiter configuration registers */
33 /* PMIC Arbiter channel registers offsets */
50 #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */
89 * PMIC arbiter version 5 uses different register offsets for read/write vs
97 /* Maximum number of support PMIC peripherals */
129 * struct spmi_pmic_arb - SPMI PMIC Arbiter object
134 * @cnfg: address of the PMIC Arbiter configuration registers.
137 * @irq: PMIC ARB interrupt.
146 * @mapping_table: in-memory copy of PPID -> APID mapping table.
147 * @domain: irq domain object for PMIC IRQ domain
150 * @ppid_to_apid: in-memory copy of PPID -> APID mapping table.
183 * struct pmic_arb_ver_ops - version dependent functionality.
187 * @non_data_cmd: on v1 issues an spmi non-data command.
188 * on v2 no HW support, returns -EOPNOTSUPP.
189 * @offset: on v1 offset of per-ee channel.
190 * on v2 offset of per-ee and per-ppid channel.
224 writel_relaxed(val, pmic_arb->wr_base + offset); in pmic_arb_base_write()
230 writel_relaxed(val, pmic_arb->rd_base + offset); in pmic_arb_set_rd_cmd()
234 * pmic_arb_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
235 * @bc: byte count -1. range: 0..3
242 u32 data = __raw_readl(pmic_arb->rd_base + reg); in pmic_arb_read_data()
248 * pmic_arb_write_data: write 1..4 bytes from buf to pmic-arb's register
249 * @bc: byte-count -1. range: 0..3.
259 __raw_writel(data, pmic_arb->wr_base + reg); in pmic_arb_write_data()
272 rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type); in pmic_arb_wait_for_done()
279 while (timeout--) { in pmic_arb_wait_for_done()
284 dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n", in pmic_arb_wait_for_done()
286 return -EPERM; in pmic_arb_wait_for_done()
290 dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x)\n", in pmic_arb_wait_for_done()
293 return -EIO; in pmic_arb_wait_for_done()
297 dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n", in pmic_arb_wait_for_done()
299 return -EIO; in pmic_arb_wait_for_done()
307 dev_err(&ctrl->dev, "%s: %#x %#x: timeout, status %#x\n", in pmic_arb_wait_for_done()
309 return -ETIMEDOUT; in pmic_arb_wait_for_done()
321 rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW); in pmic_arb_non_data_cmd_v1()
328 raw_spin_lock_irqsave(&pmic_arb->lock, flags); in pmic_arb_non_data_cmd_v1()
330 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0, in pmic_arb_non_data_cmd_v1()
332 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); in pmic_arb_non_data_cmd_v1()
340 return -EOPNOTSUPP; in pmic_arb_non_data_cmd_v2()
343 /* Non-data command */
348 dev_dbg(&ctrl->dev, "cmd op:0x%x sid:%d\n", opc, sid); in pmic_arb_cmd()
350 /* Check for valid non-data command */ in pmic_arb_cmd()
352 return -EINVAL; in pmic_arb_cmd()
354 return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid); in pmic_arb_cmd()
360 u8 bc = len - 1; in pmic_arb_fmt_read_cmd()
363 rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, in pmic_arb_fmt_read_cmd()
370 dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested", in pmic_arb_fmt_read_cmd()
372 return -EINVAL; in pmic_arb_fmt_read_cmd()
383 return -EINVAL; in pmic_arb_fmt_read_cmd()
385 *cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc); in pmic_arb_fmt_read_cmd()
395 u8 bc = len - 1; in pmic_arb_read_cmd_unlocked()
399 rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr, in pmic_arb_read_cmd_unlocked()
409 bc - 4); in pmic_arb_read_cmd_unlocked()
426 raw_spin_lock_irqsave(&pmic_arb->lock, flags); in pmic_arb_read_cmd()
428 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); in pmic_arb_read_cmd()
437 u8 bc = len - 1; in pmic_arb_fmt_write_cmd()
440 rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, in pmic_arb_fmt_write_cmd()
447 dev_err(&pmic_arb->spmic->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested", in pmic_arb_fmt_write_cmd()
449 return -EINVAL; in pmic_arb_fmt_write_cmd()
462 return -EINVAL; in pmic_arb_fmt_write_cmd()
464 *cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc); in pmic_arb_fmt_write_cmd()
474 u8 bc = len - 1; in pmic_arb_write_cmd_unlocked()
481 bc - 4); in pmic_arb_write_cmd_unlocked()
485 return pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr, in pmic_arb_write_cmd_unlocked()
502 raw_spin_lock_irqsave(&pmic_arb->lock, flags); in pmic_arb_write_cmd()
505 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); in pmic_arb_write_cmd()
529 raw_spin_lock_irqsave(&pmic_arb->lock, flags); in pmic_arb_masked_write()
541 raw_spin_unlock_irqrestore(&pmic_arb->lock, flags); in pmic_arb_masked_write()
558 u8 type; /* 1 -> edge */
568 u8 sid = hwirq_to_sid(d->hwirq); in qpnpint_spmi_write()
569 u8 per = hwirq_to_per(d->hwirq); in qpnpint_spmi_write()
571 if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid, in qpnpint_spmi_write()
573 dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n", in qpnpint_spmi_write()
574 d->irq); in qpnpint_spmi_write()
580 u8 sid = hwirq_to_sid(d->hwirq); in qpnpint_spmi_read()
581 u8 per = hwirq_to_per(d->hwirq); in qpnpint_spmi_read()
583 if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid, in qpnpint_spmi_read()
585 dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n", in qpnpint_spmi_read()
586 d->irq); in qpnpint_spmi_read()
594 u8 sid = hwirq_to_sid(d->hwirq); in qpnpint_spmi_masked_write()
595 u8 per = hwirq_to_per(d->hwirq); in qpnpint_spmi_masked_write()
598 rc = pmic_arb_masked_write(pmic_arb->spmic, sid, (per << 8) + reg, buf, in qpnpint_spmi_masked_write()
601 dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x rc=%d\n", in qpnpint_spmi_masked_write()
602 d->irq, rc); in qpnpint_spmi_masked_write()
608 u16 ppid = pmic_arb->apid_data[apid].ppid; in cleanup_irq()
613 dev_err_ratelimited(&pmic_arb->spmic->dev, "%s apid=%d sid=0x%x per=0x%x irq=%d\n", in cleanup_irq()
615 writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid)); in cleanup_irq()
623 u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF; in periph_interrupt()
624 u8 per = pmic_arb->apid_data[apid].ppid & 0xFF; in periph_interrupt()
626 status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid)); in periph_interrupt()
628 id = ffs(status) - 1; in periph_interrupt()
630 irq = irq_find_mapping(pmic_arb->domain, in periph_interrupt()
646 const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops; in pmic_arb_chained_irq()
648 int first = pmic_arb->min_apid; in pmic_arb_chained_irq()
649 int last = pmic_arb->max_apid; in pmic_arb_chained_irq()
651 * acc_offset will be non-zero for the secondary SPMI bus instance on in pmic_arb_chained_irq()
654 int acc_offset = pmic_arb->base_apid >> 5; in pmic_arb_chained_irq()
655 u8 ee = pmic_arb->ee; in pmic_arb_chained_irq()
665 status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i - acc_offset)); in pmic_arb_chained_irq()
670 id = ffs(status) - 1; in pmic_arb_chained_irq()
679 ver_ops->acc_enable(pmic_arb, apid)); in pmic_arb_chained_irq()
690 if (pmic_arb->apid_data[i].irq_ee != pmic_arb->ee) in pmic_arb_chained_irq()
694 ver_ops->irq_status(pmic_arb, i)); in pmic_arb_chained_irq()
697 ver_ops->acc_enable(pmic_arb, i)); in pmic_arb_chained_irq()
699 dev_dbg(&pmic_arb->spmic->dev, in pmic_arb_chained_irq()
718 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_ack()
719 u16 apid = hwirq_to_apid(d->hwirq); in qpnpint_irq_ack()
722 writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid)); in qpnpint_irq_ack()
730 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_mask()
739 const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops; in qpnpint_irq_unmask()
740 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_unmask()
741 u16 apid = hwirq_to_apid(d->hwirq); in qpnpint_irq_unmask()
745 ver_ops->acc_enable(pmic_arb, apid)); in qpnpint_irq_unmask()
765 u8 irq_bit = BIT(hwirq_to_irq(d->hwirq)); in qpnpint_irq_set_type()
779 return -EINVAL; in qpnpint_irq_set_type()
804 return irq_set_irq_wake(pmic_arb->irq, on); in qpnpint_irq_set_wake()
811 u8 irq = hwirq_to_irq(d->hwirq); in qpnpint_get_irqchip_state()
815 return -EINVAL; in qpnpint_get_irqchip_state()
827 u16 periph = hwirq_to_per(d->hwirq); in qpnpint_irq_domain_activate()
828 u16 apid = hwirq_to_apid(d->hwirq); in qpnpint_irq_domain_activate()
829 u16 sid = hwirq_to_sid(d->hwirq); in qpnpint_irq_domain_activate()
830 u16 irq = hwirq_to_irq(d->hwirq); in qpnpint_irq_domain_activate()
833 if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) { in qpnpint_irq_domain_activate()
834 …dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner… in qpnpint_irq_domain_activate()
835 sid, periph, irq, pmic_arb->ee, in qpnpint_irq_domain_activate()
836 pmic_arb->apid_data[apid].irq_ee); in qpnpint_irq_domain_activate()
837 return -ENODEV; in qpnpint_irq_domain_activate()
863 struct spmi_pmic_arb *pmic_arb = d->host_data; in qpnpint_irq_domain_translate()
864 u32 *intspec = fwspec->param; in qpnpint_irq_domain_translate()
868 dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n", in qpnpint_irq_domain_translate()
871 if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node) in qpnpint_irq_domain_translate()
872 return -EINVAL; in qpnpint_irq_domain_translate()
873 if (fwspec->param_count != 4) in qpnpint_irq_domain_translate()
874 return -EINVAL; in qpnpint_irq_domain_translate()
876 return -EINVAL; in qpnpint_irq_domain_translate()
879 rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid); in qpnpint_irq_domain_translate()
881 dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n", in qpnpint_irq_domain_translate()
888 if (apid > pmic_arb->max_apid) in qpnpint_irq_domain_translate()
889 pmic_arb->max_apid = apid; in qpnpint_irq_domain_translate()
890 if (apid < pmic_arb->min_apid) in qpnpint_irq_domain_translate()
891 pmic_arb->min_apid = apid; in qpnpint_irq_domain_translate()
896 dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq); in qpnpint_irq_domain_translate()
909 dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n", in qpnpint_irq_domain_map()
928 struct spmi_pmic_arb *pmic_arb = domain->host_data; in qpnpint_irq_domain_alloc()
947 u32 *mapping_table = pmic_arb->mapping_table; in pmic_arb_ppid_to_apid_v1()
953 apid_valid = pmic_arb->ppid_to_apid[ppid]; in pmic_arb_ppid_to_apid_v1()
960 if (!test_and_set_bit(index, pmic_arb->mapping_table_valid)) in pmic_arb_ppid_to_apid_v1()
961 mapping_table[index] = readl_relaxed(pmic_arb->cnfg + in pmic_arb_ppid_to_apid_v1()
971 pmic_arb->ppid_to_apid[ppid] in pmic_arb_ppid_to_apid_v1()
973 pmic_arb->apid_data[apid].ppid = ppid; in pmic_arb_ppid_to_apid_v1()
981 pmic_arb->ppid_to_apid[ppid] in pmic_arb_ppid_to_apid_v1()
983 pmic_arb->apid_data[apid].ppid = ppid; in pmic_arb_ppid_to_apid_v1()
989 return -ENODEV; in pmic_arb_ppid_to_apid_v1()
996 return 0x800 + 0x80 * pmic_arb->channel; in pmic_arb_offset_v1()
1001 struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid]; in pmic_arb_find_apid()
1005 for (apid = pmic_arb->last_apid; ; apid++, apidd++) { in pmic_arb_find_apid()
1006 offset = pmic_arb->ver_ops->apid_map_offset(apid); in pmic_arb_find_apid()
1007 if (offset >= pmic_arb->core_size) in pmic_arb_find_apid()
1010 regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb, in pmic_arb_find_apid()
1012 apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); in pmic_arb_find_apid()
1013 apidd->write_ee = apidd->irq_ee; in pmic_arb_find_apid()
1015 regval = readl_relaxed(pmic_arb->core + offset); in pmic_arb_find_apid()
1020 pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID; in pmic_arb_find_apid()
1021 apidd->ppid = id; in pmic_arb_find_apid()
1027 pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID; in pmic_arb_find_apid()
1036 apid_valid = pmic_arb->ppid_to_apid[ppid]; in pmic_arb_ppid_to_apid_v2()
1040 return -ENODEV; in pmic_arb_ppid_to_apid_v2()
1054 * In order to allow multiple EEs to write to a single PPID in arbiter in pmic_arb_read_apid_map_v5()
1061 * In arbiter version 7, the APID numbering space is divided between in pmic_arb_read_apid_map_v5()
1063 * APID = 0 to N-1 are assigned to the primary bus in pmic_arb_read_apid_map_v5()
1064 * APID = N to N+M-1 are assigned to the secondary bus in pmic_arb_read_apid_map_v5()
1068 apidd = &pmic_arb->apid_data[pmic_arb->base_apid]; in pmic_arb_read_apid_map_v5()
1069 apid_max = pmic_arb->base_apid + pmic_arb->apid_count; in pmic_arb_read_apid_map_v5()
1070 for (i = pmic_arb->base_apid; i < apid_max; i++, apidd++) { in pmic_arb_read_apid_map_v5()
1071 offset = pmic_arb->ver_ops->apid_map_offset(i); in pmic_arb_read_apid_map_v5()
1072 if (offset >= pmic_arb->core_size) in pmic_arb_read_apid_map_v5()
1075 regval = readl_relaxed(pmic_arb->core + offset); in pmic_arb_read_apid_map_v5()
1081 regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(pmic_arb, in pmic_arb_read_apid_map_v5()
1083 apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); in pmic_arb_read_apid_map_v5()
1085 apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE; in pmic_arb_read_apid_map_v5()
1087 valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID; in pmic_arb_read_apid_map_v5()
1088 apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; in pmic_arb_read_apid_map_v5()
1089 prev_apidd = &pmic_arb->apid_data[apid]; in pmic_arb_read_apid_map_v5()
1091 if (!valid || apidd->write_ee == pmic_arb->ee) { in pmic_arb_read_apid_map_v5()
1093 pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; in pmic_arb_read_apid_map_v5()
1095 prev_apidd->write_ee == pmic_arb->ee) { in pmic_arb_read_apid_map_v5()
1100 prev_apidd->irq_ee = apidd->irq_ee; in pmic_arb_read_apid_map_v5()
1103 apidd->ppid = ppid; in pmic_arb_read_apid_map_v5()
1104 pmic_arb->last_apid = i; in pmic_arb_read_apid_map_v5()
1108 dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n"); in pmic_arb_read_apid_map_v5()
1110 apid = pmic_arb->ppid_to_apid[ppid]; in pmic_arb_read_apid_map_v5()
1113 apidd = &pmic_arb->apid_data[apid]; in pmic_arb_read_apid_map_v5()
1114 dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n", in pmic_arb_read_apid_map_v5()
1115 ppid, apid, apidd->write_ee, apidd->irq_ee); in pmic_arb_read_apid_map_v5()
1124 if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID)) in pmic_arb_ppid_to_apid_v5()
1125 return -ENODEV; in pmic_arb_ppid_to_apid_v5()
1127 return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; in pmic_arb_ppid_to_apid_v5()
1144 return 0x1000 * pmic_arb->ee + 0x8000 * apid; in pmic_arb_offset_v2()
1166 offset = 0x10000 * pmic_arb->ee + 0x80 * apid; in pmic_arb_offset_v5()
1169 if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) { in pmic_arb_offset_v5()
1170 dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", in pmic_arb_offset_v5()
1172 return -EPERM; in pmic_arb_offset_v5()
1193 rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid); in pmic_arb_offset_v7()
1200 offset = 0x8000 * pmic_arb->ee + 0x20 * apid; in pmic_arb_offset_v7()
1203 if (pmic_arb->apid_data[apid].write_ee != pmic_arb->ee) { in pmic_arb_offset_v7()
1204 dev_err(&pmic_arb->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", in pmic_arb_offset_v7()
1206 return -EPERM; in pmic_arb_offset_v7()
1228 return pmic_arb->intr + 0x20 * m + 0x4 * n; in pmic_arb_owner_acc_status_v1()
1234 return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v2()
1240 return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v3()
1246 return pmic_arb->intr + 0x10000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v5()
1252 return pmic_arb->intr + 0x1000 * m + 0x4 * n; in pmic_arb_owner_acc_status_v7()
1258 return pmic_arb->intr + 0x200 + 0x4 * n; in pmic_arb_acc_enable_v1()
1264 return pmic_arb->intr + 0x1000 * n; in pmic_arb_acc_enable_v2()
1270 return pmic_arb->wr_base + 0x100 + 0x10000 * n; in pmic_arb_acc_enable_v5()
1276 return pmic_arb->wr_base + 0x100 + 0x1000 * n; in pmic_arb_acc_enable_v7()
1282 return pmic_arb->intr + 0x600 + 0x4 * n; in pmic_arb_irq_status_v1()
1288 return pmic_arb->intr + 0x4 + 0x1000 * n; in pmic_arb_irq_status_v2()
1294 return pmic_arb->wr_base + 0x104 + 0x10000 * n; in pmic_arb_irq_status_v5()
1300 return pmic_arb->wr_base + 0x104 + 0x1000 * n; in pmic_arb_irq_status_v7()
1306 return pmic_arb->intr + 0xA00 + 0x4 * n; in pmic_arb_irq_clear_v1()
1312 return pmic_arb->intr + 0x8 + 0x1000 * n; in pmic_arb_irq_clear_v2()
1318 return pmic_arb->wr_base + 0x108 + 0x10000 * n; in pmic_arb_irq_clear_v5()
1324 return pmic_arb->wr_base + 0x108 + 0x1000 * n; in pmic_arb_irq_clear_v7()
1345 return pmic_arb->cnfg + 0x700 + 0x4 * n; in pmic_arb_apid_owner_v2()
1349 * For arbiter version 7, APID ownership table registers have independent
1356 return pmic_arb->cnfg + 0x4 * (n - pmic_arb->base_apid); in pmic_arb_apid_owner_v7()
1446 ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb)); in spmi_pmic_arb_probe()
1451 pmic_arb->spmic = ctrl; in spmi_pmic_arb_probe()
1457 * register address range. SoCs with PMIC arbiter v7 may define two in spmi_pmic_arb_probe()
1458 * arbiter devices, for the two physical SPMI interfaces, which share in spmi_pmic_arb_probe()
1464 core = devm_ioremap(&ctrl->dev, res->start, resource_size(res)); in spmi_pmic_arb_probe()
1468 pmic_arb->core_size = resource_size(res); in spmi_pmic_arb_probe()
1470 pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID, in spmi_pmic_arb_probe()
1471 sizeof(*pmic_arb->ppid_to_apid), in spmi_pmic_arb_probe()
1473 if (!pmic_arb->ppid_to_apid) in spmi_pmic_arb_probe()
1474 return -ENOMEM; in spmi_pmic_arb_probe()
1479 pmic_arb->ver_ops = &pmic_arb_v1; in spmi_pmic_arb_probe()
1480 pmic_arb->wr_base = core; in spmi_pmic_arb_probe()
1481 pmic_arb->rd_base = core; in spmi_pmic_arb_probe()
1483 pmic_arb->core = core; in spmi_pmic_arb_probe()
1486 pmic_arb->ver_ops = &pmic_arb_v2; in spmi_pmic_arb_probe()
1488 pmic_arb->ver_ops = &pmic_arb_v3; in spmi_pmic_arb_probe()
1490 pmic_arb->ver_ops = &pmic_arb_v5; in spmi_pmic_arb_probe()
1492 pmic_arb->ver_ops = &pmic_arb_v7; in spmi_pmic_arb_probe()
1496 pmic_arb->rd_base = devm_ioremap(&ctrl->dev, res->start, in spmi_pmic_arb_probe()
1498 if (IS_ERR(pmic_arb->rd_base)) in spmi_pmic_arb_probe()
1499 return PTR_ERR(pmic_arb->rd_base); in spmi_pmic_arb_probe()
1503 pmic_arb->wr_base = devm_ioremap(&ctrl->dev, res->start, in spmi_pmic_arb_probe()
1505 if (IS_ERR(pmic_arb->wr_base)) in spmi_pmic_arb_probe()
1506 return PTR_ERR(pmic_arb->wr_base); in spmi_pmic_arb_probe()
1509 pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS; in spmi_pmic_arb_probe()
1512 pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V7; in spmi_pmic_arb_probe()
1514 of_property_read_u32(pdev->dev.of_node, "qcom,bus-id", in spmi_pmic_arb_probe()
1515 &pmic_arb->bus_instance); in spmi_pmic_arb_probe()
1516 if (pmic_arb->bus_instance > 1) { in spmi_pmic_arb_probe()
1517 dev_err(&pdev->dev, "invalid bus instance (%u) specified\n", in spmi_pmic_arb_probe()
1518 pmic_arb->bus_instance); in spmi_pmic_arb_probe()
1519 return -EINVAL; in spmi_pmic_arb_probe()
1522 if (pmic_arb->bus_instance == 0) { in spmi_pmic_arb_probe()
1523 pmic_arb->base_apid = 0; in spmi_pmic_arb_probe()
1524 pmic_arb->apid_count = in spmi_pmic_arb_probe()
1528 pmic_arb->base_apid = in spmi_pmic_arb_probe()
1531 pmic_arb->apid_count = in spmi_pmic_arb_probe()
1536 if (pmic_arb->base_apid + pmic_arb->apid_count > pmic_arb->max_periphs) { in spmi_pmic_arb_probe()
1537 dev_err(&pdev->dev, "Unsupported APID count %d detected\n", in spmi_pmic_arb_probe()
1538 pmic_arb->base_apid + pmic_arb->apid_count); in spmi_pmic_arb_probe()
1539 return -EINVAL; in spmi_pmic_arb_probe()
1542 pmic_arb->base_apid = 0; in spmi_pmic_arb_probe()
1543 pmic_arb->apid_count = readl_relaxed(core + PMIC_ARB_FEATURES) & in spmi_pmic_arb_probe()
1546 if (pmic_arb->apid_count > pmic_arb->max_periphs) { in spmi_pmic_arb_probe()
1547 dev_err(&pdev->dev, "Unsupported APID count %d detected\n", in spmi_pmic_arb_probe()
1548 pmic_arb->apid_count); in spmi_pmic_arb_probe()
1549 return -EINVAL; in spmi_pmic_arb_probe()
1553 pmic_arb->apid_data = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs, in spmi_pmic_arb_probe()
1554 sizeof(*pmic_arb->apid_data), in spmi_pmic_arb_probe()
1556 if (!pmic_arb->apid_data) in spmi_pmic_arb_probe()
1557 return -ENOMEM; in spmi_pmic_arb_probe()
1559 dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n", in spmi_pmic_arb_probe()
1560 pmic_arb->ver_ops->ver_str, hw_ver); in spmi_pmic_arb_probe()
1563 pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res); in spmi_pmic_arb_probe()
1564 if (IS_ERR(pmic_arb->intr)) in spmi_pmic_arb_probe()
1565 return PTR_ERR(pmic_arb->intr); in spmi_pmic_arb_probe()
1568 pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res); in spmi_pmic_arb_probe()
1569 if (IS_ERR(pmic_arb->cnfg)) in spmi_pmic_arb_probe()
1570 return PTR_ERR(pmic_arb->cnfg); in spmi_pmic_arb_probe()
1572 pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq"); in spmi_pmic_arb_probe()
1573 if (pmic_arb->irq < 0) in spmi_pmic_arb_probe()
1574 return pmic_arb->irq; in spmi_pmic_arb_probe()
1576 err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel); in spmi_pmic_arb_probe()
1578 dev_err(&pdev->dev, "channel unspecified.\n"); in spmi_pmic_arb_probe()
1583 dev_err(&pdev->dev, "invalid channel (%u) specified.\n", in spmi_pmic_arb_probe()
1585 return -EINVAL; in spmi_pmic_arb_probe()
1588 pmic_arb->channel = channel; in spmi_pmic_arb_probe()
1590 err = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &ee); in spmi_pmic_arb_probe()
1592 dev_err(&pdev->dev, "EE unspecified.\n"); in spmi_pmic_arb_probe()
1597 dev_err(&pdev->dev, "invalid EE (%u) specified\n", ee); in spmi_pmic_arb_probe()
1598 return -EINVAL; in spmi_pmic_arb_probe()
1601 pmic_arb->ee = ee; in spmi_pmic_arb_probe()
1602 mapping_table = devm_kcalloc(&ctrl->dev, pmic_arb->max_periphs, in spmi_pmic_arb_probe()
1605 return -ENOMEM; in spmi_pmic_arb_probe()
1607 pmic_arb->mapping_table = mapping_table; in spmi_pmic_arb_probe()
1610 pmic_arb->max_apid = 0; in spmi_pmic_arb_probe()
1611 pmic_arb->min_apid = pmic_arb->max_periphs - 1; in spmi_pmic_arb_probe()
1614 raw_spin_lock_init(&pmic_arb->lock); in spmi_pmic_arb_probe()
1616 ctrl->cmd = pmic_arb_cmd; in spmi_pmic_arb_probe()
1617 ctrl->read_cmd = pmic_arb_read_cmd; in spmi_pmic_arb_probe()
1618 ctrl->write_cmd = pmic_arb_write_cmd; in spmi_pmic_arb_probe()
1623 dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n", in spmi_pmic_arb_probe()
1629 dev_dbg(&pdev->dev, "adding irq domain\n"); in spmi_pmic_arb_probe()
1630 pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node, in spmi_pmic_arb_probe()
1632 if (!pmic_arb->domain) { in spmi_pmic_arb_probe()
1633 dev_err(&pdev->dev, "unable to create irq_domain\n"); in spmi_pmic_arb_probe()
1634 return -ENOMEM; in spmi_pmic_arb_probe()
1637 irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq, in spmi_pmic_arb_probe()
1646 irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); in spmi_pmic_arb_probe()
1647 irq_domain_remove(pmic_arb->domain); in spmi_pmic_arb_probe()
1656 irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL); in spmi_pmic_arb_remove()
1657 irq_domain_remove(pmic_arb->domain); in spmi_pmic_arb_remove()
1661 { .compatible = "qcom,spmi-pmic-arb", },