^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/irqchip/chained_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* PMIC Arbiter configuration registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PMIC_ARB_VERSION 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define PMIC_ARB_VERSION_V2_MIN 0x20010000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define PMIC_ARB_VERSION_V3_MIN 0x30000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PMIC_ARB_VERSION_V5_MIN 0x50000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define PMIC_ARB_INT_EN 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* PMIC Arbiter channel registers offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PMIC_ARB_CMD 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PMIC_ARB_CONFIG 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PMIC_ARB_STATUS 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PMIC_ARB_WDATA0 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PMIC_ARB_WDATA1 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PMIC_ARB_RDATA0 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PMIC_ARB_RDATA1 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Mapping Table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SPMI_MAPPING_TABLE_REG(N) (0x0B00 + (4 * (N)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SPMI_MAPPING_BIT_INDEX(X) (((X) >> 18) & 0xF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SPMI_MAPPING_BIT_IS_0_FLAG(X) (((X) >> 17) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SPMI_MAPPING_BIT_IS_0_RESULT(X) (((X) >> 9) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SPMI_MAPPING_BIT_IS_1_FLAG(X) (((X) >> 8) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SPMI_MAPPING_BIT_IS_1_RESULT(X) (((X) >> 0) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PMIC_ARB_APID_VALID BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define INVALID_EE 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Ownership Table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SPMI_OWNERSHIP_TABLE_REG(N) (0x0700 + (4 * (N)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SPMI_OWNERSHIP_PERIPH2OWNER(X) ((X) & 0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Channel Status fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) enum pmic_arb_chnl_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) PMIC_ARB_STATUS_DONE = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) PMIC_ARB_STATUS_FAILURE = BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) PMIC_ARB_STATUS_DENIED = BIT(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) PMIC_ARB_STATUS_DROPPED = BIT(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Command register fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PMIC_ARB_CMD_MAX_BYTE_COUNT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Command Opcodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum pmic_arb_cmd_op_code {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) PMIC_ARB_OP_EXT_WRITEL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) PMIC_ARB_OP_EXT_READL = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) PMIC_ARB_OP_EXT_WRITE = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) PMIC_ARB_OP_RESET = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) PMIC_ARB_OP_SLEEP = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) PMIC_ARB_OP_SHUTDOWN = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) PMIC_ARB_OP_WAKEUP = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) PMIC_ARB_OP_AUTHENTICATE = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) PMIC_ARB_OP_MSTR_READ = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) PMIC_ARB_OP_MSTR_WRITE = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) PMIC_ARB_OP_EXT_READ = 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) PMIC_ARB_OP_WRITE = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) PMIC_ARB_OP_READ = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) PMIC_ARB_OP_ZERO_WRITE = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * PMIC arbiter version 5 uses different register offsets for read/write vs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * observer channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) enum pmic_arb_channel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) PMIC_ARB_CHANNEL_RW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) PMIC_ARB_CHANNEL_OBS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Maximum number of support PMIC peripherals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define PMIC_ARB_MAX_PERIPHS 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define PMIC_ARB_TIMEOUT_US 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define PMIC_ARB_MAX_TRANS_BYTES (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define PMIC_ARB_APID_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define PMIC_ARB_PPID_MASK 0xFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* interrupt enable bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define SPMI_PIC_ACC_ENABLE_BIT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ((((slave_id) & 0xF) << 28) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) (((periph_id) & 0xFF) << 20) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) (((irq_id) & 0x7) << 16) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) (((apid) & 0x1FF) << 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define hwirq_to_sid(hwirq) (((hwirq) >> 28) & 0xF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define hwirq_to_per(hwirq) (((hwirq) >> 20) & 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define hwirq_to_irq(hwirq) (((hwirq) >> 16) & 0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x1FF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct pmic_arb_ver_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct apid_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u16 ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 write_ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 irq_ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * spmi_pmic_arb - SPMI PMIC Arbiter object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @rd_base: on v1 "core", on v2 "observer" register base off DT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @wr_base: on v1 "core", on v2 "chnls" register base off DT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @intr: address of the SPMI interrupt control registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @cnfg: address of the PMIC Arbiter configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @lock: lock to synchronize accesses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @channel: execution environment channel to use for accesses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @irq: PMIC ARB interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @ee: the current Execution Environment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @min_apid: minimum APID (used for bounding IRQ search)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @max_apid: maximum APID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * @mapping_table: in-memory copy of PPID -> APID mapping table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * @domain: irq domain object for PMIC IRQ domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * @spmic: SPMI controller object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * @ver_ops: version dependent operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * @ppid_to_apid in-memory copy of PPID -> APID mapping table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct spmi_pmic_arb {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) void __iomem *rd_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) void __iomem *wr_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) void __iomem *intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) void __iomem *cnfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) void __iomem *core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) resource_size_t core_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) raw_spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u8 ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) u16 min_apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u16 max_apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u32 *mapping_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) DECLARE_BITMAP(mapping_table_valid, PMIC_ARB_MAX_PERIPHS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct irq_domain *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct spmi_controller *spmic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) const struct pmic_arb_ver_ops *ver_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u16 *ppid_to_apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u16 last_apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct apid_data apid_data[PMIC_ARB_MAX_PERIPHS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * pmic_arb_ver: version dependent functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * @ver_str: version string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @ppid_to_apid: finds the apid for a given ppid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * @non_data_cmd: on v1 issues an spmi non-data command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * on v2 no HW support, returns -EOPNOTSUPP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @offset: on v1 offset of per-ee channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * on v2 offset of per-ee and per-ppid channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @fmt_cmd: formats a GENI/SPMI command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @owner_acc_status: on v1 address of PMIC_ARB_SPMI_PIC_OWNERm_ACC_STATUSn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * on v2 address of SPMI_PIC_OWNERm_ACC_STATUSn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @acc_enable: on v1 address of PMIC_ARB_SPMI_PIC_ACC_ENABLEn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * on v2 address of SPMI_PIC_ACC_ENABLEn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * @irq_status: on v1 address of PMIC_ARB_SPMI_PIC_IRQ_STATUSn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * on v2 address of SPMI_PIC_IRQ_STATUSn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * @irq_clear: on v1 address of PMIC_ARB_SPMI_PIC_IRQ_CLEARn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * on v2 address of SPMI_PIC_IRQ_CLEARn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * @apid_map_offset: offset of PMIC_ARB_REG_CHNLn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct pmic_arb_ver_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) const char *ver_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* spmi commands (read_cmd, write_cmd, cmd) functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) enum pmic_arb_channel ch_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /* Interrupts controller functionality (offset of PIC registers) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u16 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u32 (*apid_map_offset)(u16 n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) writel_relaxed(val, pmic_arb->wr_base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static inline void pmic_arb_set_rd_cmd(struct spmi_pmic_arb *pmic_arb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) writel_relaxed(val, pmic_arb->rd_base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * pmic_arb_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @bc: byte count -1. range: 0..3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * @reg: register's address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @buf: output parameter, length must be bc + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pmic_arb_read_data(struct spmi_pmic_arb *pmic_arb, u8 *buf, u32 reg, u8 bc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u32 data = __raw_readl(pmic_arb->rd_base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) memcpy(buf, &data, (bc & 3) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * pmic_arb_write_data: write 1..4 bytes from buf to pmic-arb's register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @bc: byte-count -1. range: 0..3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @reg: register's address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @buf: buffer to write. length must be bc + 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void pmic_arb_write_data(struct spmi_pmic_arb *pmic_arb, const u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u32 reg, u8 bc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u32 data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) memcpy(&data, buf, (bc & 3) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) __raw_writel(data, pmic_arb->wr_base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) void __iomem *base, u8 sid, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) enum pmic_arb_channel ch_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u32 status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) u32 timeout = PMIC_ARB_TIMEOUT_US;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) offset = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) offset += PMIC_ARB_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) while (timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) status = readl_relaxed(base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (status & PMIC_ARB_STATUS_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (status & PMIC_ARB_STATUS_DENIED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_err(&ctrl->dev, "%s: transaction denied (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (status & PMIC_ARB_STATUS_FAILURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dev_err(&ctrl->dev, "%s: transaction failed (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (status & PMIC_ARB_STATUS_DROPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev_err(&ctrl->dev, "%s: transaction dropped (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dev_err(&ctrl->dev, "%s: timeout, status 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pmic_arb_non_data_cmd_v1(struct spmi_controller *ctrl, u8 opc, u8 sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) offset = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) raw_spin_lock_irqsave(&pmic_arb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) PMIC_ARB_CHANNEL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pmic_arb_non_data_cmd_v2(struct spmi_controller *ctrl, u8 opc, u8 sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Non-data command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dev_dbg(&ctrl->dev, "cmd op:0x%x sid:%d\n", opc, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* Check for valid non-data command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return pmic_arb->ver_ops->non_data_cmd(ctrl, opc, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u16 addr, u8 *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u8 bc = len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) PMIC_ARB_CHANNEL_OBS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) offset = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dev_err(&ctrl->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) PMIC_ARB_MAX_TRANS_BYTES, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* Check the opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (opc >= 0x60 && opc <= 0x7F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) opc = PMIC_ARB_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else if (opc >= 0x20 && opc <= 0x2F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) opc = PMIC_ARB_OP_EXT_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) else if (opc >= 0x38 && opc <= 0x3F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) opc = PMIC_ARB_OP_EXT_READL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) raw_spin_lock_irqsave(&pmic_arb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pmic_arb_set_rd_cmd(pmic_arb, offset + PMIC_ARB_CMD, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) PMIC_ARB_CHANNEL_OBS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pmic_arb_read_data(pmic_arb, buf, offset + PMIC_ARB_RDATA0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) min_t(u8, bc, 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (bc > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) pmic_arb_read_data(pmic_arb, buf + 4, offset + PMIC_ARB_RDATA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) bc - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) u16 addr, const u8 *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) u8 bc = len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u32 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) PMIC_ARB_CHANNEL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) offset = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) dev_err(&ctrl->dev, "pmic-arb supports 1..%d bytes per trans, but:%zu requested",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) PMIC_ARB_MAX_TRANS_BYTES, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Check the opcode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (opc >= 0x40 && opc <= 0x5F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) opc = PMIC_ARB_OP_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) else if (opc <= 0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) opc = PMIC_ARB_OP_EXT_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) else if (opc >= 0x30 && opc <= 0x37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) opc = PMIC_ARB_OP_EXT_WRITEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) else if (opc >= 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) opc = PMIC_ARB_OP_ZERO_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) cmd = pmic_arb->ver_ops->fmt_cmd(opc, sid, addr, bc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Write data to FIFOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) raw_spin_lock_irqsave(&pmic_arb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pmic_arb_write_data(pmic_arb, buf, offset + PMIC_ARB_WDATA0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) min_t(u8, bc, 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (bc > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pmic_arb_write_data(pmic_arb, buf + 4, offset + PMIC_ARB_WDATA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) bc - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Start the transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) PMIC_ARB_CHANNEL_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) enum qpnpint_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) QPNPINT_REG_RT_STS = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) QPNPINT_REG_SET_TYPE = 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) QPNPINT_REG_POLARITY_HIGH = 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) QPNPINT_REG_POLARITY_LOW = 0x13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) QPNPINT_REG_LATCHED_CLR = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) QPNPINT_REG_EN_SET = 0x15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) QPNPINT_REG_EN_CLR = 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) QPNPINT_REG_LATCHED_STS = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct spmi_pmic_arb_qpnpint_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u8 type; /* 1 -> edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u8 polarity_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u8 polarity_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Simplified accessor functions for irqchip callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static void qpnpint_spmi_write(struct irq_data *d, u8 reg, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) u8 sid = hwirq_to_sid(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u8 per = hwirq_to_per(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) (per << 8) + reg, buf, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void qpnpint_spmi_read(struct irq_data *d, u8 reg, void *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u8 sid = hwirq_to_sid(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) u8 per = hwirq_to_per(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (pmic_arb_read_cmd(pmic_arb->spmic, SPMI_CMD_EXT_READL, sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) (per << 8) + reg, buf, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dev_err_ratelimited(&pmic_arb->spmic->dev, "failed irqchip transaction on %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) d->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u16 ppid = pmic_arb->apid_data[apid].ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u8 sid = ppid >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u8 per = ppid & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u8 irq_mask = BIT(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) writel_relaxed(irq_mask, pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) (per << 8) + QPNPINT_REG_LATCHED_CLR, &irq_mask, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dev_err_ratelimited(&pmic_arb->spmic->dev, "failed to ack irq_mask = 0x%x for ppid = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) irq_mask, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) (per << 8) + QPNPINT_REG_EN_CLR, &irq_mask, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) dev_err_ratelimited(&pmic_arb->spmic->dev, "failed to ack irq_mask = 0x%x for ppid = %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) irq_mask, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) u32 status, id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) u8 per = pmic_arb->apid_data[apid].ppid & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) status = readl_relaxed(pmic_arb->ver_ops->irq_status(pmic_arb, apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) while (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) id = ffs(status) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) status &= ~BIT(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) irq = irq_find_mapping(pmic_arb->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) spec_to_hwirq(sid, per, id, apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (irq == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cleanup_irq(pmic_arb, apid, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void pmic_arb_chained_irq(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct irq_chip *chip = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int first = pmic_arb->min_apid >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int last = pmic_arb->max_apid >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) u8 ee = pmic_arb->ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u32 status, enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int i, id, apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) chained_irq_enter(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) for (i = first; i <= last; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) status = readl_relaxed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ver_ops->owner_acc_status(pmic_arb, ee, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) while (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) id = ffs(status) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) status &= ~BIT(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) apid = id + i * 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) enable = readl_relaxed(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ver_ops->acc_enable(pmic_arb, apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (enable & SPMI_PIC_ACC_ENABLE_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) periph_interrupt(pmic_arb, apid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) chained_irq_exit(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static void qpnpint_irq_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u8 irq = hwirq_to_irq(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) u16 apid = hwirq_to_apid(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) writel_relaxed(BIT(irq), pmic_arb->ver_ops->irq_clear(pmic_arb, apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) data = BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static void qpnpint_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u8 irq = hwirq_to_irq(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u8 data = BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) qpnpint_spmi_write(d, QPNPINT_REG_EN_CLR, &data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static void qpnpint_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) u8 irq = hwirq_to_irq(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) u16 apid = hwirq_to_apid(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ver_ops->acc_enable(pmic_arb, apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (!(buf[0] & BIT(irq))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * Since the interrupt is currently disabled, write to both the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * LATCHED_CLR and EN_SET registers so that a spurious interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * cannot be triggered when the interrupt is enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) buf[0] = BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) buf[1] = BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int qpnpint_irq_set_type(struct irq_data *d, unsigned int flow_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct spmi_pmic_arb_qpnpint_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) irq_flow_handler_t flow_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) u8 irq = hwirq_to_irq(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) qpnpint_spmi_read(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) type.type |= BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (flow_type & IRQF_TRIGGER_RISING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) type.polarity_high |= BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (flow_type & IRQF_TRIGGER_FALLING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) type.polarity_low |= BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) flow_handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if ((flow_type & (IRQF_TRIGGER_HIGH)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) (flow_type & (IRQF_TRIGGER_LOW)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) type.type &= ~BIT(irq); /* level trig */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (flow_type & IRQF_TRIGGER_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) type.polarity_high |= BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) type.polarity_low |= BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) flow_handler = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) qpnpint_spmi_write(d, QPNPINT_REG_SET_TYPE, &type, sizeof(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) irq_set_handler_locked(d, flow_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static int qpnpint_irq_set_wake(struct irq_data *d, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return irq_set_irq_wake(pmic_arb->irq, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static int qpnpint_get_irqchip_state(struct irq_data *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) enum irqchip_irq_state which,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) bool *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u8 irq = hwirq_to_irq(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) u8 status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (which != IRQCHIP_STATE_LINE_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) qpnpint_spmi_read(d, QPNPINT_REG_RT_STS, &status, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) *state = !!(status & BIT(irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static int qpnpint_irq_domain_activate(struct irq_domain *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct irq_data *d, bool reserve)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) u16 periph = hwirq_to_per(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u16 apid = hwirq_to_apid(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u16 sid = hwirq_to_sid(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u16 irq = hwirq_to_irq(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) sid, periph, irq, pmic_arb->ee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) pmic_arb->apid_data[apid].irq_ee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static struct irq_chip pmic_arb_irqchip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .name = "pmic_arb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .irq_ack = qpnpint_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .irq_mask = qpnpint_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .irq_unmask = qpnpint_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) .irq_set_type = qpnpint_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) .irq_set_wake = qpnpint_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .irq_get_irqchip_state = qpnpint_get_irqchip_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) .flags = IRQCHIP_MASK_ON_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static int qpnpint_irq_domain_translate(struct irq_domain *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct irq_fwspec *fwspec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) unsigned long *out_hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) unsigned int *out_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct spmi_pmic_arb *pmic_arb = d->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) u32 *intspec = fwspec->param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u16 apid, ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) dev_dbg(&pmic_arb->spmic->dev, "intspec[0] 0x%1x intspec[1] 0x%02x intspec[2] 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) intspec[0], intspec[1], intspec[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (irq_domain_get_of_node(d) != pmic_arb->spmic->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (fwspec->param_count != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ppid = intspec[0] << 8 | intspec[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) intspec[0], intspec[1], intspec[2], rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) apid = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Keep track of {max,min}_apid for bounding search during interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (apid > pmic_arb->max_apid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) pmic_arb->max_apid = apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (apid < pmic_arb->min_apid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) pmic_arb->min_apid = apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) *out_hwirq = spec_to_hwirq(intspec[0], intspec[1], intspec[2], apid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) *out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) dev_dbg(&pmic_arb->spmic->dev, "out_hwirq = %lu\n", *out_hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct irq_domain *domain, unsigned int virq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) irq_hw_number_t hwirq, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) irq_flow_handler_t handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) dev_dbg(&pmic_arb->spmic->dev, "virq = %u, hwirq = %lu, type = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) virq, hwirq, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (type & IRQ_TYPE_EDGE_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) handler = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) irq_set_lockdep_class(virq, &qpnpint_irq_lock_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) &qpnpint_irq_request_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, pmic_arb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) handler, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static int qpnpint_irq_domain_alloc(struct irq_domain *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) unsigned int virq, unsigned int nr_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct spmi_pmic_arb *pmic_arb = domain->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct irq_fwspec *fwspec = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) irq_hw_number_t hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ret = qpnpint_irq_domain_translate(domain, fwspec, &hwirq, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) for (i = 0; i < nr_irqs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) qpnpint_irq_domain_map(pmic_arb, domain, virq + i, hwirq + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u32 *mapping_table = pmic_arb->mapping_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) int index = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) u16 apid_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) u16 apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) apid_valid = pmic_arb->ppid_to_apid[ppid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (apid_valid & PMIC_ARB_APID_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) apid = apid_valid & ~PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) for (i = 0; i < SPMI_MAPPING_TABLE_TREE_DEPTH; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (!test_and_set_bit(index, pmic_arb->mapping_table_valid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) mapping_table[index] = readl_relaxed(pmic_arb->cnfg +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) SPMI_MAPPING_TABLE_REG(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) data = mapping_table[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (ppid & BIT(SPMI_MAPPING_BIT_INDEX(data))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (SPMI_MAPPING_BIT_IS_1_FLAG(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) index = SPMI_MAPPING_BIT_IS_1_RESULT(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) apid = SPMI_MAPPING_BIT_IS_1_RESULT(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) pmic_arb->ppid_to_apid[ppid]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) = apid | PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) pmic_arb->apid_data[apid].ppid = ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (SPMI_MAPPING_BIT_IS_0_FLAG(data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) index = SPMI_MAPPING_BIT_IS_0_RESULT(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) apid = SPMI_MAPPING_BIT_IS_0_RESULT(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pmic_arb->ppid_to_apid[ppid]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) = apid | PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) pmic_arb->apid_data[apid].ppid = ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* v1 offset per ee */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) enum pmic_arb_channel ch_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return 0x800 + 0x80 * pmic_arb->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) struct apid_data *apidd = &pmic_arb->apid_data[pmic_arb->last_apid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) u32 regval, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) u16 id, apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) for (apid = pmic_arb->last_apid; ; apid++, apidd++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) offset = pmic_arb->ver_ops->apid_map_offset(apid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (offset >= pmic_arb->core_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) regval = readl_relaxed(pmic_arb->cnfg +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) SPMI_OWNERSHIP_TABLE_REG(apid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) apidd->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) apidd->write_ee = apidd->irq_ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) regval = readl_relaxed(pmic_arb->core + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (!regval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) id = (regval >> 8) & PMIC_ARB_PPID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) pmic_arb->ppid_to_apid[id] = apid | PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) apidd->ppid = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (id == ppid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) apid |= PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) pmic_arb->last_apid = apid & ~PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) u16 apid_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) apid_valid = pmic_arb->ppid_to_apid[ppid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (!(apid_valid & PMIC_ARB_APID_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) apid_valid = pmic_arb_find_apid(pmic_arb, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (!(apid_valid & PMIC_ARB_APID_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return apid_valid & ~PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct apid_data *apidd = pmic_arb->apid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct apid_data *prev_apidd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) u16 i, apid, ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) bool valid, is_irq_ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) u32 regval, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * In order to allow multiple EEs to write to a single PPID in arbiter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * version 5, there is more than one APID mapped to each PPID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * The owner field for each of these mappings specifies the EE which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * allowed to write to the APID. The owner of the last (highest) APID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * for a given PPID will receive interrupts from the PPID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) for (i = 0; ; i++, apidd++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) offset = pmic_arb->ver_ops->apid_map_offset(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (offset >= pmic_arb->core_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) regval = readl_relaxed(pmic_arb->core + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (!regval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) regval = readl_relaxed(pmic_arb->cnfg +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) SPMI_OWNERSHIP_TABLE_REG(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) apidd->irq_ee = is_irq_ee ? apidd->write_ee : INVALID_EE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) prev_apidd = &pmic_arb->apid_data[apid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (valid && is_irq_ee &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) prev_apidd->write_ee == pmic_arb->ee) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * Duplicate PPID mapping after the one for this EE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * override the irq owner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) prev_apidd->irq_ee = apidd->irq_ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else if (!valid || is_irq_ee) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /* First PPID mapping or duplicate for another EE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) apidd->ppid = ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) pmic_arb->last_apid = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* Dump the mapping table for debug purposes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) apid = pmic_arb->ppid_to_apid[ppid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (apid & PMIC_ARB_APID_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) apid &= ~PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) apidd = &pmic_arb->apid_data[apid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ppid, apid, apidd->write_ee, apidd->irq_ee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) /* v2 offset per ppid and per ee */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) enum pmic_arb_channel ch_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) u16 apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) u16 ppid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ppid = sid << 8 | ((addr >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) rc = pmic_arb_ppid_to_apid_v2(pmic_arb, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) apid = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return 0x1000 * pmic_arb->ee + 0x8000 * apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * v5 offset per ee and per apid for observer channels and per apid for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * read/write channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) enum pmic_arb_channel ch_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) u16 apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) u32 offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) u16 ppid = (sid << 8) | (addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) apid = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) switch (ch_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) case PMIC_ARB_CHANNEL_OBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) case PMIC_ARB_CHANNEL_RW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) offset = 0x10000 * apid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return (opc << 27) | ((addr & 0xff) << 4) | (bc & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return pmic_arb->intr + 0x20 * m + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return pmic_arb->intr + 0x10000 * m + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return pmic_arb->intr + 0x200 + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return pmic_arb->intr + 0x1000 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return pmic_arb->wr_base + 0x100 + 0x10000 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return pmic_arb->intr + 0x600 + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return pmic_arb->intr + 0x4 + 0x1000 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return pmic_arb->wr_base + 0x104 + 0x10000 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return pmic_arb->intr + 0xA00 + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return pmic_arb->intr + 0x8 + 0x1000 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static void __iomem *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return pmic_arb->wr_base + 0x108 + 0x10000 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static u32 pmic_arb_apid_map_offset_v2(u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return 0x800 + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static u32 pmic_arb_apid_map_offset_v5(u16 n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return 0x900 + 0x4 * n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static const struct pmic_arb_ver_ops pmic_arb_v1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .ver_str = "v1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .ppid_to_apid = pmic_arb_ppid_to_apid_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .non_data_cmd = pmic_arb_non_data_cmd_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .offset = pmic_arb_offset_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .fmt_cmd = pmic_arb_fmt_cmd_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .owner_acc_status = pmic_arb_owner_acc_status_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) .acc_enable = pmic_arb_acc_enable_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) .irq_status = pmic_arb_irq_status_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) .irq_clear = pmic_arb_irq_clear_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) .apid_map_offset = pmic_arb_apid_map_offset_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static const struct pmic_arb_ver_ops pmic_arb_v2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .ver_str = "v2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .ppid_to_apid = pmic_arb_ppid_to_apid_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .non_data_cmd = pmic_arb_non_data_cmd_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .offset = pmic_arb_offset_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .fmt_cmd = pmic_arb_fmt_cmd_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .owner_acc_status = pmic_arb_owner_acc_status_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .acc_enable = pmic_arb_acc_enable_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .irq_status = pmic_arb_irq_status_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .irq_clear = pmic_arb_irq_clear_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .apid_map_offset = pmic_arb_apid_map_offset_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static const struct pmic_arb_ver_ops pmic_arb_v3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .ver_str = "v3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .ppid_to_apid = pmic_arb_ppid_to_apid_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .non_data_cmd = pmic_arb_non_data_cmd_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .offset = pmic_arb_offset_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .fmt_cmd = pmic_arb_fmt_cmd_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) .owner_acc_status = pmic_arb_owner_acc_status_v3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .acc_enable = pmic_arb_acc_enable_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) .irq_status = pmic_arb_irq_status_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) .irq_clear = pmic_arb_irq_clear_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .apid_map_offset = pmic_arb_apid_map_offset_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static const struct pmic_arb_ver_ops pmic_arb_v5 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .ver_str = "v5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .ppid_to_apid = pmic_arb_ppid_to_apid_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .non_data_cmd = pmic_arb_non_data_cmd_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .offset = pmic_arb_offset_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .fmt_cmd = pmic_arb_fmt_cmd_v2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .owner_acc_status = pmic_arb_owner_acc_status_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) .acc_enable = pmic_arb_acc_enable_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) .irq_status = pmic_arb_irq_status_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .irq_clear = pmic_arb_irq_clear_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .apid_map_offset = pmic_arb_apid_map_offset_v5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .activate = qpnpint_irq_domain_activate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .alloc = qpnpint_irq_domain_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .free = irq_domain_free_irqs_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) .translate = qpnpint_irq_domain_translate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int spmi_pmic_arb_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct spmi_pmic_arb *pmic_arb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) struct spmi_controller *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) void __iomem *core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) u32 *mapping_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) u32 channel, ee, hw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*pmic_arb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (!ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) pmic_arb->spmic = ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) core = devm_ioremap_resource(&ctrl->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (IS_ERR(core)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) err = PTR_ERR(core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) pmic_arb->core_size = resource_size(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) sizeof(*pmic_arb->ppid_to_apid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (!pmic_arb->ppid_to_apid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) hw_ver = readl_relaxed(core + PMIC_ARB_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (hw_ver < PMIC_ARB_VERSION_V2_MIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) pmic_arb->ver_ops = &pmic_arb_v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) pmic_arb->wr_base = core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) pmic_arb->rd_base = core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) pmic_arb->core = core;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) pmic_arb->ver_ops = &pmic_arb_v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) pmic_arb->ver_ops = &pmic_arb_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) pmic_arb->ver_ops = &pmic_arb_v5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) "obsrvr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) pmic_arb->rd_base = devm_ioremap_resource(&ctrl->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (IS_ERR(pmic_arb->rd_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) err = PTR_ERR(pmic_arb->rd_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) "chnls");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) pmic_arb->wr_base = devm_ioremap_resource(&ctrl->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (IS_ERR(pmic_arb->wr_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) err = PTR_ERR(pmic_arb->wr_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) dev_info(&ctrl->dev, "PMIC arbiter version %s (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) pmic_arb->ver_ops->ver_str, hw_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "intr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pmic_arb->intr = devm_ioremap_resource(&ctrl->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (IS_ERR(pmic_arb->intr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) err = PTR_ERR(pmic_arb->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cnfg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) pmic_arb->cnfg = devm_ioremap_resource(&ctrl->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (IS_ERR(pmic_arb->cnfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) err = PTR_ERR(pmic_arb->cnfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) pmic_arb->irq = platform_get_irq_byname(pdev, "periph_irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (pmic_arb->irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) err = pmic_arb->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) err = of_property_read_u32(pdev->dev.of_node, "qcom,channel", &channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) dev_err(&pdev->dev, "channel unspecified.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (channel > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dev_err(&pdev->dev, "invalid channel (%u) specified.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) pmic_arb->channel = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) err = of_property_read_u32(pdev->dev.of_node, "qcom,ee", &ee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) dev_err(&pdev->dev, "EE unspecified.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (ee > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) dev_err(&pdev->dev, "invalid EE (%u) specified\n", ee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) pmic_arb->ee = ee;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) mapping_table = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PERIPHS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) sizeof(*mapping_table), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (!mapping_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) pmic_arb->mapping_table = mapping_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) /* Initialize max_apid/min_apid to the opposite bounds, during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) * the irq domain translation, we are sure to update these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) pmic_arb->max_apid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) pmic_arb->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) platform_set_drvdata(pdev, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) raw_spin_lock_init(&pmic_arb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) ctrl->cmd = pmic_arb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ctrl->read_cmd = pmic_arb_read_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ctrl->write_cmd = pmic_arb_write_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) err = pmic_arb_read_apid_map_v5(pmic_arb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) dev_dbg(&pdev->dev, "adding irq domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) &pmic_arb_irq_domain_ops, pmic_arb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (!pmic_arb->domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) dev_err(&pdev->dev, "unable to create irq_domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) goto err_put_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) irq_set_chained_handler_and_data(pmic_arb->irq, pmic_arb_chained_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) pmic_arb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) err = spmi_controller_add(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) goto err_domain_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) err_domain_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) irq_domain_remove(pmic_arb->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) err_put_ctrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) spmi_controller_put(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) static int spmi_pmic_arb_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct spmi_controller *ctrl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) spmi_controller_remove(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) irq_set_chained_handler_and_data(pmic_arb->irq, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) irq_domain_remove(pmic_arb->domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) spmi_controller_put(ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static const struct of_device_id spmi_pmic_arb_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) { .compatible = "qcom,spmi-pmic-arb", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) static struct platform_driver spmi_pmic_arb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) .probe = spmi_pmic_arb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) .remove = spmi_pmic_arb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .name = "spmi_pmic_arb",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) .of_match_table = spmi_pmic_arb_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) module_platform_driver(spmi_pmic_arb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) MODULE_ALIAS("platform:spmi_pmic_arb");