diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/thermal.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index bc6d5866ef98..69ec73b0239d 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -195,6 +195,7 @@ struct acpi_thermal { | |||
195 | struct acpi_thermal_trips trips; | 195 | struct acpi_thermal_trips trips; |
196 | struct acpi_handle_list devices; | 196 | struct acpi_handle_list devices; |
197 | struct timer_list timer; | 197 | struct timer_list timer; |
198 | struct mutex lock; | ||
198 | }; | 199 | }; |
199 | 200 | ||
200 | static const struct file_operations acpi_thermal_state_fops = { | 201 | static const struct file_operations acpi_thermal_state_fops = { |
@@ -711,6 +712,7 @@ static void acpi_thermal_check(void *data) | |||
711 | int result = 0; | 712 | int result = 0; |
712 | struct acpi_thermal *tz = data; | 713 | struct acpi_thermal *tz = data; |
713 | unsigned long sleep_time = 0; | 714 | unsigned long sleep_time = 0; |
715 | unsigned long timeout_jiffies = 0; | ||
714 | int i = 0; | 716 | int i = 0; |
715 | struct acpi_thermal_state state; | 717 | struct acpi_thermal_state state; |
716 | 718 | ||
@@ -720,11 +722,15 @@ static void acpi_thermal_check(void *data) | |||
720 | return; | 722 | return; |
721 | } | 723 | } |
722 | 724 | ||
725 | /* Check if someone else is already running */ | ||
726 | if (!mutex_trylock(&tz->lock)) | ||
727 | return; | ||
728 | |||
723 | state = tz->state; | 729 | state = tz->state; |
724 | 730 | ||
725 | result = acpi_thermal_get_temperature(tz); | 731 | result = acpi_thermal_get_temperature(tz); |
726 | if (result) | 732 | if (result) |
727 | return; | 733 | goto unlock; |
728 | 734 | ||
729 | memset(&tz->state, 0, sizeof(tz->state)); | 735 | memset(&tz->state, 0, sizeof(tz->state)); |
730 | 736 | ||
@@ -787,10 +793,13 @@ static void acpi_thermal_check(void *data) | |||
787 | * a thermal event occurs). Note that _TSP and _TZD values are | 793 | * a thermal event occurs). Note that _TSP and _TZD values are |
788 | * given in 1/10th seconds (we must covert to milliseconds). | 794 | * given in 1/10th seconds (we must covert to milliseconds). |
789 | */ | 795 | */ |
790 | if (tz->state.passive) | 796 | if (tz->state.passive) { |
791 | sleep_time = tz->trips.passive.tsp * 100; | 797 | sleep_time = tz->trips.passive.tsp * 100; |
792 | else if (tz->polling_frequency > 0) | 798 | timeout_jiffies = jiffies + (HZ * sleep_time) / 1000; |
799 | } else if (tz->polling_frequency > 0) { | ||
793 | sleep_time = tz->polling_frequency * 100; | 800 | sleep_time = tz->polling_frequency * 100; |
801 | timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000); | ||
802 | } | ||
794 | 803 | ||
795 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", | 804 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", |
796 | tz->name, tz->temperature, sleep_time)); | 805 | tz->name, tz->temperature, sleep_time)); |
@@ -804,17 +813,16 @@ static void acpi_thermal_check(void *data) | |||
804 | del_timer(&(tz->timer)); | 813 | del_timer(&(tz->timer)); |
805 | } else { | 814 | } else { |
806 | if (timer_pending(&(tz->timer))) | 815 | if (timer_pending(&(tz->timer))) |
807 | mod_timer(&(tz->timer), | 816 | mod_timer(&(tz->timer), timeout_jiffies); |
808 | jiffies + (HZ * sleep_time) / 1000); | ||
809 | else { | 817 | else { |
810 | tz->timer.data = (unsigned long)tz; | 818 | tz->timer.data = (unsigned long)tz; |
811 | tz->timer.function = acpi_thermal_run; | 819 | tz->timer.function = acpi_thermal_run; |
812 | tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; | 820 | tz->timer.expires = timeout_jiffies; |
813 | add_timer(&(tz->timer)); | 821 | add_timer(&(tz->timer)); |
814 | } | 822 | } |
815 | } | 823 | } |
816 | 824 | unlock: | |
817 | return; | 825 | mutex_unlock(&tz->lock); |
818 | } | 826 | } |
819 | 827 | ||
820 | /* -------------------------------------------------------------------------- | 828 | /* -------------------------------------------------------------------------- |
@@ -1251,7 +1259,7 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1251 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); | 1259 | strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); |
1252 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); | 1260 | strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); |
1253 | acpi_driver_data(device) = tz; | 1261 | acpi_driver_data(device) = tz; |
1254 | 1262 | mutex_init(&tz->lock); | |
1255 | result = acpi_thermal_get_info(tz); | 1263 | result = acpi_thermal_get_info(tz); |
1256 | if (result) | 1264 | if (result) |
1257 | goto end; | 1265 | goto end; |
@@ -1321,7 +1329,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1321 | } | 1329 | } |
1322 | 1330 | ||
1323 | acpi_thermal_remove_fs(device); | 1331 | acpi_thermal_remove_fs(device); |
1324 | 1332 | mutex_destroy(&tz->lock); | |
1325 | kfree(tz); | 1333 | kfree(tz); |
1326 | return 0; | 1334 | return 0; |
1327 | } | 1335 | } |