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

Commit f8145cd5 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa3: Fix to race condition in IPA client lock"

parents 53d553d7 dac3adc8
Loading
Loading
Loading
Loading
+37 −23
Original line number Original line Diff line number Diff line
@@ -638,66 +638,80 @@ int ipa3_smmu_map_peer_buff(u64 iova, u32 size, bool map, struct sg_table *sgt,
	return 0;
	return 0;
}
}


static enum ipa_client_cb_type ipa_get_client_cb_type(u32 ipa_ep_idx)
{
	enum ipa_client_type client_type;
	enum ipa_client_cb_type client_cb;

	client_type = ipa3_get_client_by_pipe(ipa_ep_idx);

	if (client_type == IPA_CLIENT_USB_PROD ||
			client_type == IPA_CLIENT_USB_CONS) {
		IPADBG("USB Client registered\n");
		client_cb = IPA_USB_CLNT;
	} else if (client_type == IPA_CLIENT_MHI_PROD ||
			client_type == IPA_CLIENT_MHI_CONS) {
		IPADBG("MHI Client registered\n");
		client_cb = IPA_MHI_CLNT;
	} else {
		IPAERR("Invalid IPA client\n");
		client_cb = IPA_MAX_CLNT;
	}

	return client_cb;
}
void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock),
void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock),
						u32 ipa_ep_idx)
						u32 ipa_ep_idx)
{
{
	struct ipa3_ep_context *ep;
	enum ipa_client_cb_type client;


	IPADBG("entry\n");
	IPADBG("entry\n");


	ep = &ipa3_ctx->ep[ipa_ep_idx];
	client = ipa_get_client_cb_type(ipa_ep_idx);

	if (client == IPA_MAX_CLNT)
	if (!ep->valid) {
		IPAERR("Invalid EP\n");
		return;
		return;
	}


	if (client_cb == NULL) {
	if (client_cb == NULL) {
		IPAERR("Bad Param");
		IPAERR("Bad Param");
		return;
		return;
	}
	}


	ep->client_lock_unlock = client_cb;
	if (!ipa3_ctx->client_lock_unlock[client])
		ipa3_ctx->client_lock_unlock[client] = client_cb;
	IPADBG("exit\n");
	IPADBG("exit\n");
}
}


void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx)
void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx)
{
{
	struct ipa3_ep_context *ep;
	enum ipa_client_cb_type client_cb;


	IPADBG("entry\n");
	IPADBG("entry\n");


	ep = &ipa3_ctx->ep[ipa_ep_idx];
	client_cb = ipa_get_client_cb_type(ipa_ep_idx);

	if (client_cb == IPA_MAX_CLNT)
	if (!ep->valid) {
		IPAERR("Invalid EP\n");
		return;
		return;
	}


	if (ep->client_lock_unlock == NULL) {
	if (ipa3_ctx->client_lock_unlock[client_cb] == NULL) {
		IPAERR("client_lock_unlock is already NULL");
		IPAERR("client_lock_unlock is already NULL");
		return;
		return;
	}
	}


	ep->client_lock_unlock = NULL;
	ipa3_ctx->client_lock_unlock[client_cb] = NULL;
	IPADBG("exit\n");
	IPADBG("exit\n");
}
}


static void client_lock_unlock_cb(u32 ipa_ep_idx, bool is_lock)
static void client_lock_unlock_cb(u32 ipa_ep_idx, bool is_lock)
{
{
	struct ipa3_ep_context *ep;
	enum ipa_client_cb_type client_cb;


	IPADBG("entry\n");
	IPADBG("entry\n");


	ep = &ipa3_ctx->ep[ipa_ep_idx];
	client_cb = ipa_get_client_cb_type(ipa_ep_idx);

	if (client_cb == IPA_MAX_CLNT)
	if (!ep->valid) {
		IPAERR("Invalid EP\n");
		return;
		return;
	}


	if (ep->client_lock_unlock)
	if (ipa3_ctx->client_lock_unlock[client_cb])
		ep->client_lock_unlock(is_lock);
		ipa3_ctx->client_lock_unlock[client_cb](is_lock);


	IPADBG("exit\n");
	IPADBG("exit\n");
}
}
+7 −2
Original line number Original line Diff line number Diff line
@@ -808,8 +808,6 @@ struct ipa3_ep_context {
	u32 eot_in_poll_err;
	u32 eot_in_poll_err;
	bool ep_delay_set;
	bool ep_delay_set;


	int (*client_lock_unlock)(bool is_lock);

	/* sys MUST be the last element of this struct */
	/* sys MUST be the last element of this struct */
	struct ipa3_sys_context *sys;
	struct ipa3_sys_context *sys;
};
};
@@ -1435,6 +1433,12 @@ enum ipa_smmu_cb_type {
#define VALID_IPA_SMMU_CB_TYPE(t) \
#define VALID_IPA_SMMU_CB_TYPE(t) \
	((t) >= IPA_SMMU_CB_AP && (t) < IPA_SMMU_CB_MAX)
	((t) >= IPA_SMMU_CB_AP && (t) < IPA_SMMU_CB_MAX)


enum ipa_client_cb_type {
	IPA_USB_CLNT,
	IPA_MHI_CLNT,
	IPA_MAX_CLNT
};

/**
/**
 * struct ipa3_char_device_context - IPA character device
 * struct ipa3_char_device_context - IPA character device
 * @class: pointer to the struct class
 * @class: pointer to the struct class
@@ -1692,6 +1696,7 @@ struct ipa3_context {
	struct mbox_client mbox_client;
	struct mbox_client mbox_client;
	struct mbox_chan *mbox;
	struct mbox_chan *mbox;
	atomic_t ipa_clk_vote;
	atomic_t ipa_clk_vote;
	int (*client_lock_unlock[IPA_MAX_CLNT])(bool is_lock);
};
};


struct ipa3_plat_drv_res {
struct ipa3_plat_drv_res {