rpm-smd: Avoid deadlocking while waiting for ACK from RPM

The RPM may give back no ACK when sending a command: this
means that it is locking up for some reason, or the
command itself didn't get sent to it.

When we get in this situation, an infinite wait for completion
will lock up the device for an infinite amount of time, until
the user manually reboots it with a power cut or KPDPWR+RESIN
combination.

For this reason, add a timeout to the completion wait (as of
now, very large I'd say) to avoid indefinitely waiting and,
if the timeout is reached with no ACK reply, just return a
-ETIMEDOUT error, so that we will either end up recoverying
from this error state or rebooting the device by panicking
the kernel if subsequent retries won't work.

This issue is largely seen on SMD communication and rarely
on SoCs using GLINK to communicate to the RPM.

Change-Id: Ifb701e767edab792d92d71fdc05a3e0edd91d766
Signed-off-by: Richard Raya <rdxzv.dev@gmail.com>
This commit is contained in:
Angelo G. Del Regno 2019-05-27 11:33:20 +02:00 committed by Richard Raya
parent a8725c7240
commit ef222e3b72

View File

@ -44,6 +44,8 @@
#define CREATE_TRACE_POINTS
#include <trace/events/trace_rpm_smd.h>
#define WAIT_FOR_ACK_TIMEOUT 5 * HZ
#define DEFAULT_BUFFER_SIZE 256
#define DEBUG_PRINT_BUFFER_SIZE 512
#define MAX_SLEEP_BUFFER 128
@ -1376,7 +1378,14 @@ int msm_rpm_wait_for_ack(uint32_t msg_id)
if (!elem)
return rc;
wait_for_completion(&elem->ack);
rc = wait_for_completion_timeout(&elem->ack, WAIT_FOR_ACK_TIMEOUT);
if (rc == 0) {
if (elem->errno == 0)
elem->errno = -ETIMEDOUT;
pr_err("Timeout while waiting for ack.\n");
}
trace_rpm_smd_ack_recvd(0, msg_id, 0xDEADFEED);
rc = elem->errno;