diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 35c066489a19..5f88d767671e 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -136,6 +136,7 @@ config SPEAR_THERMAL config RCAR_THERMAL tristate "Renesas R-Car thermal driver" depends on ARCH_SHMOBILE || COMPILE_TEST + depends on HAS_IOMEM help Enable this to plug the R-Car thermal sensor driver into the Linux thermal framework. @@ -210,8 +211,16 @@ config ACPI_INT3403_THERMAL tristate "ACPI INT3403 thermal driver" depends on X86 && ACPI help - This driver uses ACPI INT3403 device objects. If present, it will - register each INT3403 thermal sensor as a thermal zone. + Newer laptops and tablets that use ACPI may have thermal sensors + outside the core CPU/SOC for thermal safety reasons. These + temperature sensors are also exposed for the OS to use via the so + called INT3403 ACPI object. This driver will, on devices that have + such sensors, expose the temperature information from these sensors + to userspace via the normal thermal framework. This means that a wide + range of applications and GUI widgets can show this information to + the user or use this information for making decisions. For example, + the Intel Thermal Daemon can use this information to allow the user + to select his laptop to run without turning on the fans. menu "Texas Instruments thermal drivers" source "drivers/thermal/ti-soc-thermal/Kconfig" diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 338a88bf6662..71b0ec0c370d 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -56,10 +56,15 @@ static LIST_HEAD(thermal_governor_list); static DEFINE_MUTEX(thermal_list_lock); static DEFINE_MUTEX(thermal_governor_lock); +static struct thermal_governor *def_governor; + static struct thermal_governor *__find_governor(const char *name) { struct thermal_governor *pos; + if (!name || !name[0]) + return def_governor; + list_for_each_entry(pos, &thermal_governor_list, governor_list) if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) return pos; @@ -82,17 +87,23 @@ int thermal_register_governor(struct thermal_governor *governor) if (__find_governor(governor->name) == NULL) { err = 0; list_add(&governor->governor_list, &thermal_governor_list); + if (!def_governor && !strncmp(governor->name, + DEFAULT_THERMAL_GOVERNOR, THERMAL_NAME_LENGTH)) + def_governor = governor; } mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_tz_list, node) { + /* + * only thermal zones with specified tz->tzp->governor_name + * may run with tz->govenor unset + */ if (pos->governor) continue; - if (pos->tzp) - name = pos->tzp->governor_name; - else - name = DEFAULT_THERMAL_GOVERNOR; + + name = pos->tzp->governor_name; + if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) pos->governor = governor; } @@ -342,8 +353,8 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz) static void handle_non_critical_trips(struct thermal_zone_device *tz, int trip, enum thermal_trip_type trip_type) { - if (tz->governor) - tz->governor->throttle(tz, trip); + tz->governor ? tz->governor->throttle(tz, trip) : + def_governor->throttle(tz, trip); } static void handle_critical_trips(struct thermal_zone_device *tz, @@ -1107,7 +1118,7 @@ __thermal_cooling_device_register(struct device_node *np, INIT_LIST_HEAD(&cdev->thermal_instances); cdev->np = np; cdev->ops = ops; - cdev->updated = true; + cdev->updated = false; cdev->device.class = &thermal_class; cdev->devdata = devdata; dev_set_name(&cdev->device, "cooling_device%d", cdev->id); @@ -1533,7 +1544,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, if (tz->tzp) tz->governor = __find_governor(tz->tzp->governor_name); else - tz->governor = __find_governor(DEFAULT_THERMAL_GOVERNOR); + tz->governor = def_governor; mutex_unlock(&thermal_governor_lock); diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c index 972e1c73722a..081fd7e6a9f0 100644 --- a/drivers/thermal/x86_pkg_temp_thermal.c +++ b/drivers/thermal/x86_pkg_temp_thermal.c @@ -68,6 +68,10 @@ struct phy_dev_entry { struct thermal_zone_device *tzone; }; +static const struct thermal_zone_params pkg_temp_tz_params = { + .no_hwmon = true, +}; + /* List maintaining number of package instances */ static LIST_HEAD(phy_dev_list); static DEFINE_MUTEX(phy_dev_list_mutex); @@ -394,7 +398,6 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) int err; u32 tj_max; struct phy_dev_entry *phy_dev_entry; - char buffer[30]; int thres_count; u32 eax, ebx, ecx, edx; u8 *temp; @@ -440,13 +443,11 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) phy_dev_entry->first_cpu = cpu; phy_dev_entry->tj_max = tj_max; phy_dev_entry->ref_cnt = 1; - snprintf(buffer, sizeof(buffer), "pkg-temp-%d\n", - phy_dev_entry->phys_proc_id); - phy_dev_entry->tzone = thermal_zone_device_register(buffer, + phy_dev_entry->tzone = thermal_zone_device_register("x86_pkg_temp", thres_count, (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01, - phy_dev_entry, &tzone_ops, NULL, 0, 0); + phy_dev_entry, &tzone_ops, &pkg_temp_tz_params, 0, 0); if (IS_ERR(phy_dev_entry->tzone)) { err = PTR_ERR(phy_dev_entry->tzone); goto err_ret_free;