|
@@ -78,6 +78,7 @@
|
|
|
#include <linux/semaphore.h>
|
|
|
#include <linux/ctype.h>
|
|
|
#include <linux/compat.h>
|
|
|
+#include <linux/reboot.h>
|
|
|
#ifdef MSM_PLATFORM
|
|
|
#include <soc/qcom/subsystem_restart.h>
|
|
|
#endif
|
|
@@ -167,6 +168,7 @@
|
|
|
#define PANIC_ON_BUG_STR ""
|
|
|
#endif
|
|
|
|
|
|
+bool g_is_system_reboot_triggered;
|
|
|
int wlan_start_ret_val;
|
|
|
static DECLARE_COMPLETION(wlan_start_comp);
|
|
|
static unsigned int dev_num = 1;
|
|
@@ -297,8 +299,8 @@ int limit_off_chan_tbl[HDD_MAX_AC][HDD_MAX_OFF_CHAN_ENTRIES] = {
|
|
|
{ HDD_AC_VO_BIT, HDD_MAX_OFF_CHAN_TIME_FOR_VO },
|
|
|
};
|
|
|
|
|
|
-/* internal function declaration */
|
|
|
struct notifier_block hdd_netdev_notifier;
|
|
|
+struct notifier_block system_reboot_notifier;
|
|
|
|
|
|
struct sock *cesium_nl_srv_sock;
|
|
|
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
|
|
@@ -527,6 +529,12 @@ static bool hdd_wait_for_recovery_completion(void)
|
|
|
while (cds_is_driver_recovering()) {
|
|
|
if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
|
|
|
hdd_err("Recovery in progress; wait here!!!");
|
|
|
+
|
|
|
+ if (g_is_system_reboot_triggered) {
|
|
|
+ hdd_info("System Reboot happening ignore unload!!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
msleep(1000);
|
|
|
if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
|
|
|
hdd_err("SSR never completed, error");
|
|
@@ -545,6 +553,7 @@ static bool hdd_wait_for_recovery_completion(void)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static int __hdd_netdev_notifier_call(struct notifier_block *nb,
|
|
|
unsigned long state, void *data)
|
|
|
{
|
|
@@ -661,6 +670,27 @@ struct notifier_block hdd_netdev_notifier = {
|
|
|
.notifier_call = hdd_netdev_notifier_call,
|
|
|
};
|
|
|
|
|
|
+static int system_reboot_notifier_call(struct notifier_block *nb,
|
|
|
+ unsigned long msg_type, void *_unused)
|
|
|
+{
|
|
|
+ switch (msg_type) {
|
|
|
+ case SYS_DOWN:
|
|
|
+ case SYS_HALT:
|
|
|
+ case SYS_POWER_OFF:
|
|
|
+ g_is_system_reboot_triggered = true;
|
|
|
+ hdd_info("reboot, reason: %ld", msg_type);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return NOTIFY_OK;
|
|
|
+}
|
|
|
+
|
|
|
+struct notifier_block system_reboot_notifier = {
|
|
|
+ .notifier_call = system_reboot_notifier_call,
|
|
|
+};
|
|
|
+
|
|
|
/* variable to hold the insmod parameters */
|
|
|
static int con_mode;
|
|
|
|
|
@@ -6577,6 +6607,7 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
|
|
|
hdd_deinit_all_adapters(hdd_ctx, false);
|
|
|
}
|
|
|
|
|
|
+ unregister_reboot_notifier(&system_reboot_notifier);
|
|
|
unregister_netdevice_notifier(&hdd_netdev_notifier);
|
|
|
|
|
|
hdd_wlan_stop_modules(hdd_ctx, false);
|
|
@@ -10542,6 +10573,12 @@ int hdd_wlan_startup(struct device *dev)
|
|
|
goto err_wiphy_unregister;
|
|
|
}
|
|
|
|
|
|
+ ret = register_reboot_notifier(&system_reboot_notifier);
|
|
|
+ if (ret) {
|
|
|
+ hdd_err("Failed to register reboot notifier: %d", ret);
|
|
|
+ goto err_unregister_netdev;
|
|
|
+ }
|
|
|
+
|
|
|
rtnl_held = hdd_hold_rtnl_lock();
|
|
|
|
|
|
ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
|
|
@@ -10601,9 +10638,11 @@ err_close_adapters:
|
|
|
hdd_close_all_adapters(hdd_ctx, rtnl_held);
|
|
|
|
|
|
err_release_rtnl_lock:
|
|
|
+ unregister_reboot_notifier(&system_reboot_notifier);
|
|
|
if (rtnl_held)
|
|
|
hdd_release_rtnl_lock();
|
|
|
|
|
|
+err_unregister_netdev:
|
|
|
unregister_netdevice_notifier(&hdd_netdev_notifier);
|
|
|
|
|
|
err_wiphy_unregister:
|
|
@@ -11924,7 +11963,8 @@ static void __hdd_module_exit(void)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- hdd_wait_for_recovery_completion();
|
|
|
+ if (!hdd_wait_for_recovery_completion())
|
|
|
+ return;
|
|
|
|
|
|
qdf_cancel_delayed_work(&hdd_ctx->iface_idle_work);
|
|
|
|