Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Srinivas Pandruvada | 571 | 50.80% | 6 | 21.43% |
Rafael J. Wysocki | 479 | 42.62% | 13 | 46.43% |
Daniel Lezcano | 34 | 3.02% | 3 | 10.71% |
Kai-Heng Feng | 18 | 1.60% | 1 | 3.57% |
Andrzej Pietrasiewicz | 10 | 0.89% | 1 | 3.57% |
Akinobu Mita | 5 | 0.44% | 1 | 3.57% |
Tushar Dave | 3 | 0.27% | 1 | 3.57% |
Sascha Hauer | 2 | 0.18% | 1 | 3.57% |
Thomas Gleixner | 2 | 0.18% | 1 | 3.57% |
Total | 1124 | 28 |
// SPDX-License-Identifier: GPL-2.0-only /* * int340x_thermal_zone.c * Copyright (c) 2015, Intel Corporation. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/acpi.h> #include <linux/thermal.h> #include <linux/units.h> #include "int340x_thermal_zone.h" static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, int *temp) { struct int34x_thermal_zone *d = thermal_zone_device_priv(zone); unsigned long long tmp; acpi_status status; status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp); if (ACPI_FAILURE(status)) return -EIO; if (d->lpat_table) { int conv_temp; conv_temp = acpi_lpat_raw_to_temp(d->lpat_table, (int)tmp); if (conv_temp < 0) return conv_temp; *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_set_trip_temp(struct thermal_zone_device *zone, int trip, int temp) { struct int34x_thermal_zone *d = thermal_zone_device_priv(zone); char name[] = {'P', 'A', 'T', '0' + trip, '\0'}; acpi_status status; if (trip > 9) return -EINVAL; status = acpi_execute_simple_method(d->adev->handle, name, millicelsius_to_deci_kelvin(temp)); if (ACPI_FAILURE(status)) return -EIO; return 0; } static void int340x_thermal_critical(struct thermal_zone_device *zone) { dev_dbg(thermal_zone_device(zone), "%s: critical temperature reached\n", thermal_zone_device_type(zone)); } static inline void *int_to_trip_priv(int i) { return (void *)(long)i; } static inline int trip_priv_to_int(const struct thermal_trip *trip) { return (long)trip->priv; } static int int340x_thermal_read_trips(struct acpi_device *zone_adev, struct thermal_trip *zone_trips, int trip_cnt) { int i, ret; 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++; } 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++; } 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++) { ret = thermal_acpi_active_trip_temp(zone_adev, i, &zone_trips[trip_cnt].temperature); if (ret) break; zone_trips[trip_cnt].type = THERMAL_TRIP_ACTIVE; zone_trips[trip_cnt].priv = int_to_trip_priv(i); trip_cnt++; } return trip_cnt; } static struct thermal_zone_params int340x_thermal_params = { .governor_name = "user_space", .no_hwmon = true, }; struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, int (*get_temp) (struct thermal_zone_device *, int *)) { const struct thermal_zone_device_ops zone_ops = { .set_trip_temp = int340x_thermal_set_trip_temp, .critical = int340x_thermal_critical, .get_temp = get_temp ? get_temp : int340x_thermal_get_zone_temp, }; struct int34x_thermal_zone *int34x_zone; struct thermal_trip *zone_trips; unsigned long long trip_cnt = 0; unsigned long long hyst; acpi_status status; int i, ret; int34x_zone = kzalloc(sizeof(*int34x_zone), GFP_KERNEL); if (!int34x_zone) return ERR_PTR(-ENOMEM); int34x_zone->adev = adev; status = acpi_evaluate_integer(adev->handle, "PATC", NULL, &trip_cnt); if (ACPI_SUCCESS(status)) int34x_zone->aux_trip_nr = trip_cnt; 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; zone_trips[i].flags |= THERMAL_TRIP_FLAG_RW_TEMP; } trip_cnt = int340x_thermal_read_trips(adev, zone_trips, trip_cnt); 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->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, int34x_zone, &zone_ops, &int340x_thermal_params, 0, 0); kfree(zone_trips); if (IS_ERR(int34x_zone->zone)) { ret = PTR_ERR(int34x_zone->zone); goto err_thermal_zone; } ret = thermal_zone_device_enable(int34x_zone->zone); if (ret) goto err_enable; return int34x_zone; err_enable: thermal_zone_device_unregister(int34x_zone->zone); err_thermal_zone: acpi_lpat_free_conversion_table(int34x_zone->lpat_table); err_trips_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_zone) { thermal_zone_device_unregister(int34x_zone->zone); acpi_lpat_free_conversion_table(int34x_zone->lpat_table); kfree(int34x_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); static int int340x_update_one_trip(struct thermal_trip *trip, void *arg) { struct int34x_thermal_zone *int34x_zone = arg; struct acpi_device *zone_adev = int34x_zone->adev; int temp, err; switch (trip->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, trip_priv_to_int(trip), &temp); break; default: err = -ENODEV; } if (err) temp = THERMAL_TEMP_INVALID; thermal_zone_set_trip_temp(int34x_zone->zone, trip, temp); return 0; } void int340x_thermal_update_trips(struct int34x_thermal_zone *int34x_zone) { thermal_zone_for_each_trip(int34x_zone->zone, int340x_update_one_trip, int34x_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_update_trips); MODULE_AUTHOR("Aaron Lu <aaron.lu@intel.com>"); MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); MODULE_DESCRIPTION("Intel INT340x common thermal zone handler"); MODULE_LICENSE("GPL v2");
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1