Skip to content

Commit 8f943dd

Browse files
committed
soc: microchip: mpfs: handle timeouts and failed services differently
The system controller will only deliver an interrupt if a service succeeds. This leaves us in the unfortunate position with current code where there is no way to differentiate between a legitimate timeout where the service has not completed & where it has completed, but failed. mbox_send_message() has its own completion, and it will time out of the system controller does not lower the busy flag. In this case, a timeout has occurred and the error can be propagated back to the caller. If the busy flag is lowered, but no interrupt has arrived to trigger the rx callback, the service can be deemed to have failed. Report -EBADMSG in this case so that callers can differentiate. Tested-by: Valentina Fernandez <valentina.fernandezalanis@microchip.com> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
1 parent 7606f4d commit 8f943dd

1 file changed

Lines changed: 22 additions & 5 deletions

File tree

drivers/soc/microchip/mpfs-sys-controller.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
#include <linux/platform_device.h>
1919
#include <soc/microchip/mpfs.h>
2020

21-
#define MPFS_SYS_CTRL_TIMEOUT_MS 100
21+
/*
22+
* This timeout must be long, as some services (example: image authentication)
23+
* take significant time to complete
24+
*/
25+
#define MPFS_SYS_CTRL_TIMEOUT_MS 30000
2226

2327
static DEFINE_MUTEX(transaction_lock);
2428

@@ -41,14 +45,26 @@ int mpfs_blocking_transaction(struct mpfs_sys_controller *sys_controller, struct
4145
reinit_completion(&sys_controller->c);
4246

4347
ret = mbox_send_message(sys_controller->chan, msg);
44-
if (ret < 0)
48+
if (ret < 0) {
49+
dev_warn(sys_controller->client.dev, "MPFS sys controller service timeout\n");
4550
goto out;
51+
}
4652

53+
/*
54+
* Unfortunately, the system controller will only deliver an interrupt
55+
* if a service succeeds. mbox_send_message() will block until the busy
56+
* flag is gone. If the busy flag is gone but no interrupt has arrived
57+
* to trigger the rx callback then the service can be deemed to have
58+
* failed.
59+
* The caller can then interrogate msg::response::resp_status to
60+
* determine the cause of the failure.
61+
* mbox_send_message() returns positive integers in the success path, so
62+
* ret needs to be cleared if we do get an interrupt.
63+
*/
4764
if (!wait_for_completion_timeout(&sys_controller->c, timeout)) {
48-
ret = -ETIMEDOUT;
49-
dev_warn(sys_controller->client.dev, "MPFS sys controller transaction timeout\n");
65+
ret = -EBADMSG;
66+
dev_warn(sys_controller->client.dev, "MPFS sys controller service failed\n");
5067
} else {
51-
/* mbox_send_message() returns positive integers on success */
5268
ret = 0;
5369
}
5470

@@ -107,6 +123,7 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev)
107123
sys_controller->client.dev = dev;
108124
sys_controller->client.rx_callback = rx_callback;
109125
sys_controller->client.tx_block = 1U;
126+
sys_controller->client.tx_tout = msecs_to_jiffies(MPFS_SYS_CTRL_TIMEOUT_MS);
110127

111128
sys_controller->chan = mbox_request_channel(&sys_controller->client, 0);
112129
if (IS_ERR(sys_controller->chan)) {

0 commit comments

Comments
 (0)