Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd5f442c authored by Archana Sathyakumar's avatar Archana Sathyakumar
Browse files

msm: rpm-smd: Read RPM acks before entering system sleep



The driver does not currently handle acks from RPM for the sleep sets
sent to RPM to reduce the time to suspend. If the cores execute
power collapse modes part of suspend, we might overrun the RPM SMD
buffer causing a fatal error in RPM.

Read the ACK if more than 24 messages have been sent before sending
another one.

Change-Id: I6a5cd5409282c960c3f694800f45ae3ff8b366fe
Signed-off-by: default avatarArchana Sathyakumar <asathyak@codeaurora.org>
parent 61d15c3a
Loading
Loading
Loading
Loading
+22 −9
Original line number Original line Diff line number Diff line
@@ -71,6 +71,7 @@ struct msm_rpm_driver_data {
#define INV_RSC "resource does not exist"
#define INV_RSC "resource does not exist"
#define ERR "err\0"
#define ERR "err\0"
#define MAX_ERR_BUFFER_SIZE 128
#define MAX_ERR_BUFFER_SIZE 128
#define MAX_WAIT_ON_ACK 24
#define INIT_ERROR 1
#define INIT_ERROR 1


static ATOMIC_NOTIFIER_HEAD(msm_rpm_sleep_notifier);
static ATOMIC_NOTIFIER_HEAD(msm_rpm_sleep_notifier);
@@ -130,7 +131,6 @@ struct slp_buf {
	bool valid;
	bool valid;
};
};
static struct rb_root tr_root = RB_ROOT;
static struct rb_root tr_root = RB_ROOT;

static int msm_rpm_send_smd_buffer(char *buf, int size, bool noirq);
static int msm_rpm_send_smd_buffer(char *buf, int size, bool noirq);
static uint32_t msm_rpm_get_next_msg_id(void);
static uint32_t msm_rpm_get_next_msg_id(void);


@@ -386,10 +386,15 @@ static void msm_rpm_print_sleep_buffer(struct slp_buf *s)
	printk(buf);
	printk(buf);
}
}


static struct msm_rpm_driver_data msm_rpm_data;

static int msm_rpm_flush_requests(bool print)
static int msm_rpm_flush_requests(bool print)
{
{
	struct rb_node *t;
	struct rb_node *t;
	int ret;
	int ret;
	int pkt_sz;
	char buf[MAX_ERR_BUFFER_SIZE] = {0};
	int count = 0;


	for (t = rb_first(&tr_root); t; t = rb_next(t)) {
	for (t = rb_first(&tr_root); t; t = rb_next(t)) {


@@ -404,12 +409,23 @@ static int msm_rpm_flush_requests(bool print)
		get_msg_id(s->buf) = msm_rpm_get_next_msg_id();
		get_msg_id(s->buf) = msm_rpm_get_next_msg_id();
		ret = msm_rpm_send_smd_buffer(s->buf,
		ret = msm_rpm_send_smd_buffer(s->buf,
				get_buf_len(s->buf), true);
				get_buf_len(s->buf), true);
		/* By not adding the message to a wait list we can reduce

		 * latency involved in waiting for a ACK from RPM. The ACK
		/*
		 * messages will be processed when we wakeup from sleep but
		 * RPM acks need to be handled here if we have sent over
		 * processing should be minimal
		 * 24 messages such that we do not overrun SMD buffer. Since
		 * msm_rpm_wait_for_ack_noirq(get_msg_id(s->buf));
		 * we expect only sleep sets at this point (RPM PC would be
		 * disallowed if we had pending active requests), we need not
		 * process these sleep set acks.
		 */
		 */
		count++;
		if (count > MAX_WAIT_ON_ACK) {
			int len;
			pkt_sz = smd_cur_packet_size(msm_rpm_data.ch_info);
			if (pkt_sz)
				len = smd_read(msm_rpm_data.ch_info, buf,
							pkt_sz);
			count--;
		}


		WARN_ON(ret != get_buf_len(s->buf));
		WARN_ON(ret != get_buf_len(s->buf));


@@ -421,14 +437,11 @@ static int msm_rpm_flush_requests(bool print)
		s->valid = false;
		s->valid = false;
	}
	}
	return 0;
	return 0;

}
}




static atomic_t msm_rpm_msg_id = ATOMIC_INIT(0);
static atomic_t msm_rpm_msg_id = ATOMIC_INIT(0);


static struct msm_rpm_driver_data msm_rpm_data;

struct msm_rpm_request {
struct msm_rpm_request {
	struct rpm_request_header req_hdr;
	struct rpm_request_header req_hdr;
	struct rpm_message_header msg_hdr;
	struct rpm_message_header msg_hdr;