linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V1 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes
@ 2017-07-03 12:52 Kiran Gunda
  2017-07-03 12:52 ` [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset Kiran Gunda
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Kiran Gunda @ 2017-07-03 12:52 UTC (permalink / raw)
  Cc: linux-arm-msm, linux-kernel, sboyd, Kiran Gunda

This patch series add the support for pmic arbiter hardware v5 along with
the few bug fixes and code cleanup.

This patch series is dependent on the below patches and can be merged
cleanly only after picking the below patches in to the tree.

https://patchwork.kernel.org/patch/9810723/
https://patchwork.kernel.org/patch/9822597/
https://patchwork.kernel.org/patch/9822601/
https://patchwork.kernel.org/patch/9822607/
https://patchwork.kernel.org/patch/9822609/
https://patchwork.kernel.org/patch/9822613/


David Collins (1):
  spmi: pmic-arb: add support for HW version 5

Fenglin Wu (1):
  spmi: pmic-arb: Remove checking opc value not less than 0

Kiran Gunda (2):
  spmi: pmic-arb: return __iomem pointer instead of offset
  spmi: pmic-arb: fix a possible null pointer dereference

 drivers/spmi/spmi-pmic-arb.c | 326 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 265 insertions(+), 61 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset
  2017-07-03 12:52 [PATCH V1 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes Kiran Gunda
@ 2017-07-03 12:52 ` Kiran Gunda
  2017-07-06  6:51   ` Stephen Boyd
  2017-07-03 12:52 ` [PATCH V1 2/4] spmi: pmic-arb: fix a possible null pointer dereference Kiran Gunda
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Kiran Gunda @ 2017-07-03 12:52 UTC (permalink / raw)
  To: Kiran Gunda, Abhijeet Dharmapurikar, Stephen Boyd, David Collins,
	linux-kernel
  Cc: linux-arm-msm

Modify the pmic_arb version ops to return an __iomem pointer
to the address instead of an offset. That way we do not need to
care about the base address changes in the new HW version.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
---
 drivers/spmi/spmi-pmic-arb.c | 87 ++++++++++++++++++++++++--------------------
 1 file changed, 48 insertions(+), 39 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 2d2e39c..f1851cb 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -168,14 +168,14 @@ struct spmi_pmic_arb {
  * @offset:		on v1 offset of per-ee channel.
  *			on v2 offset of per-ee and per-ppid channel.
  * @fmt_cmd:		formats a GENI/SPMI command.
- * @owner_acc_status:	on v1 offset of PMIC_ARB_SPMI_PIC_OWNERm_ACC_STATUSn
- *			on v2 offset of SPMI_PIC_OWNERm_ACC_STATUSn.
- * @acc_enable:		on v1 offset of PMIC_ARB_SPMI_PIC_ACC_ENABLEn
- *			on v2 offset of SPMI_PIC_ACC_ENABLEn.
- * @irq_status:		on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_STATUSn
- *			on v2 offset of SPMI_PIC_IRQ_STATUSn.
- * @irq_clear:		on v1 offset of PMIC_ARB_SPMI_PIC_IRQ_CLEARn
- *			on v2 offset of SPMI_PIC_IRQ_CLEARn.
+ * @owner_acc_status:	on v1 address of PMIC_ARB_SPMI_PIC_OWNERm_ACC_STATUSn
+ *			on v2 address of SPMI_PIC_OWNERm_ACC_STATUSn.
+ * @acc_enable:		on v1 address of PMIC_ARB_SPMI_PIC_ACC_ENABLEn
+ *			on v2 address of SPMI_PIC_ACC_ENABLEn.
+ * @irq_status:		on v1 address of PMIC_ARB_SPMI_PIC_IRQ_STATUSn
+ *			on v2 address of SPMI_PIC_IRQ_STATUSn.
+ * @irq_clear:		on v1 address of PMIC_ARB_SPMI_PIC_IRQ_CLEARn
+ *			on v2 address of SPMI_PIC_IRQ_CLEARn.
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
@@ -186,10 +186,11 @@ struct pmic_arb_ver_ops {
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
-	u32 (*owner_acc_status)(u8 m, u16 n);
-	u32 (*acc_enable)(u16 n);
-	u32 (*irq_status)(u16 n);
-	u32 (*irq_clear)(u16 n);
+	void __iomem *(*owner_acc_status)(struct spmi_pmic_arb *pmic_arb, u8 m,
+					  u16 n);
+	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -474,7 +475,7 @@ static void cleanup_irq(struct spmi_pmic_arb *pmic_arb, u16 apid, int id)
 	u8 per = ppid & 0xFF;
 	u8 irq_mask = BIT(id);
 
-	writel_relaxed(irq_mask, pmic_arb->intr + ver_ops->irq_clear(apid));
+	writel_relaxed(irq_mask, ver_ops->irq_clear(pmic_arb, apid));
 
 	if (pmic_arb_write_cmd(pmic_arb->spmic, SPMI_CMD_EXT_WRITEL, sid,
 			(per << 8) + QPNPINT_REG_LATCHED_CLR, &irq_mask, 1))
@@ -496,7 +497,7 @@ static void periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid)
 	u32 status;
 	int id;
 
-	status = readl_relaxed(pmic_arb->intr + ver_ops->irq_status(apid));
+	status = readl_relaxed(ver_ops->irq_status(pmic_arb, apid));
 	while (status) {
 		id = ffs(status) - 1;
 		status &= ~BIT(id);
@@ -515,23 +516,21 @@ static void pmic_arb_chained_irq(struct irq_desc *desc)
 	struct spmi_pmic_arb *pmic_arb = irq_desc_get_handler_data(desc);
 	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	void __iomem *intr = pmic_arb->intr;
 	int first = pmic_arb->min_apid >> 5;
 	int last = pmic_arb->max_apid >> 5;
+	u8 ee = pmic_arb->ee;
 	u32 status, enable;
 	int i, id, apid;
 
 	chained_irq_enter(chip, desc);
 
 	for (i = first; i <= last; ++i) {
-		status = readl_relaxed(intr +
-				    ver_ops->owner_acc_status(pmic_arb->ee, i));
+		status = readl_relaxed(ver_ops->owner_acc_status(pmic_arb, ee, i));
 		while (status) {
 			id = ffs(status) - 1;
 			status &= ~BIT(id);
 			apid = id + i * 32;
-			enable = readl_relaxed(intr +
-					pmic_arb->ver_ops->acc_enable(apid));
+			enable = readl_relaxed(ver_ops->acc_enable(pmic_arb, apid));
 			if (enable & SPMI_PIC_ACC_ENABLE_BIT)
 				periph_interrupt(pmic_arb, apid);
 		}
@@ -548,7 +547,7 @@ static void qpnpint_irq_ack(struct irq_data *d)
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 data;
 
-	writel_relaxed(BIT(irq), pmic_arb->intr + ver_ops->irq_clear(apid));
+	writel_relaxed(BIT(irq), ver_ops->irq_clear(pmic_arb, apid));
 
 	data = BIT(irq);
 	qpnpint_spmi_write(d, QPNPINT_REG_LATCHED_CLR, &data, 1);
@@ -565,12 +564,13 @@ static void qpnpint_irq_mask(struct irq_data *d)
 static void qpnpint_irq_unmask(struct irq_data *d)
 {
 	struct spmi_pmic_arb *pmic_arb = irq_data_get_irq_chip_data(d);
+	const struct pmic_arb_ver_ops *ver_ops = pmic_arb->ver_ops;
 	u8 irq = hwirq_to_irq(d->hwirq);
 	u16 apid = hwirq_to_apid(d->hwirq);
 	u8 buf[2];
 
 	writel_relaxed(SPMI_PIC_ACC_ENABLE_BIT,
-		pmic_arb->intr + pmic_arb->ver_ops->acc_enable(apid));
+			ver_ops->acc_enable(pmic_arb, apid));
 
 	qpnpint_spmi_read(d, QPNPINT_REG_EN_SET, &buf[0], 1);
 	if (!(buf[0] & BIT(irq))) {
@@ -851,49 +851,58 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 	return (opc << 27) | ((addr & 0xff) << 4) | (bc & 0x7);
 }
 
-static u32 pmic_arb_owner_acc_status_v1(u8 m, u16 n)
+static void __iomem *
+pmic_arb_owner_acc_status_v1(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
 {
-	return 0x20 * m + 0x4 * n;
+	return pmic_arb->intr + 0x20 * m + 0x4 * n;
 }
 
-static u32 pmic_arb_owner_acc_status_v2(u8 m, u16 n)
+static void __iomem *
+pmic_arb_owner_acc_status_v2(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
 {
-	return 0x100000 + 0x1000 * m + 0x4 * n;
+	return pmic_arb->intr + 0x100000 + 0x1000 * m + 0x4 * n;
 }
 
-static u32 pmic_arb_owner_acc_status_v3(u8 m, u16 n)
+static void __iomem *
+pmic_arb_owner_acc_status_v3(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
 {
-	return 0x200000 + 0x1000 * m + 0x4 * n;
+	return pmic_arb->intr + 0x200000 + 0x1000 * m + 0x4 * n;
 }
 
-static u32 pmic_arb_acc_enable_v1(u16 n)
+static void __iomem *
+pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
-	return 0x200 + 0x4 * n;
+	return pmic_arb->intr + 0x200 + 0x4 * n;
 }
 
-static u32 pmic_arb_acc_enable_v2(u16 n)
+static void __iomem *
+pmic_arb_acc_enable_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
-	return 0x1000 * n;
+	return pmic_arb->intr + 0x1000 * n;
 }
 
-static u32 pmic_arb_irq_status_v1(u16 n)
+static void __iomem *
+pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
-	return 0x600 + 0x4 * n;
+	return pmic_arb->intr + 0x600 + 0x4 * n;
 }
 
-static u32 pmic_arb_irq_status_v2(u16 n)
+static void __iomem *
+pmic_arb_irq_status_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
-	return 0x4 + 0x1000 * n;
+	return pmic_arb->intr + 0x4 + 0x1000 * n;
 }
 
-static u32 pmic_arb_irq_clear_v1(u16 n)
+static void __iomem *
+pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
-	return 0xA00 + 0x4 * n;
+	return pmic_arb->intr + 0xA00 + 0x4 * n;
 }
 
-static u32 pmic_arb_irq_clear_v2(u16 n)
+static void __iomem *
+pmic_arb_irq_clear_v2(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
-	return 0x8 + 0x1000 * n;
+	return pmic_arb->intr + 0x8 + 0x1000 * n;
 }
 
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH V1 2/4] spmi: pmic-arb: fix a possible null pointer dereference
  2017-07-03 12:52 [PATCH V1 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes Kiran Gunda
  2017-07-03 12:52 ` [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset Kiran Gunda
@ 2017-07-03 12:52 ` Kiran Gunda
  2017-07-06  6:52   ` Stephen Boyd
  2017-07-03 12:52 ` [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5 Kiran Gunda
  2017-07-03 12:52 ` [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0 Kiran Gunda
  3 siblings, 1 reply; 12+ messages in thread
From: Kiran Gunda @ 2017-07-03 12:52 UTC (permalink / raw)
  To: Kiran Gunda, Abhijeet Dharmapurikar, Stephen Boyd, David Collins,
	linux-kernel
  Cc: linux-arm-msm

If "core" memory resource is not specified, then the driver could
end up dereferencing a null pointer. Fix this issue.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
---
 drivers/spmi/spmi-pmic-arb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index f1851cb..86affb0 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -964,14 +964,14 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	pmic_arb->spmic = ctrl;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
-	pmic_arb->core_size = resource_size(res);
-
 	core = devm_ioremap_resource(&ctrl->dev, res);
 	if (IS_ERR(core)) {
 		err = PTR_ERR(core);
 		goto err_put_ctrl;
 	}
 
+	pmic_arb->core_size = resource_size(res);
+
 	pmic_arb->ppid_to_apid = devm_kcalloc(&ctrl->dev, PMIC_ARB_MAX_PPID,
 					      sizeof(*pmic_arb->ppid_to_apid),
 					      GFP_KERNEL);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5
  2017-07-03 12:52 [PATCH V1 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes Kiran Gunda
  2017-07-03 12:52 ` [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset Kiran Gunda
  2017-07-03 12:52 ` [PATCH V1 2/4] spmi: pmic-arb: fix a possible null pointer dereference Kiran Gunda
@ 2017-07-03 12:52 ` Kiran Gunda
  2017-07-06  6:59   ` Stephen Boyd
  2017-07-03 12:52 ` [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0 Kiran Gunda
  3 siblings, 1 reply; 12+ messages in thread
From: Kiran Gunda @ 2017-07-03 12:52 UTC (permalink / raw)
  To: Kiran Gunda, Abhijeet Dharmapurikar, Stephen Boyd, David Collins,
	linux-kernel
  Cc: linux-arm-msm

From: David Collins <collinsd@codeaurora.org>

Add support for version 5 of the SPMI PMIC arbiter.  It utilizes
different offsets for registers than those found on version 3.
Also, the procedure to determine if writing and IRQ access is
allowed for a given PPID changes for version 5.

Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
---
 drivers/spmi/spmi-pmic-arb.c | 233 +++++++++++++++++++++++++++++++++++++++----
 1 file changed, 214 insertions(+), 19 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 86affb0..bc88c19 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,7 @@
 #define PMIC_ARB_VERSION		0x0000
 #define PMIC_ARB_VERSION_V2_MIN		0x20010000
 #define PMIC_ARB_VERSION_V3_MIN		0x30000000
+#define PMIC_ARB_VERSION_V5_MIN		0x50000000
 #define PMIC_ARB_INT_EN			0x0004
 
 /* PMIC Arbiter channel registers offsets */
@@ -39,7 +40,6 @@
 #define PMIC_ARB_WDATA1			0x14
 #define PMIC_ARB_RDATA0			0x18
 #define PMIC_ARB_RDATA1			0x1C
-#define PMIC_ARB_REG_CHNL(N)		(0x800 + 0x4 * (N))
 
 /* Mapping Table */
 #define SPMI_MAPPING_TABLE_REG(N)	(0x0B00 + (4 * (N)))
@@ -52,6 +52,8 @@
 #define SPMI_MAPPING_TABLE_TREE_DEPTH	16	/* Maximum of 16-bits */
 #define PMIC_ARB_MAX_PPID		BIT(12) /* PPID is 12bit */
 #define PMIC_ARB_APID_VALID		BIT(15)
+#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg)	((reg) & BIT(24))
+#define INVALID				(-1)
 
 /* Ownership Table */
 #define SPMI_OWNERSHIP_TABLE_REG(N)	(0x0700 + (4 * (N)))
@@ -86,6 +88,15 @@ enum pmic_arb_cmd_op_code {
 	PMIC_ARB_OP_ZERO_WRITE = 16,
 };
 
+/*
+ * PMIC arbiter version 5 uses different register offsets for read/write vs
+ * observer channels.
+ */
+enum pmic_arb_channel {
+	PMIC_ARB_CHANNEL_RW,
+	PMIC_ARB_CHANNEL_OBS,
+};
+
 /* Maximum number of support PMIC peripherals */
 #define PMIC_ARB_MAX_PERIPHS		512
 #define PMIC_ARB_TIMEOUT_US		100
@@ -112,7 +123,8 @@ enum pmic_arb_cmd_op_code {
 
 struct apid_data {
 	u16		ppid;
-	u8		owner;
+	u8		write_ee;
+	u8		irq_ee;
 };
 
 /**
@@ -176,13 +188,14 @@ struct spmi_pmic_arb {
  *			on v2 address of SPMI_PIC_IRQ_STATUSn.
  * @irq_clear:		on v1 address of PMIC_ARB_SPMI_PIC_IRQ_CLEARn
  *			on v2 address of SPMI_PIC_IRQ_CLEARn.
+ * @apid_map_offset:	offset of PMIC_ARB_REG_CHNLn
  */
 struct pmic_arb_ver_ops {
 	const char *ver_str;
 	int (*ppid_to_apid)(struct spmi_pmic_arb *pmic_arb, u16 ppid);
 	/* spmi commands (read_cmd, write_cmd, cmd) functionality */
-	int (*offset)(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-		      u32 *offset);
+	int (*offset)(struct spmi_pmic_arb *dev, u8 sid, u16 addr,
+			enum pmic_arb_channel ch_type, u32 *offset);
 	u32 (*fmt_cmd)(u8 opc, u8 sid, u16 addr, u8 bc);
 	int (*non_data_cmd)(struct spmi_controller *ctrl, u8 opc, u8 sid);
 	/* Interrupts controller functionality (offset of PIC registers) */
@@ -191,6 +204,7 @@ struct pmic_arb_ver_ops {
 	void __iomem *(*acc_enable)(struct spmi_pmic_arb *pmic_arb, u16 n);
 	void __iomem *(*irq_status)(struct spmi_pmic_arb *pmic_arb, u16 n);
 	void __iomem *(*irq_clear)(struct spmi_pmic_arb *pmic_arb, u16 n);
+	u32 (*apid_map_offset)(u16 n);
 };
 
 static inline void pmic_arb_base_write(struct spmi_pmic_arb *pmic_arb,
@@ -235,7 +249,8 @@ static void pmic_arb_write_data(struct spmi_pmic_arb *pmic_arb, const u8 *buf,
 }
 
 static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
-				  void __iomem *base, u8 sid, u16 addr)
+				  void __iomem *base, u8 sid, u16 addr,
+				  enum pmic_arb_channel ch_type)
 {
 	struct spmi_pmic_arb *pmic_arb = spmi_controller_get_drvdata(ctrl);
 	u32 status = 0;
@@ -243,7 +258,7 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 	u32 offset;
 	int rc;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, &offset);
+	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, ch_type, &offset);
 	if (rc)
 		return rc;
 
@@ -290,7 +305,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, &offset);
+	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, 0, PMIC_ARB_CHANNEL_RW,
+					&offset);
 	if (rc)
 		return rc;
 
@@ -298,7 +314,8 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
 	pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
-	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0);
+	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, 0,
+				    PMIC_ARB_CHANNEL_RW);
 	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
 
 	return rc;
@@ -334,7 +351,8 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, &offset);
+	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr,
+				       PMIC_ARB_CHANNEL_OBS, &offset);
 	if (rc)
 		return rc;
 
@@ -358,7 +376,8 @@ static int pmic_arb_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 
 	raw_spin_lock_irqsave(&pmic_arb->lock, flags);
 	pmic_arb_set_rd_cmd(pmic_arb, offset + PMIC_ARB_CMD, cmd);
-	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr);
+	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->rd_base, sid, addr,
+				    PMIC_ARB_CHANNEL_OBS);
 	if (rc)
 		goto done;
 
@@ -384,7 +403,8 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	int rc;
 	u32 offset;
 
-	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, &offset);
+	rc = pmic_arb->ver_ops->offset(pmic_arb, sid, addr, PMIC_ARB_CHANNEL_RW,
+					&offset);
 	if (rc)
 		return rc;
 
@@ -418,7 +438,8 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 
 	/* Start the transaction */
 	pmic_arb_base_write(pmic_arb, offset + PMIC_ARB_CMD, cmd);
-	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr);
+	rc = pmic_arb_wait_for_done(ctrl, pmic_arb->wr_base, sid, addr,
+				    PMIC_ARB_CHANNEL_RW);
 	raw_spin_unlock_irqrestore(&pmic_arb->lock, flags);
 
 	return rc;
@@ -685,12 +706,19 @@ static int qpnpint_irq_domain_dt_translate(struct irq_domain *d,
 	ppid = intspec[0] << 8 | intspec[1];
 	rc = pmic_arb->ver_ops->ppid_to_apid(pmic_arb, ppid);
 	if (rc < 0) {
-		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = 0x%x, periph = 0x%x, irq = %x rc = %d\n",
+		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u rc = %d\n",
 		intspec[0], intspec[1], intspec[2], rc);
 		return rc;
 	}
 
 	apid = rc;
+	if (pmic_arb->apid_data[apid].irq_ee != pmic_arb->ee) {
+		dev_err(&pmic_arb->spmic->dev, "failed to xlate sid = %#x, periph = %#x, irq = %u: ee=%u but owner=%u\n",
+			intspec[0], intspec[1], intspec[2], pmic_arb->ee,
+			pmic_arb->apid_data[apid].irq_ee);
+		return -ENODEV;
+	}
+
 	/* Keep track of {max,min}_apid for bounding search during interrupt */
 	if (apid > pmic_arb->max_apid)
 		pmic_arb->max_apid = apid;
@@ -768,7 +796,7 @@ static int pmic_arb_ppid_to_apid_v1(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 
 /* v1 offset per ee */
 static int pmic_arb_offset_v1(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-				u32 *offset)
+			enum pmic_arb_channel ch_type, u32 *offset)
 {
 	*offset = 0x800 + 0x80 * pmic_arb->channel;
 	return 0;
@@ -785,13 +813,14 @@ static u16 pmic_arb_find_apid(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 	 * ppid_to_apid is an in-memory invert of that table.
 	 */
 	for (i = pmic_arb->last_apid; ; i++, apid_info++) {
-		offset = PMIC_ARB_REG_CHNL(i);
+		offset = pmic_arb->ver_ops->apid_map_offset(i);
 		if (offset >= pmic_arb->core_size)
 			break;
 
 		regval = readl_relaxed(pmic_arb->cnfg +
 					SPMI_OWNERSHIP_TABLE_REG(i));
-		apid_info->owner = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+		apid_info->irq_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+		apid_info->write_ee = apid_info->irq_ee;
 
 		regval = readl_relaxed(pmic_arb->core + offset);
 		if (!regval)
@@ -823,9 +852,86 @@ static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb *pmic_arb, u16 ppid)
 	return apid_valid & ~PMIC_ARB_APID_VALID;
 }
 
+static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+{
+	struct apid_data *apid_info = pmic_arb->apid_data;
+	struct apid_data *prev_apid_info;
+	u16 i, j, ppid;
+	bool valid, is_irq_ee;
+	u32 regval, offset;
+
+	/*
+	 * PMIC_ARB_REG_CHNL is a table in HW mapping APID (channel) to PPID.
+	 * ppid_to_apid is an in-memory invert of that table.  In order to allow
+	 * multiple EEs to write to a single PPID in arbiter version 5, there
+	 * is more than one APID mapped to each PPID.  The owner field for each
+	 * of these mappings specifies the EE which is allowed to write to the
+	 * APID.  The owner of the last (highest) APID for a given PPID will
+	 * receive interrupts from the PPID.
+	 */
+	for (i = 0; ; i++, apid_info++) {
+		offset = pmic_arb->ver_ops->apid_map_offset(i);
+		if (offset >= pmic_arb->core_size)
+			break;
+
+		regval = readl_relaxed(pmic_arb->core + offset);
+		if (!regval)
+			continue;
+		ppid = (regval >> 8) & PMIC_ARB_PPID_MASK;
+		is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval);
+
+		regval = readl_relaxed(pmic_arb->cnfg +
+				      SPMI_OWNERSHIP_TABLE_REG(i));
+		apid_info->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval);
+
+		apid_info->irq_ee = is_irq_ee ? apid_info->write_ee : INVALID;
+
+		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		j = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		prev_apid_info = &pmic_arb->apid_data[j];
+
+		if (valid && is_irq_ee &&
+				prev_apid_info->write_ee == pmic_arb->ee) {
+			/*
+			 * Duplicate PPID mapping after the one for this EE;
+			 * override the irq owner
+			 */
+			prev_apid_info->irq_ee = apid_info->irq_ee;
+		} else if (!valid || is_irq_ee) {
+			/* First PPID mapping or duplicate for another EE */
+			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+		}
+
+		apid_info->ppid = ppid;
+		pmic_arb->last_apid = i;
+	}
+
+	/* Dump the mapping table for debug purposes. */
+	dev_dbg(&pmic_arb->spmic->dev, "PPID APID Write-EE IRQ-EE\n");
+	for (ppid = 0; ppid < PMIC_ARB_MAX_PPID; ppid++) {
+		valid = pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID;
+		i = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+		if (valid) {
+			apid_info = &pmic_arb->apid_data[i];
+			dev_dbg(&pmic_arb->spmic->dev, "%#03X %3u %2u %2u\n",
+			      ppid, i, apid_info->write_ee, apid_info->irq_ee);
+		}
+	}
+
+	return 0;
+}
+
+static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb *pmic_arb, u16 ppid)
+{
+	if (!(pmic_arb->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID))
+		return -ENODEV;
+
+	return pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+}
+
 /* v2 offset per ppid and per ee */
 static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
-				u32 *offset)
+			   enum pmic_arb_channel ch_type, u32 *offset)
 {
 	u16 apid;
 	u16 ppid;
@@ -841,6 +947,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
 	return 0;
 }
 
+/*
+ * v5 offset per ee and per apid for observer channels and per apid for
+ * read/write channels.
+ */
+static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
+			   enum pmic_arb_channel ch_type, u32 *offset)
+{
+	u16 apid;
+	int rc;
+	u16 ppid = (sid << 8) | (addr >> 8);
+
+	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
+	if (rc < 0)
+		return rc;
+
+	apid = rc;
+	switch (ch_type) {
+	case PMIC_ARB_CHANNEL_OBS:
+		*offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
+		break;
+	case PMIC_ARB_CHANNEL_RW:
+		*offset = 0x10000 * apid;
+		break;
+	}
+
+	return 0;
+}
+
 static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc)
 {
 	return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
@@ -870,6 +1004,12 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
+pmic_arb_owner_acc_status_v5(struct spmi_pmic_arb *pmic_arb, u8 m, u16 n)
+{
+	return pmic_arb->intr + 0x10000 * m + 0x4 * n;
+}
+
+static void __iomem *
 pmic_arb_acc_enable_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
 	return pmic_arb->intr + 0x200 + 0x4 * n;
@@ -882,6 +1022,12 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
+pmic_arb_acc_enable_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+{
+	return pmic_arb->wr_base + 0x100 + 0x10000 * n;
+}
+
+static void __iomem *
 pmic_arb_irq_status_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
 	return pmic_arb->intr + 0x600 + 0x4 * n;
@@ -894,6 +1040,12 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 }
 
 static void __iomem *
+pmic_arb_irq_status_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+{
+	return pmic_arb->wr_base + 0x104 + 0x10000 * n;
+}
+
+static void __iomem *
 pmic_arb_irq_clear_v1(struct spmi_pmic_arb *pmic_arb, u16 n)
 {
 	return pmic_arb->intr + 0xA00 + 0x4 * n;
@@ -905,6 +1057,22 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 	return pmic_arb->intr + 0x8 + 0x1000 * n;
 }
 
+static void __iomem *
+pmic_arb_irq_clear_v5(struct spmi_pmic_arb *pmic_arb, u16 n)
+{
+	return pmic_arb->wr_base + 0x108 + 0x10000 * n;
+}
+
+static u32 pmic_arb_apid_map_offset_v2(u16 n)
+{
+	return 0x800 + 0x4 * n;
+}
+
+static u32 pmic_arb_apid_map_offset_v5(u16 n)
+{
+	return 0x900 + 0x4 * n;
+}
+
 static const struct pmic_arb_ver_ops pmic_arb_v1 = {
 	.ver_str		= "v1",
 	.ppid_to_apid		= pmic_arb_ppid_to_apid_v1,
@@ -915,6 +1083,7 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 	.acc_enable		= pmic_arb_acc_enable_v1,
 	.irq_status		= pmic_arb_irq_status_v1,
 	.irq_clear		= pmic_arb_irq_clear_v1,
+	.apid_map_offset	= pmic_arb_apid_map_offset_v2,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v2 = {
@@ -927,6 +1096,7 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 	.acc_enable		= pmic_arb_acc_enable_v2,
 	.irq_status		= pmic_arb_irq_status_v2,
 	.irq_clear		= pmic_arb_irq_clear_v2,
+	.apid_map_offset	= pmic_arb_apid_map_offset_v2,
 };
 
 static const struct pmic_arb_ver_ops pmic_arb_v3 = {
@@ -939,6 +1109,20 @@ static u32 pmic_arb_fmt_cmd_v2(u8 opc, u8 sid, u16 addr, u8 bc)
 	.acc_enable		= pmic_arb_acc_enable_v2,
 	.irq_status		= pmic_arb_irq_status_v2,
 	.irq_clear		= pmic_arb_irq_clear_v2,
+	.apid_map_offset	= pmic_arb_apid_map_offset_v2,
+};
+
+static const struct pmic_arb_ver_ops pmic_arb_v5 = {
+	.ver_str		= "v5",
+	.ppid_to_apid		= pmic_arb_ppid_to_apid_v5,
+	.non_data_cmd		= pmic_arb_non_data_cmd_v2,
+	.offset			= pmic_arb_offset_v5,
+	.fmt_cmd		= pmic_arb_fmt_cmd_v2,
+	.owner_acc_status	= pmic_arb_owner_acc_status_v5,
+	.acc_enable		= pmic_arb_acc_enable_v5,
+	.irq_status		= pmic_arb_irq_status_v5,
+	.irq_clear		= pmic_arb_irq_clear_v5,
+	.apid_map_offset	= pmic_arb_apid_map_offset_v5,
 };
 
 static const struct irq_domain_ops pmic_arb_irq_domain_ops = {
@@ -991,8 +1175,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 
 		if (hw_ver < PMIC_ARB_VERSION_V3_MIN)
 			pmic_arb->ver_ops = &pmic_arb_v2;
-		else
+		else if (hw_ver < PMIC_ARB_VERSION_V5_MIN)
 			pmic_arb->ver_ops = &pmic_arb_v3;
+		else
+			pmic_arb->ver_ops = &pmic_arb_v5;
 
 		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 						   "obsrvr");
@@ -1082,6 +1268,15 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	ctrl->read_cmd = pmic_arb_read_cmd;
 	ctrl->write_cmd = pmic_arb_write_cmd;
 
+	if (hw_ver >= PMIC_ARB_VERSION_V5_MIN) {
+		err = pmic_arb_read_apid_map_v5(pmic_arb);
+		if (err) {
+			dev_err(&pdev->dev, "could not read APID->PPID mapping table, rc= %d\n",
+				err);
+			goto err_put_ctrl;
+		}
+	}
+
 	dev_dbg(&pdev->dev, "adding irq domain\n");
 	pmic_arb->domain = irq_domain_add_tree(pdev->dev.of_node,
 					 &pmic_arb_irq_domain_ops, pmic_arb);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0
  2017-07-03 12:52 [PATCH V1 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes Kiran Gunda
                   ` (2 preceding siblings ...)
  2017-07-03 12:52 ` [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5 Kiran Gunda
@ 2017-07-03 12:52 ` Kiran Gunda
  2017-07-06  6:53   ` Stephen Boyd
  2017-07-06  6:53   ` Stephen Boyd
  3 siblings, 2 replies; 12+ messages in thread
From: Kiran Gunda @ 2017-07-03 12:52 UTC (permalink / raw)
  To: Kiran Gunda, Abhijeet Dharmapurikar, Stephen Boyd, David Collins,
	linux-kernel
  Cc: linux-arm-msm, Fenglin Wu

From: Fenglin Wu <fenglinw@codeaurora.org>

The opc parameter in pmic_arb_write_cmd() function is defined with type
u8 and it's always greater than or equal to 0. Checking that it's not
less than 0 is redundant and it can cause a forbidden warning during
compilation. Remove the check.

Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
---
 drivers/spmi/spmi-pmic-arb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index bc88c19..b49e77a 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -417,7 +417,7 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 	/* Check the opcode */
 	if (opc >= 0x40 && opc <= 0x5F)
 		opc = PMIC_ARB_OP_WRITE;
-	else if (opc >= 0x00 && opc <= 0x0F)
+	else if (opc <= 0x0F)
 		opc = PMIC_ARB_OP_EXT_WRITE;
 	else if (opc >= 0x30 && opc <= 0x37)
 		opc = PMIC_ARB_OP_EXT_WRITEL;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset
  2017-07-03 12:52 ` [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset Kiran Gunda
@ 2017-07-06  6:51   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2017-07-06  6:51 UTC (permalink / raw)
  To: Kiran Gunda
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel, linux-arm-msm

On 07/03, Kiran Gunda wrote:
> Modify the pmic_arb version ops to return an __iomem pointer
> to the address instead of an offset. That way we do not need to
> care about the base address changes in the new HW version.
> 
> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 2/4] spmi: pmic-arb: fix a possible null pointer dereference
  2017-07-03 12:52 ` [PATCH V1 2/4] spmi: pmic-arb: fix a possible null pointer dereference Kiran Gunda
@ 2017-07-06  6:52   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2017-07-06  6:52 UTC (permalink / raw)
  To: Kiran Gunda
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel, linux-arm-msm

On 07/03, Kiran Gunda wrote:
> If "core" memory resource is not specified, then the driver could
> end up dereferencing a null pointer. Fix this issue.
> 
> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0
  2017-07-03 12:52 ` [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0 Kiran Gunda
@ 2017-07-06  6:53   ` Stephen Boyd
  2017-07-06  6:53   ` Stephen Boyd
  1 sibling, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2017-07-06  6:53 UTC (permalink / raw)
  To: Kiran Gunda
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel,
	linux-arm-msm, Fenglin Wu

On 07/03, Kiran Gunda wrote:
> From: Fenglin Wu <fenglinw@codeaurora.org>
> 
> The opc parameter in pmic_arb_write_cmd() function is defined with type
> u8 and it's always greater than or equal to 0. Checking that it's not
> less than 0 is redundant and it can cause a forbidden warning during
> compilation. Remove the check.
> 
> Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0
  2017-07-03 12:52 ` [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0 Kiran Gunda
  2017-07-06  6:53   ` Stephen Boyd
@ 2017-07-06  6:53   ` Stephen Boyd
  2017-07-06 10:21     ` kgunda
  1 sibling, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2017-07-06  6:53 UTC (permalink / raw)
  To: Kiran Gunda
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel,
	linux-arm-msm, Fenglin Wu

On 07/03, Kiran Gunda wrote:
> From: Fenglin Wu <fenglinw@codeaurora.org>
> 
> The opc parameter in pmic_arb_write_cmd() function is defined with type
> u8 and it's always greater than or equal to 0. Checking that it's not
> less than 0 is redundant and it can cause a forbidden warning during
> compilation. Remove the check.
> 
> Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
> ---

You forgot your sign-off here.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5
  2017-07-03 12:52 ` [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5 Kiran Gunda
@ 2017-07-06  6:59   ` Stephen Boyd
  2017-07-06 10:48     ` kgunda
  0 siblings, 1 reply; 12+ messages in thread
From: Stephen Boyd @ 2017-07-06  6:59 UTC (permalink / raw)
  To: Kiran Gunda
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel, linux-arm-msm

On 07/03, Kiran Gunda wrote:
> From: David Collins <collinsd@codeaurora.org>
> 
> Add support for version 5 of the SPMI PMIC arbiter.  It utilizes
> different offsets for registers than those found on version 3.
> Also, the procedure to determine if writing and IRQ access is
> allowed for a given PPID changes for version 5.
> 

David's sign-off is missing?

> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
> ---
>  drivers/spmi/spmi-pmic-arb.c | 233 +++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 214 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 86affb0..bc88c19 100644
> --- a/drivers/spmi/spmi-pmic-arb.c
> +++ b/drivers/spmi/spmi-pmic-arb.c
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 and
> @@ -29,6 +29,7 @@
>  #define PMIC_ARB_VERSION		0x0000
>  #define PMIC_ARB_VERSION_V2_MIN		0x20010000
>  #define PMIC_ARB_VERSION_V3_MIN		0x30000000
> +#define PMIC_ARB_VERSION_V5_MIN		0x50000000
>  #define PMIC_ARB_INT_EN			0x0004
>  
>  /* PMIC Arbiter channel registers offsets */
> @@ -39,7 +40,6 @@
>  #define PMIC_ARB_WDATA1			0x14
>  #define PMIC_ARB_RDATA0			0x18
>  #define PMIC_ARB_RDATA1			0x1C
> -#define PMIC_ARB_REG_CHNL(N)		(0x800 + 0x4 * (N))
>  
>  /* Mapping Table */
>  #define SPMI_MAPPING_TABLE_REG(N)	(0x0B00 + (4 * (N)))
> @@ -52,6 +52,8 @@
>  #define SPMI_MAPPING_TABLE_TREE_DEPTH	16	/* Maximum of 16-bits */
>  #define PMIC_ARB_MAX_PPID		BIT(12) /* PPID is 12bit */
>  #define PMIC_ARB_APID_VALID		BIT(15)
> +#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg)	((reg) & BIT(24))
> +#define INVALID				(-1)

INVALID_EE? And then define it to be 0xff?

>  
>  /* Ownership Table */
>  #define SPMI_OWNERSHIP_TABLE_REG(N)	(0x0700 + (4 * (N)))
> @@ -86,6 +88,15 @@ enum pmic_arb_cmd_op_code {
>  	PMIC_ARB_OP_ZERO_WRITE = 16,
>  };
>  
> +/*
> + * PMIC arbiter version 5 uses different register offsets for read/write vs
> + * observer channels.
> + */
> +enum pmic_arb_channel {
> +	PMIC_ARB_CHANNEL_RW,
> +	PMIC_ARB_CHANNEL_OBS,
> +};
> +
>  /* Maximum number of support PMIC peripherals */
>  #define PMIC_ARB_MAX_PERIPHS		512
[...]
> @@ -112,7 +123,8 @@ enum pmic_arb_cmd_op_code {
>  
> +
>  /* v2 offset per ppid and per ee */
>  static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
> -				u32 *offset)
> +			   enum pmic_arb_channel ch_type, u32 *offset)
>  {
>  	u16 apid;
>  	u16 ppid;
> @@ -841,6 +947,34 @@ static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
>  	return 0;
>  }
>  
> +/*
> + * v5 offset per ee and per apid for observer channels and per apid for
> + * read/write channels.
> + */
> +static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
> +			   enum pmic_arb_channel ch_type, u32 *offset)
> +{
> +	u16 apid;
> +	int rc;
> +	u16 ppid = (sid << 8) | (addr >> 8);
> +
> +	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
> +	if (rc < 0)
> +		return rc;
> +
> +	apid = rc;
> +	switch (ch_type) {
> +	case PMIC_ARB_CHANNEL_OBS:
> +		*offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
> +		break;
> +	case PMIC_ARB_CHANNEL_RW:
> +		*offset = 0x10000 * apid;
> +		break;
> +	}
> +
> +	return 0;

Why doesn't this also return an iomem pointer?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0
  2017-07-06  6:53   ` Stephen Boyd
@ 2017-07-06 10:21     ` kgunda
  0 siblings, 0 replies; 12+ messages in thread
From: kgunda @ 2017-07-06 10:21 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel,
	linux-arm-msm, Fenglin Wu, linux-arm-msm-owner

On 2017-07-06 12:23, Stephen Boyd wrote:
> On 07/03, Kiran Gunda wrote:
>> From: Fenglin Wu <fenglinw@codeaurora.org>
>> 
>> The opc parameter in pmic_arb_write_cmd() function is defined with 
>> type
>> u8 and it's always greater than or equal to 0. Checking that it's not
>> less than 0 is redundant and it can cause a forbidden warning during
>> compilation. Remove the check.
>> 
>> Signed-off-by: Fenglin Wu <fenglinw@codeaurora.org>
>> ---
> 
> You forgot your sign-off here.
yeah.. forgot. Will add it.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5
  2017-07-06  6:59   ` Stephen Boyd
@ 2017-07-06 10:48     ` kgunda
  0 siblings, 0 replies; 12+ messages in thread
From: kgunda @ 2017-07-06 10:48 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Abhijeet Dharmapurikar, David Collins, linux-kernel,
	linux-arm-msm, linux-arm-msm-owner

On 2017-07-06 12:29, Stephen Boyd wrote:
> On 07/03, Kiran Gunda wrote:
>> From: David Collins <collinsd@codeaurora.org>
>> 
>> Add support for version 5 of the SPMI PMIC arbiter.  It utilizes
>> different offsets for registers than those found on version 3.
>> Also, the procedure to determine if writing and IRQ access is
>> allowed for a given PPID changes for version 5.
>> 
> 
> David's sign-off is missing?
> 
Looks like mistakenly removed along with change-id. Will add it in the 
next patch.
>> Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
>> ---
>>  drivers/spmi/spmi-pmic-arb.c | 233 
>> +++++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 214 insertions(+), 19 deletions(-)
>> 
>> diff --git a/drivers/spmi/spmi-pmic-arb.c 
>> b/drivers/spmi/spmi-pmic-arb.c
>> index 86affb0..bc88c19 100644
>> --- a/drivers/spmi/spmi-pmic-arb.c
>> +++ b/drivers/spmi/spmi-pmic-arb.c
>> @@ -1,5 +1,5 @@
>>  /*
>> - * Copyright (c) 2012-2015, The Linux Foundation. All rights 
>> reserved.
>> + * Copyright (c) 2012-2017, The Linux Foundation. All rights 
>> reserved.
>>   *
>>   * This program is free software; you can redistribute it and/or 
>> modify
>>   * it under the terms of the GNU General Public License version 2 and
>> @@ -29,6 +29,7 @@
>>  #define PMIC_ARB_VERSION		0x0000
>>  #define PMIC_ARB_VERSION_V2_MIN		0x20010000
>>  #define PMIC_ARB_VERSION_V3_MIN		0x30000000
>> +#define PMIC_ARB_VERSION_V5_MIN		0x50000000
>>  #define PMIC_ARB_INT_EN			0x0004
>> 
>>  /* PMIC Arbiter channel registers offsets */
>> @@ -39,7 +40,6 @@
>>  #define PMIC_ARB_WDATA1			0x14
>>  #define PMIC_ARB_RDATA0			0x18
>>  #define PMIC_ARB_RDATA1			0x1C
>> -#define PMIC_ARB_REG_CHNL(N)		(0x800 + 0x4 * (N))
>> 
>>  /* Mapping Table */
>>  #define SPMI_MAPPING_TABLE_REG(N)	(0x0B00 + (4 * (N)))
>> @@ -52,6 +52,8 @@
>>  #define SPMI_MAPPING_TABLE_TREE_DEPTH	16	/* Maximum of 16-bits */
>>  #define PMIC_ARB_MAX_PPID		BIT(12) /* PPID is 12bit */
>>  #define PMIC_ARB_APID_VALID		BIT(15)
>> +#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg)	((reg) & BIT(24))
>> +#define INVALID				(-1)
> 
> INVALID_EE? And then define it to be 0xff?
> 
ok... will modify it.
>> 
>>  /* Ownership Table */
>>  #define SPMI_OWNERSHIP_TABLE_REG(N)	(0x0700 + (4 * (N)))
>> @@ -86,6 +88,15 @@ enum pmic_arb_cmd_op_code {
>>  	PMIC_ARB_OP_ZERO_WRITE = 16,
>>  };
>> 
>> +/*
>> + * PMIC arbiter version 5 uses different register offsets for 
>> read/write vs
>> + * observer channels.
>> + */
>> +enum pmic_arb_channel {
>> +	PMIC_ARB_CHANNEL_RW,
>> +	PMIC_ARB_CHANNEL_OBS,
>> +};
>> +
>>  /* Maximum number of support PMIC peripherals */
>>  #define PMIC_ARB_MAX_PERIPHS		512
> [...]
>> @@ -112,7 +123,8 @@ enum pmic_arb_cmd_op_code {
>> 
>> +
>>  /* v2 offset per ppid and per ee */
>>  static int pmic_arb_offset_v2(struct spmi_pmic_arb *pmic_arb, u8 sid, 
>> u16 addr,
>> -				u32 *offset)
>> +			   enum pmic_arb_channel ch_type, u32 *offset)
>>  {
>>  	u16 apid;
>>  	u16 ppid;
>> @@ -841,6 +947,34 @@ static int pmic_arb_offset_v2(struct 
>> spmi_pmic_arb *pmic_arb, u8 sid, u16 addr,
>>  	return 0;
>>  }
>> 
>> +/*
>> + * v5 offset per ee and per apid for observer channels and per apid 
>> for
>> + * read/write channels.
>> + */
>> +static int pmic_arb_offset_v5(struct spmi_pmic_arb *pmic_arb, u8 sid, 
>> u16 addr,
>> +			   enum pmic_arb_channel ch_type, u32 *offset)
>> +{
>> +	u16 apid;
>> +	int rc;
>> +	u16 ppid = (sid << 8) | (addr >> 8);
>> +
>> +	rc = pmic_arb_ppid_to_apid_v5(pmic_arb, ppid);
>> +	if (rc < 0)
>> +		return rc;
>> +
>> +	apid = rc;
>> +	switch (ch_type) {
>> +	case PMIC_ARB_CHANNEL_OBS:
>> +		*offset = 0x10000 * pmic_arb->ee + 0x80 * apid;
>> +		break;
>> +	case PMIC_ARB_CHANNEL_RW:
>> +		*offset = 0x10000 * apid;
>> +		break;
>> +	}
>> +
>> +	return 0;
> 
> Why doesn't this also return an iomem pointer?
Actually the purpose of this function is to find the offset of the APID.
That's why we are not returning the iomem pointer. But we can return the 
offset
from this function, instead of a pass by pointer. Will change it to 
return the offset
in next patch.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-07-06 10:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-03 12:52 [PATCH V1 0/4]: spmi: pmic-arb: support for V5 HW and bug fixes Kiran Gunda
2017-07-03 12:52 ` [PATCH V1 1/4] spmi: pmic-arb: return __iomem pointer instead of offset Kiran Gunda
2017-07-06  6:51   ` Stephen Boyd
2017-07-03 12:52 ` [PATCH V1 2/4] spmi: pmic-arb: fix a possible null pointer dereference Kiran Gunda
2017-07-06  6:52   ` Stephen Boyd
2017-07-03 12:52 ` [PATCH V1 3/4] spmi: pmic-arb: add support for HW version 5 Kiran Gunda
2017-07-06  6:59   ` Stephen Boyd
2017-07-06 10:48     ` kgunda
2017-07-03 12:52 ` [PATCH V1 4/4] spmi: pmic-arb: Remove checking opc value not less than 0 Kiran Gunda
2017-07-06  6:53   ` Stephen Boyd
2017-07-06  6:53   ` Stephen Boyd
2017-07-06 10:21     ` kgunda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).