Merge tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kerne...
[firefly-linux-kernel-4.4.55.git] / drivers / thermal / thermal_core.c
index 4cdc3e327222676d43e72e8a3a6eb81f1fb24916..d755440791b7ce0a01d3e186e423ed6769fcc8be 100644 (file)
@@ -40,7 +40,7 @@
 
 MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 static DEFINE_IDR(thermal_tz_idr);
 static DEFINE_IDR(thermal_cdev_idr);
@@ -369,16 +369,28 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip)
        monitor_thermal_zone(tz);
 }
 
-static int thermal_zone_get_temp(struct thermal_zone_device *tz,
-                               unsigned long *temp)
+/**
+ * thermal_zone_get_temp() - returns its the temperature of thermal zone
+ * @tz: a valid pointer to a struct thermal_zone_device
+ * @temp: a valid pointer to where to store the resulting temperature.
+ *
+ * When a valid thermal zone reference is passed, it will fetch its
+ * temperature and fill @temp.
+ *
+ * Return: On success returns 0, an error code otherwise
+ */
+int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp)
 {
-       int ret = 0;
+       int ret = -EINVAL;
 #ifdef CONFIG_THERMAL_EMULATION
        int count;
        unsigned long crit_temp = -1UL;
        enum thermal_trip_type type;
 #endif
 
+       if (!tz || IS_ERR(tz))
+               goto exit;
+
        mutex_lock(&tz->lock);
 
        ret = tz->ops->get_temp(tz, temp);
@@ -402,8 +414,10 @@ static int thermal_zone_get_temp(struct thermal_zone_device *tz,
 skip_emul:
 #endif
        mutex_unlock(&tz->lock);
+exit:
        return ret;
 }
+EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
 
 static void update_temperature(struct thermal_zone_device *tz)
 {
@@ -432,7 +446,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
        for (count = 0; count < tz->trips; count++)
                handle_thermal_trip(tz, count);
 }
-EXPORT_SYMBOL(thermal_zone_device_update);
+EXPORT_SYMBOL_GPL(thermal_zone_device_update);
 
 static void thermal_zone_device_check(struct work_struct *work)
 {
@@ -1095,13 +1109,23 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
 #endif
 
 /**
- * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
- * @tz:                thermal zone device
+ * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone
+ * @tz:                pointer to struct thermal_zone_device
  * @trip:      indicates which trip point the cooling devices is
  *             associated with in this thermal zone.
- * @cdev:      thermal cooling device
+ * @cdev:      pointer to struct thermal_cooling_device
+ * @upper:     the Maximum cooling state for this trip point.
+ *             THERMAL_NO_LIMIT means no upper limit,
+ *             and the cooling device can be in max_state.
+ * @lower:     the Minimum cooling state can be used for this trip point.
+ *             THERMAL_NO_LIMIT means no lower limit,
+ *             and the cooling device can be in cooling state 0.
  *
+ * This interface function bind a thermal cooling device to the certain trip
+ * point of a thermal zone device.
  * This function is usually called in the thermal zone device .bind callback.
+ *
+ * Return: 0 on success, the proper error value otherwise.
  */
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
                                     int trip,
@@ -1195,16 +1219,21 @@ free_mem:
        kfree(dev);
        return result;
 }
-EXPORT_SYMBOL(thermal_zone_bind_cooling_device);
+EXPORT_SYMBOL_GPL(thermal_zone_bind_cooling_device);
 
 /**
- * thermal_zone_unbind_cooling_device - unbind a cooling device from a thermal zone
- * @tz:                thermal zone device
+ * thermal_zone_unbind_cooling_device() - unbind a cooling device from a
+ *                                       thermal zone.
+ * @tz:                pointer to a struct thermal_zone_device.
  * @trip:      indicates which trip point the cooling devices is
  *             associated with in this thermal zone.
- * @cdev:      thermal cooling device
+ * @cdev:      pointer to a struct thermal_cooling_device.
  *
+ * This interface function unbind a thermal cooling device from the certain
+ * trip point of a thermal zone device.
  * This function is usually called in the thermal zone device .unbind callback.
+ *
+ * Return: 0 on success, the proper error value otherwise.
  */
 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
                                       int trip,
@@ -1235,7 +1264,7 @@ unbind:
        kfree(pos);
        return 0;
 }
-EXPORT_SYMBOL(thermal_zone_unbind_cooling_device);
+EXPORT_SYMBOL_GPL(thermal_zone_unbind_cooling_device);
 
 static void thermal_release(struct device *dev)
 {
@@ -1258,10 +1287,17 @@ static struct class thermal_class = {
 };
 
 /**
- * thermal_cooling_device_register - register a new thermal cooling device
+ * thermal_cooling_device_register() - register a new thermal cooling device
  * @type:      the thermal cooling device type.
  * @devdata:   device private data.
  * @ops:               standard thermal cooling devices callbacks.
+ *
+ * This interface function adds a new thermal cooling device (fan/processor/...)
+ * to /sys/class/thermal/ folder as cooling_device[0-*]. It tries to bind itself
+ * to all the thermal zone devices registered at the same time.
+ *
+ * Return: a pointer to the created struct thermal_cooling_device or an
+ * ERR_PTR. Caller must check return value with IS_ERR*() helpers.
  */
 struct thermal_cooling_device *
 thermal_cooling_device_register(char *type, void *devdata,
@@ -1287,7 +1323,7 @@ thermal_cooling_device_register(char *type, void *devdata,
                return ERR_PTR(result);
        }
 
-       strcpy(cdev->type, type ? : "");
+       strlcpy(cdev->type, type ? : "", sizeof(cdev->type));
        mutex_init(&cdev->lock);
        INIT_LIST_HEAD(&cdev->thermal_instances);
        cdev->ops = ops;
@@ -1332,7 +1368,7 @@ unregister:
        device_unregister(&cdev->device);
        return ERR_PTR(result);
 }
-EXPORT_SYMBOL(thermal_cooling_device_register);
+EXPORT_SYMBOL_GPL(thermal_cooling_device_register);
 
 /**
  * thermal_cooling_device_unregister - removes the registered thermal cooling device
@@ -1392,7 +1428,7 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
        device_unregister(&cdev->device);
        return;
 }
-EXPORT_SYMBOL(thermal_cooling_device_unregister);
+EXPORT_SYMBOL_GPL(thermal_cooling_device_unregister);
 
 void thermal_cdev_update(struct thermal_cooling_device *cdev)
 {
@@ -1418,7 +1454,7 @@ void thermal_cdev_update(struct thermal_cooling_device *cdev)
 EXPORT_SYMBOL(thermal_cdev_update);
 
 /**
- * notify_thermal_framework - Sensor drivers use this API to notify framework
+ * thermal_notify_framework - Sensor drivers use this API to notify framework
  * @tz:                thermal zone device
  * @trip:      indicates which trip point has been crossed
  *
@@ -1429,16 +1465,21 @@ EXPORT_SYMBOL(thermal_cdev_update);
  * The throttling policy is based on the configured platform data; if no
  * platform data is provided, this uses the step_wise throttling policy.
  */
-void notify_thermal_framework(struct thermal_zone_device *tz, int trip)
+void thermal_notify_framework(struct thermal_zone_device *tz, int trip)
 {
        handle_thermal_trip(tz, trip);
 }
-EXPORT_SYMBOL(notify_thermal_framework);
+EXPORT_SYMBOL_GPL(thermal_notify_framework);
 
 /**
- * create_trip_attrs - create attributes for trip points
+ * create_trip_attrs() - create attributes for trip points
  * @tz:                the thermal zone device
  * @mask:      Writeable trip point bitmap.
+ *
+ * helper function to instantiate sysfs entries for every trip
+ * point and its properties of a struct thermal_zone_device.
+ *
+ * Return: 0 on success, the proper error value otherwise.
  */
 static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
 {
@@ -1539,7 +1580,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
 }
 
 /**
- * thermal_zone_device_register - register a new thermal zone device
+ * thermal_zone_device_register() - register a new thermal zone device
  * @type:      the thermal zone device type
  * @trips:     the number of trip points the thermal zone support
  * @mask:      a bit string indicating the writeablility of trip points
@@ -1552,8 +1593,15 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
  *                whether trip points have been crossed (0 for interrupt
  *                driven systems)
  *
+ * This interface function adds a new thermal zone device (sensor) to
+ * /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
+ * thermal cooling devices registered at the same time.
  * thermal_zone_device_unregister() must be called when the device is no
  * longer needed. The passive cooling depends on the .get_trend() return value.
+ *
+ * Return: a pointer to the created struct thermal_zone_device or an
+ * in case of error, an ERR_PTR. Caller must check return value with
+ * IS_ERR*() helpers.
  */
 struct thermal_zone_device *thermal_zone_device_register(const char *type,
        int trips, int mask, void *devdata,
@@ -1592,7 +1640,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
                return ERR_PTR(result);
        }
 
-       strcpy(tz->type, type ? : "");
+       strlcpy(tz->type, type ? : "", sizeof(tz->type));
        tz->ops = ops;
        tz->tzp = tzp;
        tz->device.class = &thermal_class;
@@ -1685,7 +1733,7 @@ unregister:
        device_unregister(&tz->device);
        return ERR_PTR(result);
 }
-EXPORT_SYMBOL(thermal_zone_device_register);
+EXPORT_SYMBOL_GPL(thermal_zone_device_register);
 
 /**
  * thermal_device_unregister - removes the registered thermal zone device
@@ -1752,7 +1800,45 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
        device_unregister(&tz->device);
        return;
 }
-EXPORT_SYMBOL(thermal_zone_device_unregister);
+EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
+
+/**
+ * thermal_zone_get_zone_by_name() - search for a zone and returns its ref
+ * @name: thermal zone name to fetch the temperature
+ *
+ * When only one zone is found with the passed name, returns a reference to it.
+ *
+ * Return: On success returns a reference to an unique thermal zone with
+ * matching name equals to @name, an ERR_PTR otherwise (-EINVAL for invalid
+ * paramenters, -ENODEV for not found and -EEXIST for multiple matches).
+ */
+struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name)
+{
+       struct thermal_zone_device *pos = NULL, *ref = ERR_PTR(-EINVAL);
+       unsigned int found = 0;
+
+       if (!name)
+               goto exit;
+
+       mutex_lock(&thermal_list_lock);
+       list_for_each_entry(pos, &thermal_tz_list, node)
+               if (!strnicmp(name, pos->type, THERMAL_NAME_LENGTH)) {
+                       found++;
+                       ref = pos;
+               }
+       mutex_unlock(&thermal_list_lock);
+
+       /* nothing has been found, thus an error code for it */
+       if (found == 0)
+               ref = ERR_PTR(-ENODEV);
+       else if (found > 1)
+       /* Success only when an unique zone is found */
+               ref = ERR_PTR(-EEXIST);
+
+exit:
+       return ref;
+}
+EXPORT_SYMBOL_GPL(thermal_zone_get_zone_by_name);
 
 #ifdef CONFIG_NET
 static struct genl_family thermal_event_genl_family = {
@@ -1830,7 +1916,7 @@ int thermal_generate_netlink_event(struct thermal_zone_device *tz,
 
        return result;
 }
-EXPORT_SYMBOL(thermal_generate_netlink_event);
+EXPORT_SYMBOL_GPL(thermal_generate_netlink_event);
 
 static int genetlink_init(void)
 {