|
@@ -213,6 +213,7 @@
|
|
|
|
|
|
int wlan_start_ret_val;
|
|
|
static DECLARE_COMPLETION(wlan_start_comp);
|
|
|
+static qdf_atomic_t wlan_hdd_state_fops_ref;
|
|
|
static unsigned int dev_num = 1;
|
|
|
static struct cdev wlan_hdd_state_cdev;
|
|
|
static struct class *class;
|
|
@@ -235,7 +236,6 @@ static struct attribute *attrs[] = {
|
|
|
&wlan_boot_attribute.attr,
|
|
|
NULL,
|
|
|
};
|
|
|
-
|
|
|
#define MODULE_INITIALIZED 1
|
|
|
|
|
|
#ifdef MULTI_IF_NAME
|
|
@@ -14437,6 +14437,8 @@ void hdd_deinit(void)
|
|
|
static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
|
|
|
struct file *file)
|
|
|
{
|
|
|
+ qdf_atomic_inc(&wlan_hdd_state_fops_ref);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -14485,7 +14487,7 @@ static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
|
|
|
rc = wait_for_completion_timeout(&wlan_start_comp,
|
|
|
msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
|
|
|
if (!rc) {
|
|
|
- hdd_alert("Timed-out!!");
|
|
|
+ pr_err("Timed-out!!");
|
|
|
ret = -EINVAL;
|
|
|
return ret;
|
|
|
}
|
|
@@ -14495,11 +14497,32 @@ exit:
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * wlan_hdd_state_ctrl_param_release() - Release callback for /dev/wlan.
|
|
|
+ *
|
|
|
+ * @inode: struct inode pinter.
|
|
|
+ * @file: struct file pointer.
|
|
|
+ *
|
|
|
+ * Release callback that would be invoked when the file operations has
|
|
|
+ * completed fully. This is implemented to provide a reference count mechanism
|
|
|
+ * via which the driver can wait till all possible usage of the /dev/wlan
|
|
|
+ * file is completed.
|
|
|
+ *
|
|
|
+ * Return: Success
|
|
|
+ */
|
|
|
+static int wlan_hdd_state_ctrl_param_release(struct inode *inode,
|
|
|
+ struct file *file)
|
|
|
+{
|
|
|
+ qdf_atomic_dec(&wlan_hdd_state_fops_ref);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
const struct file_operations wlan_hdd_state_fops = {
|
|
|
.owner = THIS_MODULE,
|
|
|
.open = wlan_hdd_state_ctrl_param_open,
|
|
|
.write = wlan_hdd_state_ctrl_param_write,
|
|
|
+ .release = wlan_hdd_state_ctrl_param_release,
|
|
|
};
|
|
|
|
|
|
static int wlan_hdd_state_ctrl_param_create(void)
|
|
@@ -14509,6 +14532,7 @@ static int wlan_hdd_state_ctrl_param_create(void)
|
|
|
struct device *dev;
|
|
|
|
|
|
init_completion(&wlan_start_comp);
|
|
|
+ qdf_atomic_init(&wlan_hdd_state_fops_ref);
|
|
|
|
|
|
device = MKDEV(wlan_hdd_state_major, 0);
|
|
|
|
|
@@ -14532,6 +14556,9 @@ static int wlan_hdd_state_ctrl_param_create(void)
|
|
|
}
|
|
|
|
|
|
cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
|
|
|
+
|
|
|
+ wlan_hdd_state_cdev.owner = THIS_MODULE;
|
|
|
+
|
|
|
ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
|
|
|
if (ret) {
|
|
|
pr_err("Failed to add cdev error");
|
|
@@ -15338,6 +15365,9 @@ pld_deinit:
|
|
|
pld_deinit();
|
|
|
|
|
|
hdd_start_complete(errno);
|
|
|
+ /* Wait for any ref taken on /dev/wlan to be released */
|
|
|
+ while (qdf_atomic_read(&wlan_hdd_state_fops_ref))
|
|
|
+ ;
|
|
|
param_destroy:
|
|
|
wlan_hdd_state_ctrl_param_destroy();
|
|
|
wakelock_destroy:
|