diff options
Diffstat (limited to 'drivers/thermal')
27 files changed, 196 insertions, 289 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 17a8ae5e991d..204ed89a3ec9 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -83,17 +83,6 @@ config THERMAL_OF Say 'Y' here if you need to build thermal infrastructure based on device tree. -config THERMAL_WRITABLE_TRIPS - bool "Enable writable trip points" - help - This option allows the system integrator to choose whether - trip temperatures can be changed from userspace. The - writable trips need to be specified when setting up the - thermal zone but the choice here takes precedence. - - Say 'Y' here if you would like to allow userspace tools to - change trip temperatures. - choice prompt "Default Thermal governor" default THERMAL_DEFAULT_GOV_STEP_WISE diff --git a/drivers/thermal/da9062-thermal.c b/drivers/thermal/da9062-thermal.c index 160d64913057..a27aff88cd96 100644 --- a/drivers/thermal/da9062-thermal.c +++ b/drivers/thermal/da9062-thermal.c @@ -197,7 +197,7 @@ static int da9062_thermal_probe(struct platform_device *pdev) mutex_init(&thermal->lock); thermal->zone = thermal_zone_device_register_with_trips(thermal->config->name, - trips, ARRAY_SIZE(trips), 0, thermal, + trips, ARRAY_SIZE(trips), thermal, &da9062_thermal_ops, NULL, pp_tmp, 0); if (IS_ERR(thermal->zone)) { diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c index 6ddf0accdc98..c3b2943a2db8 100644 --- a/drivers/thermal/gov_bang_bang.c +++ b/drivers/thermal/gov_bang_bang.c @@ -49,7 +49,7 @@ static int thermal_zone_trip_update(struct thermal_zone_device *tz, if (instance->target == 0 && tz->temperature >= trip->temperature) instance->target = 1; else if (instance->target == 1 && - tz->temperature <= trip->temperature - trip->hysteresis) + tz->temperature < trip->temperature - trip->hysteresis) instance->target = 0; dev_dbg(&instance->cdev->device, "target=%d\n", diff --git a/drivers/thermal/gov_fair_share.c b/drivers/thermal/gov_fair_share.c index 538abb7de4e2..4da25a0009d7 100644 --- a/drivers/thermal/gov_fair_share.c +++ b/drivers/thermal/gov_fair_share.c @@ -18,22 +18,24 @@ static int get_trip_level(struct thermal_zone_device *tz) { const struct thermal_trip *trip, *level_trip = NULL; - int trip_level; + int trip_level = -1; for_each_trip(tz, trip) { if (trip->temperature >= tz->temperature) - break; + continue; + + trip_level++; - level_trip = trip; + if (!level_trip || trip->temperature > level_trip->temperature) + level_trip = trip; } /* Bail out if the temperature is not greater than any trips. */ - if (!level_trip) + if (trip_level < 0) return 0; - trip_level = thermal_zone_trip_id(tz, level_trip); - - trace_thermal_zone_trip(tz, trip_level, level_trip->type); + trace_thermal_zone_trip(tz, thermal_zone_trip_id(tz, level_trip), + level_trip->type); return trip_level; } diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 81e061f183ad..1b17dc4c219c 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -711,6 +711,8 @@ static int power_allocator_bind(struct thermal_zone_device *tz) if (!tz->tzp->sustainable_power) dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n"); + else + params->sustainable_power = tz->tzp->sustainable_power; estimate_pid_constants(tz, tz->tzp->sustainable_power, params->trip_switch_on, diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 7019c4fdd549..83eaae5ca3b8 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c @@ -115,7 +115,8 @@ struct thermal_soc_data { }; static struct thermal_trip trips[] = { - [IMX_TRIP_PASSIVE] = { .type = THERMAL_TRIP_PASSIVE }, + [IMX_TRIP_PASSIVE] = { .type = THERMAL_TRIP_PASSIVE, + .flags = THERMAL_TRIP_FLAG_RW_TEMP }, [IMX_TRIP_CRITICAL] = { .type = THERMAL_TRIP_CRITICAL }, }; @@ -354,6 +355,7 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip_id, return -EINVAL; imx_set_alarm_temp(data, temp); + trips[IMX_TRIP_PASSIVE].temperature = temp; pm_runtime_put(data->dev); @@ -699,7 +701,7 @@ static int imx_thermal_probe(struct platform_device *pdev) data->tz = thermal_zone_device_register_with_trips("imx_thermal_zone", trips, ARRAY_SIZE(trips), - BIT(IMX_TRIP_PASSIVE), data, + data, &imx_tz_ops, NULL, IMX_PASSIVE_DELAY, IMX_POLLING_DELAY); 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..400fde7cb3b1 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -58,15 +58,10 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, static void int340x_thermal_critical(struct thermal_zone_device *zone) { - dev_dbg(&zone->device, "%s: critical temperature reached\n", zone->type); + dev_dbg(thermal_zone_device(zone), "%s: critical temperature reached\n", + thermal_zone_device_type(zone)); } -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 +121,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 +139,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 +153,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 +167,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 +191,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 +202,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.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c index 649f67fdf345..d75fae7b7ed2 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c @@ -176,14 +176,14 @@ static int proc_thermal_get_zone_temp(struct thermal_zone_device *zone, int *temp) { int cpu; - int curr_temp; + int curr_temp, ret; *temp = 0; for_each_online_cpu(cpu) { - curr_temp = intel_tcc_get_temp(cpu, false); - if (curr_temp < 0) - return curr_temp; + ret = intel_tcc_get_temp(cpu, &curr_temp, false); + if (ret < 0) + return ret; if (!*temp || curr_temp > *temp) *temp = curr_temp; } diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h index 95c6013a33fb..674f3c85dfbc 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.h @@ -25,6 +25,7 @@ #define PCI_DEVICE_ID_INTEL_HSB_THERMAL 0x0A03 #define PCI_DEVICE_ID_INTEL_ICL_THERMAL 0x8a03 #define PCI_DEVICE_ID_INTEL_JSL_THERMAL 0x4E03 +#define PCI_DEVICE_ID_INTEL_LNLM_THERMAL 0x641D #define PCI_DEVICE_ID_INTEL_MTLP_THERMAL 0x7D03 #define PCI_DEVICE_ID_INTEL_RPL_THERMAL 0xA71D #define PCI_DEVICE_ID_INTEL_SKL_THERMAL 0x1903 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 d7495571dd5d..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)) { @@ -407,6 +407,7 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend, static const struct pci_device_id proc_thermal_pci_ids[] = { { PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ) }, + { PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_RAPL) }, { PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR | PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) }, 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/intel_tcc.c b/drivers/thermal/intel/intel_tcc.c index 2e5c741c41ca..5e8b7f34b395 100644 --- a/drivers/thermal/intel/intel_tcc.c +++ b/drivers/thermal/intel/intel_tcc.c @@ -103,18 +103,19 @@ EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, INTEL_TCC); /** * intel_tcc_get_temp() - returns the current temperature * @cpu: cpu that the MSR should be run on, nagative value means any cpu. + * @temp: pointer to the memory for saving cpu temperature. * @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor. * * Get the current temperature returned by the CPU core/package level * thermal sensor, in degrees C. * - * Return: Temperature in degrees C on success, negative error code otherwise. + * Return: 0 on success, negative error code otherwise. */ -int intel_tcc_get_temp(int cpu, bool pkg) +int intel_tcc_get_temp(int cpu, int *temp, bool pkg) { u32 low, high; u32 msr = pkg ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS; - int tjmax, temp, err; + int tjmax, err; tjmax = intel_tcc_get_tjmax(cpu); if (tjmax < 0) @@ -131,9 +132,8 @@ int intel_tcc_get_temp(int cpu, bool pkg) if (!(low & BIT(31))) return -ENODATA; - temp = tjmax - ((low >> 16) & 0x7f); + *temp = tjmax - ((low >> 16) & 0x7f); - /* Do not allow negative CPU temperature */ - return temp >= 0 ? temp : -ENODATA; + return 0; } EXPORT_SYMBOL_NS_GPL(intel_tcc_get_temp, INTEL_TCC); diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index f6c2e5964b8f..c0ca8e3ff2e7 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; }; @@ -108,11 +107,11 @@ static struct zone_device *pkg_temp_thermal_get_dev(unsigned int cpu) static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) { struct zone_device *zonedev = thermal_zone_device_priv(tzd); - int val; + int val, ret; - val = intel_tcc_get_temp(zonedev->cpu, true); - if (val < 0) - return val; + ret = intel_tcc_get_temp(zonedev->cpu, &val, true); + if (ret < 0) + return ret; *temp = val * 1000; pr_debug("sys_get_curr_temp %d\n", *temp); @@ -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; } diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index feb848d595fa..925183753fcb 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -489,7 +489,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) &rcar_thermal_zone_ops); } else { priv->zone = thermal_zone_device_register_with_trips( - "rcar_thermal", trips, ARRAY_SIZE(trips), 0, priv, + "rcar_thermal", trips, ARRAY_SIZE(trips), priv, &rcar_thermal_zone_ops, NULL, 0, idle); diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c index 0d6249b36609..2a105409864e 100644 --- a/drivers/thermal/st/st_thermal.c +++ b/drivers/thermal/st/st_thermal.c @@ -203,7 +203,7 @@ int st_thermal_register(struct platform_device *pdev, trip.type = THERMAL_TRIP_CRITICAL; sensor->thermal_dev = - thermal_zone_device_register_with_trips(dev_name(dev), &trip, 1, 0, sensor, + thermal_zone_device_register_with_trips(dev_name(dev), &trip, 1, sensor, &st_tz_ops, NULL, 0, polling_delay); if (IS_ERR(sensor->thermal_dev)) { dev_err(dev, "failed to register thermal zone device\n"); diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index dfaa6341694a..34a31bc72023 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -273,7 +273,6 @@ static int __init thermal_register_governors(void) /* * Zone update section: main control loop applied to each zone while monitoring - * * in polling mode. The monitoring is done using a workqueue. * Same update may be done on a zone by calling thermal_zone_device_update(). * @@ -356,9 +355,9 @@ static void handle_critical_trips(struct thermal_zone_device *tz, trace_thermal_zone_trip(tz, thermal_zone_trip_id(tz, trip), trip->type); if (trip->type == THERMAL_TRIP_CRITICAL) - tz->ops->critical(tz); - else if (tz->ops->hot) - tz->ops->hot(tz); + tz->ops.critical(tz); + else if (tz->ops.hot) + tz->ops.hot(tz); } static void handle_thermal_trip(struct thermal_zone_device *tz, @@ -493,8 +492,8 @@ static int thermal_zone_device_set_mode(struct thermal_zone_device *tz, return ret; } - if (tz->ops->change_mode) - ret = tz->ops->change_mode(tz, mode); + if (tz->ops.change_mode) + ret = tz->ops.change_mode(tz, mode); if (!ret) tz->mode = mode; @@ -867,8 +866,8 @@ static void bind_cdev(struct thermal_cooling_device *cdev) struct thermal_zone_device *pos = NULL; list_for_each_entry(pos, &thermal_tz_list, node) { - if (pos->ops->bind) { - ret = pos->ops->bind(pos, cdev); + if (pos->ops.bind) { + ret = pos->ops.bind(pos, cdev); if (ret) print_bind_err_msg(pos, cdev, ret); } @@ -1184,8 +1183,8 @@ void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev) /* Unbind all thermal zones associated with 'this' cdev */ list_for_each_entry(tz, &thermal_tz_list, node) { - if (tz->ops->unbind) - tz->ops->unbind(tz, cdev); + if (tz->ops.unbind) + tz->ops.unbind(tz, cdev); } mutex_unlock(&thermal_list_lock); @@ -1199,13 +1198,13 @@ static void bind_tz(struct thermal_zone_device *tz) int ret; struct thermal_cooling_device *pos = NULL; - if (!tz->ops->bind) + if (!tz->ops.bind) return; mutex_lock(&thermal_list_lock); list_for_each_entry(pos, &thermal_cdev_list, node) { - ret = tz->ops->bind(tz, pos); + ret = tz->ops.bind(tz, pos); if (ret) print_bind_err_msg(tz, pos, ret); } @@ -1224,11 +1223,8 @@ int thermal_zone_get_crit_temp(struct thermal_zone_device *tz, int *temp) { int i, ret = -EINVAL; - if (tz->ops->get_crit_temp) - return tz->ops->get_crit_temp(tz, temp); - - if (!tz->trips) - return -EINVAL; + if (tz->ops.get_crit_temp) + return tz->ops.get_crit_temp(tz, temp); mutex_lock(&tz->lock); @@ -1251,7 +1247,6 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp); * @type: the thermal zone device type * @trips: a pointer to an array of thermal trips * @num_trips: the number of trip points the thermal zone support - * @mask: a bit string indicating the writeablility of trip points * @devdata: private device data * @ops: standard thermal zone device callbacks * @tzp: thermal zone platform parameters @@ -1272,10 +1267,12 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp); * IS_ERR*() helpers. */ struct thermal_zone_device * -thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask, - void *devdata, struct thermal_zone_device_ops *ops, - const struct thermal_zone_params *tzp, int passive_delay, - int polling_delay) +thermal_zone_device_register_with_trips(const char *type, + const struct thermal_trip *trips, + int num_trips, void *devdata, + const struct thermal_zone_device_ops *ops, + const struct thermal_zone_params *tzp, + int passive_delay, int polling_delay) { struct thermal_zone_device *tz; int id; @@ -1293,20 +1290,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t return ERR_PTR(-EINVAL); } - /* - * Max trip count can't exceed 31 as the "mask >> num_trips" condition. - * For example, shifting by 32 will result in compiler warning: - * warning: right shift count >= width of type [-Wshift-count- overflow] - * - * Also "mask >> num_trips" will always be true with 32 bit shift. - * E.g. mask = 0x80000000 for trip id 31 to be RW. Then - * mask >> 32 = 0x80000000 - * This will result in failure for the below condition. - * - * Check will be true when the bit 31 of the mask is set. - * 32 bit shift will cause overflow of 4 byte integer. - */ - if (num_trips > (BITS_PER_TYPE(int) - 1) || num_trips < 0 || mask >> num_trips) { + if (num_trips < 0) { pr_err("Incorrect number of thermal trips\n"); return ERR_PTR(-EINVAL); } @@ -1322,7 +1306,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t if (!thermal_class) return ERR_PTR(-ENODEV); - tz = kzalloc(sizeof(*tz), GFP_KERNEL); + tz = kzalloc(struct_size(tz, trips, num_trips), GFP_KERNEL); if (!tz) return ERR_PTR(-ENOMEM); @@ -1348,21 +1332,21 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t tz->id = id; strscpy(tz->type, type, sizeof(tz->type)); - if (!ops->critical) - ops->critical = thermal_zone_device_critical; + tz->ops = *ops; + if (!tz->ops.critical) + tz->ops.critical = thermal_zone_device_critical; - tz->ops = ops; tz->device.class = thermal_class; tz->devdata = devdata; - tz->trips = trips; tz->num_trips = num_trips; + memcpy(tz->trips, trips, num_trips * sizeof(*trips)); thermal_set_delay_jiffies(&tz->passive_delay_jiffies, passive_delay); thermal_set_delay_jiffies(&tz->polling_delay_jiffies, polling_delay); /* sys I/F */ /* Add nodes that are always present via .groups */ - result = thermal_zone_create_device_groups(tz, mask); + result = thermal_zone_create_device_groups(tz); if (result) goto remove_id; @@ -1437,10 +1421,10 @@ EXPORT_SYMBOL_GPL(thermal_zone_device_register_with_trips); struct thermal_zone_device *thermal_tripless_zone_device_register( const char *type, void *devdata, - struct thermal_zone_device_ops *ops, + const struct thermal_zone_device_ops *ops, const struct thermal_zone_params *tzp) { - return thermal_zone_device_register_with_trips(type, NULL, 0, 0, devdata, + return thermal_zone_device_register_with_trips(type, NULL, 0, devdata, ops, tzp, 0, 0); } EXPORT_SYMBOL_GPL(thermal_tripless_zone_device_register); @@ -1499,8 +1483,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) /* Unbind all cdevs associated with 'this' thermal zone */ list_for_each_entry(cdev, &thermal_cdev_list, node) - if (tz->ops->unbind) - tz->ops->unbind(tz, cdev); + if (tz->ops.unbind) + tz->ops.unbind(tz, cdev); mutex_unlock(&thermal_list_lock); diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index e9c099ecdd0f..0d8a42bb7ce8 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -131,7 +131,7 @@ void thermal_zone_trip_updated(struct thermal_zone_device *tz, int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); /* sysfs I/F */ -int thermal_zone_create_device_groups(struct thermal_zone_device *, int); +int thermal_zone_create_device_groups(struct thermal_zone_device *tz); void thermal_zone_destroy_device_groups(struct thermal_zone_device *); void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *); void thermal_cooling_device_destroy_sysfs(struct thermal_cooling_device *cdev); diff --git a/drivers/thermal/thermal_helpers.c b/drivers/thermal/thermal_helpers.c index 0329f4a71b02..c5a057b59c42 100644 --- a/drivers/thermal/thermal_helpers.c +++ b/drivers/thermal/thermal_helpers.c @@ -26,8 +26,8 @@ int get_tz_trend(struct thermal_zone_device *tz, const struct thermal_trip *trip { enum thermal_trend trend; - if (tz->emul_temperature || !tz->ops->get_trend || - tz->ops->get_trend(tz, trip, &trend)) { + if (tz->emul_temperature || !tz->ops.get_trend || + tz->ops.get_trend(tz, trip, &trend)) { if (tz->temperature > tz->last_temperature) trend = THERMAL_TREND_RAISING; else if (tz->temperature < tz->last_temperature) @@ -75,7 +75,7 @@ EXPORT_SYMBOL(get_thermal_instance); * temperature and fill @temp. * * Both tz and tz->ops must be valid pointers when calling this function, - * and the tz->ops->get_temp callback must be provided. + * and the tz->ops.get_temp callback must be provided. * The function must be called under tz->lock. * * Return: On success returns 0, an error code otherwise @@ -88,7 +88,7 @@ int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) lockdep_assert_held(&tz->lock); - ret = tz->ops->get_temp(tz, temp); + ret = tz->ops.get_temp(tz, temp); if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) { for_each_trip(tz, trip) { @@ -132,7 +132,7 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) mutex_lock(&tz->lock); - if (!tz->ops->get_temp) { + if (!tz->ops.get_temp) { ret = -EINVAL; goto unlock; } diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index 252116f1e535..f0e504fd866a 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -80,7 +80,7 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf) mutex_lock(&tz->lock); - ret = tz->ops->get_crit_temp(tz, &temperature); + ret = tz->ops.get_crit_temp(tz, &temperature); mutex_unlock(&tz->lock); @@ -132,7 +132,7 @@ thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon, static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz) { int temp; - return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp); + return tz->ops.get_crit_temp && !tz->ops.get_crit_temp(tz, &temp); } int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 4d6c22e0ed85..f1cbf9aa62cf 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -117,6 +117,8 @@ static int thermal_of_populate_trip(struct device_node *np, return ret; } + trip->flags = THERMAL_TRIP_FLAG_RW_TEMP; + return 0; } @@ -438,13 +440,8 @@ static int thermal_of_unbind(struct thermal_zone_device *tz, */ static void thermal_of_zone_unregister(struct thermal_zone_device *tz) { - struct thermal_trip *trips = tz->trips; - struct thermal_zone_device_ops *ops = tz->ops; - thermal_zone_device_disable(tz); thermal_zone_device_unregister(tz); - kfree(trips); - kfree(ops); } /** @@ -470,33 +467,27 @@ static void thermal_of_zone_unregister(struct thermal_zone_device *tz) static struct thermal_zone_device *thermal_of_zone_register(struct device_node *sensor, int id, void *data, const struct thermal_zone_device_ops *ops) { + struct thermal_zone_device_ops of_ops = *ops; struct thermal_zone_device *tz; struct thermal_trip *trips; struct thermal_zone_params tzp = {}; - struct thermal_zone_device_ops *of_ops; struct device_node *np; const char *action; int delay, pdelay; - int ntrips, mask; + int ntrips; int ret; - of_ops = kmemdup(ops, sizeof(*ops), GFP_KERNEL); - if (!of_ops) - return ERR_PTR(-ENOMEM); - np = of_thermal_zone_find(sensor, id); if (IS_ERR(np)) { if (PTR_ERR(np) != -ENODEV) pr_err("Failed to find thermal zone for %pOFn id=%d\n", sensor, id); - ret = PTR_ERR(np); - goto out_kfree_of_ops; + return ERR_CAST(np); } trips = thermal_of_trips_init(np, &ntrips); if (IS_ERR(trips)) { pr_err("Failed to find trip points for %pOFn id=%d\n", sensor, id); - ret = PTR_ERR(trips); - goto out_kfree_of_ops; + return ERR_CAST(trips); } ret = thermal_of_monitor_init(np, &delay, &pdelay); @@ -507,18 +498,16 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * thermal_of_parameters_init(np, &tzp); - of_ops->bind = thermal_of_bind; - of_ops->unbind = thermal_of_unbind; - - mask = GENMASK_ULL((ntrips) - 1, 0); + of_ops.bind = thermal_of_bind; + of_ops.unbind = thermal_of_unbind; ret = of_property_read_string(np, "critical-action", &action); if (!ret) - if (!of_ops->critical && !strcasecmp(action, "reboot")) - of_ops->critical = thermal_zone_device_critical_reboot; + if (!of_ops.critical && !strcasecmp(action, "reboot")) + of_ops.critical = thermal_zone_device_critical_reboot; tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips, - mask, data, of_ops, &tzp, + data, &of_ops, &tzp, pdelay, delay); if (IS_ERR(tz)) { ret = PTR_ERR(tz); @@ -526,6 +515,8 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * goto out_kfree_trips; } + kfree(trips); + ret = thermal_zone_device_enable(tz); if (ret) { pr_err("Failed to enabled thermal zone '%s', id=%d: %d\n", @@ -538,8 +529,6 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * out_kfree_trips: kfree(trips); -out_kfree_of_ops: - kfree(of_ops); return ERR_PTR(ret); } diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index f4033865b093..5b533fa40437 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -123,8 +123,8 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, trip = &tz->trips[trip_id]; if (temp != trip->temperature) { - if (tz->ops->set_trip_temp) { - ret = tz->ops->set_trip_temp(tz, trip_id, temp); + if (tz->ops.set_trip_temp) { + ret = tz->ops.set_trip_temp(tz, trip_id, temp); if (ret) goto unlock; } @@ -136,7 +136,7 @@ trip_point_temp_store(struct device *dev, struct device_attribute *attr, unlock: mutex_unlock(&tz->lock); - + return ret ? ret : count; } @@ -174,21 +174,14 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, trip = &tz->trips[trip_id]; if (hyst != trip->hysteresis) { - if (tz->ops->set_trip_hyst) { - ret = tz->ops->set_trip_hyst(tz, trip_id, hyst); - if (ret) - goto unlock; - } - trip->hysteresis = hyst; thermal_zone_trip_updated(tz, trip); } -unlock: mutex_unlock(&tz->lock); - return ret ? ret : count; + return count; } static ssize_t @@ -250,10 +243,10 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, mutex_lock(&tz->lock); - if (!tz->ops->set_emul_temp) + if (!tz->ops.set_emul_temp) tz->emul_temperature = temperature; else - ret = tz->ops->set_emul_temp(tz, temperature); + ret = tz->ops.set_emul_temp(tz, temperature); if (!ret) __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); @@ -392,17 +385,16 @@ static const struct attribute_group *thermal_zone_attribute_groups[] = { /** * create_trip_attrs() - create attributes for trip points * @tz: the thermal zone device - * @mask: Writeable trip point bitmap. * * helper function to instantiate sysfs entries for every trip * point and its properties of a struct thermal_zone_device. * * Return: 0 on success, the proper error value otherwise. */ -static int create_trip_attrs(struct thermal_zone_device *tz, int mask) +static int create_trip_attrs(struct thermal_zone_device *tz) { + const struct thermal_trip *trip; struct attribute **attrs; - int indx; /* This function works only for zones with at least one trip */ if (tz->num_trips <= 0) @@ -437,7 +429,9 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) return -ENOMEM; } - for (indx = 0; indx < tz->num_trips; indx++) { + for_each_trip(tz, trip) { + int indx = thermal_zone_trip_id(tz, trip); + /* create trip type attribute */ snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH, "trip_point_%d_type", indx); @@ -458,8 +452,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) tz->trip_temp_attrs[indx].name; tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO; tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show; - if (IS_ENABLED(CONFIG_THERMAL_WRITABLE_TRIPS) && - mask & (1 << indx)) { + if (trip->flags & THERMAL_TRIP_FLAG_RW_TEMP) { tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR; tz->trip_temp_attrs[indx].attr.store = trip_point_temp_store; @@ -474,7 +467,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) tz->trip_hyst_attrs[indx].name; tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO; tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show; - if (tz->ops->set_trip_hyst) { + if (trip->flags & THERMAL_TRIP_FLAG_RW_HYST) { tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR; tz->trip_hyst_attrs[indx].attr.store = trip_point_hyst_store; @@ -506,8 +499,7 @@ static void destroy_trip_attrs(struct thermal_zone_device *tz) kfree(tz->trips_attribute_group.attrs); } -int thermal_zone_create_device_groups(struct thermal_zone_device *tz, - int mask) +int thermal_zone_create_device_groups(struct thermal_zone_device *tz) { const struct attribute_group **groups; int i, size, result; @@ -523,7 +515,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *tz, groups[i] = thermal_zone_attribute_groups[i]; if (tz->num_trips) { - result = create_trip_attrs(tz, mask); + result = create_trip_attrs(tz); if (result) { kfree(groups); diff --git a/drivers/thermal/thermal_trip.c b/drivers/thermal/thermal_trip.c index c875a26d5adf..09f6050dd041 100644 --- a/drivers/thermal/thermal_trip.c +++ b/drivers/thermal/thermal_trip.c @@ -70,7 +70,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) lockdep_assert_held(&tz->lock); - if (!tz->ops->set_trips) + if (!tz->ops.set_trips) return; for_each_trip(tz, trip) { @@ -114,7 +114,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) * Set a temperature window. When this window is left the driver * must inform the thermal core via thermal_zone_device_update. */ - ret = tz->ops->set_trips(tz, low, high); + ret = tz->ops.set_trips(tz, low, high); if (ret) dev_err(&tz->device, "Failed to set trips: %d\n", ret); } @@ -122,7 +122,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip) { - if (!tz || !tz->trips || trip_id < 0 || trip_id >= tz->num_trips || !trip) + if (!tz || trip_id < 0 || trip_id >= tz->num_trips || !trip) return -EINVAL; *trip = tz->trips[trip_id]; |