From 370d010f0ef09db7ab157a6b5d6d9a737b148f2a Mon Sep 17 00:00:00 2001 From: Timo Alho Date: Thu, 7 Sep 2017 12:31:01 +0300 Subject: 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: Timo Alho Acked-by: Jon Hunter Signed-off-by: Thierry Reding --- drivers/firmware/tegra/bpmp.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/firmware/tegra/bpmp.c') diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c index 73ca55b7b7ec..33683b5a0d48 100644 --- a/drivers/firmware/tegra/bpmp.c +++ b/drivers/firmware/tegra/bpmp.c @@ -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); -- cgit From 2e1e09ed423781d209c1fea773b1c3e614550ea5 Mon Sep 17 00:00:00 2001 From: Mikko Perttunen Date: Mon, 24 Jul 2017 19:29:16 +0300 Subject: firmware: tegra: Expose tegra_bpmp_mrq_return() Expose and export the tegra_bpmp_mrq_return() function for use by drivers outside the core BPMP driver. This function is used to reply to messages originating from the BPMP, which is required in the thermal driver. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/firmware/tegra/bpmp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/firmware/tegra/bpmp.c') diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c index 33683b5a0d48..aa4bbbd7bdb4 100644 --- a/drivers/firmware/tegra/bpmp.c +++ b/drivers/firmware/tegra/bpmp.c @@ -397,8 +397,8 @@ static struct tegra_bpmp_mrq *tegra_bpmp_find_mrq(struct tegra_bpmp *bpmp, return NULL; } -static void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, - int code, const void *data, size_t size) +void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, int code, + const void *data, size_t size) { unsigned long flags = channel->ib->flags; struct tegra_bpmp *bpmp = channel->bpmp; @@ -436,6 +436,7 @@ static void tegra_bpmp_mrq_return(struct tegra_bpmp_channel *channel, mbox_client_txdone(bpmp->mbox.channel, 0); } } +EXPORT_SYMBOL_GPL(tegra_bpmp_mrq_return); static void tegra_bpmp_handle_mrq(struct tegra_bpmp *bpmp, unsigned int mrq, -- cgit From f2381f652266fabfb7a8f5c4b2a05de36cad3a73 Mon Sep 17 00:00:00 2001 From: Timo Alho Date: Tue, 3 Oct 2017 09:12:13 +0300 Subject: firmware: tegra: Add BPMP debugfs support Tegra power management firmware running on the co-processor (BPMP) implements a simple pseudo file system akin to debugfs. The file system can be used for debugging purposes to examine and change the status of selected resources controlled by the firmware (such as clocks, resets, voltages, powergates, ...). Add support to "mirror" the firmware's file system to debugfs. At boot, query firmware for a list of all possible files and create corresponding debugfs entries. Read/write of individual files is implemented by sending a Message ReQuest (MRQ) that passes the full file path name and data to firmware via DRAM. Signed-off-by: Timo Alho Reviewed-by: Jon Hunter Signed-off-by: Thierry Reding --- drivers/firmware/tegra/bpmp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/firmware/tegra/bpmp.c') diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c index aa4bbbd7bdb4..a7f461f2e650 100644 --- a/drivers/firmware/tegra/bpmp.c +++ b/drivers/firmware/tegra/bpmp.c @@ -835,6 +835,10 @@ static int tegra_bpmp_probe(struct platform_device *pdev) if (err < 0) goto free_mrq; + err = tegra_bpmp_init_debugfs(bpmp); + if (err < 0) + dev_err(&pdev->dev, "debugfs initialization failed: %d\n", err); + return 0; free_mrq: -- cgit