[PATCH 2/2] spmi: spmi-pmic-arb: add support for PMIC arbiter v8.5

Fenglin Wu posted 2 patches 12 hours ago
[PATCH 2/2] spmi: spmi-pmic-arb: add support for PMIC arbiter v8.5
Posted by Fenglin Wu 12 hours ago
PMIC arbiter v8.5 is an extension of PMIC arbiter v8 that updated
the definition of the channel status register bit fields. Add support
to handle this difference.

Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
---
 drivers/spmi/spmi-pmic-arb.c | 69 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 60 insertions(+), 9 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 69f8d456324a..deeaa39bb647 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -28,6 +28,7 @@
 #define PMIC_ARB_VERSION_V5_MIN		0x50000000
 #define PMIC_ARB_VERSION_V7_MIN		0x70000000
 #define PMIC_ARB_VERSION_V8_MIN		0x80000000
+#define PMIC_ARB_VERSION_V8P5_MIN	0x80050000
 #define PMIC_ARB_INT_EN			0x0004
 
 #define PMIC_ARB_FEATURES		0x0004
@@ -63,11 +64,34 @@
 #define SPMI_OWNERSHIP_PERIPH2OWNER(X)	((X) & 0x7)
 
 /* Channel Status fields */
-enum pmic_arb_chnl_status {
-	PMIC_ARB_STATUS_DONE	= BIT(0),
-	PMIC_ARB_STATUS_FAILURE	= BIT(1),
-	PMIC_ARB_STATUS_DENIED	= BIT(2),
-	PMIC_ARB_STATUS_DROPPED	= BIT(3),
+struct pmic_arb_chnl_status_mask {
+	u8	done;
+	u8	failure;
+	u8	crc;
+	u8	parity;
+	u8	nack;
+	u8	denied;
+	u8	dropped;
+};
+
+static const struct pmic_arb_chnl_status_mask chnl_status_mask = {
+	.done		= BIT(0),
+	.failure	= BIT(1),
+	.crc		= 0,
+	.parity		= 0,
+	.nack		= 0,
+	.denied		= BIT(2),
+	.dropped	= BIT(3),
+};
+
+static const struct pmic_arb_chnl_status_mask chnl_status_mask_v8p5 = {
+	.done		= BIT(0),
+	.failure	= BIT(1),
+	.crc		= BIT(2),
+	.parity		= BIT(3),
+	.nack		= BIT(4),
+	.denied		= BIT(5),
+	.dropped	= BIT(6),
 };
 
 /* Command register fields */
@@ -201,6 +225,7 @@ struct spmi_pmic_arb_bus {
  * @max_periphs:	Number of elements in apid_data[]
  * @buses:		per arbiter buses instances
  * @buses_available:	number of buses registered
+ * @chnl_status_mask:	Bit masks of channel status fields
  */
 struct spmi_pmic_arb {
 	void __iomem		*rd_base;
@@ -214,6 +239,7 @@ struct spmi_pmic_arb {
 	int			max_periphs;
 	struct spmi_pmic_arb_bus *buses[PMIC_ARB_MAX_BUSES];
 	int			buses_available;
+	const struct pmic_arb_chnl_status_mask *chnl_status_mask;
 };
 
 /**
@@ -312,6 +338,7 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 {
 	struct spmi_pmic_arb_bus *bus = spmi_controller_get_drvdata(ctrl);
 	struct spmi_pmic_arb *pmic_arb = bus->pmic_arb;
+	const struct pmic_arb_chnl_status_mask *mask;
 	u32 status = 0;
 	u32 timeout = PMIC_ARB_TIMEOUT_US;
 	u32 offset;
@@ -323,30 +350,49 @@ static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
 
 	offset = rc;
 	offset += PMIC_ARB_STATUS;
+	mask = pmic_arb->chnl_status_mask;
 
 	while (timeout--) {
 		status = readl_relaxed(base + offset);
 
-		if (status & PMIC_ARB_STATUS_DONE) {
-			if (status & PMIC_ARB_STATUS_DENIED) {
+		if (status & mask->done) {
+			if (status & mask->denied) {
 				dev_err(&ctrl->dev, "%s: %#x %#x: transaction denied (%#x)\n",
 					__func__, sid, addr, status);
 				return -EPERM;
 			}
 
-			if (status & PMIC_ARB_STATUS_FAILURE) {
+			if (status & mask->failure) {
 				dev_err(&ctrl->dev, "%s: %#x %#x: transaction failed (%#x) reg: 0x%x\n",
 					__func__, sid, addr, status, offset);
 				WARN_ON(1);
 				return -EIO;
 			}
 
-			if (status & PMIC_ARB_STATUS_DROPPED) {
+			if (status & mask->dropped) {
 				dev_err(&ctrl->dev, "%s: %#x %#x: transaction dropped (%#x)\n",
 					__func__, sid, addr, status);
 				return -EIO;
 			}
 
+			if (status & mask->crc) {
+				dev_err(&ctrl->dev, "%s: %#x %#x: CRC error (%#x)\n",
+					__func__, sid, addr, status);
+				return -EIO;
+			}
+
+			if (status & mask->parity) {
+				dev_err(&ctrl->dev, "%s: %#x %#x: parity error (%#x)\n",
+					__func__, sid, addr, status);
+				return -EIO;
+			}
+
+			if (status & mask->nack) {
+				dev_err(&ctrl->dev, "%s: %#x %#x: NACK error (%#x)\n",
+					__func__, sid, addr, status);
+				return -EIO;
+			}
+
 			return 0;
 		}
 		udelay(1);
@@ -2033,6 +2079,11 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev)
 	else
 		pmic_arb->ver_ops = &pmic_arb_v8;
 
+	if (hw_ver < PMIC_ARB_VERSION_V8P5_MIN)
+		pmic_arb->chnl_status_mask = &chnl_status_mask;
+	else
+		pmic_arb->chnl_status_mask = &chnl_status_mask_v8p5;
+
 	err = pmic_arb->ver_ops->get_core_resources(pdev, core);
 	if (err)
 		return err;

-- 
2.43.0
Re: [PATCH 2/2] spmi: spmi-pmic-arb: add support for PMIC arbiter v8.5
Posted by Dmitry Baryshkov 11 hours ago
On Wed, Apr 01, 2026 at 02:41:24AM -0700, Fenglin Wu wrote:
> PMIC arbiter v8.5 is an extension of PMIC arbiter v8 that updated
> the definition of the channel status register bit fields. Add support
> to handle this difference.
> 
> Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
> ---
>  drivers/spmi/spmi-pmic-arb.c | 69 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 60 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
> index 69f8d456324a..deeaa39bb647 100644
> --- a/drivers/spmi/spmi-pmic-arb.c
> +++ b/drivers/spmi/spmi-pmic-arb.c
> @@ -28,6 +28,7 @@
>  #define PMIC_ARB_VERSION_V5_MIN		0x50000000
>  #define PMIC_ARB_VERSION_V7_MIN		0x70000000
>  #define PMIC_ARB_VERSION_V8_MIN		0x80000000
> +#define PMIC_ARB_VERSION_V8P5_MIN	0x80050000
>  #define PMIC_ARB_INT_EN			0x0004
>  
>  #define PMIC_ARB_FEATURES		0x0004
> @@ -63,11 +64,34 @@
>  #define SPMI_OWNERSHIP_PERIPH2OWNER(X)	((X) & 0x7)
>  
>  /* Channel Status fields */
> -enum pmic_arb_chnl_status {
> -	PMIC_ARB_STATUS_DONE	= BIT(0),
> -	PMIC_ARB_STATUS_FAILURE	= BIT(1),
> -	PMIC_ARB_STATUS_DENIED	= BIT(2),
> -	PMIC_ARB_STATUS_DROPPED	= BIT(3),
> +struct pmic_arb_chnl_status_mask {
> +	u8	done;
> +	u8	failure;
> +	u8	crc;
> +	u8	parity;
> +	u8	nack;
> +	u8	denied;
> +	u8	dropped;
> +};
> +
> +static const struct pmic_arb_chnl_status_mask chnl_status_mask = {
> +	.done		= BIT(0),
> +	.failure	= BIT(1),
> +	.crc		= 0,
> +	.parity		= 0,
> +	.nack		= 0,
> +	.denied		= BIT(2),
> +	.dropped	= BIT(3),
> +};
> +
> +static const struct pmic_arb_chnl_status_mask chnl_status_mask_v8p5 = {
> +	.done		= BIT(0),
> +	.failure	= BIT(1),
> +	.crc		= BIT(2),
> +	.parity		= BIT(3),
> +	.nack		= BIT(4),
> +	.denied		= BIT(5),
> +	.dropped	= BIT(6),

Would it be better to extract generation-specific callback to decode the
error rather than defining the list of masks?

>  };
>  
>  /* Command register fields */

-- 
With best wishes
Dmitry
Re: [PATCH 2/2] spmi: spmi-pmic-arb: add support for PMIC arbiter v8.5
Posted by Konrad Dybcio 12 hours ago
On 4/1/26 11:41 AM, Fenglin Wu wrote:
> PMIC arbiter v8.5 is an extension of PMIC arbiter v8 that updated
> the definition of the channel status register bit fields. Add support
> to handle this difference.
> 
> Signed-off-by: Fenglin Wu <fenglin.wu@oss.qualcomm.com>
> ---

Please carry the internal review tags..

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad