Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 160ff06b authored by Len Brown's avatar Len Brown
Browse files

Merge branches 'release' and 'thermal' into release

parents 1ca721cd 5e012760
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -143,10 +143,10 @@ type Strings which represent the thermal zone type.
				This is given by thermal zone driver as part of registration.
				Eg: "ACPI thermal zone" indicates it's a ACPI thermal device
				RO
				Optional
				Required

temp				Current temperature as reported by thermal zone (sensor)
				Unit: degree Celsius
				Unit: millidegree Celsius
				RO
				Required

@@ -163,7 +163,7 @@ mode One of the predefined values in [kernel, user]
					  charge of the thermal management.

trip_point_[0-*]_temp		The temperature above which trip point will be fired
				Unit: degree Celsius
				Unit: millidegree Celsius
				RO
				Optional

@@ -193,7 +193,7 @@ type String which represents the type of device
				eg. For memory controller device on intel_menlow platform:
				this should be "Memory controller"
				RO
				Optional
				Required

max_state			The maximum permissible cooling state of this cooling device.
				RO
@@ -219,16 +219,16 @@ the sys I/F structure will be built like this:

|thermal_zone1:
	|-----type:			ACPI thermal zone
	|-----temp:			37
	|-----temp:			37000
	|-----mode:			kernel
	|-----trip_point_0_temp:	100
	|-----trip_point_0_temp:	100000
	|-----trip_point_0_type:	critical
	|-----trip_point_1_temp:	80
	|-----trip_point_1_temp:	80000
	|-----trip_point_1_type:	passive
	|-----trip_point_2_temp:	70
	|-----trip_point_2_type:	active[0]
	|-----trip_point_3_temp:	60
	|-----trip_point_3_type:	active[1]
	|-----trip_point_2_temp:	70000
	|-----trip_point_2_type:	active0
	|-----trip_point_3_temp:	60000
	|-----trip_point_3_type:	active1
	|-----cdev0:			--->/sys/class/thermal/cooling_device0
	|-----cdev0_trip_point:		1	/* cdev0 can be used for passive */
	|-----cdev1:			--->/sys/class/thermal/cooling_device3
+7 −5
Original line number Diff line number Diff line
@@ -879,6 +879,8 @@ static void acpi_thermal_check(void *data)
}

/* sys I/F for generic thermal sysfs support */
#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)

static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
{
	struct acpi_thermal *tz = thermal->devdata;
@@ -886,7 +888,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
	if (!tz)
		return -EINVAL;

	return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(tz->temperature));
	return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
}

static const char enabled[] = "kernel";
@@ -980,21 +982,21 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,

	if (tz->trips.critical.flags.valid) {
		if (!trip)
			return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
				tz->trips.critical.temperature));
		trip--;
	}

	if (tz->trips.hot.flags.valid) {
		if (!trip)
			return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
					tz->trips.hot.temperature));
		trip--;
	}

	if (tz->trips.passive.flags.valid) {
		if (!trip)
			return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
					tz->trips.passive.temperature));
		trip--;
	}
@@ -1002,7 +1004,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
		tz->trips.active[i].flags.valid; i++) {
		if (!trip)
			return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(
			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
					tz->trips.active[i].temperature));
		trip--;
	}
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

menuconfig THERMAL
	bool "Generic Thermal sysfs driver"
	select HWMON
	default y
	help
	  Generic Thermal Sysfs driver offers a generic mechanism for
+143 −26
Original line number Diff line number Diff line
@@ -30,8 +30,10 @@
#include <linux/idr.h>
#include <linux/thermal.h>
#include <linux/spinlock.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>

MODULE_AUTHOR("Zhang Rui")
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
MODULE_LICENSE("GPL");

@@ -56,6 +58,9 @@ static LIST_HEAD(thermal_tz_list);
static LIST_HEAD(thermal_cdev_list);
static DEFINE_MUTEX(thermal_list_lock);

static struct device *thermal_hwmon;
#define MAX_THERMAL_ZONES	10

static int get_idr(struct idr *idr, struct mutex *lock, int *id)
{
	int err;
@@ -87,7 +92,67 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id)
		mutex_unlock(lock);
}

/* sys I/F for thermal zone */
/* hwmon sys I/F*/
static ssize_t
name_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "thermal_sys_class\n");
}

static ssize_t
temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct thermal_zone_device *tz;
	struct sensor_device_attribute *sensor_attr
						= to_sensor_dev_attr(attr);

	list_for_each_entry(tz, &thermal_tz_list, node)
		if (tz->id == sensor_attr->index)
			return tz->ops->get_temp(tz, buf);

	return -ENODEV;
}

static ssize_t
temp_crit_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{
	struct thermal_zone_device *tz;
	struct sensor_device_attribute *sensor_attr
						= to_sensor_dev_attr(attr);

	list_for_each_entry(tz, &thermal_tz_list, node)
		if (tz->id == sensor_attr->index)
			return tz->ops->get_trip_temp(tz, 0, buf);

	return -ENODEV;
}

static DEVICE_ATTR(name, 0444, name_show, NULL);
static struct sensor_device_attribute sensor_attrs[] = {
	SENSOR_ATTR(temp1_input, 0444, temp_input_show, NULL, 0),
	SENSOR_ATTR(temp1_crit, 0444, temp_crit_show, NULL, 0),
	SENSOR_ATTR(temp2_input, 0444, temp_input_show, NULL, 1),
	SENSOR_ATTR(temp2_crit, 0444, temp_crit_show, NULL, 1),
	SENSOR_ATTR(temp3_input, 0444, temp_input_show, NULL, 2),
	SENSOR_ATTR(temp3_crit, 0444, temp_crit_show, NULL, 2),
	SENSOR_ATTR(temp4_input, 0444, temp_input_show, NULL, 3),
	SENSOR_ATTR(temp4_crit, 0444, temp_crit_show, NULL, 3),
	SENSOR_ATTR(temp5_input, 0444, temp_input_show, NULL, 4),
	SENSOR_ATTR(temp5_crit, 0444, temp_crit_show, NULL, 4),
	SENSOR_ATTR(temp6_input, 0444, temp_input_show, NULL, 5),
	SENSOR_ATTR(temp6_crit, 0444, temp_crit_show, NULL, 5),
	SENSOR_ATTR(temp7_input, 0444, temp_input_show, NULL, 6),
	SENSOR_ATTR(temp7_crit, 0444, temp_crit_show, NULL, 6),
	SENSOR_ATTR(temp8_input, 0444, temp_input_show, NULL, 7),
	SENSOR_ATTR(temp8_crit, 0444, temp_crit_show, NULL, 7),
	SENSOR_ATTR(temp9_input, 0444, temp_input_show, NULL, 8),
	SENSOR_ATTR(temp9_crit, 0444, temp_crit_show, NULL, 8),
	SENSOR_ATTR(temp10_input, 0444, temp_input_show, NULL, 9),
	SENSOR_ATTR(temp10_crit, 0444, temp_crit_show, NULL, 9),
};

/* thermal zone sys I/F */

#define to_thermal_zone(_dev) \
	container_of(_dev, struct thermal_zone_device, device)
@@ -214,7 +279,7 @@ do { \
	device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]);	\
} while (0)

/* sys I/F for cooling device */
/* cooling device sys I/F */
#define to_cooling_device(_dev)	\
	container_of(_dev, struct thermal_cooling_device, device)

@@ -447,6 +512,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
	struct thermal_zone_device *pos;
	int result;

	if (!type)
		return ERR_PTR(-EINVAL);

	if (strlen(type) >= THERMAL_NAME_LENGTH)
		return ERR_PTR(-EINVAL);

@@ -477,11 +545,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
	}

	/* sys I/F */
	if (type) {
	result = device_create_file(&cdev->device, &dev_attr_cdev_type);
	if (result)
		goto unregister;
	}

	result = device_create_file(&cdev->device, &dev_attr_max_state);
	if (result)
@@ -547,7 +613,7 @@ void thermal_cooling_device_unregister(struct
		tz->ops->unbind(tz, cdev);
	}
	mutex_unlock(&thermal_list_lock);
	if (cdev->type[0])

	device_remove_file(&cdev->device, &dev_attr_cdev_type);
	device_remove_file(&cdev->device, &dev_attr_max_state);
	device_remove_file(&cdev->device, &dev_attr_cur_state);
@@ -580,6 +646,9 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
	int result;
	int count;

	if (!type)
		return ERR_PTR(-EINVAL);

	if (strlen(type) >= THERMAL_NAME_LENGTH)
		return ERR_PTR(-EINVAL);

@@ -601,6 +670,13 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
		kfree(tz);
		return ERR_PTR(result);
	}
	if (tz->id >= MAX_THERMAL_ZONES) {
		printk(KERN_ERR PREFIX
			"Too many thermal zones\n");
		release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
		kfree(tz);
		return ERR_PTR(-EINVAL);
	}

	strcpy(tz->type, type);
	tz->ops = ops;
@@ -615,12 +691,27 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
		return ERR_PTR(result);
	}

	/* hwmon sys I/F */
	result = device_create_file(thermal_hwmon,
					&sensor_attrs[tz->id * 2].dev_attr);
	if (result)
		goto unregister;

	if (trips > 0) {
		char buf[40];
		result = tz->ops->get_trip_type(tz, 0, buf);
		if (result > 0 && !strcmp(buf, "critical\n")) {
			result = device_create_file(thermal_hwmon,
					&sensor_attrs[tz->id * 2 + 1].dev_attr);
			if (result)
				goto unregister;
		}
	}

	/* sys I/F */
	if (type) {
	result = device_create_file(&tz->device, &dev_attr_type);
	if (result)
		goto unregister;
	}

	result = device_create_file(&tz->device, &dev_attr_temp);
	if (result)
@@ -687,7 +778,16 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
		    tz->ops->unbind(tz, cdev);
	mutex_unlock(&thermal_list_lock);

	if (tz->type[0])
	device_remove_file(thermal_hwmon,
				&sensor_attrs[tz->id * 2].dev_attr);
	if (tz->trips > 0) {
		char buf[40];
		if (tz->ops->get_trip_type(tz, 0, buf) > 0)
			if (!strcmp(buf, "critical\n"))
				device_remove_file(thermal_hwmon,
				&sensor_attrs[tz->id * 2 + 1].dev_attr);
	}

	device_remove_file(&tz->device, &dev_attr_type);
	device_remove_file(&tz->device, &dev_attr_temp);
	if (tz->ops->get_mode)
@@ -705,6 +805,19 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)

EXPORT_SYMBOL(thermal_zone_device_unregister);

static void thermal_exit(void)
{
	if (thermal_hwmon) {
		device_remove_file(thermal_hwmon, &dev_attr_name);
		hwmon_device_unregister(thermal_hwmon);
	}
	class_unregister(&thermal_class);
	idr_destroy(&thermal_tz_idr);
	idr_destroy(&thermal_cdev_idr);
	mutex_destroy(&thermal_idr_lock);
	mutex_destroy(&thermal_list_lock);
}

static int __init thermal_init(void)
{
	int result = 0;
@@ -716,16 +829,20 @@ static int __init thermal_init(void)
		mutex_destroy(&thermal_idr_lock);
		mutex_destroy(&thermal_list_lock);
	}

	thermal_hwmon = hwmon_device_register(NULL);
	if (IS_ERR(thermal_hwmon)) {
		result = PTR_ERR(thermal_hwmon);
		thermal_hwmon = NULL;
		printk(KERN_ERR PREFIX
			"unable to register hwmon device\n");
		thermal_exit();
		return result;
	}

static void __exit thermal_exit(void)
{
	class_unregister(&thermal_class);
	idr_destroy(&thermal_tz_idr);
	idr_destroy(&thermal_cdev_idr);
	mutex_destroy(&thermal_idr_lock);
	mutex_destroy(&thermal_list_lock);
	result = device_create_file(thermal_hwmon, &dev_attr_name);

	return result;
}

subsys_initcall(thermal_init);