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

Commit 27ede17f authored by Ashok Vuyyuru's avatar Ashok Vuyyuru
Browse files

msm: ipa3: Fix to handle packets over MHI pipe in SSR



Make a change to handle packets coming from MHI pipe
when modem is in SSR to clean up the host state. Otherwise
host state is not clean up as packets are not processed by
IPA.

Change-Id: I4f30301d390b36bb673e0006b9f58a943b191fd8
Signed-off-by: default avatarChaitanya Pratapa <cpratapa@codeaurora.org>
Signed-off-by: default avatarAshok Vuyyuru <avuyyuru@codeaurora.org>
parent 4fe45567
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -3428,6 +3428,20 @@ int ipa_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs)
	return ret;
}

void ipa_register_client_callback(int (*client_cb)(bool is_lock),
				bool (*teth_port_state)(void), u32 ipa_ep_idx)
{
	IPA_API_DISPATCH(ipa_register_client_callback,
		client_cb, teth_port_state, ipa_ep_idx);
}

void ipa_deregister_client_callback(u32 ipa_ep_idx)
{
	IPA_API_DISPATCH(ipa_deregister_client_callback,
		ipa_ep_idx);
}


/**
 * ipa_pm_is_used() - Returns if IPA PM framework is used
 */
+6 −0
Original line number Diff line number Diff line
@@ -435,6 +435,12 @@ struct ipa_api_controller {
	bool (*ipa_pm_is_used)(void);

	bool (*ipa_get_lan_rx_napi)(void);

	void (*ipa_register_client_callback)(
		int (*client_cb)(bool is_lock),
		bool (*teth_port_state)(void), u32 ipa_ep_idx);

	void (*ipa_deregister_client_callback)(u32 ipa_ep_idx);
};

#ifdef CONFIG_IPA
+32 −2
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ struct ipa_mhi_client_ctx {
};

static struct ipa_mhi_client_ctx *ipa_mhi_client_ctx;
static DEFINE_MUTEX(mhi_client_general_mutex);

#ifdef CONFIG_DEBUG_FS
#define IPA_MHI_MAX_MSG_LEN 512
@@ -191,6 +192,18 @@ static char *ipa_mhi_channel_state_str[] = {
	ipa_mhi_channel_state_str[(state)] : \
	"INVALID")

static int ipa_mhi_set_lock_unlock(bool is_lock)
{
	IPA_MHI_DBG("entry\n");
	if (is_lock)
		mutex_lock(&mhi_client_general_mutex);
	else
		mutex_unlock(&mhi_client_general_mutex);
	IPA_MHI_DBG("exit\n");

	return 0;
}

static int ipa_mhi_read_write_host(enum ipa_mhi_dma_dir dir, void *dev_addr,
	u64 host_addr, int size)
{
@@ -1616,6 +1629,7 @@ int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, u32 *clnt_hdl)
				&channel->cached_gsi_evt_ring_hdl;
		internal.start.gsi.evchid = channel->index;

		mutex_lock(&mhi_client_general_mutex);
		res = ipa_connect_mhi_pipe(&internal, clnt_hdl);
		if (res) {
			IPA_MHI_ERR("ipa_connect_mhi_pipe failed %d\n", res);
@@ -1631,6 +1645,8 @@ int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, u32 *clnt_hdl)
				sizeof(((struct ipa_mhi_ch_ctx *)0)->chstate));
		if (res) {
			IPA_MHI_ERR("ipa_mhi_read_write_host failed\n");
			mutex_unlock(&mhi_client_general_mutex);
			IPA_ACTIVE_CLIENTS_DEC_EP(in->sys.client);
			return res;

		}
@@ -1650,6 +1666,12 @@ int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, u32 *clnt_hdl)
		channel->state = IPA_HW_MHI_CHANNEL_STATE_RUN;
	}

	if (IPA_CLIENT_IS_PROD(in->sys.client)) {
		ipa_register_client_callback(&ipa_mhi_set_lock_unlock,
			NULL, *clnt_hdl);
	}
	mutex_unlock(&mhi_client_general_mutex);

	if (!in->sys.keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_DEC_EP(in->sys.client);

@@ -1657,6 +1679,7 @@ int ipa_mhi_connect_pipe(struct ipa_mhi_connect_params *in, u32 *clnt_hdl)

	return 0;
fail_connect_pipe:
	mutex_unlock(&mhi_client_general_mutex);
	ipa_mhi_reset_channel(channel);
fail_start_channel:
	IPA_ACTIVE_CLIENTS_DEC_EP(in->sys.client);
@@ -1711,19 +1734,27 @@ int ipa_mhi_disconnect_pipe(u32 clnt_hdl)
		goto fail_reset_channel;
	}

	mutex_lock(&mhi_client_general_mutex);
	res = ipa_disconnect_mhi_pipe(clnt_hdl);
	if (res) {
		IPA_MHI_ERR(
			"IPA core driver failed to disconnect the pipe hdl %d, res %d"
				, clnt_hdl, res);
		return res;
		goto fail_disconnect_pipe;
	}

	if (IPA_CLIENT_IS_PROD(client))
		ipa_deregister_client_callback(clnt_hdl);

	mutex_unlock(&mhi_client_general_mutex);

	IPA_ACTIVE_CLIENTS_DEC_EP(ipa_get_client_mapping(clnt_hdl));

	IPA_MHI_DBG("client (ep: %d) disconnected\n", clnt_hdl);
	IPA_MHI_FUNC_EXIT();
	return 0;
fail_disconnect_pipe:
	mutex_unlock(&mhi_client_general_mutex);
fail_reset_channel:
	IPA_ACTIVE_CLIENTS_DEC_EP(ipa_get_client_mapping(clnt_hdl));
	return res;
@@ -2907,6 +2938,5 @@ const char *ipa_mhi_get_state_str(int state)
	return MHI_STATE_STR(state);
}
EXPORT_SYMBOL(ipa_mhi_get_state_str);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("IPA MHI client driver");
+6 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -445,4 +445,9 @@ int ipa_smmu_free_sgt(struct sg_table **out_sgt_ptr);
int ipa_ut_module_init(void);
void ipa_ut_module_exit(void);

void ipa_register_client_callback(int (*client_cb)(bool is_lock),
			bool (*teth_port_state)(void), u32 ipa_ep_idx);

void ipa_deregister_client_callback(u32 ipa_ep_idx);

#endif /* _IPA_COMMON_I_H_ */
+28 −10
Original line number Diff line number Diff line
@@ -2881,16 +2881,6 @@ void ipa3_q6_pre_shutdown_cleanup(void)
	ipa3_q6_pipe_delay(false);
	ipa3_set_reset_client_prod_pipe_delay(true,
		IPA_CLIENT_USB_PROD);
	if (ipa3_ctx->ipa_config_is_auto)
		ipa3_set_reset_client_prod_pipe_delay(true,
		IPA_CLIENT_USB2_PROD);
	if (ipa3_ctx->ipa_config_is_mhi) {
		ipa3_set_reset_client_prod_pipe_delay(true,
		IPA_CLIENT_MHI_PROD);
		if (ipa3_ctx->ipa_config_is_auto)
			ipa3_set_reset_client_prod_pipe_delay(true,
				IPA_CLIENT_MHI2_PROD);
	}

	IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
	IPADBG_LOW("Exit with success\n");
@@ -2950,6 +2940,34 @@ void ipa3_q6_post_shutdown_cleanup(void)
	IPADBG_LOW("Exit with success\n");
}

/**
 * ipa3_q6_pre_powerup_cleanup() - A cleanup routine for pheripheral
 * configuration in IPA HW. This is performed in case of SSR.
 *
 * This is a mandatory procedure, in case one of the steps fails, the
 * AP needs to restart.
 */
void ipa3_q6_pre_powerup_cleanup(void)
{
	IPADBG_LOW("ENTER\n");

	IPA_ACTIVE_CLIENTS_INC_SIMPLE();

	if (ipa3_ctx->ipa_config_is_auto)
		ipa3_set_reset_client_prod_pipe_delay(true,
		IPA_CLIENT_USB2_PROD);
	if (ipa3_ctx->ipa_config_is_mhi) {
		ipa3_set_reset_client_prod_pipe_delay(true,
		IPA_CLIENT_MHI_PROD);
		if (ipa3_ctx->ipa_config_is_auto)
			ipa3_set_reset_client_prod_pipe_delay(true,
				IPA_CLIENT_MHI2_PROD);
	}

	IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
	IPADBG_LOW("Exit with success\n");
}

static inline void ipa3_sram_set_canary(u32 *sram_mmio, int offset)
{
	/* Set 4 bytes of CANARY before the offset */
Loading