diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2024-03-05 23:37:49 +0300 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2024-03-05 23:37:49 +0300 |
commit | 166d017d345904444f21b203f3b7bc75f34b94ac (patch) | |
tree | 7da8169d891056776882c707e6792951ae69cda7 /drivers/thermal/intel | |
parent | f1f0c445226c8f03ad329cc2d8072556198fb24a (diff) | |
parent | 32abd250879a272fd96da48db59fde5ef71946cf (diff) | |
download | linux-166d017d345904444f21b203f3b7bc75f34b94ac.tar.xz |
Merge thermal core changes for 6.9 to satisfy a dependency.
Diffstat (limited to 'drivers/thermal/intel')
-rw-r--r-- | drivers/thermal/intel/Kconfig | 2 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c | 40 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h | 2 | ||||
-rw-r--r-- | drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c | 12 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_pch_thermal.c | 28 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_quark_dts_thermal.c | 34 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_soc_dts_iosf.c | 77 | ||||
-rw-r--r-- | drivers/thermal/intel/intel_soc_dts_iosf.h | 2 | ||||
-rw-r--r-- | drivers/thermal/intel/x86_pkg_temp_thermal.c | 39 |
9 files changed, 90 insertions, 146 deletions
diff --git a/drivers/thermal/intel/Kconfig b/drivers/thermal/intel/Kconfig index b43953b5539f..a31f2f32996a 100644 --- a/drivers/thermal/intel/Kconfig +++ b/drivers/thermal/intel/Kconfig @@ -23,7 +23,6 @@ config X86_PKG_TEMP_THERMAL tristate "X86 package temperature thermal driver" depends on X86_THERMAL_VECTOR select THERMAL_GOV_USER_SPACE - select THERMAL_WRITABLE_TRIPS select INTEL_TCC default m help @@ -47,7 +46,6 @@ config INTEL_SOC_DTS_THERMAL tristate "Intel SoCs DTS thermal driver" depends on X86 && PCI && ACPI select INTEL_SOC_DTS_IOSF_CORE - select THERMAL_WRITABLE_TRIPS help Enable this to register Intel SoCs (e.g. Bay Trail) platform digital temperature sensor (DTS). These SoCs have two additional DTSs in diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 3e4bfe817fac..e8182f0929d3 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -61,12 +61,6 @@ static void int340x_thermal_critical(struct thermal_zone_device *zone) dev_dbg(&zone->device, "%s: critical temperature reached\n", zone->type); } -static struct thermal_zone_device_ops int340x_thermal_zone_ops = { - .get_temp = int340x_thermal_get_zone_temp, - .set_trip_temp = int340x_thermal_set_trip_temp, - .critical = int340x_thermal_critical, -}; - static inline void *int_to_trip_priv(int i) { return (void *)(long)i; @@ -126,11 +120,15 @@ static struct thermal_zone_params int340x_thermal_params = { 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; - int trip_mask = 0; acpi_status status; int i, ret; @@ -140,21 +138,9 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, 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_SUCCESS(status)) { + if (ACPI_SUCCESS(status)) int34x_zone->aux_trip_nr = trip_cnt; - trip_mask = BIT(trip_cnt) - 1; - } zone_trips = kzalloc(sizeof(*zone_trips) * (trip_cnt + INT340X_THERMAL_MAX_TRIP_COUNT), GFP_KERNEL); @@ -166,6 +152,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, 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); @@ -179,17 +166,17 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, for (i = 0; i < trip_cnt; ++i) zone_trips[i].hysteresis = hyst; - int34x_zone->trips = zone_trips; - 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, + 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; @@ -203,11 +190,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, err_enable: thermal_zone_device_unregister(int34x_zone->zone); err_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); } @@ -217,8 +201,6 @@ 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->trips); - kfree(int34x_zone->ops); kfree(int34x_zone); } EXPORT_SYMBOL_GPL(int340x_thermal_zone_remove); diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h index e0df6271facc..d504e271009a 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.h @@ -20,10 +20,8 @@ struct active_trip { struct int34x_thermal_zone { struct acpi_device *adev; - struct thermal_trip *trips; int aux_trip_nr; struct thermal_zone_device *zone; - struct thermal_zone_device_ops *ops; void *priv_data; struct acpi_lpat_conversion_table *lpat_table; }; 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 4e1dfd283651..14e34eabc419 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c @@ -233,11 +233,7 @@ static int get_trip_temp(struct proc_thermal_pci *pci_info) return temp; } -static struct thermal_trip psv_trip = { - .type = THERMAL_TRIP_PASSIVE, -}; - -static struct thermal_zone_device_ops tzone_ops = { +static const struct thermal_zone_device_ops tzone_ops = { .get_temp = sys_get_curr_temp, .set_trip_temp = sys_set_trip_temp, }; @@ -251,6 +247,10 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ { struct proc_thermal_device *proc_priv; struct proc_thermal_pci *pci_info; + struct thermal_trip psv_trip = { + .type = THERMAL_TRIP_PASSIVE, + .flags = THERMAL_TRIP_FLAG_RW_TEMP, + }; int irq_flag = 0, irq, ret; bool msi_irq = false; @@ -290,7 +290,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ 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, + 1, pci_info, &tzone_ops, &tzone_params, 0, 0); if (IS_ERR(pci_info->tzone)) { diff --git a/drivers/thermal/intel/intel_pch_thermal.c b/drivers/thermal/intel/intel_pch_thermal.c index b3905e34c507..f5be2c389351 100644 --- a/drivers/thermal/intel/intel_pch_thermal.c +++ b/drivers/thermal/intel/intel_pch_thermal.c @@ -84,7 +84,6 @@ struct pch_thermal_device { void __iomem *hw_base; struct pci_dev *pdev; struct thermal_zone_device *tzd; - struct thermal_trip trips[PCH_MAX_TRIPS]; bool bios_enabled; }; @@ -94,7 +93,8 @@ struct pch_thermal_device { * passive trip temperature using _PSV method. There is no specific * passive temperature setting in MMIO interface of this PCI device. */ -static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip) +static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, + struct thermal_trip *trip) { struct acpi_device *adev; int temp; @@ -106,12 +106,13 @@ static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip) if (thermal_acpi_passive_trip_temp(adev, &temp) || temp <= 0) return 0; - ptd->trips[trip].type = THERMAL_TRIP_PASSIVE; - ptd->trips[trip].temperature = temp; + trip->type = THERMAL_TRIP_PASSIVE; + trip->temperature = temp; return 1; } #else -static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, int trip) +static int pch_wpt_add_acpi_psv_trip(struct pch_thermal_device *ptd, + struct thermal_trip *trip) { return 0; } @@ -131,7 +132,7 @@ static void pch_critical(struct thermal_zone_device *tzd) thermal_zone_device_type(tzd)); } -static struct thermal_zone_device_ops tzd_ops = { +static const struct thermal_zone_device_ops tzd_ops = { .get_temp = pch_thermal_get_temp, .critical = pch_critical, }; @@ -159,6 +160,7 @@ static const char *board_names[] = { static int intel_pch_thermal_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct thermal_trip ptd_trips[PCH_MAX_TRIPS] = { 0 }; enum pch_board_ids board_id = id->driver_data; struct pch_thermal_device *ptd; int nr_trips = 0; @@ -220,22 +222,22 @@ read_trips: trip_temp = readw(ptd->hw_base + WPT_CTT); trip_temp &= 0x1FF; if (trip_temp) { - ptd->trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp); - ptd->trips[nr_trips++].type = THERMAL_TRIP_CRITICAL; + ptd_trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp); + ptd_trips[nr_trips++].type = THERMAL_TRIP_CRITICAL; } trip_temp = readw(ptd->hw_base + WPT_PHL); trip_temp &= 0x1FF; if (trip_temp) { - ptd->trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp); - ptd->trips[nr_trips++].type = THERMAL_TRIP_HOT; + ptd_trips[nr_trips].temperature = GET_WPT_TEMP(trip_temp); + ptd_trips[nr_trips++].type = THERMAL_TRIP_HOT; } - nr_trips += pch_wpt_add_acpi_psv_trip(ptd, nr_trips); + nr_trips += pch_wpt_add_acpi_psv_trip(ptd, &ptd_trips[nr_trips]); ptd->tzd = thermal_zone_device_register_with_trips(board_names[board_id], - ptd->trips, nr_trips, - 0, ptd, &tzd_ops, + ptd_trips, nr_trips, + ptd, &tzd_ops, NULL, 0, 0); if (IS_ERR(ptd->tzd)) { dev_err(&pdev->dev, "Failed to register thermal zone %s\n", diff --git a/drivers/thermal/intel/intel_quark_dts_thermal.c b/drivers/thermal/intel/intel_quark_dts_thermal.c index 646ca8bd40a9..ec6ad26027bc 100644 --- a/drivers/thermal/intel/intel_quark_dts_thermal.c +++ b/drivers/thermal/intel/intel_quark_dts_thermal.c @@ -93,10 +93,6 @@ /* Quark DTS has 2 trip points: hot & catastrophic */ #define QRK_MAX_DTS_TRIPS 2 -/* If DTS not locked, all trip points are configurable */ -#define QRK_DTS_WR_MASK_SET 0x3 -/* If DTS locked, all trip points are not configurable */ -#define QRK_DTS_WR_MASK_CLR 0 #define DEFAULT_POLL_DELAY 2000 @@ -105,7 +101,6 @@ struct soc_sensor_entry { u32 store_ptps; u32 store_dts_enable; struct thermal_zone_device *tzone; - struct thermal_trip trips[QRK_MAX_DTS_TRIPS]; }; static struct soc_sensor_entry *soc_dts; @@ -293,7 +288,7 @@ static int sys_change_mode(struct thermal_zone_device *tzd, return ret; } -static struct thermal_zone_device_ops tzone_ops = { +static const struct thermal_zone_device_ops tzone_ops = { .get_temp = sys_get_curr_temp, .set_trip_temp = sys_set_trip_temp, .change_mode = sys_change_mode, @@ -320,10 +315,10 @@ static void free_soc_dts(struct soc_sensor_entry *aux_entry) static struct soc_sensor_entry *alloc_soc_dts(void) { + struct thermal_trip trips[QRK_MAX_DTS_TRIPS] = { 0 }; struct soc_sensor_entry *aux_entry; int err; u32 out; - int wr_mask; aux_entry = kzalloc(sizeof(*aux_entry), GFP_KERNEL); if (!aux_entry) { @@ -337,13 +332,7 @@ static struct soc_sensor_entry *alloc_soc_dts(void) if (err) goto err_ret; - if (out & QRK_DTS_LOCK_BIT) { - aux_entry->locked = true; - wr_mask = QRK_DTS_WR_MASK_CLR; - } else { - aux_entry->locked = false; - wr_mask = QRK_DTS_WR_MASK_SET; - } + aux_entry->locked = !!(out & QRK_DTS_LOCK_BIT); /* Store DTS default state if DTS registers are not locked */ if (!aux_entry->locked) { @@ -360,19 +349,22 @@ static struct soc_sensor_entry *alloc_soc_dts(void) &aux_entry->store_ptps); if (err) goto err_ret; + + trips[QRK_DTS_ID_TP_CRITICAL].flags |= THERMAL_TRIP_FLAG_RW_TEMP; + trips[QRK_DTS_ID_TP_HOT].flags |= THERMAL_TRIP_FLAG_RW_TEMP; } - aux_entry->trips[QRK_DTS_ID_TP_CRITICAL].temperature = get_trip_temp(QRK_DTS_ID_TP_CRITICAL); - aux_entry->trips[QRK_DTS_ID_TP_CRITICAL].type = THERMAL_TRIP_CRITICAL; + trips[QRK_DTS_ID_TP_CRITICAL].temperature = get_trip_temp(QRK_DTS_ID_TP_CRITICAL); + trips[QRK_DTS_ID_TP_CRITICAL].type = THERMAL_TRIP_CRITICAL; - aux_entry->trips[QRK_DTS_ID_TP_HOT].temperature = get_trip_temp(QRK_DTS_ID_TP_HOT); - aux_entry->trips[QRK_DTS_ID_TP_HOT].type = THERMAL_TRIP_HOT; + trips[QRK_DTS_ID_TP_HOT].temperature = get_trip_temp(QRK_DTS_ID_TP_HOT); + trips[QRK_DTS_ID_TP_HOT].type = THERMAL_TRIP_HOT; aux_entry->tzone = thermal_zone_device_register_with_trips("quark_dts", - aux_entry->trips, + trips, QRK_MAX_DTS_TRIPS, - wr_mask, - aux_entry, &tzone_ops, + aux_entry, + &tzone_ops, NULL, 0, polling_delay); if (IS_ERR(aux_entry->tzone)) { err = PTR_ERR(aux_entry->tzone); diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c index d00def3c4703..2ab943b66f7a 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -129,22 +129,6 @@ err_restore_ptps: return status; } -static int configure_trip(struct intel_soc_dts_sensor_entry *dts, - int thres_index, enum thermal_trip_type trip_type, - int temp) -{ - int ret; - - ret = update_trip_temp(dts->sensors, thres_index, temp); - if (ret) - return ret; - - dts->trips[thres_index].temperature = temp; - dts->trips[thres_index].type = trip_type; - - return 0; -} - static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) { @@ -184,7 +168,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, return 0; } -static struct thermal_zone_device_ops tzone_ops = { +static const struct thermal_zone_device_ops tzone_ops = { .get_temp = sys_get_curr_temp, .set_trip_temp = sys_set_trip_temp, }; @@ -218,15 +202,10 @@ static void remove_dts_thermal_zone(struct intel_soc_dts_sensor_entry *dts) } static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts, - bool critical_trip) + struct thermal_trip *trips) { - int writable_trip_cnt = SOC_MAX_DTS_TRIPS; char name[10]; - unsigned long trip; - int trip_mask; - unsigned long ptps; u32 store_ptps; - unsigned long i; int ret; /* Store status to restor on exit */ @@ -237,26 +216,20 @@ static int add_dts_thermal_zone(int id, struct intel_soc_dts_sensor_entry *dts, dts->id = id; - if (critical_trip) - writable_trip_cnt--; - - trip_mask = GENMASK(writable_trip_cnt - 1, 0); - /* Check if the writable trip we provide is not used by BIOS */ ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, SOC_DTS_OFFSET_PTPS, &store_ptps); - if (ret) - trip_mask = 0; - else { - ptps = store_ptps; - for_each_set_clump8(i, trip, &ptps, writable_trip_cnt * 8) - trip_mask &= ~BIT(i / 8); + if (!ret) { + int i; + + for (i = 0; i <= 1; i++) { + if (store_ptps & (0xFFU << i * 8)) + trips[i].flags &= ~THERMAL_TRIP_FLAG_RW_TEMP; + } } - dts->trip_mask = trip_mask; snprintf(name, sizeof(name), "soc_dts%d", id); - dts->tzone = thermal_zone_device_register_with_trips(name, dts->trips, + dts->tzone = thermal_zone_device_register_with_trips(name, trips, SOC_MAX_DTS_TRIPS, - trip_mask, dts, &tzone_ops, NULL, 0, 0); if (IS_ERR(dts->tzone)) { @@ -315,14 +288,23 @@ EXPORT_SYMBOL_GPL(intel_soc_dts_iosf_interrupt_handler); static void dts_trips_reset(struct intel_soc_dts_sensors *sensors, int dts_index) { - configure_trip(&sensors->soc_dts[dts_index], 0, 0, 0); - configure_trip(&sensors->soc_dts[dts_index], 1, 0, 0); + update_trip_temp(sensors, 0, 0); + update_trip_temp(sensors, 1, 0); +} + +static void set_trip(struct thermal_trip *trip, enum thermal_trip_type type, + u8 flags, int temp) +{ + trip->type = type; + trip->flags = flags; + trip->temperature = temp; } struct intel_soc_dts_sensors * intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type, bool critical_trip, int crit_offset) { + struct thermal_trip trips[SOC_MAX_DTS_SENSORS][SOC_MAX_DTS_TRIPS] = { 0 }; struct intel_soc_dts_sensors *sensors; int tj_max; int ret; @@ -345,30 +327,33 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type, sensors->tj_max = tj_max * 1000; for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { - enum thermal_trip_type trip_type; int temp; sensors->soc_dts[i].sensors = sensors; - ret = configure_trip(&sensors->soc_dts[i], 0, - THERMAL_TRIP_PASSIVE, 0); + set_trip(&trips[i][0], THERMAL_TRIP_PASSIVE, + THERMAL_TRIP_FLAG_RW_TEMP, 0); + + ret = update_trip_temp(sensors, 0, 0); if (ret) goto err_reset_trips; if (critical_trip) { - trip_type = THERMAL_TRIP_CRITICAL; temp = sensors->tj_max - crit_offset; + set_trip(&trips[i][1], THERMAL_TRIP_CRITICAL, 0, temp); } else { - trip_type = THERMAL_TRIP_PASSIVE; + set_trip(&trips[i][1], THERMAL_TRIP_PASSIVE, + THERMAL_TRIP_FLAG_RW_TEMP, 0); temp = 0; } - ret = configure_trip(&sensors->soc_dts[i], 1, trip_type, temp); + + ret = update_trip_temp(sensors, 1, temp); if (ret) goto err_reset_trips; } for (i = 0; i < SOC_MAX_DTS_SENSORS; ++i) { - ret = add_dts_thermal_zone(i, &sensors->soc_dts[i], critical_trip); + ret = add_dts_thermal_zone(i, &sensors->soc_dts[i], trips[i]); if (ret) goto err_remove_zone; } diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.h b/drivers/thermal/intel/intel_soc_dts_iosf.h index 162841df0ebe..44eee844ab3c 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.h +++ b/drivers/thermal/intel/intel_soc_dts_iosf.h @@ -28,8 +28,6 @@ struct intel_soc_dts_sensors; struct intel_soc_dts_sensor_entry { int id; u32 store_status; - u32 trip_mask; - struct thermal_trip trips[SOC_MAX_DTS_TRIPS]; struct thermal_zone_device *tzone; struct intel_soc_dts_sensors *sensors; }; diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index 61c3d450ee60..22a1e3268a98 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -53,7 +53,6 @@ struct zone_device { u32 msr_pkg_therm_high; struct delayed_work work; struct thermal_zone_device *tzone; - struct thermal_trip *trips; struct cpumask cpumask; }; @@ -167,7 +166,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp) } /* Thermal zone callback registry */ -static struct thermal_zone_device_ops tzone_ops = { +static const struct thermal_zone_device_ops tzone_ops = { .get_temp = sys_get_curr_temp, .set_trip_temp = sys_set_trip_temp, }; @@ -268,17 +267,13 @@ static int pkg_thermal_notify(u64 msr_val) return 0; } -static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int num_trips) +static int pkg_temp_thermal_trips_init(int cpu, int tj_max, + struct thermal_trip *trips, int num_trips) { - struct thermal_trip *trips; unsigned long thres_reg_value; u32 mask, shift, eax, edx; int ret, i; - trips = kzalloc(sizeof(*trips) * num_trips, GFP_KERNEL); - if (!trips) - return ERR_PTR(-ENOMEM); - for (i = 0; i < num_trips; i++) { if (i) { @@ -291,10 +286,8 @@ static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int ret = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, &eax, &edx); - if (ret < 0) { - kfree(trips); - return ERR_PTR(ret); - } + if (ret < 0) + return ret; thres_reg_value = (eax & mask) >> shift; @@ -302,16 +295,18 @@ static struct thermal_trip *pkg_temp_thermal_trips_init(int cpu, int tj_max, int tj_max - thres_reg_value * 1000 : THERMAL_TEMP_INVALID; trips[i].type = THERMAL_TRIP_PASSIVE; + trips[i].flags |= THERMAL_TRIP_FLAG_RW_TEMP; pr_debug("%s: cpu=%d, trip=%d, temp=%d\n", __func__, cpu, i, trips[i].temperature); } - return trips; + return 0; } static int pkg_temp_thermal_device_add(unsigned int cpu) { + struct thermal_trip trips[MAX_NUMBER_OF_TRIPS] = { 0 }; int id = topology_logical_die_id(cpu); u32 eax, ebx, ecx, edx; struct zone_device *zonedev; @@ -336,21 +331,18 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) if (!zonedev) return -ENOMEM; - zonedev->trips = pkg_temp_thermal_trips_init(cpu, tj_max, thres_count); - if (IS_ERR(zonedev->trips)) { - err = PTR_ERR(zonedev->trips); + err = pkg_temp_thermal_trips_init(cpu, tj_max, trips, thres_count); + if (err) goto out_kfree_zonedev; - } INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn); zonedev->cpu = cpu; zonedev->tzone = thermal_zone_device_register_with_trips("x86_pkg_temp", - zonedev->trips, thres_count, - (thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01, + trips, thres_count, zonedev, &tzone_ops, &pkg_temp_tz_params, 0, 0); if (IS_ERR(zonedev->tzone)) { err = PTR_ERR(zonedev->tzone); - goto out_kfree_trips; + goto out_kfree_zonedev; } err = thermal_zone_device_enable(zonedev->tzone); if (err) @@ -369,8 +361,6 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) out_unregister_tz: thermal_zone_device_unregister(zonedev->tzone); -out_kfree_trips: - kfree(zonedev->trips); out_kfree_zonedev: kfree(zonedev); return err; @@ -457,10 +447,9 @@ static int pkg_thermal_cpu_offline(unsigned int cpu) raw_spin_unlock_irq(&pkg_temp_lock); /* Final cleanup if this is the last cpu */ - if (lastcpu) { - kfree(zonedev->trips); + if (lastcpu) kfree(zonedev); - } + return 0; } |