icnss2: Add support for Hibernate low power mode

Hibernate is a system wide power mode during which Modem
would be brought down along with DDR and the RAM contents
would be saved on the disk (suspend-to-Disk).

Modem would be do graceful shutdown in Hibernate mode,
so BEFORE_SUBSYS_DOWN notification will be received.
Based on dtsi node "is_low_power", if BEFORE_SUBSYS_DOWN
with notif->crashed bit not set is received, platform
driver will trigger an idle shutdown and set low power mode.

On AFTER_SUBSYS_DOWN notification, low power mode will be
cleared if it was set and ramdump collection will happen
only in case of crash.

Change-Id: I7b618e7c23950e4055079cde237ed75d6861620f
CRs-Fixed: 3394501
This commit is contained in:
Surabhi Vishnoi
2022-11-08 16:17:34 +05:30
committed by Gerrit - the friendly Code Review server
parent 6c9f906a94
commit 26e2742f2f
2 changed files with 24 additions and 2 deletions

View File

@@ -2171,10 +2171,25 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
switch (code) {
case QCOM_SSR_BEFORE_SHUTDOWN:
if (!notif->crashed &&
priv->low_power_support) { /* Hibernate */
if (test_bit(ICNSS_MODE_ON, &priv->state))
icnss_driver_event_post(
priv, ICNSS_DRIVER_EVENT_IDLE_SHUTDOWN,
ICNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL);
set_bit(ICNSS_LOW_POWER, &priv->state);
}
break;
case QCOM_SSR_AFTER_SHUTDOWN:
icnss_pr_info("Collecting msa0 segment dump\n");
icnss_msa0_ramdump(priv);
/* Collect ramdump only when there was a crash. */
if (notif->crashed) {
icnss_pr_info("Collecting msa0 segment dump\n");
icnss_msa0_ramdump(priv);
}
if (test_bit(ICNSS_LOW_POWER, &priv->state) &&
priv->low_power_support)
clear_bit(ICNSS_LOW_POWER, &priv->state);
goto out;
default:
goto out;
@@ -4049,6 +4064,12 @@ static int icnss_resource_parse(struct icnss_priv *priv)
}
}
if (of_property_read_bool(pdev->dev.of_node,
"qcom,is_low_power")) {
priv->low_power_support = true;
icnss_pr_dbg("Deep Sleep/Hibernate mode supported\n");
}
if (of_property_read_u32(pdev->dev.of_node, "qcom,rf_subtype",
&priv->rf_subtype) == 0) {
priv->is_rf_subtype_valid = true;