summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSultanxda <sultanxda@gmail.com>2018-01-03 12:40:12 -0800
committerMichael Bestas <mkbestas@lineageos.org>2019-12-23 23:43:29 +0200
commit5c27bb6d8547112a8b815742c5dbcaae520b4497 (patch)
tree6dccf807c6e4922db94fd6fd13bc87f2c63d3b9d
parentbe2d01153b3fd2b5ea31c63069da5f0c381096dd (diff)
staging: qcacld-3.0: load driver on late initcall when not built as a module
Requiring userspace to write to /sys/kernel/boot_wlan/boot_wlan to boot up the wlan device is unnecessary and blocks userspace for the large amount of time it takes for wlan boot to finish. Instead, load the driver asynchronously on late_initcall. Change-Id: I4d696b9d46de032158fd223c60d9a7dbde26cc3f Signed-off-by: Sultanxda <sultanxda@gmail.com> [nc: Fix unused variable function warning] Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
-rw-r--r--drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c186
1 files changed, 20 insertions, 166 deletions
diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c
index b322a0b128fd..8791c0173783 100644
--- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c
+++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c
@@ -146,25 +146,7 @@ static struct cdev wlan_hdd_state_cdev;
static struct class *class;
static dev_t device;
#ifndef MODULE
-static struct gwlan_loader *wlan_loader;
-static ssize_t wlan_boot_cb(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf, size_t count);
-struct gwlan_loader {
- bool loaded_state;
- struct kobject *boot_wlan_obj;
- struct attribute_group *attr_group;
-};
-
-static struct kobj_attribute wlan_boot_attribute =
- __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
-
-static struct attribute *attrs[] = {
- &wlan_boot_attribute.attr,
- NULL,
-};
-
-#define MODULE_INITIALIZED 1
+static struct work_struct boot_work;
#endif
#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
@@ -399,6 +381,7 @@ int hdd_validate_channel_and_bandwidth(hdd_adapter_t *adapter,
return 0;
}
+#ifdef MODULE
/**
* hdd_wait_for_recovery_completion() - Wait for cds recovery completion
*
@@ -438,6 +421,7 @@ static bool hdd_wait_for_recovery_completion(void)
hdd_info("Recovery completed successfully!");
return true;
}
+#endif
static int __hdd_netdev_notifier_call(struct notifier_block *nb,
@@ -12830,6 +12814,7 @@ dev_alloc_err:
return -ENODEV;
}
+#ifdef MODULE
static void wlan_hdd_state_ctrl_param_destroy(void)
{
cdev_del(&wlan_hdd_state_cdev);
@@ -12839,6 +12824,7 @@ static void wlan_hdd_state_ctrl_param_destroy(void)
pr_info("Device node unregistered");
}
+#endif
/**
* __hdd_module_init - Module init helper
@@ -12892,7 +12878,7 @@ err_hdd_init:
return ret;
}
-
+#ifdef MODULE
/**
* __hdd_module_exit - Module exit helper
*
@@ -12922,135 +12908,6 @@ static void __hdd_module_exit(void)
wlan_hdd_state_ctrl_param_destroy();
}
-#ifndef MODULE
-/**
- * wlan_boot_cb() - Wlan boot callback
- * @kobj: object whose directory we're creating the link in.
- * @attr: attribute the user is interacting with
- * @buff: the buffer containing the user data
- * @count: number of bytes in the buffer
- *
- * This callback is invoked when the fs is ready to start the
- * wlan driver initialization.
- *
- * Return: 'count' on success or a negative error code in case of failure
- */
-static ssize_t wlan_boot_cb(struct kobject *kobj,
- struct kobj_attribute *attr,
- const char *buf,
- size_t count)
-{
-
- if (wlan_loader->loaded_state) {
- pr_err("%s: wlan driver already initialized\n", __func__);
- return -EALREADY;
- }
-
- if (__hdd_module_init()) {
- pr_err("%s: wlan driver initialization failed\n", __func__);
- return -EIO;
- }
-
- wlan_loader->loaded_state = MODULE_INITIALIZED;
-
- return count;
-}
-
-/**
- * hdd_sysfs_cleanup() - cleanup sysfs
- *
- * Return: None
- *
- */
-static void hdd_sysfs_cleanup(void)
-{
- /* remove from group */
- if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
- sysfs_remove_group(wlan_loader->boot_wlan_obj,
- wlan_loader->attr_group);
-
- /* unlink the object from parent */
- kobject_del(wlan_loader->boot_wlan_obj);
-
- /* free the object */
- kobject_put(wlan_loader->boot_wlan_obj);
-
- kfree(wlan_loader->attr_group);
- kfree(wlan_loader);
-
- wlan_loader = NULL;
-}
-
-/**
- * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
- * ready
- *
- * This is creates the syfs entry boot_wlan. Which shall be invoked
- * when the filesystem is ready.
- *
- * QDF API cannot be used here since this function is called even before
- * initializing WLAN driver.
- *
- * Return: 0 for success, errno on failure
- */
-static int wlan_init_sysfs(void)
-{
- int ret = -ENOMEM;
-
- wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
- if (!wlan_loader)
- return -ENOMEM;
-
- wlan_loader->boot_wlan_obj = NULL;
- wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
- GFP_KERNEL);
- if (!wlan_loader->attr_group)
- goto error_return;
-
- wlan_loader->loaded_state = 0;
- wlan_loader->attr_group->attrs = attrs;
-
- wlan_loader->boot_wlan_obj = kobject_create_and_add("boot_wlan",
- kernel_kobj);
- if (!wlan_loader->boot_wlan_obj) {
- pr_err("%s: sysfs create and add failed\n", __func__);
- goto error_return;
- }
-
- ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
- wlan_loader->attr_group);
- if (ret) {
- pr_err("%s: sysfs create group failed %d\n", __func__, ret);
- goto error_return;
- }
-
- return 0;
-
-error_return:
- hdd_sysfs_cleanup();
-
- return ret;
-}
-
-/**
- * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
- *
- * Return: 0 on success or errno on failure
- */
-static int wlan_deinit_sysfs(void)
-{
- if (!wlan_loader) {
- hdd_err("wlan loader context is Null!");
- return -EINVAL;
- }
-
- hdd_sysfs_cleanup();
- return 0;
-}
-
-#endif /* MODULE */
-
-#ifdef MODULE
/**
* __hdd_module_init - Module init helper
*
@@ -13067,21 +12924,7 @@ static int hdd_module_init(void)
return 0;
}
-#else
-static int __init hdd_module_init(void)
-{
- int ret = -EINVAL;
-
- ret = wlan_init_sysfs();
- if (ret)
- pr_err("Failed to create sysfs entry for loading wlan");
-
- return ret;
-}
-#endif
-
-#ifdef MODULE
/**
* hdd_module_exit() - Exit function
*
@@ -13094,10 +12937,17 @@ static void __exit hdd_module_exit(void)
__hdd_module_exit();
}
#else
-static void __exit hdd_module_exit(void)
+static void wlan_hdd_boot_fn(struct work_struct *work)
{
- __hdd_module_exit();
- wlan_deinit_sysfs();
+ __hdd_module_init();
+}
+
+static int __init hdd_module_init(void)
+{
+ INIT_WORK(&boot_work, wlan_hdd_boot_fn);
+ schedule_work(&boot_work);
+
+ return 0;
}
#endif
@@ -13889,8 +13739,12 @@ void hdd_drv_ops_inactivity_handler(unsigned long arg)
}
/* Register the module init/exit functions */
+#ifdef MODULE
module_init(hdd_module_init);
module_exit(hdd_module_exit);
+#else
+late_initcall(hdd_module_init);
+#endif
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Qualcomm Atheros, Inc.");