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:

committed by
Gerrit - the friendly Code Review server

parent
6c9f906a94
commit
26e2742f2f
@@ -2171,10 +2171,25 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
|
|||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case QCOM_SSR_BEFORE_SHUTDOWN:
|
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;
|
break;
|
||||||
case QCOM_SSR_AFTER_SHUTDOWN:
|
case QCOM_SSR_AFTER_SHUTDOWN:
|
||||||
|
/* Collect ramdump only when there was a crash. */
|
||||||
|
if (notif->crashed) {
|
||||||
icnss_pr_info("Collecting msa0 segment dump\n");
|
icnss_pr_info("Collecting msa0 segment dump\n");
|
||||||
icnss_msa0_ramdump(priv);
|
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;
|
goto out;
|
||||||
default:
|
default:
|
||||||
goto out;
|
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",
|
if (of_property_read_u32(pdev->dev.of_node, "qcom,rf_subtype",
|
||||||
&priv->rf_subtype) == 0) {
|
&priv->rf_subtype) == 0) {
|
||||||
priv->is_rf_subtype_valid = true;
|
priv->is_rf_subtype_valid = true;
|
||||||
|
@@ -499,6 +499,7 @@ struct icnss_priv {
|
|||||||
struct workqueue_struct *soc_update_wq;
|
struct workqueue_struct *soc_update_wq;
|
||||||
unsigned long device_config;
|
unsigned long device_config;
|
||||||
bool wpss_supported;
|
bool wpss_supported;
|
||||||
|
u8 low_power_support;
|
||||||
bool is_rf_subtype_valid;
|
bool is_rf_subtype_valid;
|
||||||
u32 rf_subtype;
|
u32 rf_subtype;
|
||||||
u8 is_slate_rfa;
|
u8 is_slate_rfa;
|
||||||
|
Reference in New Issue
Block a user