Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 223d2092 authored by Yu Wang's avatar Yu Wang Committed by Gerrit - the friendly Code Review server
Browse files

cnss2: Add sysfs entry for system shutdown



Add sysfs entry '/sys/kernel/shutdown_wlan/shutdown'.
When system is shutting down or rebooting, this entry will be
written so that drvier can be notified and handle it properly.

Change-Id: I2537a2893f8787ff7c9d33608ef6c42075c3d128
Signed-off-by: default avatarYu Wang <yyuwang@codeaurora.org>
Signed-off-by: default avatarYue Ma <yuem@codeaurora.org>
parent d7f72c76
Loading
Loading
Loading
Loading
+63 −1
Original line number Diff line number Diff line
@@ -679,6 +679,13 @@ int cnss_idle_restart(struct device *dev)
	timeout = cnss_get_boot_timeout(dev);

	reinit_completion(&plat_priv->power_up_complete);

	if (test_bit(CNSS_IN_REBOOT, &plat_priv->driver_state)) {
		cnss_pr_dbg("Reboot or shutdown is in progress, ignore idle restart\n");
		ret = -EINVAL;
		goto out;
	}

	ret = wait_for_completion_timeout(&plat_priv->power_up_complete,
					  msecs_to_jiffies(timeout) << 2);
	if (!ret) {
@@ -1949,6 +1956,23 @@ static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv)
		msm_bus_scale_unregister_client(bus_bw_info->bus_client);
}

static ssize_t shutdown_store(struct kobject *kobj,
			      struct kobj_attribute *attr,
			      const char *buf, size_t count)
{
	struct cnss_plat_data *plat_priv = cnss_get_plat_priv(NULL);

	if (plat_priv) {
		set_bit(CNSS_IN_REBOOT, &plat_priv->driver_state);
		del_timer(&plat_priv->fw_boot_timer);
		complete_all(&plat_priv->power_up_complete);
	}

	cnss_pr_dbg("Received shutdown notification\n");

	return count;
}

static ssize_t fs_ready_store(struct device *dev,
			      struct device_attribute *attr,
			      const char *buf, size_t count)
@@ -1992,18 +2016,55 @@ static ssize_t fs_ready_store(struct device *dev,
	return count;
}

static struct kobj_attribute shutdown_attribute = __ATTR_WO(shutdown);
static DEVICE_ATTR_WO(fs_ready);

static int cnss_create_shutdown_sysfs(struct cnss_plat_data *plat_priv)
{
	int ret = 0;

	plat_priv->shutdown_kobj = kobject_create_and_add("shutdown_wlan",
							  kernel_kobj);
	if (!plat_priv->shutdown_kobj) {
		cnss_pr_err("Failed to create shutdown_wlan kernel object\n");
		return -ENOMEM;
	}

	ret = sysfs_create_file(plat_priv->shutdown_kobj,
				&shutdown_attribute.attr);
	if (ret) {
		cnss_pr_err("Failed to create sysfs shutdown file, err = %d\n",
			    ret);
		kobject_put(plat_priv->shutdown_kobj);
		plat_priv->shutdown_kobj = NULL;
	}

	return ret;
}

static void cnss_remove_shutdown_sysfs(struct cnss_plat_data *plat_priv)
{
	if (plat_priv->shutdown_kobj) {
		sysfs_remove_file(plat_priv->shutdown_kobj,
				  &shutdown_attribute.attr);
		kobject_put(plat_priv->shutdown_kobj);
		plat_priv->shutdown_kobj = NULL;
	}
}

static int cnss_create_sysfs(struct cnss_plat_data *plat_priv)
{
	int ret = 0;

	ret = device_create_file(&plat_priv->plat_dev->dev, &dev_attr_fs_ready);
	if (ret) {
		cnss_pr_err("Failed to create device file, err = %d\n", ret);
		cnss_pr_err("Failed to create device fs_ready file, err = %d\n",
			    ret);
		goto out;
	}

	cnss_create_shutdown_sysfs(plat_priv);

	return 0;
out:
	return ret;
@@ -2011,6 +2072,7 @@ static int cnss_create_sysfs(struct cnss_plat_data *plat_priv)

static void cnss_remove_sysfs(struct cnss_plat_data *plat_priv)
{
	cnss_remove_shutdown_sysfs(plat_priv);
	device_remove_file(&plat_priv->plat_dev->dev, &dev_attr_fs_ready);
}

+1 −0
Original line number Diff line number Diff line
@@ -363,6 +363,7 @@ struct cnss_plat_data {
	int (*get_info_cb)(void *ctx, void *event, int event_len);
	u8 use_nv_mac;
	u8 set_wlaon_pwr_ctrl;
	struct kobject *shutdown_kobj;
};

#ifdef CONFIG_ARCH_QCOM