msm: ipa: Add new API to check for ipa uC readiness

Adding new API for IPA clients to check for IPA
uC ready before bringing up IPA uC offload data path.

CRs-Fixed: 2030217
Change-Id: I0328658cba829cacc89b7c0b8edf7e52aa16e45c
Signed-off-by: Sunil Paidimarri <hisunil@codeaurora.org>
Signed-off-by: Skylar Chang <chiaweic@codeaurora.org>
This commit is contained in:
Skylar Chang 2017-09-12 11:48:06 -07:00
parent e9ecb016e6
commit 54225e4364
12 changed files with 173 additions and 5 deletions

View file

@ -2943,6 +2943,25 @@ struct device *ipa_get_pdev(void)
}
EXPORT_SYMBOL(ipa_get_pdev);
int ipa_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *user_data),
void *user_data)
{
int ret;
IPA_API_DISPATCH_RETURN(ipa_ntn_uc_reg_rdyCB,
ipauc_ready_cb, user_data);
return ret;
}
EXPORT_SYMBOL(ipa_ntn_uc_reg_rdyCB);
void ipa_ntn_uc_dereg_rdyCB(void)
{
IPA_API_DISPATCH(ipa_ntn_uc_dereg_rdyCB);
}
EXPORT_SYMBOL(ipa_ntn_uc_dereg_rdyCB);
static const struct dev_pm_ops ipa_pm_ops = {
.suspend_noirq = ipa_ap_suspend,
.resume_noirq = ipa_ap_resume,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017, 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
@ -374,6 +374,11 @@ struct ipa_api_controller {
int ipa_ep_idx_dl);
struct device *(*ipa_get_pdev)(void);
int (*ipa_ntn_uc_reg_rdyCB)(void (*ipauc_ready_cb)(void *user_data),
void *user_data);
void (*ipa_ntn_uc_dereg_rdyCB)(void);
};
#ifdef CONFIG_IPA

View file

@ -622,3 +622,41 @@ int ipa_uc_offload_cleanup(u32 clnt_hdl)
return ret;
}
EXPORT_SYMBOL(ipa_uc_offload_cleanup);
/**
* ipa_uc_offload_uc_rdyCB() - To register uC ready CB if uC not
* ready
* @inout: [in/out] input/output parameters
* from/to client
*
* Returns: 0 on success, negative on failure
*
*/
int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *inp)
{
int ret = 0;
if (!inp) {
IPA_UC_OFFLOAD_ERR("Invalid input\n");
return -EINVAL;
}
if (inp->proto == IPA_UC_NTN)
ret = ipa_ntn_uc_reg_rdyCB(inp->notify, inp->priv);
if (ret == -EEXIST) {
inp->is_uC_ready = true;
ret = 0;
} else
inp->is_uC_ready = false;
return ret;
}
EXPORT_SYMBOL(ipa_uc_offload_reg_rdyCB);
void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto)
{
if (proto == IPA_UC_NTN)
ipa_ntn_uc_dereg_rdyCB();
}
EXPORT_SYMBOL(ipa_uc_offload_dereg_rdyCB);

View file

@ -379,6 +379,9 @@ u8 *ipa_write_16(u16 hw, u8 *dest);
u8 *ipa_write_8(u8 b, u8 *dest);
u8 *ipa_pad_to_64(u8 *dest);
u8 *ipa_pad_to_32(u8 *dest);
int ipa_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *user_data),
void *user_data);
void ipa_ntn_uc_dereg_rdyCB(void);
const char *ipa_get_version_string(enum ipa_hw_type ver);
#endif /* _IPA_COMMON_I_H_ */

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, 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
@ -21,4 +21,7 @@ int ipa_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
struct ipa_ntn_conn_out_params *outp);
int ipa_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, int ipa_ep_idx_dl);
int ipa_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *user_data),
void *user_data);
void ipa_ntn_uc_dereg_rdyCB(void);
#endif /* _IPA_UC_OFFLOAD_COMMON_I_H_ */

View file

@ -1576,6 +1576,8 @@ int ipa2_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *inp,
ipa_notify_cb notify, void *priv, u8 hdr_len,
struct ipa_ntn_conn_out_params *outp);
int ipa2_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, int ipa_ep_idx_dl);
int ipa2_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *), void *priv);
void ipa2_ntn_uc_dereg_rdyCB(void);
/*
* To retrieve doorbell physical address of

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, 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
@ -165,6 +165,17 @@ int ipa2_register_ipa_ready_cb(void (*ipa_ready_cb)(void *), void *user_data)
return -EEXIST;
}
int ipa2_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *), void *priv)
{
return ipa2_register_ipa_ready_cb(ipauc_ready_cb, priv);
}
void ipa2_ntn_uc_dereg_rdyCB(void)
{
ipa_ctx->uc_ntn_ctx.uc_ready_cb = NULL;
ipa_ctx->uc_ntn_ctx.priv = NULL;
}
static void ipa_uc_ntn_loaded_handler(void)
{
if (!ipa_ctx) {

View file

@ -5155,6 +5155,8 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
api_ctrl->ipa_tear_down_uc_offload_pipes =
ipa2_tear_down_uc_offload_pipes;
api_ctrl->ipa_get_pdev = ipa2_get_pdev;
api_ctrl->ipa_ntn_uc_reg_rdyCB = ipa2_ntn_uc_reg_rdyCB;
api_ctrl->ipa_ntn_uc_dereg_rdyCB = ipa2_ntn_uc_dereg_rdyCB;
return 0;
}

View file

@ -1733,6 +1733,8 @@ int ipa3_setup_uc_ntn_pipes(struct ipa_ntn_conn_in_params *in,
ipa_notify_cb notify, void *priv, u8 hdr_len,
struct ipa_ntn_conn_out_params *outp);
int ipa3_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, int ipa_ep_idx_dl);
int ipa3_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *), void *priv);
void ipa3_ntn_uc_dereg_rdyCB(void);
/*
* To retrieve doorbell physical address of

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, 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
@ -149,6 +149,49 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats)
return 0;
}
int ipa3_ntn_uc_reg_rdyCB(void (*ipa_ready_cb)(void *), void *user_data)
{
int ret;
if (!ipa3_ctx) {
IPAERR("IPA ctx is null\n");
return -ENXIO;
}
ret = ipa3_uc_state_check();
if (ret) {
ipa3_ctx->uc_ntn_ctx.uc_ready_cb = ipa_ready_cb;
ipa3_ctx->uc_ntn_ctx.priv = user_data;
return 0;
}
return -EEXIST;
}
void ipa3_ntn_uc_dereg_rdyCB(void)
{
ipa3_ctx->uc_ntn_ctx.uc_ready_cb = NULL;
ipa3_ctx->uc_ntn_ctx.priv = NULL;
}
static void ipa3_uc_ntn_loaded_handler(void)
{
if (!ipa3_ctx) {
IPAERR("IPA ctx is null\n");
return;
}
if (ipa3_ctx->uc_ntn_ctx.uc_ready_cb) {
ipa3_ctx->uc_ntn_ctx.uc_ready_cb(
ipa3_ctx->uc_ntn_ctx.priv);
ipa3_ctx->uc_ntn_ctx.uc_ready_cb =
NULL;
ipa3_ctx->uc_ntn_ctx.priv = NULL;
}
}
int ipa3_ntn_init(void)
{
struct ipa3_uc_hdlrs uc_ntn_cbs = { 0 };
@ -156,6 +199,8 @@ int ipa3_ntn_init(void)
uc_ntn_cbs.ipa_uc_event_hdlr = ipa3_uc_ntn_event_handler;
uc_ntn_cbs.ipa_uc_event_log_info_hdlr =
ipa3_uc_ntn_event_log_info_handler;
uc_ntn_cbs.ipa_uc_loaded_hdlr =
ipa3_uc_ntn_loaded_handler;
ipa3_uc_register_handlers(IPA_HW_FEATURE_NTN, &uc_ntn_cbs);

View file

@ -3287,6 +3287,8 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
api_ctrl->ipa_tear_down_uc_offload_pipes =
ipa3_tear_down_uc_offload_pipes;
api_ctrl->ipa_get_pdev = ipa3_get_pdev;
api_ctrl->ipa_ntn_uc_reg_rdyCB = ipa3_ntn_uc_reg_rdyCB;
api_ctrl->ipa_ntn_uc_dereg_rdyCB = ipa3_ntn_uc_dereg_rdyCB;
return 0;
}

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, 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
@ -163,6 +163,20 @@ struct ipa_perf_profile {
u32 max_supported_bw_mbps;
};
/**
* struct ipa_uc_ready_params - uC ready CB parameters
* @is_uC_ready: uC loaded or not
* @priv : callback cookie
* @notify: callback
* @proto: uC offload protocol type
*/
struct ipa_uc_ready_params {
bool is_uC_ready;
void *priv;
ipa_uc_ready_cb notify;
enum ipa_uc_offload_proto proto;
};
#if defined CONFIG_IPA || defined CONFIG_IPA3
/**
@ -223,6 +237,19 @@ int ipa_uc_offload_disconn_pipes(u32 clnt_hdl);
*/
int ipa_set_perf_profile(struct ipa_perf_profile *profile);
/*
* To register uC ready callback if uC not ready
* and also check uC readiness
* if uC not ready only, register callback
*/
int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *param);
/*
* To de-register uC ready callback
*/
void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto);
#else /* (CONFIG_IPA || CONFIG_IPA3) */
static inline int ipa_uc_offload_reg_intf(
@ -254,6 +281,15 @@ static inline int ipa_set_perf_profile(struct ipa_perf_profile *profile)
return -EPERM;
}
static inline int ipa_uc_offload_reg_rdyCB(struct ipa_uc_ready_params *param)
{
return -EPERM;
}
static void ipa_uc_offload_dereg_rdyCB(enum ipa_uc_offload_proto proto)
{
}
#endif /* CONFIG_IPA3 */
#endif /* _IPA_UC_OFFLOAD_H_ */