Commit 0f84d1d1 authored by Zhang Rui's avatar Zhang Rui

Merge branches 'thermal-core', 'thermal-intel' and 'thermal-soc' into for-5.4

...@@ -23,6 +23,7 @@ Required properties: ...@@ -23,6 +23,7 @@ Required properties:
Optional property: Optional property:
- little-endian : If present, the TMU registers are little endian. If absent, - little-endian : If present, the TMU registers are little endian. If absent,
the default is big endian. the default is big endian.
- clocks : the clock for clocking the TMU silicon.
Example: Example:
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#define CONTROL0_TSEN_MODE_EXTERNAL 0x2 #define CONTROL0_TSEN_MODE_EXTERNAL 0x2
#define CONTROL0_TSEN_MODE_MASK 0x3 #define CONTROL0_TSEN_MODE_MASK 0x3
#define CONTROL1_TSEN_AVG_SHIFT 0
#define CONTROL1_TSEN_AVG_MASK 0x7 #define CONTROL1_TSEN_AVG_MASK 0x7
#define CONTROL1_EXT_TSEN_SW_RESET BIT(7) #define CONTROL1_EXT_TSEN_SW_RESET BIT(7)
#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8) #define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)
...@@ -267,8 +266,8 @@ static void armada_cp110_init(struct platform_device *pdev, ...@@ -267,8 +266,8 @@ static void armada_cp110_init(struct platform_device *pdev,
/* Average the output value over 2^1 = 2 samples */ /* Average the output value over 2^1 = 2 samples */
regmap_read(priv->syscon, data->syscon_control1_off, &reg); regmap_read(priv->syscon, data->syscon_control1_off, &reg);
reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT; reg &= ~CONTROL1_TSEN_AVG_MASK;
reg |= 1 << CONTROL1_TSEN_AVG_SHIFT; reg |= 1;
regmap_write(priv->syscon, data->syscon_control1_off, reg); regmap_write(priv->syscon, data->syscon_control1_off, reg);
} }
......
...@@ -77,9 +77,6 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, ...@@ -77,9 +77,6 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
struct acpi_buffer element = { 0, NULL }; struct acpi_buffer element = { 0, NULL };
struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" };
if (!acpi_has_method(handle, "_TRT"))
return -ENODEV;
status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
...@@ -158,9 +155,6 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, ...@@ -158,9 +155,6 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
struct acpi_buffer art_format = { struct acpi_buffer art_format = {
sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" };
if (!acpi_has_method(handle, "_ART"))
return -ENODEV;
status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); status = acpi_evaluate_object(handle, "_ART", NULL, &buffer);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
......
...@@ -181,7 +181,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) ...@@ -181,7 +181,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
p = buf.pointer; p = buf.pointer;
if (!p || (p->type != ACPI_TYPE_PACKAGE)) { if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
printk(KERN_WARNING "Invalid PPSS data\n"); pr_warn("Invalid PPSS data\n");
kfree(buf.pointer); kfree(buf.pointer);
return -EFAULT; return -EFAULT;
} }
......
...@@ -39,6 +39,9 @@ ...@@ -39,6 +39,9 @@
/* GeminiLake thermal reporting device */ /* GeminiLake thermal reporting device */
#define PCI_DEVICE_ID_PROC_GLK_THERMAL 0x318C #define PCI_DEVICE_ID_PROC_GLK_THERMAL 0x318C
/* IceLake thermal reporting device */
#define PCI_DEVICE_ID_PROC_ICL_THERMAL 0x8a03
#define DRV_NAME "proc_thermal" #define DRV_NAME "proc_thermal"
struct power_config { struct power_config {
...@@ -137,6 +140,72 @@ static const struct attribute_group power_limit_attribute_group = { ...@@ -137,6 +140,72 @@ static const struct attribute_group power_limit_attribute_group = {
.name = "power_limits" .name = "power_limits"
}; };
static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
u64 val;
int err;
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
if (err)
return err;
val = (val >> 24) & 0xff;
return sprintf(buf, "%d\n", (int)val);
}
static int tcc_offset_update(int tcc)
{
u64 val;
int err;
if (!tcc)
return -EINVAL;
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
if (err)
return err;
val &= ~GENMASK_ULL(31, 24);
val |= (tcc & 0xff) << 24;
err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
if (err)
return err;
return 0;
}
static int tcc_offset_save;
static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
u64 val;
int tcc, err;
err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
if (err)
return err;
if (!(val & BIT(30)))
return -EACCES;
if (kstrtoint(buf, 0, &tcc))
return -EINVAL;
err = tcc_offset_update(tcc);
if (err)
return err;
tcc_offset_save = tcc;
return count;
}
static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
static int stored_tjmax; /* since it is fixed, we can have local storage */ static int stored_tjmax; /* since it is fixed, we can have local storage */
static int get_tjmax(void) static int get_tjmax(void)
...@@ -332,6 +401,7 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv) ...@@ -332,6 +401,7 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
acpi_remove_notify_handler(proc_priv->adev->handle, acpi_remove_notify_handler(proc_priv->adev->handle,
ACPI_DEVICE_NOTIFY, proc_thermal_notify); ACPI_DEVICE_NOTIFY, proc_thermal_notify);
int340x_thermal_zone_remove(proc_priv->int340x_zone); int340x_thermal_zone_remove(proc_priv->int340x_zone);
sysfs_remove_file(&proc_priv->dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
sysfs_remove_group(&proc_priv->dev->kobj, sysfs_remove_group(&proc_priv->dev->kobj,
&power_limit_attribute_group); &power_limit_attribute_group);
} }
...@@ -355,8 +425,15 @@ static int int3401_add(struct platform_device *pdev) ...@@ -355,8 +425,15 @@ static int int3401_add(struct platform_device *pdev)
dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n"); dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
return sysfs_create_group(&pdev->dev.kobj, ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
&power_limit_attribute_group); if (ret)
return ret;
ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
if (ret)
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
return ret;
} }
static int int3401_remove(struct platform_device *pdev) static int int3401_remove(struct platform_device *pdev)
...@@ -588,8 +665,15 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, ...@@ -588,8 +665,15 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n"); dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
return sysfs_create_group(&pdev->dev.kobj, ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
&power_limit_attribute_group); if (ret)
return ret;
ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
if (ret)
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
return ret;
} }
static void proc_thermal_pci_remove(struct pci_dev *pdev) static void proc_thermal_pci_remove(struct pci_dev *pdev)
...@@ -615,6 +699,8 @@ static int proc_thermal_resume(struct device *dev) ...@@ -615,6 +699,8 @@ static int proc_thermal_resume(struct device *dev)
proc_dev = dev_get_drvdata(dev); proc_dev = dev_get_drvdata(dev);
proc_thermal_read_ppcc(proc_dev); proc_thermal_read_ppcc(proc_dev);
tcc_offset_update(tcc_offset_save);
return 0; return 0;
} }
#else #else
...@@ -636,6 +722,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = { ...@@ -636,6 +722,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)}, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)},
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)}, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)},
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_GLK_THERMAL)}, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_GLK_THERMAL)},
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_ICL_THERMAL),
.driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
{ 0, }, { 0, },
}; };
......
...@@ -371,16 +371,14 @@ static void intel_pch_thermal_remove(struct pci_dev *pdev) ...@@ -371,16 +371,14 @@ static void intel_pch_thermal_remove(struct pci_dev *pdev)
static int intel_pch_thermal_suspend(struct device *device) static int intel_pch_thermal_suspend(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pch_thermal_device *ptd = dev_get_drvdata(device);
struct pch_thermal_device *ptd = pci_get_drvdata(pdev);
return ptd->ops->suspend(ptd); return ptd->ops->suspend(ptd);
} }
static int intel_pch_thermal_resume(struct device *device) static int intel_pch_thermal_resume(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pch_thermal_device *ptd = dev_get_drvdata(device);
struct pch_thermal_device *ptd = pci_get_drvdata(pdev);
return ptd->ops->resume(ptd); return ptd->ops->resume(ptd);
} }
......
...@@ -229,6 +229,8 @@ static int calibrate_8960(struct tsens_priv *priv) ...@@ -229,6 +229,8 @@ static int calibrate_8960(struct tsens_priv *priv)
for (i = 0; i < num_read; i++, s++) for (i = 0; i < num_read; i++, s++)
s->offset = data[i]; s->offset = data[i];
kfree(data);
return 0; return 0;
} }
......
...@@ -145,8 +145,10 @@ static int calibrate_8916(struct tsens_priv *priv) ...@@ -145,8 +145,10 @@ static int calibrate_8916(struct tsens_priv *priv)
return PTR_ERR(qfprom_cdata); return PTR_ERR(qfprom_cdata);
qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel"); qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel");
if (IS_ERR(qfprom_csel)) if (IS_ERR(qfprom_csel)) {
kfree(qfprom_cdata);
return PTR_ERR(qfprom_csel); return PTR_ERR(qfprom_csel);
}
mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT; mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT;
dev_dbg(priv->dev, "calibration mode is %d\n", mode); dev_dbg(priv->dev, "calibration mode is %d\n", mode);
...@@ -181,6 +183,8 @@ static int calibrate_8916(struct tsens_priv *priv) ...@@ -181,6 +183,8 @@ static int calibrate_8916(struct tsens_priv *priv)
} }
compute_intercept_slope(priv, p1, p2, mode); compute_intercept_slope(priv, p1, p2, mode);
kfree(qfprom_cdata);
kfree(qfprom_csel);
return 0; return 0;
} }
...@@ -198,8 +202,10 @@ static int calibrate_8974(struct tsens_priv *priv) ...@@ -198,8 +202,10 @@ static int calibrate_8974(struct tsens_priv *priv)
return PTR_ERR(calib); return PTR_ERR(calib);
bkp = (u32 *)qfprom_read(priv->dev, "calib_backup"); bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
if (IS_ERR(bkp)) if (IS_ERR(bkp)) {
kfree(calib);
return PTR_ERR(bkp); return PTR_ERR(bkp);
}
calib_redun_sel = bkp[1] & BKP_REDUN_SEL; calib_redun_sel = bkp[1] & BKP_REDUN_SEL;
calib_redun_sel >>= BKP_REDUN_SHIFT; calib_redun_sel >>= BKP_REDUN_SHIFT;
...@@ -313,6 +319,8 @@ static int calibrate_8974(struct tsens_priv *priv) ...@@ -313,6 +319,8 @@ static int calibrate_8974(struct tsens_priv *priv)
} }
compute_intercept_slope(priv, p1, p2, mode); compute_intercept_slope(priv, p1, p2, mode);
kfree(calib);
kfree(bkp);
return 0; return 0;
} }
......
...@@ -138,6 +138,7 @@ static int calibrate_v1(struct tsens_priv *priv) ...@@ -138,6 +138,7 @@ static int calibrate_v1(struct tsens_priv *priv)
} }
compute_intercept_slope(priv, p1, p2, mode); compute_intercept_slope(priv, p1, p2, mode);
kfree(qfprom_cdata);
return 0; return 0;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/thermal.h> #include <linux/thermal.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h>
struct tsens_priv; struct tsens_priv;
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// //
// Copyright 2016 Freescale Semiconductor, Inc. // Copyright 2016 Freescale Semiconductor, Inc.
#include <linux/clk.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -72,6 +73,7 @@ struct qoriq_sensor { ...@@ -72,6 +73,7 @@ struct qoriq_sensor {
struct qoriq_tmu_data { struct qoriq_tmu_data {
struct qoriq_tmu_regs __iomem *regs; struct qoriq_tmu_regs __iomem *regs;
struct clk *clk;
bool little_endian; bool little_endian;
struct qoriq_sensor *sensor[SITES_MAX]; struct qoriq_sensor *sensor[SITES_MAX];
}; };
...@@ -202,32 +204,39 @@ static int qoriq_tmu_probe(struct platform_device *pdev) ...@@ -202,32 +204,39 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
data->little_endian = of_property_read_bool(np, "little-endian"); data->little_endian = of_property_read_bool(np, "little-endian");
data->regs = of_iomap(np, 0); data->regs = devm_platform_ioremap_resource(pdev, 0);
if (!data->regs) { if (IS_ERR(data->regs)) {
dev_err(&pdev->dev, "Failed to get memory region\n"); dev_err(&pdev->dev, "Failed to get memory region\n");
ret = -ENODEV; return PTR_ERR(data->regs);
goto err_iomap; }
data->clk = devm_clk_get_optional(&pdev->dev, NULL);
if (IS_ERR(data->clk))
return PTR_ERR(data->clk);
ret = clk_prepare_enable(data->clk);
if (ret) {
dev_err(&pdev->dev, "Failed to enable clock\n");
return ret;
} }
qoriq_tmu_init_device(data); /* TMU initialization */ qoriq_tmu_init_device(data); /* TMU initialization */
ret = qoriq_tmu_calibration(pdev); /* TMU calibration */ ret = qoriq_tmu_calibration(pdev); /* TMU calibration */
if (ret < 0) if (ret < 0)
goto err_tmu; goto err;
ret = qoriq_tmu_register_tmu_zone(pdev); ret = qoriq_tmu_register_tmu_zone(pdev);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "Failed to register sensors\n"); dev_err(&pdev->dev, "Failed to register sensors\n");
ret = -ENODEV; ret = -ENODEV;
goto err_iomap; goto err;
} }
return 0; return 0;
err_tmu: err:
iounmap(data->regs); clk_disable_unprepare(data->clk);
err_iomap:
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return ret; return ret;
...@@ -240,14 +249,14 @@ static int qoriq_tmu_remove(struct platform_device *pdev) ...@@ -240,14 +249,14 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
/* Disable monitoring */ /* Disable monitoring */
tmu_write(data, TMR_DISABLE, &data->regs->tmr); tmu_write(data, TMR_DISABLE, &data->regs->tmr);
iounmap(data->regs); clk_disable_unprepare(data->clk);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
static int qoriq_tmu_suspend(struct device *dev)
{ {
u32 tmr; u32 tmr;
struct qoriq_tmu_data *data = dev_get_drvdata(dev); struct qoriq_tmu_data *data = dev_get_drvdata(dev);
...@@ -257,14 +266,21 @@ static int qoriq_tmu_suspend(struct device *dev) ...@@ -257,14 +266,21 @@ static int qoriq_tmu_suspend(struct device *dev)
tmr &= ~TMR_ME; tmr &= ~TMR_ME;
tmu_write(data, tmr, &data->regs->tmr); tmu_write(data, tmr, &data->regs->tmr);
clk_disable_unprepare(data->clk);
return 0; return 0;
} }
static int qoriq_tmu_resume(struct device *dev) static int __maybe_unused qoriq_tmu_resume(struct device *dev)
{ {
u32 tmr; u32 tmr;
int ret;
struct qoriq_tmu_data *data = dev_get_drvdata(dev); struct qoriq_tmu_data *data = dev_get_drvdata(dev);
ret = clk_prepare_enable(data->clk);
if (ret)
return ret;
/* Enable monitoring */ /* Enable monitoring */
tmr = tmu_read(data, &data->regs->tmr); tmr = tmu_read(data, &data->regs->tmr);
tmr |= TMR_ME; tmr |= TMR_ME;
...@@ -272,7 +288,6 @@ static int qoriq_tmu_resume(struct device *dev) ...@@ -272,7 +288,6 @@ static int qoriq_tmu_resume(struct device *dev)
return 0; return 0;
} }
#endif
static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops, static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
qoriq_tmu_suspend, qoriq_tmu_resume); qoriq_tmu_suspend, qoriq_tmu_resume);
......
...@@ -443,9 +443,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev) ...@@ -443,9 +443,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
if (ret) if (ret)
goto error_unregister; goto error_unregister;
ret = devm_add_action(dev, rcar_gen3_hwmon_action, zone); ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone);
if (ret) { if (ret) {
rcar_gen3_hwmon_action(zone);
goto error_unregister; goto error_unregister;
} }
......
...@@ -202,7 +202,7 @@ ...@@ -202,7 +202,7 @@
/* get dividend from the depth */ /* get dividend from the depth */
#define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1) #define THROT_DEPTH_DIVIDEND(depth) ((256 * (100 - (depth)) / 100) - 1)
/* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-sochterm.h /* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-soctherm.h
* level vector * level vector
* NONE 3'b000 * NONE 3'b000
* LOW 3'b001 * LOW 3'b001
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment