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

Commit 564b5e24 authored by Lina Iyer's avatar Lina Iyer Committed by Andy Gross
Browse files

drivers: qcom: rpmh: allow requests to be sent asynchronously



Platform drivers that want to send a request but do not want to block
until the RPMH request completes have now a new API -
rpmh_write_async().

The API allocates memory and send the requests and returns the control
back to the platform driver. The tx_done callback from the controller is
handled in the context of the controller's thread and frees the
allocated memory. This API allows RPMH requests from atomic contexts as
well.

Signed-off-by: default avatarLina Iyer <ilina@codeaurora.org>
Signed-off-by: default avatarRaju P.L.S.S.S.N <rplsssn@codeaurora.org>
Signed-off-by: default avatarAndy Gross <andy.gross@linaro.org>
parent 600513df
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ struct tcs_group {
 * @completion: triggered when request is done
 * @dev: the device making the request
 * @err: err return from the controller
 * @needs_free: check to free dynamically allocated request object
 */
struct rpmh_request {
	struct tcs_request msg;
@@ -61,6 +62,7 @@ struct rpmh_request {
	struct completion *completion;
	const struct device *dev;
	int err;
	bool needs_free;
};

/**
+51 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
		.cmd = { { 0 } },			\
		.completion = q,			\
		.dev = dev,				\
		.needs_free = false,				\
	}

#define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client)
@@ -75,6 +76,9 @@ void rpmh_tx_done(const struct tcs_request *msg, int r)
	/* Signal the blocking thread we are done */
	if (compl)
		complete(compl);

	if (rpm_msg->needs_free)
		kfree(rpm_msg);
}

static struct cache_req *__find_req(struct rpmh_ctrlr *ctrlr, u32 addr)
@@ -180,6 +184,53 @@ static int __rpmh_write(const struct device *dev, enum rpmh_state state,
	return ret;
}

static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state,
		const struct tcs_cmd *cmd, u32 n)
{
	if (!cmd || !n || n > MAX_RPMH_PAYLOAD)
		return -EINVAL;

	memcpy(req->cmd, cmd, n * sizeof(*cmd));

	req->msg.state = state;
	req->msg.cmds = req->cmd;
	req->msg.num_cmds = n;

	return 0;
}

/**
 * rpmh_write_async: Write a set of RPMH commands
 *
 * @dev: The device making the request
 * @state: Active/sleep set
 * @cmd: The payload data
 * @n: The number of elements in payload
 *
 * Write a set of RPMH commands, the order of commands is maintained
 * and will be sent as a single shot.
 */
int rpmh_write_async(const struct device *dev, enum rpmh_state state,
		     const struct tcs_cmd *cmd, u32 n)
{
	struct rpmh_request *rpm_msg;
	int ret;

	rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC);
	if (!rpm_msg)
		return -ENOMEM;
	rpm_msg->needs_free = true;

	ret = __fill_rpmh_msg(rpm_msg, state, cmd, n);
	if (ret) {
		kfree(rpm_msg);
		return ret;
	}

	return __rpmh_write(dev, state, rpm_msg);
}
EXPORT_SYMBOL(rpmh_write_async);

/**
 * rpmh_write: Write a set of RPMH commands and block until response
 *
+7 −0
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
int rpmh_write(const struct device *dev, enum rpmh_state state,
	       const struct tcs_cmd *cmd, u32 n);

int rpmh_write_async(const struct device *dev, enum rpmh_state state,
		     const struct tcs_cmd *cmd, u32 n);

int rpmh_flush(const struct device *dev);

int rpmh_invalidate(const struct device *dev);
@@ -24,6 +27,10 @@ static inline int rpmh_write(const struct device *dev, enum rpmh_state state,
			     const struct tcs_cmd *cmd, u32 n)
{ return -ENODEV; }

static inline int rpmh_write_async(const struct device *dev,
				   enum rpmh_state state,
				   const struct tcs_cmd *cmd, u32 n)
{ return -ENODEV; }

static inline int rpmh_flush(const struct device *dev)
{ return -ENODEV; }