Skip to contentSkip to conversation

firmware: tegra: add checks for BPMP error return code

PATCH Applied Timo Alho 5 participants 20 messages Sep 7, 2017 – Oct 21, 2017

Subsystems (4)
lore
Share & tools
lore

Timo Alho

author
#0 lore raw

cover firmware: tegra: add checks for BPMP error return code

Hi Thierry,

There is a bug in the BPMP driver as error code in response message is not being checked.

Patch 1 adds the error code as part of tegra_bpmp_message struct and propagates that code to callers

Patches 2 through 4 add code to client drivers to check the error code appropriately

BR,
Timo

Timo Alho (4):
firmware: tegra: propagate error code to caller
clk: tegra: check BPMP response return code
reset: tegra: check BPMP response return code soc/tegra: bpmp: check BPMP response return code

 drivers/clk/tegra/clk-bpmp.c       | 15 ++++++++++-----
 drivers/firmware/tegra/bpmp.c      | 22 ++++++++++++++++------
 drivers/reset/tegra/reset-bpmp.c   |  9 ++++++++-
 drivers/soc/tegra/powergate-bpmp.c | 15 +++++++++++++--
 include/soc/tegra/bpmp.h           |  1 +
 5 files changed, 48 insertions(+), 14 deletions(-)
Signature · 1 line
2.7.4
author
#1 lore raw

PATCH 1/4 firmware: tegra: propagate error code to caller

Response messages from Tegra BPMP firmware contain an error return code as the first word of payload. The error code is used to indicate incorrectly formatted request message or use of non-existing resource (clk, reset, powergate) identifier. Current implementation of tegra_bpmp_transfer() ignores this code and does not pass it to caller. Fix this by adding an extra struct member to tegra_bpmp_message and populate that with return code.

---
 drivers/firmware/tegra/bpmp.c | 22 ++++++++++++++++------
 include/soc/tegra/bpmp.h      |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)
drivers/firmware/tegra/bpmp.c +16 -6
index 73ca55b..33683b5 100644
@@ -194,16 +194,24 @@ static int tegra_bpmp_wait_master_free(struct tegra_bpmp_channel *channel)
 }
 
 static ssize_t __tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
-					 void *data, size_t size)
+					 void *data, size_t size, int *ret)
 {
+	int err;
+
 	if (data && size > 0)
 		memcpy(data, channel->ib->data, size);
 
-	return tegra_ivc_read_advance(channel->ivc);
+	err = tegra_ivc_read_advance(channel->ivc);
+	if (err < 0)
+		return err;
+
+	*ret = channel->ib->code;
+
+	return 0;
 }
 
 static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
-				       void *data, size_t size)
+				       void *data, size_t size, int *ret)
 {
 	struct tegra_bpmp *bpmp = channel->bpmp;
 	unsigned long flags;
@@ -217,7 +225,7 @@ static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
 	}
 
 	spin_lock_irqsave(&bpmp->lock, flags);
-	err = __tegra_bpmp_channel_read(channel, data, size);
+	err = __tegra_bpmp_channel_read(channel, data, size, ret);
 	clear_bit(index, bpmp->threaded.allocated);
 	spin_unlock_irqrestore(&bpmp->lock, flags);
 
@@ -337,7 +345,8 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
 	if (err < 0)
 		return err;
 
-	return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size);
+	return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size,
+					 &msg->rx.ret);
 }
 EXPORT_SYMBOL_GPL(tegra_bpmp_transfer_atomic);
 
@@ -371,7 +380,8 @@ int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
 	if (err == 0)
 		return -ETIMEDOUT;
 
-	return tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size);
+	return tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size,
+				       &msg->rx.ret);
 }
 EXPORT_SYMBOL_GPL(tegra_bpmp_transfer);
 
include/soc/tegra/bpmp.h +1 -0
index 9ba6522..57519f4 100644
@@ -110,6 +110,7 @@ struct tegra_bpmp_message {
 	struct {
 		void *data;
 		size_t size;
+		int ret;
 	} rx;
 };
 
Signature · 1 line
2.7.4
maintainer Acked-by on v1 1/4
#2 lore raw

Re: [PATCH 1/4] firmware: tegra: propagate error code to caller

Quoted 80 lines · Timo Alho

Response messages from Tegra BPMP firmware contain an error return code as the first word of payload. The error code is used to indicate incorrectly formatted request message or use of non-existing resource (clk, reset, powergate) identifier. Current implementation of tegra_bpmp_transfer() ignores this code and does not pass it to caller. Fix this by adding an extra struct member to tegra_bpmp_message and populate that with return code.

---
 drivers/firmware/tegra/bpmp.c | 22 ++++++++++++++++------
 include/soc/tegra/bpmp.h      |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)
drivers/firmware/tegra/bpmp.c +16 -6
index 73ca55b..33683b5 100644
@@ -194,16 +194,24 @@ static int tegra_bpmp_wait_master_free(struct tegra_bpmp_channel *channel)
 }
 
 static ssize_t __tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
-					 void *data, size_t size)
+					 void *data, size_t size, int *ret)
 {
+	int err;
+
 	if (data && size > 0)
 		memcpy(data, channel->ib->data, size);
 
-	return tegra_ivc_read_advance(channel->ivc);
+	err = tegra_ivc_read_advance(channel->ivc);
+	if (err < 0)
+		return err;
+
+	*ret = channel->ib->code;
+
+	return 0;
 }
 
 static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
-				       void *data, size_t size)
+				       void *data, size_t size, int *ret)
 {
 	struct tegra_bpmp *bpmp = channel->bpmp;
 	unsigned long flags;
@@ -217,7 +225,7 @@ static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
 	}
 
 	spin_lock_irqsave(&bpmp->lock, flags);
-	err = __tegra_bpmp_channel_read(channel, data, size);
+	err = __tegra_bpmp_channel_read(channel, data, size, ret);
 	clear_bit(index, bpmp->threaded.allocated);
 	spin_unlock_irqrestore(&bpmp->lock, flags);
 
@@ -337,7 +345,8 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
 	if (err < 0)
 		return err;
 
-	return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size);
+	return __tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size,
+					 &msg->rx.ret);
 }
 EXPORT_SYMBOL_GPL(tegra_bpmp_transfer_atomic);
 
@@ -371,7 +380,8 @@ int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
 	if (err == 0)
 		return -ETIMEDOUT;
 
-	return tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size);
+	return tegra_bpmp_channel_read(channel, msg->rx.data, msg->rx.size,
+				       &msg->rx.ret);
 }
 EXPORT_SYMBOL_GPL(tegra_bpmp_transfer);
 
include/soc/tegra/bpmp.h +0 -0
index 9ba6522..57519f4 100644

include/soc/tegra/bpmp.h struct tegra_bpmp_message { · line 115

Quoted 6 lines
include/soc/tegra/bpmp.h +1 -0
@@ -110,6 +110,7 @@ struct tegra_bpmp_message {
 	struct {
 		void *data;
 		size_t size;
+		int ret;
 	} rx;
 };

Looks good to me ...

Cheers
Jon

Signature · 1 line
nvpublic
#3 lore raw

Re: [PATCH 1/4] firmware: tegra: propagate error code to caller

In reply to Timo Alho
Quoted 8 lines · Timo Alho

Response messages from Tegra BPMP firmware contain an error return code as the first word of payload. The error code is used to indicate incorrectly formatted request message or use of non-existing resource (clk, reset, powergate) identifier. Current implementation of tegra_bpmp_transfer() ignores this code and does not pass it to caller. Fix this by adding an extra struct member to tegra_bpmp_message and populate that with return code.

Quoted 5 lines
---
 drivers/firmware/tegra/bpmp.c | 22 ++++++++++++++++------
 include/soc/tegra/bpmp.h      |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)

Applied, thanks.

Thierry

author
#4 lore raw

PATCH 2/4 clk: tegra: check BPMP response return code

In reply to Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
 drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/tegra/clk-bpmp.c +10 -5
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
 	struct {
 		void *data;
 		size_t size;
+		int ret;
 	} rx;
 };
 
@@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
 	struct mrq_clk_request request;
 	struct tegra_bpmp_message msg;
 	void *req = &request;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd_and_id = (clk->cmd << 24) | clk->id;
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
 	msg.rx.data = clk->rx.data;
 	msg.rx.size = clk->rx.size;
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
@@ -414,11 +422,8 @@ static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
 		struct tegra_bpmp_clk_info *info = &clocks[count];
 
 		err = tegra_bpmp_clk_get_info(bpmp, id, info);
-		if (err < 0) {
-			dev_err(bpmp->dev, "failed to query clock %u: %d\n",
-				id, err);
+		if (err < 0)
 			continue;
-		}
 
 		if (info->num_parents >= U8_MAX) {
 			dev_err(bpmp->dev,
Signature · 1 line
2.7.4
maintainer
#5 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

Quoted 33 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
 drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/tegra/clk-bpmp.c +2 -0
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
 	struct {
 		void *data;
 		size_t size;
+		int ret;
 	} rx;
 };
 
@@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
 	struct mrq_clk_request request;
 	struct tegra_bpmp_message msg;
 	void *req = &request;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd_and_id = (clk->cmd << 24) | clk->id;

drivers/clk/tegra/clk-bpmp.c static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp, · line 93

Quoted 9 lines
drivers/clk/tegra/clk-bpmp.c +5 -1
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
 	msg.rx.data = clk->rx.data;
 	msg.rx.size = clk->rx.size;
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;

I assume that the error codes returned do not correlated to the Linux error codes here. Is that correct? If not we could just return the actual error code. Otherwise would it be useful to print a message with the bpmp error code for debug?

Quoted 9 lines
drivers/clk/tegra/clk-bpmp.c +2 -0
+
+	return 0;
 }
 
 static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
@@ -414,11 +422,8 @@ static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
 		struct tegra_bpmp_clk_info *info = &clocks[count];
 

drivers/clk/tegra/clk-bpmp.c static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp, · line 429

Quoted 10 lines
drivers/clk/tegra/clk-bpmp.c +1 -4
 		err = tegra_bpmp_clk_get_info(bpmp, id, info);
-		if (err < 0) {
-			dev_err(bpmp->dev, "failed to query clock %u: %d\n",
-				id, err);
+		if (err < 0)
 			continue;
-		}
 
 		if (info->num_parents >= U8_MAX) {
 			dev_err(bpmp->dev,

Cheers
Jon

Signature · 1 line
nvpublic
author
#6 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

Hi Jon,

Quoted 39 lines · Jonathan Hunter
Quoted 36 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
  drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----
  1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/tegra/clk-bpmp.c +2 -0
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
  	struct {
  		void *data;
  		size_t size;
+		int ret;
  	} rx;
  };
 
@@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
  	struct mrq_clk_request request;
  	struct tegra_bpmp_message msg;
  	void *req = &request;
+	int err;
 
  	memset(&request, 0, sizeof(request));
  	request.cmd_and_id = (clk->cmd << 24) | clk->id;
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
  	msg.rx.data = clk->rx.data;
  	msg.rx.size = clk->rx.size;
 
Quoted 11 lines

drivers/clk/tegra/clk-bpmp.c static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp, · line 93

Quoted 6 lines
drivers/clk/tegra/clk-bpmp.c +5 -1
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;

I assume that the error codes returned do not correlated to the Linux error codes here. Is that correct? If not we could just return the actual error code. Otherwise would it be useful to print a message with the bpmp error code for debug?

The error codes are not 1:1 match with Linux. Unfortunately, printing message for debug is not either viable as during clock probing we are expecting many of the calls to return -BPMP_EINVAL to indicate that particular clock ID is unused.

-Timo

maintainer
#7 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

Quoted 53 lines · Timo Alho

Hi Jon,

Quoted 41 lines · Jonathan Hunter
Quoted 38 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
  drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----

  1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/tegra/clk-bpmp.c +1 -0
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
       struct {
           void *data;
           size_t size;
+        int ret;
       } rx;
   };

  @@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
      struct mrq_clk_request request;
      struct tegra_bpmp_message msg;
      void *req = &request;
+    int err;
        memset(&request, 0, sizeof(request)); request.cmd_and_id = (clk->cmd << 24) | clk->id;

drivers/clk/tegra/clk-bpmp.c +2 -0
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct
 tegra_bpmp *bpmp,
       msg.rx.data = clk->rx.data;
       msg.rx.size = clk->rx.size;
   -    return tegra_bpmp_transfer(bpmp, &msg);
+    err = tegra_bpmp_transfer(bpmp, &msg);
+    if (err < 0)
Quoted 8 lines

drivers/clk/tegra/clk-bpmp.c static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp, · line 93

Quoted 3 lines
drivers/clk/tegra/clk-bpmp.c +3 -0
+        return err;
+    else if (msg.rx.ret < 0)
+        return -EINVAL;

I assume that the error codes returned do not correlated to the Linux error codes here. Is that correct? If not we could just return the actual error code. Otherwise would it be useful to print a message with the bpmp error code for debug?

Quoted 4 lines

The error codes are not 1:1 match with Linux. Unfortunately, printing message for debug is not either viable as during clock probing we are expecting many of the calls to return -BPMP_EINVAL to indicate that particular clock ID is unused.

OK. Could it return other errors other than BPMP_EINVAL? I am just wondering if we need to differentiate between unused and an actual error? Maybe that is not possible here?

Cheers
Jon

Signature · 1 line
nvpublic
author
#8 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

Quoted 55 lines · Jonathan Hunter
Quoted 53 lines · Timo Alho

Hi Jon,

Quoted 49 lines · Jonathan Hunter
Quoted 32 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
   drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----
   1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/tegra/clk-bpmp.c +1 -0
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
       struct {
           void *data;
           size_t size;
+        int ret;
       } rx;
   };
   @@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct

tegra_bpmp *bpmp,
      struct mrq_clk_request request;
      struct tegra_bpmp_message msg;
      void *req = &request;
+    int err;
        memset(&request, 0, sizeof(request)); request.cmd_and_id = (clk->cmd << 24) | clk->id;

drivers/clk/tegra/clk-bpmp.c static int tegra_bpmp_clk_transfer(struct · line 94

Quoted 9 lines
drivers/clk/tegra/clk-bpmp.c +5 -0
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct
 tegra_bpmp *bpmp,
       msg.rx.data = clk->rx.data;
       msg.rx.size = clk->rx.size;
   -    return tegra_bpmp_transfer(bpmp, &msg);
+    err = tegra_bpmp_transfer(bpmp, &msg);
+    if (err < 0)
+        return err;
+    else if (msg.rx.ret < 0)
+        return -EINVAL;

I assume that the error codes returned do not correlated to the Linux error codes here. Is that correct? If not we could just return the actual error code. Otherwise would it be useful to print a message with the bpmp error code for debug?

Quoted 8 lines
Quoted 4 lines

The error codes are not 1:1 match with Linux. Unfortunately, printing message for debug is not either viable as during clock probing we are expecting many of the calls to return -BPMP_EINVAL to indicate that particular clock ID is unused.

OK. Could it return other errors other than BPMP_EINVAL? I am just wondering if we need to differentiate between unused and an actual error? Maybe that is not possible here?

Other error codes are possible (though they are not explicitly documented in abi header). It's not easy to differentiate the error code at this level: -BPMP_EINVAL is "expected" condition with CMD_CLK_GET_ALL_INFO, whereas -BPMP_EINVAL is true error on other commands.

maintainer Acked-by
#9 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

Quoted 64 lines · Timo Alho
Quoted 61 lines · Jonathan Hunter
Quoted 58 lines · Timo Alho

Hi Jon,

Quoted 42 lines · Jonathan Hunter
Quoted 39 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
   drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----

   1 file changed, 10 insertions(+), 5 deletions(-)
drivers/clk/tegra/clk-bpmp.c +1 -0
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
        struct {
            void *data;
            size_t size;
+        int ret;
        } rx;
    };

   @@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
       struct mrq_clk_request request;
       struct tegra_bpmp_message msg;
       void *req = &request;
+    int err;
         memset(&request, 0, sizeof(request)); request.cmd_and_id = (clk->cmd << 24) | clk->id;

drivers/clk/tegra/clk-bpmp.c +2 -0
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct
 tegra_bpmp *bpmp,
        msg.rx.data = clk->rx.data;
        msg.rx.size = clk->rx.size;
    -    return tegra_bpmp_transfer(bpmp, &msg);
+    err = tegra_bpmp_transfer(bpmp, &msg);
+    if (err < 0)
Quoted 8 lines

drivers/clk/tegra/clk-bpmp.c static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp, · line 93

Quoted 3 lines
drivers/clk/tegra/clk-bpmp.c +3 -0
+        return err;
+    else if (msg.rx.ret < 0)
+        return -EINVAL;

I assume that the error codes returned do not correlated to the Linux error codes here. Is that correct? If not we could just return the actual error code. Otherwise would it be useful to print a message with the bpmp error code for debug?

The error codes are not 1:1 match with Linux. Unfortunately, printing message for debug is not either viable as during clock probing we are expecting many of the calls to return -BPMP_EINVAL to indicate that particular clock ID is unused.

Quoted 8 lines
Quoted 3 lines

OK. Could it return other errors other than BPMP_EINVAL? I am just wondering if we need to differentiate between unused and an actual error? Maybe that is not possible here?

Other error codes are possible (though they are not explicitly documented in abi header). It's not easy to differentiate the error code at this level: -BPMP_EINVAL is "expected" condition with CMD_CLK_GET_ALL_INFO, whereas -BPMP_EINVAL is true error on other commands.

OK, thanks for clarifying.

Cheers
Jon

Signature · 1 line
nvpublic
#10 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

In reply to Timo Alho
Quoted 11 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
 drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Hi Mike, Stephen,

do you mind if I pick this up into the Tegra tree? It has a build dependency on patch 1/4.

I only now realized that you guys weren't on Cc, hence quoting in full.

Thierry

Quoted 51 lines
drivers/clk/tegra/clk-bpmp.c +10 -5
index 638ace6..a896692 100644
@@ -55,6 +55,7 @@ struct tegra_bpmp_clk_message {
 	struct {
 		void *data;
 		size_t size;
+		int ret;
 	} rx;
 };
 
@@ -64,6 +65,7 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
 	struct mrq_clk_request request;
 	struct tegra_bpmp_message msg;
 	void *req = &request;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd_and_id = (clk->cmd << 24) | clk->id;
@@ -84,7 +86,13 @@ static int tegra_bpmp_clk_transfer(struct tegra_bpmp *bpmp,
 	msg.rx.data = clk->rx.data;
 	msg.rx.size = clk->rx.size;
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_clk_prepare(struct clk_hw *hw)
@@ -414,11 +422,8 @@ static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
 		struct tegra_bpmp_clk_info *info = &clocks[count];
 
 		err = tegra_bpmp_clk_get_info(bpmp, id, info);
-		if (err < 0) {
-			dev_err(bpmp->dev, "failed to query clock %u: %d\n",
-				id, err);
+		if (err < 0)
 			continue;
-		}
 
 		if (info->num_parents >= U8_MAX) {
 			dev_err(bpmp->dev,
Signature · 1 line
2.7.4
Acked-by
#11 lore raw

Re: [PATCH 2/4] clk: tegra: check BPMP response return code

Quoted 13 lines · Thierry Reding
Quoted 11 lines · Timo Alho

Check return code in BPMP response message(s). The typical error case is when clock operation is attempted with invalid clock identifier.

Also remove error print from call to clk_get_info() as the implementation loops through range of all possible identifier, but the operation is expected error out when the clock id is unused.

---
 drivers/clk/tegra/clk-bpmp.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
Quoted 8 lines

Hi Mike, Stephen,

do you mind if I pick this up into the Tegra tree? It has a build dependency on patch 1/4.

I only now realized that you guys weren't on Cc, hence quoting in full.

No worries

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
author
#12 lore raw

PATCH 3/4 reset: tegra: check BPMP response return code

In reply to Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/reset/tegra/reset-bpmp.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/reset/tegra/reset-bpmp.c +8 -1
index 5daf2ee..fac2db6 100644
@@ -23,6 +23,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
 	struct mrq_reset_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = command;
@@ -33,7 +34,13 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc,
Signature · 1 line
2.7.4
maintainer Acked-by on v1 3/4
#13 lore raw

Re: [PATCH 3/4] reset: tegra: check BPMP response return code

Quoted 24 lines · Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/reset/tegra/reset-bpmp.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/reset/tegra/reset-bpmp.c +1 -1
index 5daf2ee..fac2db6 100644
@@ -23,6 +23,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
 	struct mrq_reset_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = command;
@@ -33,7 +34,13 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
-	return tegra_bpmp_transfer(bpmp, &msg);

drivers/reset/tegra/reset-bpmp.c static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc, · line 46

Quoted 10 lines
drivers/reset/tegra/reset-bpmp.c +7 -0
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc,

Cheers
Jon

Signature · 1 line
nvpublic
#14 lore raw

Re: [PATCH 3/4] reset: tegra: check BPMP response return code

In reply to Timo Alho
Quoted 6 lines · Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/reset/tegra/reset-bpmp.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Hi Philipp,

Would you provide an Acked-by on this so that I can take it into the Tegra tree? There's a build dependency on patch 1/4 in the series.

Quoting in full since you were not previously on Cc, unfortunately.

Timo, please remember to always Cc the relevant maintainers.

Thierry

Quoted 30 lines
drivers/reset/tegra/reset-bpmp.c +8 -1
index 5daf2ee..fac2db6 100644
@@ -23,6 +23,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
 	struct mrq_reset_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = command;
@@ -33,7 +34,13 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc,
Signature · 1 line
2.7.4
maintainer Acked-by
#15 lore raw

Re: [PATCH 3/4] reset: tegra: check BPMP response return code

Hi Thierry,

Quoted 8 lines · Thierry Reding
Quoted 6 lines · Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/reset/tegra/reset-bpmp.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
Quoted 4 lines

Hi Philipp,

Would you provide an Acked-by on this so that I can take it into the Tegra tree? There's a build dependency on patch 1/4 in the series.

to take this via the Tegra tree.

Quoted 22 lines

Quoting in full since you were not previously on Cc, unfortunately.

Timo, please remember to always Cc the relevant maintainers.

Thierry

Quoted 16 lines
drivers/reset/tegra/reset-bpmp.c +1 -0
index 5daf2ee..fac2db6 100644
@@ -23,6 +23,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
 	struct mrq_reset_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = command;
@@ -33,7 +34,13 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
Quoted 6 lines

drivers/reset/tegra/reset-bpmp.c static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc, · line 41

Quoted 6 lines
drivers/reset/tegra/reset-bpmp.c +5 -1
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;

I don't really understand why you complicate the call sites like this instead of just letting tegra_bmp_transfer return -EINVAL if msg.rx.ret < 0, but I haven't seen the other patches.

regards
Philipp

#16 lore raw

Re: [PATCH 3/4] reset: tegra: check BPMP response return code

Quoted 11 lines · Philipp Zabel

Hi Thierry,

Quoted 8 lines · Thierry Reding
Quoted 6 lines · Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/reset/tegra/reset-bpmp.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
Quoted 8 lines
Quoted 4 lines

Hi Philipp,

Would you provide an Acked-by on this so that I can take it into the Tegra tree? There's a build dependency on patch 1/4 in the series.

to take this via the Tegra tree.

Thanks!

Quoted 22 lines
Quoted 22 lines

Quoting in full since you were not previously on Cc, unfortunately.

Timo, please remember to always Cc the relevant maintainers.

Thierry

Quoted 16 lines
drivers/reset/tegra/reset-bpmp.c +1 -0
index 5daf2ee..fac2db6 100644
@@ -23,6 +23,7 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc);
 	struct mrq_reset_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = command;
@@ -33,7 +34,13 @@ static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
Quoted 10 lines
Quoted 6 lines

drivers/reset/tegra/reset-bpmp.c static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc, · line 41

Quoted 6 lines
drivers/reset/tegra/reset-bpmp.c +5 -1
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;

I don't really understand why you complicate the call sites like this instead of just letting tegra_bmp_transfer return -EINVAL if msg.rx.ret < 0, but I haven't seen the other patches.

Timo replied to a similar question from Jon here:

	https://patchwork.ozlabs.org/patch/810934/

Essentially this boils down to that there are cases where we may want to know the exact error because it is relevant. In this case, we don't, but BPMP provides a number of other services where the errors may be useful.

Thierry

author
#17 lore raw

PATCH 4/4 soc/tegra: bpmp: check BPMP response return code

In reply to Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/soc/tegra/powergate-bpmp.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/soc/tegra/powergate-bpmp.c +13 -2
index 8fc3560..82c7e27 100644
@@ -42,6 +42,7 @@ static int tegra_bpmp_powergate_set_state(struct tegra_bpmp *bpmp,
 {
 	struct mrq_pg_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = CMD_PG_SET_STATE;
@@ -53,7 +54,13 @@ static int tegra_bpmp_powergate_set_state(struct tegra_bpmp *bpmp,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_powergate_get_state(struct tegra_bpmp *bpmp,
@@ -80,6 +87,8 @@ static int tegra_bpmp_powergate_get_state(struct tegra_bpmp *bpmp,
 	err = tegra_bpmp_transfer(bpmp, &msg);
 	if (err < 0)
 		return PG_STATE_OFF;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
 
 	return response.get_state.state;
 }
@@ -106,6 +115,8 @@ static int tegra_bpmp_powergate_get_max_id(struct tegra_bpmp *bpmp)
 	err = tegra_bpmp_transfer(bpmp, &msg);
 	if (err < 0)
 		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
 
 	return response.get_max_id.max_id;
 }
@@ -132,7 +143,7 @@ static char *tegra_bpmp_powergate_get_name(struct tegra_bpmp *bpmp,
 	msg.rx.size = sizeof(response);
 
 	err = tegra_bpmp_transfer(bpmp, &msg);
-	if (err < 0)
+	if (err < 0 || msg.rx.ret < 0)
 		return NULL;
 
 	return kstrdup(response.get_name.name, GFP_KERNEL);
Signature · 1 line
2.7.4
maintainer Acked-by on v1 4/4
#18 lore raw

Re: [PATCH 4/4] soc/tegra: bpmp: check BPMP response return code

Quoted 53 lines · Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/soc/tegra/powergate-bpmp.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/soc/tegra/powergate-bpmp.c +12 -1
index 8fc3560..82c7e27 100644
@@ -42,6 +42,7 @@ static int tegra_bpmp_powergate_set_state(struct tegra_bpmp *bpmp,
 {
 	struct mrq_pg_request request;
 	struct tegra_bpmp_message msg;
+	int err;
 
 	memset(&request, 0, sizeof(request));
 	request.cmd = CMD_PG_SET_STATE;
@@ -53,7 +54,13 @@ static int tegra_bpmp_powergate_set_state(struct tegra_bpmp *bpmp,
 	msg.tx.data = &request;
 	msg.tx.size = sizeof(request);
 
-	return tegra_bpmp_transfer(bpmp, &msg);
+	err = tegra_bpmp_transfer(bpmp, &msg);
+	if (err < 0)
+		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
+
+	return 0;
 }
 
 static int tegra_bpmp_powergate_get_state(struct tegra_bpmp *bpmp,
@@ -80,6 +87,8 @@ static int tegra_bpmp_powergate_get_state(struct tegra_bpmp *bpmp,
 	err = tegra_bpmp_transfer(bpmp, &msg);
 	if (err < 0)
 		return PG_STATE_OFF;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
 
 	return response.get_state.state;
 }
@@ -106,6 +115,8 @@ static int tegra_bpmp_powergate_get_max_id(struct tegra_bpmp *bpmp)
 	err = tegra_bpmp_transfer(bpmp, &msg);
 	if (err < 0)
 		return err;
+	else if (msg.rx.ret < 0)
+		return -EINVAL;
 
 	return response.get_max_id.max_id;
 }

drivers/soc/tegra/powergate-bpmp.c static char *tegra_bpmp_powergate_get_name(struct tegra_bpmp *bpmp, · line 149

Quoted 8 lines
drivers/soc/tegra/powergate-bpmp.c +1 -1
@@ -132,7 +143,7 @@ static char *tegra_bpmp_powergate_get_name(struct tegra_bpmp *bpmp,
 	msg.rx.size = sizeof(response);
 
 	err = tegra_bpmp_transfer(bpmp, &msg);
-	if (err < 0)
+	if (err < 0 || msg.rx.ret < 0)
 		return NULL;
 
 	return kstrdup(response.get_name.name, GFP_KERNEL);

Cheers
Jon

Signature · 1 line
nvpublic
#19 lore raw

Re: [PATCH 4/4] soc/tegra: bpmp: check BPMP response return code

In reply to Timo Alho
Quoted 6 lines · Timo Alho

Add checks for return code in BPMP response message.

---
 drivers/soc/tegra/powergate-bpmp.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

Applied, thanks.

Thierry