summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-07-30 23:59:59 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2018-07-30 23:59:59 -0700
commit6dc8f1cb011466bb3ad53157f3bdef25bc527c4f (patch)
tree07193a18874a9b681fd8930d123441c6a72fd699 /drivers/platform
parentfb5e9276e4eceeda7c605a2aee5eb5947c20ea68 (diff)
parentac27bafd6ea23c9982528f1ba707aba100e9fd6c (diff)
Merge "msm: ipa: Add support to IPA platform shutdown cleanup"
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/ipa/ipa_api.c39
-rw-r--r--drivers/platform/msm/ipa/ipa_api.h17
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa.c155
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_client.c78
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_i.h11
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c54
6 files changed, 337 insertions, 17 deletions
diff --git a/drivers/platform/msm/ipa/ipa_api.c b/drivers/platform/msm/ipa/ipa_api.c
index bc0263c371a1..719a1ec5360f 100644
--- a/drivers/platform/msm/ipa/ipa_api.c
+++ b/drivers/platform/msm/ipa/ipa_api.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 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
@@ -2672,6 +2672,42 @@ static int ipa_generic_plat_drv_probe(struct platform_device *pdev_p)
return result;
}
+static void ipa_generic_plat_drv_shutdown(struct platform_device *pdev_p)
+{
+ int result;
+
+ pr_info("ipa: IPA driver shutdown started for %s\n",
+ pdev_p->dev.of_node->name);
+
+ if (!ipa_api_ctrl) {
+ pr_err("ipa: invalid ipa_api_ctrl\n");
+ return;
+ }
+
+ /* call probe based on IPA HW version */
+ switch (ipa_api_hw_type) {
+ case IPA_HW_v2_0:
+ case IPA_HW_v2_1:
+ case IPA_HW_v2_5:
+ case IPA_HW_v2_6L:
+ result = ipa_plat_drv_shutdown(pdev_p, ipa_api_ctrl,
+ ipa_plat_drv_match);
+ break;
+ case IPA_HW_v3_0:
+ case IPA_HW_v3_1:
+ case IPA_HW_v3_5:
+ case IPA_HW_v3_5_1:
+ default:
+ pr_err("ipa: ipa_generic_plat_drv_shutdown, unsupported version %d\n",
+ ipa_api_hw_type);
+ return;
+ }
+
+ if (result)
+ pr_err("ipa: ipa_generic_plat_drv_shutdown failed\n");
+}
+
+
static int ipa_ap_suspend(struct device *dev)
{
int ret;
@@ -2975,6 +3011,7 @@ static struct platform_driver ipa_plat_drv = {
.pm = &ipa_pm_ops,
.of_match_table = ipa_plat_drv_match,
},
+ .shutdown = ipa_generic_plat_drv_shutdown,
};
static int __init ipa_module_init(void)
diff --git a/drivers/platform/msm/ipa/ipa_api.h b/drivers/platform/msm/ipa/ipa_api.h
index 1fb0e7122042..33e0f469d0d2 100644
--- a/drivers/platform/msm/ipa/ipa_api.h
+++ b/drivers/platform/msm/ipa/ipa_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 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
@@ -384,12 +384,27 @@ struct ipa_api_controller {
#ifdef CONFIG_IPA
int ipa_plat_drv_probe(struct platform_device *pdev_p,
struct ipa_api_controller *api_ctrl, struct of_device_id *pdrv_match);
+int ipa_plat_drv_shutdown(struct platform_device *pdev_p,
+ struct ipa_api_controller *api_ctrl,
+ const struct of_device_id *pdrv_match);
+void ipa_platform_shutdown(void);
#else
static inline int ipa_plat_drv_probe(struct platform_device *pdev_p,
struct ipa_api_controller *api_ctrl, struct of_device_id *pdrv_match)
{
return -ENODEV;
}
+static inline int ipa_plat_drv_shutdown(struct platform_device *pdev_p,
+ struct ipa_api_controller *api_ctrl,
+ const struct of_device_id *pdrv_match)
+{
+ return -ENODEV;
+}
+static inline int ipa_platform_shutdown(void)
+{
+ return -ENODEV;
+}
+
#endif /* (CONFIG_IPA) */
#ifdef CONFIG_IPA3
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index ad7d2d6175bd..bf46ea860fef 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -1752,6 +1752,31 @@ int ipa_q6_pipe_delay(bool zip_pipes)
return 0;
}
+/* Remove delay only for IPA consumer pipes */
+static void ipa_pipe_delay(bool set_reset)
+{
+ u32 reg_val = 0;
+ int client_idx;
+ int ep_idx;
+
+ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) {
+ /* Break the processing for IPA PROD pipes and avoid looping. */
+ if (IPA_CLIENT_IS_CONS(client_idx))
+ break;
+
+ ep_idx = ipa2_get_ep_mapping(client_idx);
+ if (ep_idx == -1)
+ continue;
+
+ IPA_SETFIELD_IN_REG(reg_val, set_reset,
+ IPA_ENDP_INIT_CTRL_N_ENDP_DELAY_SHFT,
+ IPA_ENDP_INIT_CTRL_N_ENDP_DELAY_BMSK);
+
+ ipa_write_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_CTRL_N_OFST(ep_idx), reg_val);
+ }
+}
+
int ipa_q6_monitor_holb_mitigation(bool enable)
{
int ep_idx;
@@ -1830,6 +1855,51 @@ static int ipa_q6_avoid_holb(bool zip_pipes)
return 0;
}
+/*
+ * Set HOLB drop on all IPA producer/client cons pipes,
+ * do not set suspend
+ */
+static void ipa_avoid_holb(void)
+{
+ u32 reg_val;
+ int ep_idx;
+ int client_idx = IPA_CLIENT_MAX - 1;
+
+ for (; client_idx >= 0; client_idx--) {
+ /* Break the processing for IPA CONS pipes and avoid looping. */
+ if (IPA_CLIENT_IS_PROD(client_idx))
+ break;
+
+ ep_idx = ipa2_get_ep_mapping(client_idx);
+ if (ep_idx == -1)
+ continue;
+
+ /*
+ * ipa2_cfg_ep_holb is not used here because we are
+ * also setting HOLB on Q6 pipes, and from APPS perspective
+ * they are not valid, therefore, the above function
+ * will fail.
+ */
+ reg_val = 0;
+ IPA_SETFIELD_IN_REG(reg_val, 0,
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_N_TIMER_SHFT,
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_N_TIMER_BMSK);
+
+ ipa_write_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_N_OFST_v2_0(ep_idx),
+ reg_val);
+
+ reg_val = 0;
+ IPA_SETFIELD_IN_REG(reg_val, 1,
+ IPA_ENDP_INIT_HOL_BLOCK_EN_N_EN_SHFT,
+ IPA_ENDP_INIT_HOL_BLOCK_EN_N_EN_BMSK);
+
+ ipa_write_reg(ipa_ctx->mmio,
+ IPA_ENDP_INIT_HOL_BLOCK_EN_N_OFST_v2_0(ep_idx),
+ reg_val);
+ }
+}
+
static u32 ipa_get_max_flt_rt_cmds(u32 num_pipes)
{
u32 max_cmds = 0;
@@ -2089,6 +2159,49 @@ static int ipa_q6_set_ex_path_dis_agg(void)
return retval;
}
+int register_ipa_platform_cb(int (*q6_cleanup_cb)(void))
+{
+ IPAERR("In register_ipa_platform_cb\n");
+ if (ipa_ctx) {
+ if (ipa_ctx->q6_cleanup_cb == NULL) {
+ IPAERR("reg q6_cleanup_cb\n");
+ ipa_ctx->q6_cleanup_cb = q6_cleanup_cb;
+ } else
+ IPAERR("Already registered\n");
+ } else {
+ IPAERR("IPA driver not initialized, retry\n");
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+/**
+* ipa_apps_shutdown_cleanup() - Take care Apps ep's cleanup
+* 1) Set HOLB drop on all IPA producer pipes.
+* 2) Remove delay for all IPA consumer pipes.
+* 3) Wait for all IPA consumer pipes to go empty and
+* reset it.
+* 4) Do aggregation force close for all pipes.
+* 5) Reset all IPA producer pipes
+
+* 0: success
+*/
+
+int ipa_apps_shutdown_cleanup(void)
+{
+ IPA_ACTIVE_CLIENTS_INC_SPECIAL("APPS_SHUTDOWN");
+
+ ipa_avoid_holb();
+
+ ipa_pipe_delay(false);
+
+ ipa2_apps_shutdown_apps_ep_reset();
+
+ IPA_ACTIVE_CLIENTS_DEC_SPECIAL("APPS_SHUTDOWN");
+
+ return 0;
+}
+
/**
* ipa_q6_pre_shutdown_cleanup() - A cleanup for all Q6 related configuration
* in IPA HW before modem shutdown. This is performed in
@@ -3907,6 +4020,8 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p,
ipa_ctx->skip_uc_pipe_reset = resource_p->skip_uc_pipe_reset;
ipa_ctx->use_dma_zone = resource_p->use_dma_zone;
ipa_ctx->tethered_flow_control = resource_p->tethered_flow_control;
+ ipa_ctx->is_apps_shutdown_support =
+ resource_p->is_apps_shutdown_support;
/* Setting up IPA RX Polling Timeout Seconds */
ipa_rx_timeout_min_max_calc(&ipa_ctx->ipa_rx_min_timeout_usec,
@@ -4447,6 +4562,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
ipa_drv_res->ipa_wdi2 = false;
ipa_drv_res->wan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
ipa_drv_res->lan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
+ ipa_drv_res->is_apps_shutdown_support = false;
/* Get IPA HW Version */
result = of_property_read_u32(pdev->dev.of_node, "qcom,ipa-hw-ver",
@@ -4474,6 +4590,14 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
ipa_drv_res->ipa_uc_monitor_holb
? "Enabled" : "Disabled");
+ /* Check apps_shutdown_support enabled or disabled */
+ ipa_drv_res->is_apps_shutdown_support =
+ of_property_read_bool(pdev->dev.of_node,
+ "qcom,apps-shutdown-support");
+ IPAERR(": apps shutdown support = %s\n",
+ ipa_drv_res->is_apps_shutdown_support
+ ? "Enabled" : "Disabled");
+
/* Get IPA WAN / LAN RX pool sizes */
result = of_property_read_u32(pdev->dev.of_node,
"qcom,wan-rx-ring-size",
@@ -4918,6 +5042,37 @@ static int ipa_smmu_ap_cb_probe(struct device *dev)
return result;
}
+/**
+* ipa_platform_shutdown() - Ensure Q6 ep cleanup is done and
+* followed by APPS ep's cleanup.
+*/
+void ipa_platform_shutdown(void)
+{
+ IPADBG("****************ipa_platform_shutdown****************\n");
+ if (ipa_ctx->q6_cleanup_cb)
+ ipa_ctx->q6_cleanup_cb();
+ else
+ IPADBG("No Q6 cleanup callback registered\n");
+ ipa_apps_shutdown_cleanup();
+}
+
+int ipa_plat_drv_shutdown(struct platform_device *pdev_p,
+ struct ipa_api_controller *api_ctrl,
+ const struct of_device_id *pdrv_match)
+{
+ if (!ipa_ctx) {
+ pr_err("IPA driver not initialized\n");
+ return -EOPNOTSUPP;
+ }
+ if (ipa_ctx->is_apps_shutdown_support)
+ ipa_platform_shutdown();
+ else {
+ pr_err("There is no apps IPA driver shutdown support\n");
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
int ipa_plat_drv_probe(struct platform_device *pdev_p,
struct ipa_api_controller *api_ctrl, struct of_device_id *pdrv_match)
{
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_client.c b/drivers/platform/msm/ipa/ipa_v2/ipa_client.c
index 74e7394a80b1..b1eb67dbf02c 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_client.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -84,11 +84,20 @@ int ipa_disable_data_path(u32 clnt_hdl)
IPA_ENDP_INIT_AGGR_N_OFST_v2_0(clnt_hdl));
if (((aggr_init & IPA_ENDP_INIT_AGGR_N_AGGR_EN_BMSK) >>
IPA_ENDP_INIT_AGGR_N_AGGR_EN_SHFT) == IPA_ENABLE_AGGR) {
- res = ipa_tag_aggr_force_close(clnt_hdl);
- if (res) {
- IPAERR("tag process timeout, client:%d err:%d\n",
- clnt_hdl, res);
- BUG();
+ /*
+ * Tag process will not work for,
+ * APPS CMD PROD --> Uses the same for IMM cmd over tag
+ * APPS LAN CONS --> Already suspend is set
+ */
+ if (!(ep->client == IPA_CLIENT_APPS_CMD_PROD ||
+ ep->client == IPA_CLIENT_APPS_LAN_CONS)) {
+ res = ipa_tag_aggr_force_close(clnt_hdl);
+ if (res) {
+ IPAERR("tag process timeout");
+ IPAERR("client:%d err:%d\n",
+ clnt_hdl, res);
+ ipa_assert();
+ }
}
}
@@ -765,6 +774,63 @@ bail:
}
/**
+* ipa2_apps_shutdown_apps_ep_reset() -
+* reset an endpoints from BAM perspective.
+*
+* Q6 ep reset is not handled here
+*/
+void ipa2_apps_shutdown_apps_ep_reset(void)
+{
+ struct ipa_ep_context *ep;
+ int ep_idx, client_idx;
+
+ if (unlikely(!ipa_ctx)) {
+ IPAERR("IPA driver was not initialized\n");
+ return;
+ }
+
+ for (client_idx = 0; client_idx < IPA_CLIENT_MAX; client_idx++) {
+
+ ep_idx = ipa2_get_ep_mapping(client_idx);
+ if (ep_idx == -1)
+ continue;
+
+ ep = &ipa_ctx->ep[ep_idx];
+ if (ep->valid && (IPA_CLIENT_IS_APPS_PROD(client_idx) ||
+ IPA_CLIENT_IS_APPS_CONS(client_idx))) {
+ /*
+ * we shouldn't reset APPS CMD PROD
+ * and LAN CONS in for loop
+ * these 2 ep's should be resetted at last,
+ * since it is used in Tag Process
+ */
+ if (!(client_idx == IPA_CLIENT_APPS_CMD_PROD ||
+ client_idx == IPA_CLIENT_APPS_LAN_CONS)) {
+ IPADBG("teardown ep (%d)\n", ep_idx);
+ ipa2_teardown_sys_pipe(ep_idx);
+ }
+ }
+ }
+ ep_idx = ipa2_get_ep_mapping(IPA_CLIENT_APPS_LAN_CONS);
+ if (ep_idx != -1) {
+ ep = &ipa_ctx->ep[ep_idx];
+ if (ep->valid) {
+ IPADBG("teardown ep (%d)\n", ep_idx);
+ ipa2_teardown_sys_pipe(ep_idx);
+ }
+ }
+
+ ep_idx = ipa2_get_ep_mapping(IPA_CLIENT_APPS_CMD_PROD);
+ if (ep_idx != -1) {
+ ep = &ipa_ctx->ep[ep_idx];
+ if (ep->valid) {
+ IPADBG("teardown ep (%d)\n", ep_idx);
+ ipa2_teardown_sys_pipe(ep_idx);
+ }
+ }
+}
+
+/**
* ipa2_clear_endpoint_delay() - Remove ep delay set on the IPA pipe before
* client disconnect.
* @clnt_hdl: [in] opaque client handle assigned by IPA to client
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
index 28689eb83d4e..1986dc2af097 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -1207,6 +1207,8 @@ struct ipa_context {
struct ipa_cne_evt ipa_cne_evt_req_cache[IPA_MAX_NUM_REQ_CACHE];
int num_ipa_cne_evt_req;
struct mutex ipa_cne_evt_lock;
+ int (*q6_cleanup_cb)(void);
+ bool is_apps_shutdown_support;
};
/**
@@ -1263,6 +1265,7 @@ struct ipa_plat_drv_res {
u32 ipa_rx_polling_sleep_msec;
u32 ipa_polling_iteration;
bool ipa_uc_monitor_holb;
+ bool is_apps_shutdown_support;
};
struct ipa_mem_partition {
@@ -1388,6 +1391,8 @@ int ipa2_disconnect(u32 clnt_hdl);
*/
int ipa2_reset_endpoint(u32 clnt_hdl);
+void ipa2_apps_shutdown_apps_ep_reset(void);
+
/*
* Remove ep delay
*/
@@ -1781,7 +1786,7 @@ static inline u32 ipa_read_reg_field(void *base, u32 offset,
return (ipa_read_reg(base, offset) & mask) >> shift;
}
-static inline void ipa_write_reg(void *base, u32 offset, u32 val)
+static inline void ipa_write_reg(void __iomem *base, u32 offset, u32 val)
{
iowrite32(val, base + offset);
}
@@ -1868,6 +1873,8 @@ int ipa_tag_process(struct ipa_desc *desc, int num_descs,
unsigned long timeout);
int ipa_q6_pre_shutdown_cleanup(void);
+int ipa_apps_shutdown_cleanup(void);
+int register_ipa_platform_cb(int (*cb)(void));
int ipa_q6_post_shutdown_cleanup(void);
int ipa_init_q6_smem(void);
int ipa_q6_monitor_holb_mitigation(bool enable);
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
index 3defc03c2571..c79978038668 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
@@ -76,6 +76,8 @@ static bool egress_set, a7_ul_flt_set;
static struct workqueue_struct *ipa_rm_q6_workqueue; /* IPA_RM workqueue*/
static atomic_t is_initialized;
static atomic_t is_ssr;
+static atomic_t is_after_powerup_cmpltd;
+static struct completion is_after_shutdown_cmpltd;
static void *subsys_notify_handle;
u32 apps_to_ipa_hdl, ipa_to_apps_hdl; /* get handler from ipa */
@@ -135,6 +137,14 @@ struct wwan_private {
struct napi_struct napi;
};
+static int ssr_notifier_cb(struct notifier_block *this,
+ unsigned long code,
+ void *data);
+
+static struct notifier_block ssr_notifier = {
+ .notifier_call = ssr_notifier_cb,
+};
+
/**
* ipa_setup_a7_qmap_hdr() - Setup default a7 qmap hdr
*
@@ -1958,15 +1968,34 @@ static void ipa_rm_notify(void *dev, enum ipa_rm_event event,
}
}
-/* IPA_RM related functions end*/
+/**
+* q6_cleanup_cb() - IPA q6 cleanup
+*
+* This function is called in the sequence
+* of ipa platform shutdown
+*/
-static int ssr_notifier_cb(struct notifier_block *this,
- unsigned long code,
- void *data);
+static int q6_cleanup_cb(void)
+{
+ int ret = 0;
-static struct notifier_block ssr_notifier = {
- .notifier_call = ssr_notifier_cb,
-};
+ IPAWANERR("Start\n");
+ if (atomic_read(&is_initialized) &&
+ atomic_read(&is_after_powerup_cmpltd)) {
+ pr_info("Wait for q6 cleanup\n");
+ wait_for_completion(&is_after_shutdown_cmpltd);
+ pr_info("q6_cleanup_cb: Q6 SSR cleanup is taken care\n");
+ } else {
+ if (!atomic_read(&is_initialized))
+ pr_info("RmNET IPA driver is not inited\n");
+ if (!atomic_read(&is_after_powerup_cmpltd))
+ pr_info("Modem is not up\n");
+ }
+ IPAWANERR("END\n");
+ return ret;
+}
+
+/* IPA_RM related functions end*/
static int get_ipa_rmnet_dts_configuration(struct platform_device *pdev,
struct ipa_rmnet_plat_drv_res *ipa_rmnet_drv_res)
@@ -2179,6 +2208,8 @@ static int ipa_wwan_probe(struct platform_device *pdev)
ipa2_proxy_clk_unvote();
}
atomic_set(&is_ssr, 0);
+ atomic_set(&is_after_powerup_cmpltd, 0);
+ init_completion(&is_after_shutdown_cmpltd);
pr_info("rmnet_ipa completed initialization\n");
return 0;
@@ -2221,6 +2252,7 @@ setup_dflt_wan_rt_tables_err:
setup_a7_qmap_hdr_err:
ipa_qmi_service_exit();
atomic_set(&is_ssr, 0);
+ atomic_set(&is_after_powerup_cmpltd, 0);
return ret;
}
@@ -2409,6 +2441,7 @@ static int ssr_notifier_cb(struct notifier_block *this,
if (atomic_read(&is_ssr))
ipa_q6_post_shutdown_cleanup();
pr_info("IPA AFTER_SHUTDOWN handling is complete\n");
+ complete(&is_after_shutdown_cmpltd);
return NOTIFY_DONE;
}
if (SUBSYS_AFTER_POWERUP == code) {
@@ -2416,6 +2449,7 @@ static int ssr_notifier_cb(struct notifier_block *this,
if (!atomic_read(&is_initialized)
&& atomic_read(&is_ssr))
platform_driver_register(&rmnet_ipa_driver);
+ atomic_set(&is_after_powerup_cmpltd, 1);
pr_info("IPA AFTER_POWERUP handling is complete\n");
return NOTIFY_DONE;
}
@@ -3222,6 +3256,7 @@ void ipa_q6_handshake_complete(bool ssr_bootup)
static int __init ipa_wwan_init(void)
{
+ int ret = 0;
atomic_set(&is_initialized, 0);
atomic_set(&is_ssr, 0);
@@ -3231,6 +3266,11 @@ static int __init ipa_wwan_init(void)
ipa_qmi_init();
+ IPAWANERR("Registering for q6_cleanup_cb\n");
+ ret = register_ipa_platform_cb(&q6_cleanup_cb);
+ if (ret == -EAGAIN)
+ IPAWANERR("Register for q6_cleanup_cb is un-successful\n");
+
/* Register for Modem SSR */
subsys_notify_handle = subsys_notif_register_notifier(SUBSYS_MODEM,
&ssr_notifier);