diff options
Diffstat (limited to 'drivers/thermal/intel/int340x_thermal')
8 files changed, 255 insertions, 345 deletions
diff --git a/drivers/thermal/intel/int340x_thermal/Kconfig b/drivers/thermal/intel/int340x_thermal/Kconfig index 5d046de96a5d..300ea53e9b33 100644 --- a/drivers/thermal/intel/int340x_thermal/Kconfig +++ b/drivers/thermal/intel/int340x_thermal/Kconfig @@ -9,7 +9,9 @@ config INT340X_THERMAL select THERMAL_GOV_USER_SPACE select ACPI_THERMAL_REL select ACPI_FAN + select THERMAL_ACPI select INTEL_SOC_DTS_IOSF_CORE + select INTEL_TCC select PROC_THERMAL_MMIO_RAPL if POWERCAP help Newer laptops and tablets that use ACPI may have thermal sensors and diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index db8a6f63657d..d0295123cc3e 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -60,6 +60,7 @@ struct int3400_thermal_priv { int odvp_count; int *odvp; u32 os_uuid_mask; + int production_mode; struct odvp_attr *odvp_attrs; }; @@ -130,10 +131,7 @@ static ssize_t available_uuids_show(struct device *dev, for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) { if (priv->uuid_bitmap & (1 << i)) - length += scnprintf(&buf[length], - PAGE_SIZE - length, - "%s\n", - int3400_thermal_uuids[i]); + length += sysfs_emit_at(buf, length, int3400_thermal_uuids[i]); } return length; @@ -151,10 +149,7 @@ static ssize_t current_uuid_show(struct device *dev, for (i = 0; i <= INT3400_THERMAL_CRITICAL; i++) { if (priv->os_uuid_mask & BIT(i)) - length += scnprintf(&buf[length], - PAGE_SIZE - length, - "%s\n", - int3400_thermal_uuids[i]); + length += sysfs_emit_at(buf, length, int3400_thermal_uuids[i]); } if (length) @@ -315,6 +310,44 @@ end: return result; } +static ssize_t production_mode_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct int3400_thermal_priv *priv = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%d\n", priv->production_mode); +} + +static DEVICE_ATTR_RO(production_mode); + +static int production_mode_init(struct int3400_thermal_priv *priv) +{ + unsigned long long mode; + acpi_status status; + int ret; + + priv->production_mode = -1; + + status = acpi_evaluate_integer(priv->adev->handle, "DCFG", NULL, &mode); + /* If the method is not present, this is not an error */ + if (ACPI_FAILURE(status)) + return 0; + + ret = sysfs_create_file(&priv->pdev->dev.kobj, &dev_attr_production_mode.attr); + if (ret) + return ret; + + priv->production_mode = mode; + + return 0; +} + +static void production_mode_exit(struct int3400_thermal_priv *priv) +{ + if (priv->production_mode >= 0) + sysfs_remove_file(&priv->pdev->dev.kobj, &dev_attr_production_mode.attr); +} + static ssize_t odvp_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -610,8 +643,15 @@ static int int3400_thermal_probe(struct platform_device *pdev) if (result) goto free_sysfs; + result = production_mode_init(priv); + if (result) + goto free_notify; + return 0; +free_notify: + acpi_remove_notify_handler(priv->adev->handle, ACPI_DEVICE_NOTIFY, + int3400_notify); free_sysfs: cleanup_odvp(priv); if (!ZERO_OR_NULL_PTR(priv->data_vault)) { @@ -638,6 +678,8 @@ static int int3400_thermal_remove(struct platform_device *pdev) { struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + production_mode_exit(priv); + acpi_remove_notify_handler( priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify); diff --git a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c index 71d084c4c456..e418d270bc76 100644 --- a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c @@ -69,7 +69,7 @@ static void int3403_notify(acpi_handle handle, THERMAL_TRIP_VIOLATED); break; case INT3403_PERF_TRIP_POINT_CHANGED: - int340x_thermal_read_trips(obj->int340x_zone); + int340x_thermal_update_trips(obj->int340x_zone); int340x_thermal_zone_device_update(obj->int340x_zone, THERMAL_TRIP_CHANGED); break; diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 62c0aa5d0783..00665967ca52 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -18,9 +18,6 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, unsigned long long tmp; acpi_status status; - if (d->override_ops && d->override_ops->get_temp) - return d->override_ops->get_temp(zone, temp); - status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp); if (ACPI_FAILURE(status)) return -EIO; @@ -32,117 +29,30 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, if (conv_temp < 0) return conv_temp; - *temp = (unsigned long)conv_temp * 10; - } else + *temp = conv_temp * 10; + } else { /* _TMP returns the temperature in tenths of degrees Kelvin */ *temp = deci_kelvin_to_millicelsius(tmp); - - return 0; -} - -static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone, - int trip, int *temp) -{ - struct int34x_thermal_zone *d = zone->devdata; - int i; - - if (d->override_ops && d->override_ops->get_trip_temp) - return d->override_ops->get_trip_temp(zone, trip, temp); - - if (trip < d->aux_trip_nr) - *temp = d->aux_trips[trip]; - else if (trip == d->crt_trip_id) - *temp = d->crt_temp; - else if (trip == d->psv_trip_id) - *temp = d->psv_temp; - else if (trip == d->hot_trip_id) - *temp = d->hot_temp; - else { - for (i = 0; i < INT340X_THERMAL_MAX_ACT_TRIP_COUNT; i++) { - if (d->act_trips[i].valid && - d->act_trips[i].id == trip) { - *temp = d->act_trips[i].temp; - break; - } - } - if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT) - return -EINVAL; - } - - return 0; -} - -static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone, - int trip, - enum thermal_trip_type *type) -{ - struct int34x_thermal_zone *d = zone->devdata; - int i; - - if (d->override_ops && d->override_ops->get_trip_type) - return d->override_ops->get_trip_type(zone, trip, type); - - if (trip < d->aux_trip_nr) - *type = THERMAL_TRIP_PASSIVE; - else if (trip == d->crt_trip_id) - *type = THERMAL_TRIP_CRITICAL; - else if (trip == d->hot_trip_id) - *type = THERMAL_TRIP_HOT; - else if (trip == d->psv_trip_id) - *type = THERMAL_TRIP_PASSIVE; - else { - for (i = 0; i < INT340X_THERMAL_MAX_ACT_TRIP_COUNT; i++) { - if (d->act_trips[i].valid && - d->act_trips[i].id == trip) { - *type = THERMAL_TRIP_ACTIVE; - break; - } - } - if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT) - return -EINVAL; } return 0; } static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, - int trip, int temp) + int trip, int temp) { struct int34x_thermal_zone *d = zone->devdata; + char name[] = {'P', 'A', 'T', '0' + trip, '\0'}; acpi_status status; - char name[10]; - if (d->override_ops && d->override_ops->set_trip_temp) - return d->override_ops->set_trip_temp(zone, trip, temp); + if (trip > 9) + return -EINVAL; - snprintf(name, sizeof(name), "PAT%d", trip); status = acpi_execute_simple_method(d->adev->handle, name, - millicelsius_to_deci_kelvin(temp)); + millicelsius_to_deci_kelvin(temp)); if (ACPI_FAILURE(status)) return -EIO; - d->aux_trips[trip] = temp; - - return 0; -} - - -static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone, - int trip, int *temp) -{ - struct int34x_thermal_zone *d = zone->devdata; - acpi_status status; - unsigned long long hyst; - - if (d->override_ops && d->override_ops->get_trip_hyst) - return d->override_ops->get_trip_hyst(zone, trip, temp); - - status = acpi_evaluate_integer(d->adev->handle, "GTSH", NULL, &hyst); - if (ACPI_FAILURE(status)) - *temp = 0; - else - *temp = hyst * 100; - return 0; } @@ -153,63 +63,49 @@ static void int340x_thermal_critical(struct thermal_zone_device *zone) static struct thermal_zone_device_ops int340x_thermal_zone_ops = { .get_temp = int340x_thermal_get_zone_temp, - .get_trip_temp = int340x_thermal_get_trip_temp, - .get_trip_type = int340x_thermal_get_trip_type, .set_trip_temp = int340x_thermal_set_trip_temp, - .get_trip_hyst = int340x_thermal_get_trip_hyst, .critical = int340x_thermal_critical, }; -static int int340x_thermal_get_trip_config(acpi_handle handle, char *name, - int *temp) +static int int340x_thermal_read_trips(struct acpi_device *zone_adev, + struct thermal_trip *zone_trips, + int trip_cnt) { - unsigned long long r; - acpi_status status; - - status = acpi_evaluate_integer(handle, name, NULL, &r); - if (ACPI_FAILURE(status)) - return -EIO; - - *temp = deci_kelvin_to_millicelsius(r); + int i, ret; - return 0; -} - -int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone) -{ - int trip_cnt = int34x_zone->aux_trip_nr; - int i; - - int34x_zone->crt_trip_id = -1; - if (!int340x_thermal_get_trip_config(int34x_zone->adev->handle, "_CRT", - &int34x_zone->crt_temp)) - int34x_zone->crt_trip_id = trip_cnt++; + ret = thermal_acpi_critical_trip_temp(zone_adev, + &zone_trips[trip_cnt].temperature); + if (!ret) { + zone_trips[trip_cnt].type = THERMAL_TRIP_CRITICAL; + trip_cnt++; + } - int34x_zone->hot_trip_id = -1; - if (!int340x_thermal_get_trip_config(int34x_zone->adev->handle, "_HOT", - &int34x_zone->hot_temp)) - int34x_zone->hot_trip_id = trip_cnt++; + ret = thermal_acpi_hot_trip_temp(zone_adev, + &zone_trips[trip_cnt].temperature); + if (!ret) { + zone_trips[trip_cnt].type = THERMAL_TRIP_HOT; + trip_cnt++; + } - int34x_zone->psv_trip_id = -1; - if (!int340x_thermal_get_trip_config(int34x_zone->adev->handle, "_PSV", - &int34x_zone->psv_temp)) - int34x_zone->psv_trip_id = trip_cnt++; + ret = thermal_acpi_passive_trip_temp(zone_adev, + &zone_trips[trip_cnt].temperature); + if (!ret) { + zone_trips[trip_cnt].type = THERMAL_TRIP_PASSIVE; + trip_cnt++; + } for (i = 0; i < INT340X_THERMAL_MAX_ACT_TRIP_COUNT; i++) { - char name[5] = { '_', 'A', 'C', '0' + i, '\0' }; - - if (int340x_thermal_get_trip_config(int34x_zone->adev->handle, - name, - &int34x_zone->act_trips[i].temp)) + ret = thermal_acpi_active_trip_temp(zone_adev, i, + &zone_trips[trip_cnt].temperature); + if (ret) break; - int34x_zone->act_trips[i].id = trip_cnt++; - int34x_zone->act_trips[i].valid = true; + zone_trips[trip_cnt].type = THERMAL_TRIP_ACTIVE; + trip_cnt++; } return trip_cnt; } -EXPORT_SYMBOL_GPL(int340x_thermal_read_trips); static struct thermal_zone_params int340x_thermal_params = { .governor_name = "user_space", @@ -217,85 +113,147 @@ static struct thermal_zone_params int340x_thermal_params = { }; struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, - struct thermal_zone_device_ops *override_ops) + int (*get_temp) (struct thermal_zone_device *, int *)) { - struct int34x_thermal_zone *int34x_thermal_zone; - acpi_status status; - unsigned long long trip_cnt; + struct int34x_thermal_zone *int34x_zone; + struct thermal_trip *zone_trips; + unsigned long long trip_cnt = 0; + unsigned long long hyst; int trip_mask = 0; - int ret; + acpi_status status; + int i, ret; - int34x_thermal_zone = kzalloc(sizeof(*int34x_thermal_zone), - GFP_KERNEL); - if (!int34x_thermal_zone) + int34x_zone = kzalloc(sizeof(*int34x_zone), GFP_KERNEL); + if (!int34x_zone) return ERR_PTR(-ENOMEM); - int34x_thermal_zone->adev = adev; - int34x_thermal_zone->override_ops = override_ops; + int34x_zone->adev = adev; + + int34x_zone->ops = kmemdup(&int340x_thermal_zone_ops, + sizeof(int340x_thermal_zone_ops), GFP_KERNEL); + if (!int34x_zone->ops) { + ret = -ENOMEM; + goto err_ops_alloc; + } + + if (get_temp) + int34x_zone->ops->get_temp = get_temp; status = acpi_evaluate_integer(adev->handle, "PATC", NULL, &trip_cnt); - if (ACPI_FAILURE(status)) - trip_cnt = 0; - else { - int i; - - int34x_thermal_zone->aux_trips = - kcalloc(trip_cnt, - sizeof(*int34x_thermal_zone->aux_trips), - GFP_KERNEL); - if (!int34x_thermal_zone->aux_trips) { - ret = -ENOMEM; - goto err_trip_alloc; - } + if (ACPI_SUCCESS(status)) { + int34x_zone->aux_trip_nr = trip_cnt; trip_mask = BIT(trip_cnt) - 1; - int34x_thermal_zone->aux_trip_nr = trip_cnt; - for (i = 0; i < trip_cnt; ++i) - int34x_thermal_zone->aux_trips[i] = THERMAL_TEMP_INVALID; } - trip_cnt = int340x_thermal_read_trips(int34x_thermal_zone); + zone_trips = kzalloc(sizeof(*zone_trips) * (trip_cnt + INT340X_THERMAL_MAX_TRIP_COUNT), + GFP_KERNEL); + if (!zone_trips) { + ret = -ENOMEM; + goto err_trips_alloc; + } + + for (i = 0; i < trip_cnt; i++) { + zone_trips[i].type = THERMAL_TRIP_PASSIVE; + zone_trips[i].temperature = THERMAL_TEMP_INVALID; + } + + trip_cnt = int340x_thermal_read_trips(adev, zone_trips, trip_cnt); - int34x_thermal_zone->lpat_table = acpi_lpat_get_conversion_table( - adev->handle); + status = acpi_evaluate_integer(adev->handle, "GTSH", NULL, &hyst); + if (ACPI_SUCCESS(status)) + hyst *= 100; + else + hyst = 0; + + for (i = 0; i < trip_cnt; ++i) + zone_trips[i].hysteresis = hyst; + + int34x_zone->trips = zone_trips; - int34x_thermal_zone->zone = thermal_zone_device_register( - acpi_device_bid(adev), - trip_cnt, - trip_mask, int34x_thermal_zone, - &int340x_thermal_zone_ops, - &int340x_thermal_params, - 0, 0); - if (IS_ERR(int34x_thermal_zone->zone)) { - ret = PTR_ERR(int34x_thermal_zone->zone); + int34x_zone->lpat_table = acpi_lpat_get_conversion_table(adev->handle); + + int34x_zone->zone = thermal_zone_device_register_with_trips( + acpi_device_bid(adev), + zone_trips, trip_cnt, + trip_mask, int34x_zone, + int34x_zone->ops, + &int340x_thermal_params, + 0, 0); + if (IS_ERR(int34x_zone->zone)) { + ret = PTR_ERR(int34x_zone->zone); goto err_thermal_zone; } - ret = thermal_zone_device_enable(int34x_thermal_zone->zone); + ret = thermal_zone_device_enable(int34x_zone->zone); if (ret) goto err_enable; - return int34x_thermal_zone; + return int34x_zone; err_enable: - thermal_zone_device_unregister(int34x_thermal_zone->zone); + thermal_zone_device_unregister(int34x_zone->zone); err_thermal_zone: - acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); - kfree(int34x_thermal_zone->aux_trips); -err_trip_alloc: - kfree(int34x_thermal_zone); + kfree(int34x_zone->trips); + acpi_lpat_free_conversion_table(int34x_zone->lpat_table); +err_trips_alloc: + kfree(int34x_zone->ops); +err_ops_alloc: + kfree(int34x_zone); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_add); -void int340x_thermal_zone_remove(struct int34x_thermal_zone - *int34x_thermal_zone) +void int340x_thermal_zone_remove(struct int34x_thermal_zone *int34x_zone) { - thermal_zone_device_unregister(int34x_thermal_zone->zone); - acpi_lpat_free_conversion_table(int34x_thermal_zone->lpat_table); - kfree(int34x_thermal_zone->aux_trips); - kfree(int34x_thermal_zone); + thermal_zone_device_unregister(int34x_zone->zone); + acpi_lpat_free_conversion_table(int34x_zone->lpat_table); + kfree(int34x_zone->trips); + kfree(int34x_zone->ops); + kfree(int34x_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); +void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone) +{ + struct acpi_device *zone_adev = int34x_zone->adev; + struct thermal_trip *zone_trips = int34x_zone->trips; + int trip_cnt = int34x_zone->zone->num_trips; + int act_trip_nr = 0; + int i; + + mutex_lock(&int34x_zone->zone->lock); + + for (i = int34x_zone->aux_trip_nr; i < trip_cnt; i++) { + int temp, err; + + switch (zone_trips[i].type) { + case THERMAL_TRIP_CRITICAL: + err = thermal_acpi_critical_trip_temp(zone_adev, &temp); + break; + case THERMAL_TRIP_HOT: + err = thermal_acpi_hot_trip_temp(zone_adev, &temp); + break; + case THERMAL_TRIP_PASSIVE: + err = thermal_acpi_passive_trip_temp(zone_adev, &temp); + break; + case THERMAL_TRIP_ACTIVE: + err = thermal_acpi_active_trip_temp(zone_adev, act_trip_nr++, + &temp); + break; + default: + err = -ENODEV; + } + if (err) { + zone_trips[i].temperature = THERMAL_TEMP_INVALID; + continue; + } + + zone_trips[i].temperature = temp; + } + + mutex_unlock(&int34x_zone->zone->lock); +} +EXPORT_SYMBOL_GPL(int340x_thermal_update_trips); + MODULE_AUTHOR("Aaron Lu <[email protected]>"); MODULE_AUTHOR("Srinivas Pandruvada <[email protected]>"); MODULE_DESCRIPTION("Intel INT340x common thermal zone handler"); diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h index 3b4971df1b33..e0df6271facc 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h @@ -10,6 +10,7 @@ #include <acpi/acpi_lpat.h> #define INT340X_THERMAL_MAX_ACT_TRIP_COUNT 10 +#define INT340X_THERMAL_MAX_TRIP_COUNT INT340X_THERMAL_MAX_ACT_TRIP_COUNT + 3 struct active_trip { int temp; @@ -19,25 +20,18 @@ struct active_trip { struct int34x_thermal_zone { struct acpi_device *adev; - struct active_trip act_trips[INT340X_THERMAL_MAX_ACT_TRIP_COUNT]; - unsigned long *aux_trips; + struct thermal_trip *trips; int aux_trip_nr; - int psv_temp; - int psv_trip_id; - int crt_temp; - int crt_trip_id; - int hot_temp; - int hot_trip_id; struct thermal_zone_device *zone; - struct thermal_zone_device_ops *override_ops; + struct thermal_zone_device_ops *ops; void *priv_data; struct acpi_lpat_conversion_table *lpat_table; }; struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *, - struct thermal_zone_device_ops *override_ops); + int (*get_temp) (struct thermal_zone_device *, int *)); void int340x_thermal_zone_remove(struct int34x_thermal_zone *); -int int340x_thermal_read_trips(struct int34x_thermal_zone *int34x_zone); +void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone); static inline void int340x_thermal_zone_set_priv_data( struct int34x_thermal_zone *tzone, void *priv_data) diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index a8d98f1bd6c6..a1dc18be7609 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -4,6 +4,7 @@ * Copyright (c) 2014, Intel Corporation. */ #include <linux/acpi.h> +#include <linux/intel_tcc.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> @@ -68,54 +69,17 @@ static const struct attribute_group power_limit_attribute_group = { .name = "power_limits" }; -static int tcc_get_offset(void) -{ - u64 val; - int err; - - err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); - if (err) - return err; - - return (val >> 24) & 0x3f; -} - static ssize_t tcc_offset_degree_celsius_show(struct device *dev, struct device_attribute *attr, char *buf) { - int tcc; - - tcc = tcc_get_offset(); - if (tcc < 0) - return tcc; - - return sprintf(buf, "%d\n", tcc); -} - -static int tcc_offset_update(unsigned int tcc) -{ - u64 val; - int err; + int offset; - if (tcc > 63) - return -EINVAL; - - err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val); - if (err) - return err; + offset = intel_tcc_get_offset(-1); + if (offset < 0) + return offset; - if (val & BIT(31)) - return -EPERM; - - val &= ~GENMASK_ULL(29, 24); - val |= (tcc & 0x3f) << 24; - - err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val); - if (err) - return err; - - return 0; + return sprintf(buf, "%d\n", offset); } static ssize_t tcc_offset_degree_celsius_store(struct device *dev, @@ -136,7 +100,7 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev, if (kstrtouint(buf, 0, &tcc)) return -EINVAL; - err = tcc_offset_update(tcc); + err = intel_tcc_set_offset(-1, tcc); if (err) return err; @@ -145,72 +109,27 @@ static ssize_t tcc_offset_degree_celsius_store(struct device *dev, static DEVICE_ATTR_RW(tcc_offset_degree_celsius); -static int stored_tjmax; /* since it is fixed, we can have local storage */ - -static int get_tjmax(void) -{ - u32 eax, edx; - u32 val; - int err; - - err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); - if (err) - return err; - - val = (eax >> 16) & 0xff; - if (val) - return val; - - return -EINVAL; -} - -static int read_temp_msr(int *temp) +static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, + int *temp) { int cpu; - u32 eax, edx; - int err; - unsigned long curr_temp_off = 0; + int curr_temp; *temp = 0; for_each_online_cpu(cpu) { - err = rdmsr_safe_on_cpu(cpu, MSR_IA32_THERM_STATUS, &eax, - &edx); - if (err) - goto err_ret; - else { - if (eax & 0x80000000) { - curr_temp_off = (eax >> 16) & 0x7f; - if (!*temp || curr_temp_off < *temp) - *temp = curr_temp_off; - } else { - err = -EINVAL; - goto err_ret; - } - } + curr_temp = intel_tcc_get_temp(cpu, false); + if (curr_temp < 0) + return curr_temp; + if (!*temp || curr_temp > *temp) + *temp = curr_temp; } - return 0; -err_ret: - return err; -} + *temp *= 1000; -static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, - int *temp) -{ - int ret; - - ret = read_temp_msr(temp); - if (!ret) - *temp = (stored_tjmax - *temp) * 1000; - - return ret; + return 0; } -static struct thermal_zone_device_ops proc_thermal_local_ops = { - .get_temp = proc_thermal_get_zone_temp, -}; - static int proc_thermal_read_ppcc(struct proc_thermal_device *proc_priv) { int i; @@ -285,7 +204,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) struct acpi_device *adev; acpi_status status; unsigned long long tmp; - struct thermal_zone_device_ops *ops = NULL; + int (*get_temp) (struct thermal_zone_device *, int *) = NULL; int ret; adev = ACPI_COMPANION(dev); @@ -302,12 +221,11 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv) status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp); if (ACPI_FAILURE(status)) { /* there is no _TMP method, add local method */ - stored_tjmax = get_tjmax(); - if (stored_tjmax > 0) - ops = &proc_thermal_local_ops; + if (intel_tcc_get_tjmax(-1) > 0) + get_temp = proc_thermal_get_zone_temp; } - proc_priv->int340x_zone = int340x_thermal_zone_add(adev, ops); + proc_priv->int340x_zone = int340x_thermal_zone_add(adev, get_temp); if (IS_ERR(proc_priv->int340x_zone)) { return PTR_ERR(proc_priv->int340x_zone); } else @@ -356,7 +274,7 @@ static int tcc_offset_save = -1; int proc_thermal_suspend(struct device *dev) { - tcc_offset_save = tcc_get_offset(); + tcc_offset_save = intel_tcc_get_offset(-1); if (tcc_offset_save < 0) dev_warn(dev, "failed to save offset (%d)\n", tcc_offset_save); @@ -373,7 +291,7 @@ int proc_thermal_resume(struct device *dev) /* Do not update if saving failed */ if (tcc_offset_save >= 0) - tcc_offset_update(tcc_offset_save); + intel_tcc_set_offset(-1, tcc_offset_save); return 0; } @@ -460,6 +378,7 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device * } EXPORT_SYMBOL_GPL(proc_thermal_mmio_remove); +MODULE_IMPORT_NS(INTEL_TCC); MODULE_AUTHOR("Srinivas Pandruvada <[email protected]>"); MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c index bf1b1cdfade4..40725cbc6eb0 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -144,34 +144,6 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) return 0; } -static int sys_get_trip_temp(struct thermal_zone_device *tzd, - int trip, int *temp) -{ - struct proc_thermal_pci *pci_info = tzd->devdata; - u32 _temp; - - proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_THRES_0, &_temp); - if (!_temp) { - *temp = THERMAL_TEMP_INVALID; - } else { - int tjmax; - - proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax); - _temp = tjmax - _temp; - *temp = (unsigned long)_temp * 1000; - } - - return 0; -} - -static int sys_get_trip_type(struct thermal_zone_device *tzd, int trip, - enum thermal_trip_type *type) -{ - *type = THERMAL_TRIP_PASSIVE; - - return 0; -} - static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { struct proc_thermal_pci *pci_info = tzd->devdata; @@ -200,10 +172,26 @@ static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp return 0; } +static int get_trip_temp(struct proc_thermal_pci *pci_info) +{ + int temp, tjmax; + + proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_THRES_0, &temp); + if (!temp) + return THERMAL_TEMP_INVALID; + + proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_TJMAX, &tjmax); + temp = (tjmax - temp) * 1000; + + return temp; +} + +static struct thermal_trip psv_trip = { + .type = THERMAL_TRIP_PASSIVE, +}; + static struct thermal_zone_device_ops tzone_ops = { .get_temp = sys_get_curr_temp, - .get_trip_temp = sys_get_trip_temp, - .get_trip_type = sys_get_trip_type, .set_trip_temp = sys_set_trip_temp, }; @@ -251,7 +239,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ if (ret) goto err_ret_thermal; - pci_info->tzone = thermal_zone_device_register("TCPU_PCI", 1, 1, pci_info, + psv_trip.temperature = get_trip_temp(pci_info); + + pci_info->tzone = thermal_zone_device_register_with_trips("TCPU_PCI", &psv_trip, + 1, 1, pci_info, &tzone_ops, &tzone_params, 0, 0); if (IS_ERR(pci_info->tzone)) { diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c index 8c42e7662033..92ed1213fe37 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c @@ -172,6 +172,7 @@ static const struct attribute_group fivr_attribute_group = { RFIM_SHOW(rfi_restriction_run_busy, 1) RFIM_SHOW(rfi_restriction_err_code, 1) RFIM_SHOW(rfi_restriction_data_rate, 1) +RFIM_SHOW(rfi_restriction_data_rate_base, 1) RFIM_SHOW(ddr_data_rate_point_0, 1) RFIM_SHOW(ddr_data_rate_point_1, 1) RFIM_SHOW(ddr_data_rate_point_2, 1) @@ -181,11 +182,13 @@ RFIM_SHOW(rfi_disable, 1) RFIM_STORE(rfi_restriction_run_busy, 1) RFIM_STORE(rfi_restriction_err_code, 1) RFIM_STORE(rfi_restriction_data_rate, 1) +RFIM_STORE(rfi_restriction_data_rate_base, 1) RFIM_STORE(rfi_disable, 1) static DEVICE_ATTR_RW(rfi_restriction_run_busy); static DEVICE_ATTR_RW(rfi_restriction_err_code); static DEVICE_ATTR_RW(rfi_restriction_data_rate); +static DEVICE_ATTR_RW(rfi_restriction_data_rate_base); static DEVICE_ATTR_RO(ddr_data_rate_point_0); static DEVICE_ATTR_RO(ddr_data_rate_point_1); static DEVICE_ATTR_RO(ddr_data_rate_point_2); @@ -248,6 +251,7 @@ static struct attribute *dvfs_attrs[] = { &dev_attr_rfi_restriction_run_busy.attr, &dev_attr_rfi_restriction_err_code.attr, &dev_attr_rfi_restriction_data_rate.attr, + &dev_attr_rfi_restriction_data_rate_base.attr, &dev_attr_ddr_data_rate_point_0.attr, &dev_attr_ddr_data_rate_point_1.attr, &dev_attr_ddr_data_rate_point_2.attr, |