mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 05:29:04 -04:00
icnss2: Add support for WPSS SSR
Add support to enable WPSS recovery and handle subsystem restart. Change-Id: I1b1e91680b280940d19c7eab9f54401ca4ac02d7 Signed-off-by: Naman Padhiar <npadhiar@codeaurora.org>
This commit is contained in:
parent
265c742dd3
commit
74a8a7d227
2 changed files with 104 additions and 4 deletions
|
|
@ -1560,6 +1560,63 @@ static void icnss_update_state_send_modem_shutdown(struct icnss_priv *priv,
|
|||
}
|
||||
}
|
||||
|
||||
static int icnss_wpss_notifier_nb(struct notifier_block *nb,
|
||||
unsigned long code,
|
||||
void *data)
|
||||
{
|
||||
struct icnss_event_pd_service_down_data *event_data;
|
||||
struct notif_data *notif = data;
|
||||
struct icnss_priv *priv = container_of(nb, struct icnss_priv,
|
||||
wpss_ssr_nb);
|
||||
struct icnss_uevent_fw_down_data fw_down_data = {0};
|
||||
|
||||
icnss_pr_vdbg("WPSS-Notify: event %lu\n", code);
|
||||
|
||||
if (code == SUBSYS_AFTER_SHUTDOWN) {
|
||||
icnss_pr_info("Collecting msa0 segment dump\n");
|
||||
icnss_msa0_ramdump(priv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (code != SUBSYS_BEFORE_SHUTDOWN)
|
||||
goto out;
|
||||
|
||||
priv->is_ssr = true;
|
||||
|
||||
icnss_pr_info("WPSS went down, state: 0x%lx, crashed: %d\n",
|
||||
priv->state, notif->crashed);
|
||||
|
||||
set_bit(ICNSS_FW_DOWN, &priv->state);
|
||||
|
||||
if (notif->crashed)
|
||||
priv->stats.recovery.root_pd_crash++;
|
||||
else
|
||||
priv->stats.recovery.root_pd_shutdown++;
|
||||
|
||||
icnss_ignore_fw_timeout(true);
|
||||
|
||||
event_data = kzalloc(sizeof(*event_data), GFP_KERNEL);
|
||||
|
||||
if (event_data == NULL)
|
||||
return notifier_from_errno(-ENOMEM);
|
||||
|
||||
event_data->crashed = notif->crashed;
|
||||
|
||||
fw_down_data.crashed = !!notif->crashed;
|
||||
if (test_bit(ICNSS_FW_READY, &priv->state)) {
|
||||
clear_bit(ICNSS_FW_READY, &priv->state);
|
||||
fw_down_data.crashed = !!notif->crashed;
|
||||
icnss_call_driver_uevent(priv,
|
||||
ICNSS_UEVENT_FW_DOWN,
|
||||
&fw_down_data);
|
||||
}
|
||||
icnss_driver_event_post(priv, ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
|
||||
ICNSS_EVENT_SYNC, event_data);
|
||||
out:
|
||||
icnss_pr_vdbg("Exit %s,state: 0x%lx\n", __func__, priv->state);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int icnss_modem_notifier_nb(struct notifier_block *nb,
|
||||
unsigned long code,
|
||||
void *data)
|
||||
|
|
@ -1633,6 +1690,30 @@ out:
|
|||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int icnss_wpss_ssr_register_notifier(struct icnss_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
priv->wpss_ssr_nb.notifier_call = icnss_wpss_notifier_nb;
|
||||
/*
|
||||
* Assign priority of icnss wpss notifier callback over IPA
|
||||
* modem notifier callback which is 0
|
||||
*/
|
||||
priv->wpss_ssr_nb.priority = 1;
|
||||
|
||||
priv->wpss_notify_handler =
|
||||
subsys_notif_register_notifier("wpss", &priv->wpss_ssr_nb);
|
||||
|
||||
if (IS_ERR(priv->wpss_notify_handler)) {
|
||||
ret = PTR_ERR(priv->wpss_notify_handler);
|
||||
icnss_pr_err("WPSS register notifier failed: %d\n", ret);
|
||||
}
|
||||
|
||||
set_bit(ICNSS_SSR_REGISTERED, &priv->state);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int icnss_modem_ssr_register_notifier(struct icnss_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -1657,6 +1738,18 @@ static int icnss_modem_ssr_register_notifier(struct icnss_priv *priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int icnss_wpss_ssr_unregister_notifier(struct icnss_priv *priv)
|
||||
{
|
||||
if (!test_and_clear_bit(ICNSS_SSR_REGISTERED, &priv->state))
|
||||
return 0;
|
||||
|
||||
subsys_notif_unregister_notifier(priv->wpss_notify_handler,
|
||||
&priv->wpss_ssr_nb);
|
||||
priv->wpss_notify_handler = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int icnss_modem_ssr_unregister_notifier(struct icnss_priv *priv)
|
||||
{
|
||||
if (!test_and_clear_bit(ICNSS_SSR_REGISTERED, &priv->state))
|
||||
|
|
@ -1957,6 +2050,11 @@ static int icnss_enable_recovery(struct icnss_priv *priv)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (priv->device_id == WCN6750_DEVICE_ID) {
|
||||
icnss_wpss_ssr_register_notifier(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
icnss_modem_ssr_register_notifier(priv);
|
||||
if (test_bit(SSR_ONLY, &priv->ctrl_params.quirks)) {
|
||||
icnss_pr_dbg("PDR disabled through module parameter\n");
|
||||
|
|
@ -3519,20 +3617,20 @@ static int icnss_remove(struct platform_device *pdev)
|
|||
|
||||
complete_all(&priv->unblock_shutdown);
|
||||
|
||||
icnss_modem_ssr_unregister_notifier(priv);
|
||||
|
||||
destroy_ramdump_device(priv->msa0_dump_dev);
|
||||
|
||||
if (priv->device_id == WCN6750_DEVICE_ID) {
|
||||
icnss_wpss_ssr_unregister_notifier(priv);
|
||||
destroy_ramdump_device(priv->m3_dump_dev_seg1);
|
||||
destroy_ramdump_device(priv->m3_dump_dev_seg2);
|
||||
destroy_ramdump_device(priv->m3_dump_dev_seg3);
|
||||
destroy_ramdump_device(priv->m3_dump_dev_seg4);
|
||||
destroy_ramdump_device(priv->m3_dump_dev_seg5);
|
||||
} else {
|
||||
icnss_modem_ssr_unregister_notifier(priv);
|
||||
icnss_pdr_unregister_notifier(priv);
|
||||
}
|
||||
|
||||
icnss_pdr_unregister_notifier(priv);
|
||||
|
||||
icnss_unregister_fw_service(priv);
|
||||
if (priv->event_wq)
|
||||
destroy_workqueue(priv->event_wq);
|
||||
|
|
|
|||
|
|
@ -386,7 +386,9 @@ struct icnss_priv {
|
|||
int total_domains;
|
||||
struct notifier_block get_service_nb;
|
||||
void *modem_notify_handler;
|
||||
void *wpss_notify_handler;
|
||||
struct notifier_block modem_ssr_nb;
|
||||
struct notifier_block wpss_ssr_nb;
|
||||
uint32_t diag_reg_read_addr;
|
||||
uint32_t diag_reg_read_mem_type;
|
||||
uint32_t diag_reg_read_len;
|
||||
|
|
|
|||
Loading…
Reference in a new issue