Commit 370d010f authored by Timo Alho's avatar Timo Alho Committed by Thierry Reding

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.
Signed-off-by: default avatarTimo Alho <talho@nvidia.com>
Acked-by: default avatarJon Hunter <jonathanh@nvidia.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent 2bd6bf03
...@@ -194,16 +194,24 @@ static int tegra_bpmp_wait_master_free(struct tegra_bpmp_channel *channel) ...@@ -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, 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) if (data && size > 0)
memcpy(data, channel->ib->data, size); 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, 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; struct tegra_bpmp *bpmp = channel->bpmp;
unsigned long flags; unsigned long flags;
...@@ -217,7 +225,7 @@ static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel, ...@@ -217,7 +225,7 @@ static ssize_t tegra_bpmp_channel_read(struct tegra_bpmp_channel *channel,
} }
spin_lock_irqsave(&bpmp->lock, flags); 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); clear_bit(index, bpmp->threaded.allocated);
spin_unlock_irqrestore(&bpmp->lock, flags); spin_unlock_irqrestore(&bpmp->lock, flags);
...@@ -337,7 +345,8 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp, ...@@ -337,7 +345,8 @@ int tegra_bpmp_transfer_atomic(struct tegra_bpmp *bpmp,
if (err < 0) if (err < 0)
return err; 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); EXPORT_SYMBOL_GPL(tegra_bpmp_transfer_atomic);
...@@ -371,7 +380,8 @@ int tegra_bpmp_transfer(struct tegra_bpmp *bpmp, ...@@ -371,7 +380,8 @@ int tegra_bpmp_transfer(struct tegra_bpmp *bpmp,
if (err == 0) if (err == 0)
return -ETIMEDOUT; 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); EXPORT_SYMBOL_GPL(tegra_bpmp_transfer);
......
...@@ -110,6 +110,7 @@ struct tegra_bpmp_message { ...@@ -110,6 +110,7 @@ struct tegra_bpmp_message {
struct { struct {
void *data; void *data;
size_t size; size_t size;
int ret;
} rx; } rx;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment