提交 9346116d 编写于 作者: L Linus Torvalds

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux

Pull thermal management updates from Zhang Rui:

 - Thermal core code reorganization and cleanup. Two new files are
   created for thermal sysfs I/F code and thermal helper functions
   (Eduardo Valentin).

 - Sanitize hotplug and locking for x86_pkg_temp driver (Thomas
   Gleixner)

 - Update MAINTAINER file for pwm-fan driver and Samsung thermal driver
   (Lukasz Majewski)

 - Fix module auto-load for max77620, tango and db8500 thermal driver
   (Javier Martinez Canillas)

 - Fix a bug that thermal hwmon sysfs I/F returns wrong critical trip
   point temperature value (Krzysztof Kozlowski)

 - Add Skylake PCH 100 series support for intel_pch_thermal driver
   (OGAWA Hirofumi)

 - Small fixes and cleanups for platform thermal drivers (Julia Lawall,
   Luis Henriques, Leo Yan, Stephen Boyd, Shawn Lin, Javi Merino and
   Lukasz Luba)

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (76 commits)
  MAINTAINERS: Samsung: Update maintainer for PWM FAN and SAMSUNG THERMAL
  thermal/x86 pkg temp: Convert to hotplug state machine
  thermal/x86_pkg_temp: Sanitize package management
  thermal/x86_pkg_temp: Move work into package struct
  thermal/x86_pkg_temp: Move work scheduled flag into package struct
  thermal/x86_pkg_temp: Sanitize locking
  thermal/x86_pkg_temp: Cleanup code some more
  thermal/x86_pkg_temp: Cleanup namespace
  thermal/x86_pkg_temp: Get rid of ref counting
  thermal/x86_pkg_temp: Sanitize callback (de)initialization
  thermal/x86_pkg_temp: Replace open coded cpu search
  thermal/x86_pkg_temp: Remove redundant package search
  thermal/x86_pkg_temp: Cleanup thermal interrupt handling
  thermal: hwmon: Properly report critical temperature in sysfs
  devfreq_cooling: pass a pointer to devfreq in the power model callbacks
  devfreq_cooling: make the structs devfreq_cooling_xxx visible for all
  dt-bindings: rockchip-thermal: fix the misleading description
  thermal: rockchip: improve the warning log
  thermal: db8500: Fix module autoload
  thermal: tango: Fix module autoload
  ...
...@@ -22,10 +22,13 @@ Required properties: ...@@ -22,10 +22,13 @@ Required properties:
TSADC controller. TSADC controller.
- pinctrl-2 : The "sleep" pinctrl state, it will be in for suspend. - pinctrl-2 : The "sleep" pinctrl state, it will be in for suspend.
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. - #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
Optional properties:
- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value. - rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value.
- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO. - rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO.
- rockchip,hw-tshut-polarity : The hardware-controlled active polarity 0:LOW - rockchip,hw-tshut-polarity : The hardware-controlled active polarity 0:LOW
1:HIGH. 1:HIGH.
- rockchip,grf : The phandle of the syscon node for the general register file.
Exiample: Exiample:
tsadc: tsadc@ff280000 { tsadc: tsadc@ff280000 {
......
...@@ -9838,7 +9838,7 @@ F: drivers/media/usb/pwc/* ...@@ -9838,7 +9838,7 @@ F: drivers/media/usb/pwc/*
PWM FAN DRIVER PWM FAN DRIVER
M: Kamil Debski <kamil@wypas.org> M: Kamil Debski <kamil@wypas.org>
M: Lukasz Majewski <l.majewski@samsung.com> M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-hwmon@vger.kernel.org L: linux-hwmon@vger.kernel.org
S: Supported S: Supported
F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt
...@@ -10609,7 +10609,7 @@ L: netdev@vger.kernel.org ...@@ -10609,7 +10609,7 @@ L: netdev@vger.kernel.org
F: drivers/net/ethernet/samsung/sxgbe/ F: drivers/net/ethernet/samsung/sxgbe/
SAMSUNG THERMAL DRIVER SAMSUNG THERMAL DRIVER
M: Lukasz Majewski <l.majewski@samsung.com> M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org L: linux-samsung-soc@vger.kernel.org
S: Supported S: Supported
......
...@@ -177,8 +177,10 @@ config THERMAL_EMULATION ...@@ -177,8 +177,10 @@ config THERMAL_EMULATION
config HISI_THERMAL config HISI_THERMAL
tristate "Hisilicon thermal driver" tristate "Hisilicon thermal driver"
depends on (ARCH_HISI && CPU_THERMAL && OF) || COMPILE_TEST depends on ARCH_HISI || COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
depends on OF
default y
help help
Enable this to plug hisilicon's thermal sensor driver into the Linux Enable this to plug hisilicon's thermal sensor driver into the Linux
thermal framework. cpufreq is used as the cooling device to throttle thermal framework. cpufreq is used as the cooling device to throttle
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
# #
obj-$(CONFIG_THERMAL) += thermal_sys.o obj-$(CONFIG_THERMAL) += thermal_sys.o
thermal_sys-y += thermal_core.o thermal_sys-y += thermal_core.o thermal_sysfs.o \
thermal_helpers.o
# interface to/from other layers providing sensors # interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
......
...@@ -512,6 +512,7 @@ static const struct of_device_id db8500_thermal_match[] = { ...@@ -512,6 +512,7 @@ static const struct of_device_id db8500_thermal_match[] = {
{ .compatible = "stericsson,db8500-thermal" }, { .compatible = "stericsson,db8500-thermal" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, db8500_thermal_match);
#endif #endif
static struct platform_driver db8500_thermal_driver = { static struct platform_driver db8500_thermal_driver = {
......
...@@ -238,7 +238,7 @@ get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq) ...@@ -238,7 +238,7 @@ get_static_power(struct devfreq_cooling_device *dfc, unsigned long freq)
return 0; return 0;
} }
return dfc->power_ops->get_static_power(voltage); return dfc->power_ops->get_static_power(df, voltage);
} }
/** /**
...@@ -262,7 +262,8 @@ get_dynamic_power(struct devfreq_cooling_device *dfc, unsigned long freq, ...@@ -262,7 +262,8 @@ get_dynamic_power(struct devfreq_cooling_device *dfc, unsigned long freq,
struct devfreq_cooling_power *dfc_power = dfc->power_ops; struct devfreq_cooling_power *dfc_power = dfc->power_ops;
if (dfc_power->get_dynamic_power) if (dfc_power->get_dynamic_power)
return dfc_power->get_dynamic_power(freq, voltage); return dfc_power->get_dynamic_power(dfc->devfreq, freq,
voltage);
freq_mhz = freq / 1000000; freq_mhz = freq / 1000000;
power = (u64)dfc_power->dyn_power_coeff * freq_mhz * voltage * voltage; power = (u64)dfc_power->dyn_power_coeff * freq_mhz * voltage * voltage;
......
...@@ -96,7 +96,7 @@ static ssize_t current_uuid_store(struct device *dev, ...@@ -96,7 +96,7 @@ static ssize_t current_uuid_store(struct device *dev,
return -EINVAL; return -EINVAL;
} }
static DEVICE_ATTR(current_uuid, 0644, current_uuid_show, current_uuid_store); static DEVICE_ATTR_RW(current_uuid);
static DEVICE_ATTR_RO(available_uuids); static DEVICE_ATTR_RO(available_uuids);
static struct attribute *uuid_attrs[] = { static struct attribute *uuid_attrs[] = {
&dev_attr_available_uuids.attr, &dev_attr_available_uuids.attr,
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define PCH_THERMAL_DID_HSW_2 0x8C24 /* Haswell PCH */ #define PCH_THERMAL_DID_HSW_2 0x8C24 /* Haswell PCH */
#define PCH_THERMAL_DID_WPT 0x9CA4 /* Wildcat Point */ #define PCH_THERMAL_DID_WPT 0x9CA4 /* Wildcat Point */
#define PCH_THERMAL_DID_SKL 0x9D31 /* Skylake PCH */ #define PCH_THERMAL_DID_SKL 0x9D31 /* Skylake PCH */
#define PCH_THERMAL_DID_SKL_H 0xA131 /* Skylake PCH 100 series */
/* Wildcat Point-LP PCH Thermal registers */ /* Wildcat Point-LP PCH Thermal registers */
#define WPT_TEMP 0x0000 /* Temperature */ #define WPT_TEMP 0x0000 /* Temperature */
...@@ -273,37 +274,44 @@ static struct thermal_zone_device_ops tzd_ops = { ...@@ -273,37 +274,44 @@ static struct thermal_zone_device_ops tzd_ops = {
.get_trip_temp = pch_get_trip_temp, .get_trip_temp = pch_get_trip_temp,
}; };
enum board_ids {
board_hsw,
board_wpt,
board_skl,
};
static const struct board_info {
const char *name;
const struct pch_dev_ops *ops;
} board_info[] = {
[board_hsw] = {
.name = "pch_haswell",
.ops = &pch_dev_ops_wpt,
},
[board_wpt] = {
.name = "pch_wildcat_point",
.ops = &pch_dev_ops_wpt,
},
[board_skl] = {
.name = "pch_skylake",
.ops = &pch_dev_ops_wpt,
},
};
static int intel_pch_thermal_probe(struct pci_dev *pdev, static int intel_pch_thermal_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
enum board_ids board_id = id->driver_data;
const struct board_info *bi = &board_info[board_id];
struct pch_thermal_device *ptd; struct pch_thermal_device *ptd;
int err; int err;
int nr_trips; int nr_trips;
char *dev_name;
ptd = devm_kzalloc(&pdev->dev, sizeof(*ptd), GFP_KERNEL); ptd = devm_kzalloc(&pdev->dev, sizeof(*ptd), GFP_KERNEL);
if (!ptd) if (!ptd)
return -ENOMEM; return -ENOMEM;
switch (pdev->device) { ptd->ops = bi->ops;
case PCH_THERMAL_DID_WPT:
ptd->ops = &pch_dev_ops_wpt;
dev_name = "pch_wildcat_point";
break;
case PCH_THERMAL_DID_SKL:
ptd->ops = &pch_dev_ops_wpt;
dev_name = "pch_skylake";
break;
case PCH_THERMAL_DID_HSW_1:
case PCH_THERMAL_DID_HSW_2:
ptd->ops = &pch_dev_ops_wpt;
dev_name = "pch_haswell";
break;
default:
dev_err(&pdev->dev, "unknown pch thermal device\n");
return -ENODEV;
}
pci_set_drvdata(pdev, ptd); pci_set_drvdata(pdev, ptd);
ptd->pdev = pdev; ptd->pdev = pdev;
...@@ -331,11 +339,11 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev, ...@@ -331,11 +339,11 @@ static int intel_pch_thermal_probe(struct pci_dev *pdev,
if (err) if (err)
goto error_cleanup; goto error_cleanup;
ptd->tzd = thermal_zone_device_register(dev_name, nr_trips, 0, ptd, ptd->tzd = thermal_zone_device_register(bi->name, nr_trips, 0, ptd,
&tzd_ops, NULL, 0, 0); &tzd_ops, NULL, 0, 0);
if (IS_ERR(ptd->tzd)) { if (IS_ERR(ptd->tzd)) {
dev_err(&pdev->dev, "Failed to register thermal zone %s\n", dev_err(&pdev->dev, "Failed to register thermal zone %s\n",
dev_name); bi->name);
err = PTR_ERR(ptd->tzd); err = PTR_ERR(ptd->tzd);
goto error_cleanup; goto error_cleanup;
} }
...@@ -380,10 +388,16 @@ static int intel_pch_thermal_resume(struct device *device) ...@@ -380,10 +388,16 @@ static int intel_pch_thermal_resume(struct device *device)
} }
static struct pci_device_id intel_pch_thermal_id[] = { static struct pci_device_id intel_pch_thermal_id[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_WPT) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_1),
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL) }, .driver_data = board_hsw, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_1) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_2),
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_2) }, .driver_data = board_hsw, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_WPT),
.driver_data = board_wpt, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL),
.driver_data = board_skl, },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_SKL_H),
.driver_data = board_skl, },
{ 0, }, { 0, },
}; };
MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id); MODULE_DEVICE_TABLE(pci, intel_pch_thermal_id);
......
...@@ -149,6 +149,7 @@ static struct platform_device_id max77620_thermal_devtype[] = { ...@@ -149,6 +149,7 @@ static struct platform_device_id max77620_thermal_devtype[] = {
{ .name = "max77620-thermal", }, { .name = "max77620-thermal", },
{}, {},
}; };
MODULE_DEVICE_TABLE(platform, max77620_thermal_devtype);
static struct platform_driver max77620_thermal_driver = { static struct platform_driver max77620_thermal_driver = {
.driver = { .driver = {
......
...@@ -200,7 +200,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -200,7 +200,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
struct qpnp_tm_chip *chip; struct qpnp_tm_chip *chip;
struct device_node *node; struct device_node *node;
u8 type, subtype; u8 type, subtype;
u32 res[2]; u32 res;
int ret, irq; int ret, irq;
node = pdev->dev.of_node; node = pdev->dev.of_node;
...@@ -215,7 +215,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -215,7 +215,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
if (!chip->map) if (!chip->map)
return -ENXIO; return -ENXIO;
ret = of_property_read_u32_array(node, "reg", res, 2); ret = of_property_read_u32(node, "reg", &res);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -228,7 +228,7 @@ static int qpnp_tm_probe(struct platform_device *pdev) ...@@ -228,7 +228,7 @@ static int qpnp_tm_probe(struct platform_device *pdev)
if (PTR_ERR(chip->adc) == -EPROBE_DEFER) if (PTR_ERR(chip->adc) == -EPROBE_DEFER)
return PTR_ERR(chip->adc); return PTR_ERR(chip->adc);
chip->base = res[0]; chip->base = res;
ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type); ret = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, &type);
if (ret < 0) { if (ret < 0) {
......
...@@ -524,11 +524,6 @@ static void rk_tsadcv2_initialize(struct regmap *grf, void __iomem *regs, ...@@ -524,11 +524,6 @@ static void rk_tsadcv2_initialize(struct regmap *grf, void __iomem *regs,
regs + TSADCV2_AUTO_PERIOD_HT); regs + TSADCV2_AUTO_PERIOD_HT);
writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT,
regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE); regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE);
if (IS_ERR(grf)) {
pr_warn("%s: Missing rockchip,grf property\n", __func__);
return;
}
} }
/** /**
...@@ -971,6 +966,8 @@ static int rockchip_configure_from_dt(struct device *dev, ...@@ -971,6 +966,8 @@ static int rockchip_configure_from_dt(struct device *dev,
* need this property. * need this property.
*/ */
thermal->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); thermal->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(thermal->grf))
dev_warn(dev, "Missing rockchip,grf property\n");
return 0; return 0;
} }
......
...@@ -107,6 +107,7 @@ static const struct of_device_id tango_sensor_ids[] = { ...@@ -107,6 +107,7 @@ static const struct of_device_id tango_sensor_ids[] = {
}, },
{ /* sentinel */ } { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, tango_sensor_ids);
static struct platform_driver tango_thermal_driver = { static struct platform_driver tango_thermal_driver = {
.probe = tango_thermal_probe, .probe = tango_thermal_probe,
......
此差异已折叠。
...@@ -54,8 +54,34 @@ struct thermal_instance { ...@@ -54,8 +54,34 @@ struct thermal_instance {
unsigned int weight; /* The weight of the cooling device */ unsigned int weight; /* The weight of the cooling device */
}; };
#define to_thermal_zone(_dev) \
container_of(_dev, struct thermal_zone_device, device)
#define to_cooling_device(_dev) \
container_of(_dev, struct thermal_cooling_device, device)
int thermal_register_governor(struct thermal_governor *); int thermal_register_governor(struct thermal_governor *);
void thermal_unregister_governor(struct thermal_governor *); void thermal_unregister_governor(struct thermal_governor *);
void thermal_zone_device_rebind_exception(struct thermal_zone_device *,
const char *, size_t);
void thermal_zone_device_unbind_exception(struct thermal_zone_device *,
const char *, size_t);
int thermal_zone_device_set_policy(struct thermal_zone_device *, char *);
int thermal_build_list_of_policies(char *buf);
/* sysfs I/F */
int thermal_zone_create_device_groups(struct thermal_zone_device *, int);
void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *);
/* used only at binding time */
ssize_t
thermal_cooling_device_trip_point_show(struct device *,
struct device_attribute *, char *);
ssize_t thermal_cooling_device_weight_show(struct device *,
struct device_attribute *, char *);
ssize_t thermal_cooling_device_weight_store(struct device *,
struct device_attribute *,
const char *, size_t);
#ifdef CONFIG_THERMAL_GOV_STEP_WISE #ifdef CONFIG_THERMAL_GOV_STEP_WISE
int thermal_gov_step_wise_register(void); int thermal_gov_step_wise_register(void);
......
/*
* thermal_helpers.c - helper functions to handle thermal devices
*
* Copyright (C) 2016 Eduardo Valentin <edubezval@gmail.com>
*
* Highly based on original thermal_core.c
* Copyright (C) 2008 Intel Corp
* Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
* Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <trace/events/thermal.h>
#include "thermal_core.h"
int get_tz_trend(struct thermal_zone_device *tz, int trip)
{
enum thermal_trend 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)
trend = THERMAL_TREND_DROPPING;
else
trend = THERMAL_TREND_STABLE;
}
return trend;
}
EXPORT_SYMBOL(get_tz_trend);
struct thermal_instance *
get_thermal_instance(struct thermal_zone_device *tz,
struct thermal_cooling_device *cdev, int trip)
{
struct thermal_instance *pos = NULL;
struct thermal_instance *target_instance = NULL;
mutex_lock(&tz->lock);
mutex_lock(&cdev->lock);
list_for_each_entry(pos, &tz->thermal_instances, tz_node) {
if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
target_instance = pos;
break;
}
}
mutex_unlock(&cdev->lock);
mutex_unlock(&tz->lock);
return target_instance;
}
EXPORT_SYMBOL(get_thermal_instance);
/**
* thermal_zone_get_temp() - returns the temperature of a thermal zone
* @tz: a valid pointer to a struct thermal_zone_device
* @temp: a valid pointer to where to store the resulting temperature.
*
* When a valid thermal zone reference is passed, it will fetch its
* temperature and fill @temp.
*
* Return: On success returns 0, an error code otherwise
*/
int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp)
{
int ret = -EINVAL;
int count;
int crit_temp = INT_MAX;
enum thermal_trip_type type;
if (!tz || IS_ERR(tz) || !tz->ops->get_temp)
goto exit;
mutex_lock(&tz->lock);
ret = tz->ops->get_temp(tz, temp);
if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) {
for (count = 0; count < tz->trips; count++) {
ret = tz->ops->get_trip_type(tz, count, &type);
if (!ret && type == THERMAL_TRIP_CRITICAL) {
ret = tz->ops->get_trip_temp(tz, count,
&crit_temp);
break;
}
}
/*
* Only allow emulating a temperature when the real temperature
* is below the critical temperature so that the emulation code
* cannot hide critical conditions.
*/
if (!ret && *temp < crit_temp)
*temp = tz->emul_temperature;
}
mutex_unlock(&tz->lock);
exit:
return ret;
}
EXPORT_SYMBOL_GPL(thermal_zone_get_temp);
void thermal_zone_set_trips(struct thermal_zone_device *tz)
{
int low = -INT_MAX;
int high = INT_MAX;
int trip_temp, hysteresis;
int i, ret;
mutex_lock(&tz->lock);
if (!tz->ops->set_trips || !tz->ops->get_trip_hyst)
goto exit;
for (i = 0; i < tz->trips; i++) {
int trip_low;
tz->ops->get_trip_temp(tz, i, &trip_temp);
tz->ops->get_trip_hyst(tz, i, &hysteresis);
trip_low = trip_temp - hysteresis;
if (trip_low < tz->temperature && trip_low > low)
low = trip_low;
if (trip_temp > tz->temperature && trip_temp < high)
high = trip_temp;
}
/* No need to change trip points */
if (tz->prev_low_trip == low && tz->prev_high_trip == high)
goto exit;
tz->prev_low_trip = low;
tz->prev_high_trip = high;
dev_dbg(&tz->device,
"new temperature boundaries: %d < x < %d\n", low, high);
/*
* 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);
if (ret)
dev_err(&tz->device, "Failed to set trips: %d\n", ret);
exit:
mutex_unlock(&tz->lock);
}
EXPORT_SYMBOL_GPL(thermal_zone_set_trips);
void thermal_cdev_update(struct thermal_cooling_device *cdev)
{
struct thermal_instance *instance;
unsigned long target = 0;
mutex_lock(&cdev->lock);
/* cooling device is updated*/
if (cdev->updated) {
mutex_unlock(&cdev->lock);
return;
}
/* Make sure cdev enters the deepest cooling state */
list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
dev_dbg(&cdev->device, "zone%d->target=%lu\n",
instance->tz->id, instance->target);
if (instance->target == THERMAL_NO_TARGET)
continue;
if (instance->target > target)
target = instance->target;
}
cdev->ops->set_cur_state(cdev, target);
cdev->updated = true;
mutex_unlock(&cdev->lock);
trace_cdev_update(cdev, target);
dev_dbg(&cdev->device, "set to state %lu\n", target);
}
EXPORT_SYMBOL(thermal_cdev_update);
/**
* thermal_zone_get_slope - return the slope attribute of the thermal zone
* @tz: thermal zone device with the slope attribute
*
* Return: If the thermal zone device has a slope attribute, return it, else
* return 1.
*/
int thermal_zone_get_slope(struct thermal_zone_device *tz)
{
if (tz && tz->tzp)
return tz->tzp->slope;
return 1;
}
EXPORT_SYMBOL_GPL(thermal_zone_get_slope);
/**
* thermal_zone_get_offset - return the offset attribute of the thermal zone
* @tz: thermal zone device with the offset attribute
*
* Return: If the thermal zone device has a offset attribute, return it, else
* return 0.
*/
int thermal_zone_get_offset(struct thermal_zone_device *tz)
{
if (tz && tz->tzp)
return tz->tzp->offset;
return 0;
}
EXPORT_SYMBOL_GPL(thermal_zone_get_offset);
...@@ -64,7 +64,7 @@ name_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -64,7 +64,7 @@ name_show(struct device *dev, struct device_attribute *attr, char *buf)
struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev); struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", hwmon->type); return sprintf(buf, "%s\n", hwmon->type);
} }
static DEVICE_ATTR(name, 0444, name_show, NULL); static DEVICE_ATTR_RO(name);
static ssize_t static ssize_t
temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
...@@ -98,7 +98,7 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -98,7 +98,7 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf)
int temperature; int temperature;
int ret; int ret;
ret = tz->ops->get_trip_temp(tz, 0, &temperature); ret = tz->ops->get_crit_temp(tz, &temperature);
if (ret) if (ret)
return ret; return ret;
......
此差异已折叠。
...@@ -1298,7 +1298,7 @@ int ti_bandgap_probe(struct platform_device *pdev) ...@@ -1298,7 +1298,7 @@ int ti_bandgap_probe(struct platform_device *pdev)
if (IS_ERR(bgp->div_clk)) { if (IS_ERR(bgp->div_clk)) {
dev_err(&pdev->dev, "failed to request div_ts_ck clock ref\n"); dev_err(&pdev->dev, "failed to request div_ts_ck clock ref\n");
ret = PTR_ERR(bgp->div_clk); ret = PTR_ERR(bgp->div_clk);
goto free_irqs; goto put_fclock;
} }
for (i = 0; i < bgp->conf->sensor_count; i++) { for (i = 0; i < bgp->conf->sensor_count; i++) {
...@@ -1430,8 +1430,9 @@ int ti_bandgap_probe(struct platform_device *pdev) ...@@ -1430,8 +1430,9 @@ int ti_bandgap_probe(struct platform_device *pdev)
if (TI_BANDGAP_HAS(bgp, CLK_CTRL)) if (TI_BANDGAP_HAS(bgp, CLK_CTRL))
clk_disable_unprepare(bgp->fclock); clk_disable_unprepare(bgp->fclock);
put_clks: put_clks:
clk_put(bgp->fclock);
clk_put(bgp->div_clk); clk_put(bgp->div_clk);
put_fclock:
clk_put(bgp->fclock);
free_irqs: free_irqs:
if (TI_BANDGAP_HAS(bgp, TSHUT)) { if (TI_BANDGAP_HAS(bgp, TSHUT)) {
free_irq(gpio_to_irq(bgp->tshut_gpio), NULL); free_irq(gpio_to_irq(bgp->tshut_gpio), NULL);
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/devfreq.h> #include <linux/devfreq.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#ifdef CONFIG_DEVFREQ_THERMAL
/** /**
* struct devfreq_cooling_power - Devfreq cooling power ops * struct devfreq_cooling_power - Devfreq cooling power ops
...@@ -37,12 +36,16 @@ ...@@ -37,12 +36,16 @@
* @dyn_power_coeff * frequency * voltage^2 * @dyn_power_coeff * frequency * voltage^2
*/ */
struct devfreq_cooling_power { struct devfreq_cooling_power {
unsigned long (*get_static_power)(unsigned long voltage); unsigned long (*get_static_power)(struct devfreq *devfreq,
unsigned long (*get_dynamic_power)(unsigned long freq, unsigned long voltage);
unsigned long (*get_dynamic_power)(struct devfreq *devfreq,
unsigned long freq,
unsigned long voltage); unsigned long voltage);
unsigned long dyn_power_coeff; unsigned long dyn_power_coeff;
}; };
#ifdef CONFIG_DEVFREQ_THERMAL
struct thermal_cooling_device * struct thermal_cooling_device *
of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df,
struct devfreq_cooling_power *dfc_power); struct devfreq_cooling_power *dfc_power);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <uapi/linux/thermal.h> #include <uapi/linux/thermal.h>
...@@ -204,6 +205,7 @@ struct thermal_zone_device { ...@@ -204,6 +205,7 @@ struct thermal_zone_device {
int id; int id;
char type[THERMAL_NAME_LENGTH]; char type[THERMAL_NAME_LENGTH];
struct device device; struct device device;
struct attribute_group trips_attribute_group;
struct thermal_attr *trip_temp_attrs; struct thermal_attr *trip_temp_attrs;
struct thermal_attr *trip_type_attrs; struct thermal_attr *trip_type_attrs;
struct thermal_attr *trip_hyst_attrs; struct thermal_attr *trip_hyst_attrs;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册