Lines Matching +full:thermal +full:- +full:zones

1 // SPDX-License-Identifier: GPL-2.0-only
18 #include <linux/thermal.h>
39 /* Number of trip points in thermal zone. Currently it can't
64 static struct zone_device **zones; variable
91 * - cpu hotplug: Read serialized by cpu hotplug lock
94 * - Other callsites: Must hold pkg_temp_lock
101 return zones[id]; in pkg_temp_thermal_get_dev()
106 * tj-max is is interesting because threshold is set relative to this
121 return val ? 0 : -EINVAL; in get_tj_max()
126 struct zone_device *zonedev = tzd->devdata; in sys_get_curr_temp()
129 rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_STATUS, in sys_get_curr_temp()
132 *temp = zonedev->tj_max - ((eax >> 16) & 0x7f) * 1000; in sys_get_curr_temp()
136 return -EINVAL; in sys_get_curr_temp()
142 struct zone_device *zonedev = tzd->devdata; in sys_get_trip_temp()
148 return -EINVAL; in sys_get_trip_temp()
158 ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, in sys_get_trip_temp()
165 *temp = zonedev->tj_max - thres_reg_value * 1000; in sys_get_trip_temp()
176 struct zone_device *zonedev = tzd->devdata; in sys_set_trip_temp()
180 if (trip >= MAX_NUMBER_OF_TRIPS || temp >= zonedev->tj_max) in sys_set_trip_temp()
181 return -EINVAL; in sys_set_trip_temp()
183 ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, in sys_set_trip_temp()
205 l |= (zonedev->tj_max - temp)/1000 << shift; in sys_set_trip_temp()
209 return wrmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, in sys_set_trip_temp()
213 static int sys_get_trip_type(struct thermal_zone_device *thermal, int trip, in sys_get_trip_type() argument
220 /* Thermal zone callback registry */
278 zonedev->work_scheduled = false; in pkg_temp_thermal_threshold_work_fn()
284 tzone = zonedev->tzone; in pkg_temp_thermal_threshold_work_fn()
320 if (zonedev && !zonedev->work_scheduled) { in pkg_thermal_notify()
321 zonedev->work_scheduled = true; in pkg_thermal_notify()
322 pkg_thermal_schedule_work(zonedev->cpu, &zonedev->work); in pkg_thermal_notify()
337 return -ENOMEM; in pkg_temp_thermal_device_add()
342 return -ENODEV; in pkg_temp_thermal_device_add()
352 return -ENOMEM; in pkg_temp_thermal_device_add()
354 INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn); in pkg_temp_thermal_device_add()
355 zonedev->cpu = cpu; in pkg_temp_thermal_device_add()
356 zonedev->tj_max = tj_max; in pkg_temp_thermal_device_add()
357 zonedev->tzone = thermal_zone_device_register("x86_pkg_temp", in pkg_temp_thermal_device_add()
361 if (IS_ERR(zonedev->tzone)) { in pkg_temp_thermal_device_add()
362 err = PTR_ERR(zonedev->tzone); in pkg_temp_thermal_device_add()
366 err = thermal_zone_device_enable(zonedev->tzone); in pkg_temp_thermal_device_add()
368 thermal_zone_device_unregister(zonedev->tzone); in pkg_temp_thermal_device_add()
372 /* Store MSR value for package thermal interrupt, to restore at exit */ in pkg_temp_thermal_device_add()
373 rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, zonedev->msr_pkg_therm_low, in pkg_temp_thermal_device_add()
374 zonedev->msr_pkg_therm_high); in pkg_temp_thermal_device_add()
376 cpumask_set_cpu(cpu, &zonedev->cpumask); in pkg_temp_thermal_device_add()
378 zones[id] = zonedev; in pkg_temp_thermal_device_add()
392 target = cpumask_any_but(&zonedev->cpumask, cpu); in pkg_thermal_cpu_offline()
393 cpumask_clear_cpu(cpu, &zonedev->cpumask); in pkg_thermal_cpu_offline()
400 struct thermal_zone_device *tzone = zonedev->tzone; in pkg_thermal_cpu_offline()
409 zonedev->tzone = NULL; in pkg_thermal_cpu_offline()
423 was_target = zonedev->cpu == cpu; in pkg_thermal_cpu_offline()
424 zonedev->cpu = target; in pkg_thermal_cpu_offline()
433 zones[topology_logical_die_id(cpu)] = NULL; in pkg_thermal_cpu_offline()
436 zonedev->msr_pkg_therm_low, zonedev->msr_pkg_therm_high); in pkg_thermal_cpu_offline()
443 if (zonedev->work_scheduled && was_target) { in pkg_thermal_cpu_offline()
449 cancel_delayed_work_sync(&zonedev->work); in pkg_thermal_cpu_offline()
457 if (!lastcpu && zonedev->work_scheduled) in pkg_thermal_cpu_offline()
458 pkg_thermal_schedule_work(target, &zonedev->work); in pkg_thermal_cpu_offline()
476 return -ENODEV; in pkg_thermal_cpu_online()
480 cpumask_set_cpu(cpu, &zonedev->cpumask); in pkg_thermal_cpu_online()
497 return -ENODEV; in pkg_temp_thermal_init()
500 zones = kcalloc(max_id, sizeof(struct zone_device *), in pkg_temp_thermal_init()
502 if (!zones) in pkg_temp_thermal_init()
503 return -ENOMEM; in pkg_temp_thermal_init()
505 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "thermal/x86_pkg:online", in pkg_temp_thermal_init()
521 kfree(zones); in pkg_temp_thermal_init()
533 kfree(zones); in module_init()
537 MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver");