drivers: thermal: Exit sysfs notify kthread when sensor unregisters
When a thermal zone unregisters, it initiates a blocking call kthread_stop for the sysfs notify kthread to exit. But the sysfs notify kthread is blocked on a completion event, which may not be triggered after the sensor driver initiates a thermal zone unregister call. So, the kthread_stop will be blocked forever. As a part of thermal zone unregister, set a thermal zone unregister flag and send a completion event before calling kthread_stop. Make the sysfs notify kthread to be aware of thermal zone unregister flag and exit after the completion event is triggered. Change-Id: Icf045e0ad6e28135cd3a54c15d9923f095a286ff Signed-off-by: Ram Chandrasekar <rkumbako@codeaurora.org>
This commit is contained in:
parent
487ff740cb
commit
4a86c2f3cc
2 changed files with 10 additions and 4 deletions
|
@ -4,7 +4,7 @@
|
|||
* Copyright (C) 2008 Intel Corp
|
||||
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
|
||||
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
|
||||
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
|
@ -382,9 +382,11 @@ static __ref int sensor_sysfs_notify(void *data)
|
|||
struct sensor_info *sensor = (struct sensor_info *)data;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
while (wait_for_completion_interruptible(
|
||||
&sensor->sysfs_notify_complete) != 0)
|
||||
;
|
||||
if (wait_for_completion_interruptible(
|
||||
&sensor->sysfs_notify_complete) != 0)
|
||||
continue;
|
||||
if (sensor->deregister_active)
|
||||
return ret;
|
||||
reinit_completion(&sensor->sysfs_notify_complete);
|
||||
sysfs_notify(&sensor->tz->device.kobj, NULL,
|
||||
THERMAL_UEVENT_DATA);
|
||||
|
@ -580,6 +582,7 @@ int sensor_init(struct thermal_zone_device *tz)
|
|||
sensor->threshold_max = INT_MAX;
|
||||
sensor->max_idx = -1;
|
||||
sensor->min_idx = -1;
|
||||
sensor->deregister_active = false;
|
||||
mutex_init(&sensor->lock);
|
||||
INIT_LIST_HEAD_RCU(&sensor->sensor_list);
|
||||
INIT_LIST_HEAD_RCU(&sensor->threshold_list);
|
||||
|
@ -2471,6 +2474,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
|||
|
||||
thermal_remove_hwmon_sysfs(tz);
|
||||
flush_work(&tz->sensor.work);
|
||||
tz->sensor.deregister_active = true;
|
||||
complete(&tz->sensor.sysfs_notify_complete);
|
||||
kthread_stop(tz->sensor.sysfs_notify_thread);
|
||||
mutex_lock(&thermal_list_lock);
|
||||
list_del_rcu(&tz->sensor.sensor_list);
|
||||
|
|
|
@ -178,6 +178,7 @@ struct sensor_info {
|
|||
struct work_struct work;
|
||||
struct task_struct *sysfs_notify_thread;
|
||||
struct completion sysfs_notify_complete;
|
||||
bool deregister_active;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue