]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'thermal/next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Wed, 3 Oct 2012 02:12:15 +0000 (12:12 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Wed, 3 Oct 2012 02:12:15 +0000 (12:12 +1000)
Conflicts:
drivers/staging/omap-thermal/omap-thermal-common.c
drivers/thermal/thermal_sys.c

1  2 
drivers/acpi/thermal.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/staging/omap-thermal/omap-thermal-common.c
drivers/thermal/thermal_sys.c

Simple merge
index c74e73b2069ad230cd1be4ae4d7510252d44f52b,84e02b416a4ae11cd4a6745de431a0bc61b02583..c4633de64465a2eccc5d0305238feee8a8c28375
@@@ -334,19 -324,9 +334,9 @@@ config SENSORS_DA9052_AD
          This driver can also be built as module. If so, the module
          will be called da9052-hwmon.
  
- config SENSORS_EXYNOS4_TMU
-       tristate "Temperature sensor on Samsung EXYNOS4"
-       depends on ARCH_EXYNOS4
-       help
-         If you say yes here you get support for TMU (Thermal Management
-         Unit) on SAMSUNG EXYNOS4 series of SoC.
-         This driver can also be built as a module. If so, the module
-         will be called exynos4-tmu.
  config SENSORS_I5K_AMB
        tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets"
 -      depends on PCI && EXPERIMENTAL
 +      depends on PCI
        help
          If you say yes here you get support for FB-DIMM AMB temperature
          monitoring chips on systems with the Intel 5000 series chipset.
Simple merge
index 67789b8345d25cb7a5fad998863aab3c9d999689,848553dd4bb73dbd81246ae0f18cdf4bf0528437..3b87b1840db30a5f5789b9e397ee62b2d5820950
@@@ -91,6 -161,264 +161,261 @@@ static void release_idr(struct idr *idr
                mutex_unlock(lock);
  }
  
 -      cancel_delayed_work(&(tz->poll_queue));
 -
 -      if (!delay)
 -              return;
 -
+ int get_tz_trend(struct thermal_zone_device *tz, int trip)
+ {
+       enum thermal_trend trend;
+       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
+               if (tz->temperature > tz->last_temperature)
+                       trend = THERMAL_TREND_RAISING;
+               else if (tz->temperature < tz->last_temperature)
+                       trend = THERMAL_TREND_DROPPING;
+               else
+                       trend = THERMAL_TREND_STABLE;
+       }
+       return trend;
+ }
+ EXPORT_SYMBOL(get_tz_trend);
+ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *tz,
+                       struct thermal_cooling_device *cdev, int trip)
+ {
+       struct thermal_instance *pos = NULL;
+       struct thermal_instance *target_instance = NULL;
+       mutex_lock(&tz->lock);
+       mutex_lock(&cdev->lock);
+       list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
+               if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
+                       target_instance = pos;
+                       break;
+               }
+       }
+       mutex_unlock(&cdev->lock);
+       mutex_unlock(&tz->lock);
+       return target_instance;
+ }
+ EXPORT_SYMBOL(get_thermal_instance);
+ static void print_bind_err_msg(struct thermal_zone_device *tz,
+                       struct thermal_cooling_device *cdev, int ret)
+ {
+       dev_err(&tz->device, "binding zone %s with cdev %s failed:%d\n",
+                               tz->type, cdev->type, ret);
+ }
+ static void __bind(struct thermal_zone_device *tz, int mask,
+                       struct thermal_cooling_device *cdev)
+ {
+       int i, ret;
+       for (i = 0; i < tz->trips; i++) {
+               if (mask & (1 << i)) {
+                       ret = thermal_zone_bind_cooling_device(tz, i, cdev,
+                                       THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+                       if (ret)
+                               print_bind_err_msg(tz, cdev, ret);
+               }
+       }
+ }
+ static void __unbind(struct thermal_zone_device *tz, int mask,
+                       struct thermal_cooling_device *cdev)
+ {
+       int i;
+       for (i = 0; i < tz->trips; i++)
+               if (mask & (1 << i))
+                       thermal_zone_unbind_cooling_device(tz, i, cdev);
+ }
+ static void bind_cdev(struct thermal_cooling_device *cdev)
+ {
+       int i, ret;
+       const struct thermal_zone_params *tzp;
+       struct thermal_zone_device *pos = NULL;
+       mutex_lock(&thermal_list_lock);
+       list_for_each_entry(pos, &thermal_tz_list, node) {
+               if (!pos->tzp && !pos->ops->bind)
+                       continue;
+               if (!pos->tzp && pos->ops->bind) {
+                       ret = pos->ops->bind(pos, cdev);
+                       if (ret)
+                               print_bind_err_msg(pos, cdev, ret);
+               }
+               tzp = pos->tzp;
+               if (!tzp || !tzp->tbp)
+                       continue;
+               for (i = 0; i < tzp->num_tbps; i++) {
+                       if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
+                               continue;
+                       if (tzp->tbp[i].match(pos, cdev))
+                               continue;
+                       tzp->tbp[i].cdev = cdev;
+                       __bind(pos, tzp->tbp[i].trip_mask, cdev);
+               }
+       }
+       mutex_unlock(&thermal_list_lock);
+ }
+ static void bind_tz(struct thermal_zone_device *tz)
+ {
+       int i, ret;
+       struct thermal_cooling_device *pos = NULL;
+       const struct thermal_zone_params *tzp = tz->tzp;
+       if (!tzp && !tz->ops->bind)
+               return;
+       mutex_lock(&thermal_list_lock);
+       /* If there is no platform data, try to use ops->bind */
+       if (!tzp && tz->ops->bind) {
+               list_for_each_entry(pos, &thermal_cdev_list, node) {
+                       ret = tz->ops->bind(tz, pos);
+                       if (ret)
+                               print_bind_err_msg(tz, pos, ret);
+               }
+               goto exit;
+       }
+       if (!tzp || !tzp->tbp)
+               goto exit;
+       list_for_each_entry(pos, &thermal_cdev_list, node) {
+               for (i = 0; i < tzp->num_tbps; i++) {
+                       if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
+                               continue;
+                       if (tzp->tbp[i].match(tz, pos))
+                               continue;
+                       tzp->tbp[i].cdev = pos;
+                       __bind(tz, tzp->tbp[i].trip_mask, pos);
+               }
+       }
+ exit:
+       mutex_unlock(&thermal_list_lock);
+ }
+ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+                                           int delay)
+ {
 -              queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
 -                                    round_jiffies(msecs_to_jiffies(delay)));
+       if (delay > 1000)
 -              queue_delayed_work(system_freezable_wq, &(tz->poll_queue),
 -                                    msecs_to_jiffies(delay));
++              mod_delayed_work(system_freezable_wq, &tz->poll_queue,
++                               round_jiffies(msecs_to_jiffies(delay)));
++      else if (delay)
++              mod_delayed_work(system_freezable_wq, &tz->poll_queue,
++                               msecs_to_jiffies(delay));
+       else
++              cancel_delayed_work(&tz->poll_queue);
+ }
+ static void monitor_thermal_zone(struct thermal_zone_device *tz)
+ {
+       mutex_lock(&tz->lock);
+       if (tz->passive)
+               thermal_zone_device_set_polling(tz, tz->passive_delay);
+       else if (tz->polling_delay)
+               thermal_zone_device_set_polling(tz, tz->polling_delay);
+       else
+               thermal_zone_device_set_polling(tz, 0);
+       mutex_unlock(&tz->lock);
+ }
+ static void handle_non_critical_trips(struct thermal_zone_device *tz,
+                       int trip, enum thermal_trip_type trip_type)
+ {
+       tz->governor->throttle(tz, trip);
+ }
+ static void handle_critical_trips(struct thermal_zone_device *tz,
+                               int trip, enum thermal_trip_type trip_type)
+ {
+       long trip_temp;
+       tz->ops->get_trip_temp(tz, trip, &trip_temp);
+       /* If we have not crossed the trip_temp, we do not care. */
+       if (tz->temperature < trip_temp)
+               return;
+       if (tz->ops->notify)
+               tz->ops->notify(tz, trip, trip_type);
+       if (trip_type == THERMAL_TRIP_CRITICAL) {
+               pr_emerg("Critical temperature reached(%d C),shutting down\n",
+                        tz->temperature / 1000);
+               orderly_poweroff(true);
+       }
+ }
+ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
+ {
+       enum thermal_trip_type type;
+       tz->ops->get_trip_type(tz, trip, &type);
+       if (type == THERMAL_TRIP_CRITICAL || type == THERMAL_TRIP_HOT)
+               handle_critical_trips(tz, trip, type);
+       else
+               handle_non_critical_trips(tz, trip, type);
+       /*
+        * Alright, we handled this trip successfully.
+        * So, start monitoring again.
+        */
+       monitor_thermal_zone(tz);
+ }
+ static void update_temperature(struct thermal_zone_device *tz)
+ {
+       long temp;
+       int ret;
+       mutex_lock(&tz->lock);
+       ret = tz->ops->get_temp(tz, &temp);
+       if (ret) {
+               pr_warn("failed to read out thermal zone %d\n", tz->id);
+               goto exit;
+       }
+       tz->last_temperature = tz->temperature;
+       tz->temperature = temp;
+ exit:
+       mutex_unlock(&tz->lock);
+ }
+ void thermal_zone_device_update(struct thermal_zone_device *tz)
+ {
+       int count;
+       update_temperature(tz);
+       for (count = 0; count < tz->trips; count++)
+               handle_thermal_trip(tz, count);
+ }
+ EXPORT_SYMBOL(thermal_zone_device_update);
+ static void thermal_zone_device_check(struct work_struct *work)
+ {
+       struct thermal_zone_device *tz = container_of(work, struct
+                                                     thermal_zone_device,
+                                                     poll_queue.work);
+       thermal_zone_device_update(tz);
+ }
  /* sys I/F for thermal zone */
  
  #define to_thermal_zone(_dev) \