diff options
| author | Shiju Mathew <shijum@codeaurora.org> | 2014-12-30 14:59:23 -0500 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:08:26 -0700 |
| commit | 14b0886b043fab90050f26bee9ea0ead073f1f2b (patch) | |
| tree | f12661ca53feb6b0d253569515480cbb7202f6aa /drivers/thermal | |
| parent | 6a0a9b4bbfa90444635dd7fc6cab19fa96b9155b (diff) | |
thermal-core: Add separate threads for sysfs notify
Add separate threads for sysfs notify. This is required
so that any thermal trip is not blocked while handling
sysfs notify.
Change-Id: Ifee206c29fd1b3c226a342b7f048250d5062397e
Signed-off-by: Shiju Mathew <shijum@codeaurora.org>
[imaund@codeaurora.org: Resolved context conflicts and updated a call
of INIT_COMPLETION to reinit_completion]
Signed-off-by: Ian Maund <imaund@codeaurora.org>
Diffstat (limited to 'drivers/thermal')
| -rw-r--r-- | drivers/thermal/thermal_core.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 61c87f65bc65..e66db0e030ea 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -36,6 +36,7 @@ #include <linux/reboot.h> #include <linux/string.h> #include <linux/of.h> +#include <linux/kthread.h> #include <net/netlink.h> #include <net/genetlink.h> @@ -366,6 +367,22 @@ static void sensor_update_work(struct work_struct *work) mutex_unlock(&sensor->lock); } +static __ref int sensor_sysfs_notify(void *data) +{ + int ret = 0; + struct sensor_info *sensor = (struct sensor_info *)data; + + while (!kthread_should_stop()) { + while (wait_for_completion_interruptible( + &sensor->sysfs_notify_complete) != 0) + ; + reinit_completion(&sensor->sysfs_notify_complete); + sysfs_notify(&sensor->tz->device.kobj, NULL, + THERMAL_UEVENT_DATA); + } + return ret; +} + /* Should not be called in an interrupt context. * Do NOT call sensor_set_trip from this function */ @@ -395,8 +412,7 @@ int thermal_sensor_trip(struct thermal_zone_device *tz, (pos->temp <= temp))) { if ((pos == &tz->tz_threshold[0]) || (pos == &tz->tz_threshold[1])) - sysfs_notify(&tz->device.kobj, NULL, - THERMAL_UEVENT_DATA); + complete(&tz->sensor.sysfs_notify_complete); pos->active = 0; pos->notify(trip, temp, pos->data); } @@ -570,6 +586,14 @@ int sensor_init(struct thermal_zone_device *tz) tz->tz_threshold[1].trip = THERMAL_TRIP_CONFIGURABLE_LOW; list_add(&sensor->sensor_list, &sensor_info_list); INIT_WORK(&sensor->work, sensor_update_work); + init_completion(&sensor->sysfs_notify_complete); + sensor->sysfs_notify_thread = kthread_run(sensor_sysfs_notify, + &tz->sensor, + "therm_core:notify%d", + tz->id); + if (IS_ERR(sensor->sysfs_notify_thread)) + pr_err("Failed to create notify thread %d", tz->id); + return 0; } @@ -2404,6 +2428,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) thermal_remove_hwmon_sysfs(tz); flush_work(&tz->sensor.work); + kthread_stop(tz->sensor.sysfs_notify_thread); mutex_lock(&thermal_list_lock); list_del(&tz->sensor.sensor_list); mutex_unlock(&thermal_list_lock); |
