Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management updates from Zhang Rui: "There are not too many changes this time, except two new platform thermal drivers, ti-soc-thermal driver and x86_pkg_temp_thermal driver, and a couple of small fixes. Highlights: - move the ti-soc-thermal driver out of the staging tree to the thermal tree. - introduce the x86_pkg_temp_thermal driver. This driver registers CPU digital temperature package level sensor as a thermal zone. - small fixes/cleanups including removing redundant use of platform_set_drvdata() and of_match_ptr for all platform thermal drivers" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: (34 commits) thermal: cpu_cooling: fix stub function thermal: ti-soc-thermal: use standard GPIO DT bindings thermal: MAINTAINERS: Add git tree path for SoC specific updates thermal: fix x86_pkg_temp_thermal.c build and Kconfig Thermal: Documentation for x86 package temperature thermal driver Thermal: CPU Package temperature thermal thermal: consider emul_temperature while computing trend thermal: ti-soc-thermal: add DT example for DRA752 chip thermal: ti-soc-thermal: add dra752 chip to device table thermal: ti-soc-thermal: add thermal data for DRA752 chips thermal: ti-soc-thermal: remove usage of IS_ERR_OR_NULL thermal: ti-soc-thermal: freeze FSM while computing trend thermal: ti-soc-thermal: remove external heat while extrapolating hotspot thermal: ti-soc-thermal: update DT reference for OMAP5430 x86, mcheck, therm_throt: Process package thresholds thermal: cpu_cooling: fix 'descend' check in get_property() Thermal: spear: Remove redundant use of of_match_ptr Thermal: kirkwood: Remove redundant use of of_match_ptr Thermal: dove: Remove redundant use of of_match_ptr Thermal: armada: Remove redundant use of of_match_ptr ...
This commit is contained in:
commit
8cbd0eefca
|
@ -17,8 +17,9 @@ Required properties:
|
||||||
- interrupts : this entry should indicate which interrupt line
|
- interrupts : this entry should indicate which interrupt line
|
||||||
the talert signal is routed to;
|
the talert signal is routed to;
|
||||||
Specific:
|
Specific:
|
||||||
- ti,tshut-gpio : this entry should be used to inform which GPIO
|
- gpios : this entry should be used to inform which GPIO
|
||||||
line the tshut signal is routed to;
|
line the tshut signal is routed to. The informed GPIO will
|
||||||
|
be treated as an IRQ;
|
||||||
- regs : this entry must also be specified and it is specific
|
- regs : this entry must also be specified and it is specific
|
||||||
to each bandgap version, because the mapping may change from
|
to each bandgap version, because the mapping may change from
|
||||||
soc to soc, apart of depending on available features.
|
soc to soc, apart of depending on available features.
|
||||||
|
@ -37,7 +38,7 @@ bandgap {
|
||||||
0x4a002378 0x18>;
|
0x4a002378 0x18>;
|
||||||
compatible = "ti,omap4460-bandgap";
|
compatible = "ti,omap4460-bandgap";
|
||||||
interrupts = <0 126 4>; /* talert */
|
interrupts = <0 126 4>; /* talert */
|
||||||
ti,tshut-gpio = <86>;
|
gpios = <&gpio3 22 0>; /* tshut */
|
||||||
};
|
};
|
||||||
|
|
||||||
OMAP4470:
|
OMAP4470:
|
||||||
|
@ -47,7 +48,7 @@ bandgap {
|
||||||
0x4a002378 0x18>;
|
0x4a002378 0x18>;
|
||||||
compatible = "ti,omap4470-bandgap";
|
compatible = "ti,omap4470-bandgap";
|
||||||
interrupts = <0 126 4>; /* talert */
|
interrupts = <0 126 4>; /* talert */
|
||||||
ti,tshut-gpio = <86>;
|
gpios = <&gpio3 22 0>; /* tshut */
|
||||||
};
|
};
|
||||||
|
|
||||||
OMAP5430:
|
OMAP5430:
|
||||||
|
@ -59,3 +60,15 @@ bandgap {
|
||||||
compatible = "ti,omap5430-bandgap";
|
compatible = "ti,omap5430-bandgap";
|
||||||
interrupts = <0 126 4>; /* talert */
|
interrupts = <0 126 4>; /* talert */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DRA752:
|
||||||
|
bandgap {
|
||||||
|
reg = <0x4a0021e0 0xc
|
||||||
|
0x4a00232c 0xc
|
||||||
|
0x4a002380 0x2c
|
||||||
|
0x4a0023C0 0x3c
|
||||||
|
0x4a002564 0x8
|
||||||
|
0x4a002574 0x50>;
|
||||||
|
compatible = "ti,dra752-bandgap";
|
||||||
|
interrupts = <0 126 4>; /* talert */
|
||||||
|
};
|
|
@ -0,0 +1,47 @@
|
||||||
|
Kernel driver: x86_pkg_temp_thermal
|
||||||
|
===================
|
||||||
|
|
||||||
|
Supported chips:
|
||||||
|
* x86: with package level thermal management
|
||||||
|
(Verify using: CPUID.06H:EAX[bit 6] =1)
|
||||||
|
|
||||||
|
Authors: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||||
|
|
||||||
|
Reference
|
||||||
|
---
|
||||||
|
Intel® 64 and IA-32 Architectures Software Developer’s Manual (Jan, 2013):
|
||||||
|
Chapter 14.6: PACKAGE LEVEL THERMAL MANAGEMENT
|
||||||
|
|
||||||
|
Description
|
||||||
|
---------
|
||||||
|
|
||||||
|
This driver register CPU digital temperature package level sensor as a thermal
|
||||||
|
zone with maximum two user mode configurable trip points. Number of trip points
|
||||||
|
depends on the capability of the package. Once the trip point is violated,
|
||||||
|
user mode can receive notification via thermal notification mechanism and can
|
||||||
|
take any action to control temperature.
|
||||||
|
|
||||||
|
|
||||||
|
Threshold management
|
||||||
|
--------------------
|
||||||
|
Each package will register as a thermal zone under /sys/class/thermal.
|
||||||
|
Example:
|
||||||
|
/sys/class/thermal/thermal_zone1
|
||||||
|
|
||||||
|
This contains two trip points:
|
||||||
|
- trip_point_0_temp
|
||||||
|
- trip_point_1_temp
|
||||||
|
|
||||||
|
User can set any temperature between 0 to TJ-Max temperature. Temperature units
|
||||||
|
are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.txt" for
|
||||||
|
thermal sys-fs details.
|
||||||
|
|
||||||
|
Any value other than 0 in these trip points, can trigger thermal notifications.
|
||||||
|
Setting 0, stops sending thermal notifications.
|
||||||
|
|
||||||
|
Thermal notifications: To get kobject-uevent notifications, set the thermal zone
|
||||||
|
policy to "user_space". For example: echo -n "user_space" > policy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8159,6 +8159,7 @@ M: Zhang Rui <rui.zhang@intel.com>
|
||||||
M: Eduardo Valentin <eduardo.valentin@ti.com>
|
M: Eduardo Valentin <eduardo.valentin@ti.com>
|
||||||
L: linux-pm@vger.kernel.org
|
L: linux-pm@vger.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
|
||||||
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git
|
||||||
Q: https://patchwork.kernel.org/project/linux-pm/list/
|
Q: https://patchwork.kernel.org/project/linux-pm/list/
|
||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/thermal/
|
F: drivers/thermal/
|
||||||
|
@ -8183,8 +8184,8 @@ F: drivers/platform/x86/thinkpad_acpi.c
|
||||||
TI BANDGAP AND THERMAL DRIVER
|
TI BANDGAP AND THERMAL DRIVER
|
||||||
M: Eduardo Valentin <eduardo.valentin@ti.com>
|
M: Eduardo Valentin <eduardo.valentin@ti.com>
|
||||||
L: linux-pm@vger.kernel.org
|
L: linux-pm@vger.kernel.org
|
||||||
S: Maintained
|
S: Supported
|
||||||
F: drivers/staging/omap-thermal/
|
F: drivers/thermal/ti-soc-thermal/
|
||||||
|
|
||||||
TI FLASH MEDIA INTERFACE DRIVER
|
TI FLASH MEDIA INTERFACE DRIVER
|
||||||
M: Alex Dubov <oakad@yahoo.com>
|
M: Alex Dubov <oakad@yahoo.com>
|
||||||
|
|
|
@ -214,6 +214,13 @@ void mce_log_therm_throt_event(__u64 status);
|
||||||
/* Interrupt Handler for core thermal thresholds */
|
/* Interrupt Handler for core thermal thresholds */
|
||||||
extern int (*platform_thermal_notify)(__u64 msr_val);
|
extern int (*platform_thermal_notify)(__u64 msr_val);
|
||||||
|
|
||||||
|
/* Interrupt Handler for package thermal thresholds */
|
||||||
|
extern int (*platform_thermal_package_notify)(__u64 msr_val);
|
||||||
|
|
||||||
|
/* Callback support of rate control, return true, if
|
||||||
|
* callback has rate control */
|
||||||
|
extern bool (*platform_thermal_package_rate_control)(void);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_THERMAL_VECTOR
|
#ifdef CONFIG_X86_THERMAL_VECTOR
|
||||||
extern void mcheck_intel_therm_init(void);
|
extern void mcheck_intel_therm_init(void);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -55,12 +55,24 @@ struct thermal_state {
|
||||||
struct _thermal_state package_power_limit;
|
struct _thermal_state package_power_limit;
|
||||||
struct _thermal_state core_thresh0;
|
struct _thermal_state core_thresh0;
|
||||||
struct _thermal_state core_thresh1;
|
struct _thermal_state core_thresh1;
|
||||||
|
struct _thermal_state pkg_thresh0;
|
||||||
|
struct _thermal_state pkg_thresh1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callback to handle core threshold interrupts */
|
/* Callback to handle core threshold interrupts */
|
||||||
int (*platform_thermal_notify)(__u64 msr_val);
|
int (*platform_thermal_notify)(__u64 msr_val);
|
||||||
EXPORT_SYMBOL(platform_thermal_notify);
|
EXPORT_SYMBOL(platform_thermal_notify);
|
||||||
|
|
||||||
|
/* Callback to handle core package threshold_interrupts */
|
||||||
|
int (*platform_thermal_package_notify)(__u64 msr_val);
|
||||||
|
EXPORT_SYMBOL_GPL(platform_thermal_package_notify);
|
||||||
|
|
||||||
|
/* Callback support of rate control, return true, if
|
||||||
|
* callback has rate control */
|
||||||
|
bool (*platform_thermal_package_rate_control)(void);
|
||||||
|
EXPORT_SYMBOL_GPL(platform_thermal_package_rate_control);
|
||||||
|
|
||||||
|
|
||||||
static DEFINE_PER_CPU(struct thermal_state, thermal_state);
|
static DEFINE_PER_CPU(struct thermal_state, thermal_state);
|
||||||
|
|
||||||
static atomic_t therm_throt_en = ATOMIC_INIT(0);
|
static atomic_t therm_throt_en = ATOMIC_INIT(0);
|
||||||
|
@ -195,19 +207,25 @@ static int therm_throt_process(bool new_event, int event, int level)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int thresh_event_valid(int event)
|
static int thresh_event_valid(int level, int event)
|
||||||
{
|
{
|
||||||
struct _thermal_state *state;
|
struct _thermal_state *state;
|
||||||
unsigned int this_cpu = smp_processor_id();
|
unsigned int this_cpu = smp_processor_id();
|
||||||
struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu);
|
struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu);
|
||||||
u64 now = get_jiffies_64();
|
u64 now = get_jiffies_64();
|
||||||
|
|
||||||
state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1;
|
if (level == PACKAGE_LEVEL)
|
||||||
|
state = (event == 0) ? &pstate->pkg_thresh0 :
|
||||||
|
&pstate->pkg_thresh1;
|
||||||
|
else
|
||||||
|
state = (event == 0) ? &pstate->core_thresh0 :
|
||||||
|
&pstate->core_thresh1;
|
||||||
|
|
||||||
if (time_before64(now, state->next_check))
|
if (time_before64(now, state->next_check))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
state->next_check = now + CHECK_INTERVAL;
|
state->next_check = now + CHECK_INTERVAL;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,6 +340,39 @@ device_initcall(thermal_throttle_init_device);
|
||||||
|
|
||||||
#endif /* CONFIG_SYSFS */
|
#endif /* CONFIG_SYSFS */
|
||||||
|
|
||||||
|
static void notify_package_thresholds(__u64 msr_val)
|
||||||
|
{
|
||||||
|
bool notify_thres_0 = false;
|
||||||
|
bool notify_thres_1 = false;
|
||||||
|
|
||||||
|
if (!platform_thermal_package_notify)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* lower threshold check */
|
||||||
|
if (msr_val & THERM_LOG_THRESHOLD0)
|
||||||
|
notify_thres_0 = true;
|
||||||
|
/* higher threshold check */
|
||||||
|
if (msr_val & THERM_LOG_THRESHOLD1)
|
||||||
|
notify_thres_1 = true;
|
||||||
|
|
||||||
|
if (!notify_thres_0 && !notify_thres_1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (platform_thermal_package_rate_control &&
|
||||||
|
platform_thermal_package_rate_control()) {
|
||||||
|
/* Rate control is implemented in callback */
|
||||||
|
platform_thermal_package_notify(msr_val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lower threshold reached */
|
||||||
|
if (notify_thres_0 && thresh_event_valid(PACKAGE_LEVEL, 0))
|
||||||
|
platform_thermal_package_notify(msr_val);
|
||||||
|
/* higher threshold reached */
|
||||||
|
if (notify_thres_1 && thresh_event_valid(PACKAGE_LEVEL, 1))
|
||||||
|
platform_thermal_package_notify(msr_val);
|
||||||
|
}
|
||||||
|
|
||||||
static void notify_thresholds(__u64 msr_val)
|
static void notify_thresholds(__u64 msr_val)
|
||||||
{
|
{
|
||||||
/* check whether the interrupt handler is defined;
|
/* check whether the interrupt handler is defined;
|
||||||
|
@ -331,10 +382,12 @@ static void notify_thresholds(__u64 msr_val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* lower threshold reached */
|
/* lower threshold reached */
|
||||||
if ((msr_val & THERM_LOG_THRESHOLD0) && thresh_event_valid(0))
|
if ((msr_val & THERM_LOG_THRESHOLD0) &&
|
||||||
|
thresh_event_valid(CORE_LEVEL, 0))
|
||||||
platform_thermal_notify(msr_val);
|
platform_thermal_notify(msr_val);
|
||||||
/* higher threshold reached */
|
/* higher threshold reached */
|
||||||
if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1))
|
if ((msr_val & THERM_LOG_THRESHOLD1) &&
|
||||||
|
thresh_event_valid(CORE_LEVEL, 1))
|
||||||
platform_thermal_notify(msr_val);
|
platform_thermal_notify(msr_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +413,8 @@ static void intel_thermal_interrupt(void)
|
||||||
|
|
||||||
if (this_cpu_has(X86_FEATURE_PTS)) {
|
if (this_cpu_has(X86_FEATURE_PTS)) {
|
||||||
rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
|
rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
|
||||||
|
/* check violations of package thermal thresholds */
|
||||||
|
notify_package_thresholds(msr_val);
|
||||||
therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
|
therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
|
||||||
THERMAL_THROTTLING_EVENT,
|
THERMAL_THROTTLING_EVENT,
|
||||||
PACKAGE_LEVEL);
|
PACKAGE_LEVEL);
|
||||||
|
|
|
@ -120,8 +120,6 @@ source "drivers/staging/gdm72xx/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/csr/Kconfig"
|
source "drivers/staging/csr/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/ti-soc-thermal/Kconfig"
|
|
||||||
|
|
||||||
source "drivers/staging/silicom/Kconfig"
|
source "drivers/staging/silicom/Kconfig"
|
||||||
|
|
||||||
source "drivers/staging/ced1401/Kconfig"
|
source "drivers/staging/ced1401/Kconfig"
|
||||||
|
|
|
@ -53,7 +53,6 @@ obj-$(CONFIG_ANDROID) += android/
|
||||||
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
|
obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/
|
||||||
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
|
obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/
|
||||||
obj-$(CONFIG_CSR_WIFI) += csr/
|
obj-$(CONFIG_CSR_WIFI) += csr/
|
||||||
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
|
|
||||||
obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
|
obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/
|
||||||
obj-$(CONFIG_CED1401) += ced1401/
|
obj-$(CONFIG_CED1401) += ced1401/
|
||||||
obj-$(CONFIG_DRM_IMX) += imx-drm/
|
obj-$(CONFIG_DRM_IMX) += imx-drm/
|
||||||
|
|
|
@ -169,4 +169,19 @@ config INTEL_POWERCLAMP
|
||||||
enforce idle time which results in more package C-state residency. The
|
enforce idle time which results in more package C-state residency. The
|
||||||
user interface is exposed via generic thermal framework.
|
user interface is exposed via generic thermal framework.
|
||||||
|
|
||||||
|
config X86_PKG_TEMP_THERMAL
|
||||||
|
tristate "X86 package temperature thermal driver"
|
||||||
|
depends on X86_THERMAL_VECTOR
|
||||||
|
select THERMAL_GOV_USER_SPACE
|
||||||
|
default m
|
||||||
|
help
|
||||||
|
Enable this to register CPU digital sensor for package temperature as
|
||||||
|
thermal zone. Each package will have its own thermal zone. There are
|
||||||
|
two trip points which can be set by user to get notifications via thermal
|
||||||
|
notification methods.
|
||||||
|
|
||||||
|
menu "Texas Instruments thermal drivers"
|
||||||
|
source "drivers/thermal/ti-soc-thermal/Kconfig"
|
||||||
|
endmenu
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -23,4 +23,5 @@ obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
|
||||||
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
|
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
|
||||||
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
|
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
|
||||||
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
|
||||||
|
obj-$(CONFIG_X86_PKG_TEMP_THERMAL) += x86_pkg_temp_thermal.o
|
||||||
|
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
|
||||||
|
|
|
@ -200,7 +200,6 @@ static int armada_thermal_exit(struct platform_device *pdev)
|
||||||
platform_get_drvdata(pdev);
|
platform_get_drvdata(pdev);
|
||||||
|
|
||||||
thermal_zone_device_unregister(armada_thermal);
|
thermal_zone_device_unregister(armada_thermal);
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +210,7 @@ static struct platform_driver armada_thermal_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "armada_thermal",
|
.name = "armada_thermal",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(armada_thermal_id_table),
|
.of_match_table = armada_thermal_id_table,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ static int get_property(unsigned int cpu, unsigned long input,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* get the frequency order */
|
/* get the frequency order */
|
||||||
if (freq != CPUFREQ_ENTRY_INVALID && descend != -1)
|
if (freq != CPUFREQ_ENTRY_INVALID && descend == -1)
|
||||||
descend = !!(freq > table[i].frequency);
|
descend = !!(freq > table[i].frequency);
|
||||||
|
|
||||||
freq = table[i].frequency;
|
freq = table[i].frequency;
|
||||||
|
|
|
@ -134,16 +134,11 @@ static int dove_thermal_probe(struct platform_device *pdev)
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
if (!res) {
|
|
||||||
dev_err(&pdev->dev, "Failed to get platform resource\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
|
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(priv->sensor))
|
if (IS_ERR(priv->sensor))
|
||||||
return PTR_ERR(priv->sensor);
|
return PTR_ERR(priv->sensor);
|
||||||
|
@ -178,7 +173,6 @@ static int dove_thermal_exit(struct platform_device *pdev)
|
||||||
platform_get_drvdata(pdev);
|
platform_get_drvdata(pdev);
|
||||||
|
|
||||||
thermal_zone_device_unregister(dove_thermal);
|
thermal_zone_device_unregister(dove_thermal);
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +185,7 @@ static struct platform_driver dove_thermal_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "dove_thermal",
|
.name = "dove_thermal",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(dove_thermal_id_table),
|
.of_match_table = dove_thermal_id_table,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -997,7 +997,6 @@ static int exynos_tmu_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_clk:
|
err_clk:
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
clk_unprepare(data->clk);
|
clk_unprepare(data->clk);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1012,8 +1011,6 @@ static int exynos_tmu_remove(struct platform_device *pdev)
|
||||||
|
|
||||||
clk_unprepare(data->clk);
|
clk_unprepare(data->clk);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,16 +75,11 @@ static int kirkwood_thermal_probe(struct platform_device *pdev)
|
||||||
struct kirkwood_thermal_priv *priv;
|
struct kirkwood_thermal_priv *priv;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
if (!res) {
|
|
||||||
dev_err(&pdev->dev, "Failed to get platform resource\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
|
priv->sensor = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(priv->sensor))
|
if (IS_ERR(priv->sensor))
|
||||||
return PTR_ERR(priv->sensor);
|
return PTR_ERR(priv->sensor);
|
||||||
|
@ -108,7 +103,6 @@ static int kirkwood_thermal_exit(struct platform_device *pdev)
|
||||||
platform_get_drvdata(pdev);
|
platform_get_drvdata(pdev);
|
||||||
|
|
||||||
thermal_zone_device_unregister(kirkwood_thermal);
|
thermal_zone_device_unregister(kirkwood_thermal);
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +115,7 @@ static struct platform_driver kirkwood_thermal_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "kirkwood_thermal",
|
.name = "kirkwood_thermal",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.of_match_table = of_match_ptr(kirkwood_thermal_id_table),
|
.of_match_table = kirkwood_thermal_id_table,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -389,11 +389,6 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
||||||
* platform has IRQ support.
|
* platform has IRQ support.
|
||||||
* Then, drier use common register
|
* Then, drier use common register
|
||||||
*/
|
*/
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
|
|
||||||
if (!res) {
|
|
||||||
dev_err(dev, "Could not get platform resource\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
|
ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0,
|
||||||
dev_name(dev), common);
|
dev_name(dev), common);
|
||||||
|
@ -405,6 +400,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
||||||
/*
|
/*
|
||||||
* rcar_has_irq_support() will be enabled
|
* rcar_has_irq_support() will be enabled
|
||||||
*/
|
*/
|
||||||
|
res = platform_get_resource(pdev, IORESOURCE_MEM, mres++);
|
||||||
common->base = devm_ioremap_resource(dev, res);
|
common->base = devm_ioremap_resource(dev, res);
|
||||||
if (IS_ERR(common->base))
|
if (IS_ERR(common->base))
|
||||||
return PTR_ERR(common->base);
|
return PTR_ERR(common->base);
|
||||||
|
@ -458,7 +454,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
platform_set_drvdata(pdev, common);
|
platform_set_drvdata(pdev, common);
|
||||||
|
|
||||||
dev_info(dev, "%d sensor proved\n", i);
|
dev_info(dev, "%d sensor probed\n", i);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -487,8 +483,6 @@ static int rcar_thermal_remove(struct platform_device *pdev)
|
||||||
rcar_thermal_irq_disable(priv);
|
rcar_thermal_irq_disable(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
pm_runtime_put_sync(dev);
|
pm_runtime_put_sync(dev);
|
||||||
pm_runtime_disable(dev);
|
pm_runtime_disable(dev);
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
|
||||||
struct thermal_zone_device *spear_thermal = NULL;
|
struct thermal_zone_device *spear_thermal = NULL;
|
||||||
struct spear_thermal_dev *stdev;
|
struct spear_thermal_dev *stdev;
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
struct resource *res;
|
||||||
int ret = 0, val;
|
int ret = 0, val;
|
||||||
|
|
||||||
if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
|
if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
|
||||||
|
@ -112,11 +112,6 @@ static int spear_thermal_probe(struct platform_device *pdev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stres) {
|
|
||||||
dev_err(&pdev->dev, "memory resource missing\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
|
stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL);
|
||||||
if (!stdev) {
|
if (!stdev) {
|
||||||
dev_err(&pdev->dev, "kzalloc fail\n");
|
dev_err(&pdev->dev, "kzalloc fail\n");
|
||||||
|
@ -124,12 +119,10 @@ static int spear_thermal_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable thermal sensor */
|
/* Enable thermal sensor */
|
||||||
stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start,
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
resource_size(stres));
|
stdev->thermal_base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (!stdev->thermal_base) {
|
if (IS_ERR(stdev->thermal_base))
|
||||||
dev_err(&pdev->dev, "ioremap failed\n");
|
return PTR_ERR(stdev->thermal_base);
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
stdev->clk = devm_clk_get(&pdev->dev, NULL);
|
stdev->clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (IS_ERR(stdev->clk)) {
|
if (IS_ERR(stdev->clk)) {
|
||||||
|
@ -174,7 +167,6 @@ static int spear_thermal_exit(struct platform_device *pdev)
|
||||||
struct spear_thermal_dev *stdev = spear_thermal->devdata;
|
struct spear_thermal_dev *stdev = spear_thermal->devdata;
|
||||||
|
|
||||||
thermal_zone_device_unregister(spear_thermal);
|
thermal_zone_device_unregister(spear_thermal);
|
||||||
platform_set_drvdata(pdev, NULL);
|
|
||||||
|
|
||||||
/* Disable SPEAr Thermal Sensor */
|
/* Disable SPEAr Thermal Sensor */
|
||||||
actual_mask = readl_relaxed(stdev->thermal_base);
|
actual_mask = readl_relaxed(stdev->thermal_base);
|
||||||
|
@ -198,7 +190,7 @@ static struct platform_driver spear_thermal_driver = {
|
||||||
.name = "spear_thermal",
|
.name = "spear_thermal",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &spear_thermal_pm_ops,
|
.pm = &spear_thermal_pm_ops,
|
||||||
.of_match_table = of_match_ptr(spear_thermal_id_table),
|
.of_match_table = spear_thermal_id_table,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/thermal.h>
|
#include <linux/thermal.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/string.h>
|
||||||
#include <net/netlink.h>
|
#include <net/netlink.h>
|
||||||
#include <net/genetlink.h>
|
#include <net/genetlink.h>
|
||||||
|
|
||||||
|
@ -155,7 +156,8 @@ int get_tz_trend(struct thermal_zone_device *tz, int trip)
|
||||||
{
|
{
|
||||||
enum thermal_trend trend;
|
enum thermal_trend trend;
|
||||||
|
|
||||||
if (!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)
|
if (tz->temperature > tz->last_temperature)
|
||||||
trend = THERMAL_TREND_RAISING;
|
trend = THERMAL_TREND_RAISING;
|
||||||
else if (tz->temperature < tz->last_temperature)
|
else if (tz->temperature < tz->last_temperature)
|
||||||
|
@ -713,10 +715,13 @@ policy_store(struct device *dev, struct device_attribute *attr,
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
struct thermal_zone_device *tz = to_thermal_zone(dev);
|
||||||
struct thermal_governor *gov;
|
struct thermal_governor *gov;
|
||||||
|
char name[THERMAL_NAME_LENGTH];
|
||||||
|
|
||||||
|
snprintf(name, sizeof(name), "%s", buf);
|
||||||
|
|
||||||
mutex_lock(&thermal_governor_lock);
|
mutex_lock(&thermal_governor_lock);
|
||||||
|
|
||||||
gov = __find_governor(buf);
|
gov = __find_governor(strim(name));
|
||||||
if (!gov)
|
if (!gov)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -1624,7 +1629,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
|
||||||
if (!ops || !ops->get_temp)
|
if (!ops || !ops->get_temp)
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
if (trips > 0 && !ops->get_trip_type)
|
if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
|
tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
|
||||||
|
|
|
@ -46,3 +46,15 @@ config OMAP5_THERMAL
|
||||||
|
|
||||||
This includes alert interrupts generation and also the TSHUT
|
This includes alert interrupts generation and also the TSHUT
|
||||||
support.
|
support.
|
||||||
|
|
||||||
|
config DRA752_THERMAL
|
||||||
|
bool "Texas Instruments DRA752 thermal support"
|
||||||
|
depends on TI_SOC_THERMAL
|
||||||
|
depends on SOC_DRA7XX
|
||||||
|
help
|
||||||
|
If you say yes here you get thermal support for the Texas Instruments
|
||||||
|
DRA752 SoC family. The current chip supported are:
|
||||||
|
- DRA752
|
||||||
|
|
||||||
|
This includes alert interrupts generation and also the TSHUT
|
||||||
|
support.
|
|
@ -1,5 +1,6 @@
|
||||||
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal.o
|
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal.o
|
||||||
ti-soc-thermal-y := ti-bandgap.o
|
ti-soc-thermal-y := ti-bandgap.o
|
||||||
ti-soc-thermal-$(CONFIG_TI_THERMAL) += ti-thermal-common.o
|
ti-soc-thermal-$(CONFIG_TI_THERMAL) += ti-thermal-common.o
|
||||||
|
ti-soc-thermal-$(CONFIG_DRA752_THERMAL) += dra752-thermal-data.o
|
||||||
ti-soc-thermal-$(CONFIG_OMAP4_THERMAL) += omap4-thermal-data.o
|
ti-soc-thermal-$(CONFIG_OMAP4_THERMAL) += omap4-thermal-data.o
|
||||||
ti-soc-thermal-$(CONFIG_OMAP5_THERMAL) += omap5-thermal-data.o
|
ti-soc-thermal-$(CONFIG_OMAP5_THERMAL) += omap5-thermal-data.o
|
|
@ -0,0 +1,280 @@
|
||||||
|
/*
|
||||||
|
* DRA752 bandgap registers, bitfields and temperature definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
* Contact:
|
||||||
|
* Eduardo Valentin <eduardo.valentin@ti.com>
|
||||||
|
* Tero Kristo <t-kristo@ti.com>
|
||||||
|
*
|
||||||
|
* This is an auto generated file.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __DRA752_BANDGAP_H
|
||||||
|
#define __DRA752_BANDGAP_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *** DRA752 ***
|
||||||
|
*
|
||||||
|
* Below, in sequence, are the Register definitions,
|
||||||
|
* the bitfields and the temperature definitions for DRA752.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRA752 register definitions
|
||||||
|
*
|
||||||
|
* Registers are defined as offsets. The offsets are
|
||||||
|
* relative to FUSE_OPP_BGAP_GPU on DRA752.
|
||||||
|
* DRA752_BANDGAP_BASE 0x4a0021e0
|
||||||
|
*
|
||||||
|
* Register below are grouped by domain (not necessarily in offset order)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* DRA752.common register offsets */
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_OFFSET 0x1a0
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_OFFSET 0x1c8
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_OFFSET 0x39c
|
||||||
|
#define DRA752_BANDGAP_STATUS_2_OFFSET 0x3b8
|
||||||
|
|
||||||
|
/* DRA752.core register offsets */
|
||||||
|
#define DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET 0x8
|
||||||
|
#define DRA752_TEMP_SENSOR_CORE_OFFSET 0x154
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_CORE_OFFSET 0x1ac
|
||||||
|
#define DRA752_BANDGAP_TSHUT_CORE_OFFSET 0x1b8
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET 0x1c4
|
||||||
|
#define DRA752_DTEMP_CORE_0_OFFSET 0x208
|
||||||
|
#define DRA752_DTEMP_CORE_1_OFFSET 0x20c
|
||||||
|
#define DRA752_DTEMP_CORE_2_OFFSET 0x210
|
||||||
|
#define DRA752_DTEMP_CORE_3_OFFSET 0x214
|
||||||
|
#define DRA752_DTEMP_CORE_4_OFFSET 0x218
|
||||||
|
|
||||||
|
/* DRA752.iva register offsets */
|
||||||
|
#define DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET 0x388
|
||||||
|
#define DRA752_TEMP_SENSOR_IVA_OFFSET 0x398
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_IVA_OFFSET 0x3a4
|
||||||
|
#define DRA752_BANDGAP_TSHUT_IVA_OFFSET 0x3ac
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET 0x3b4
|
||||||
|
#define DRA752_DTEMP_IVA_0_OFFSET 0x3d0
|
||||||
|
#define DRA752_DTEMP_IVA_1_OFFSET 0x3d4
|
||||||
|
#define DRA752_DTEMP_IVA_2_OFFSET 0x3d8
|
||||||
|
#define DRA752_DTEMP_IVA_3_OFFSET 0x3dc
|
||||||
|
#define DRA752_DTEMP_IVA_4_OFFSET 0x3e0
|
||||||
|
|
||||||
|
/* DRA752.mpu register offsets */
|
||||||
|
#define DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET 0x4
|
||||||
|
#define DRA752_TEMP_SENSOR_MPU_OFFSET 0x14c
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_MPU_OFFSET 0x1a4
|
||||||
|
#define DRA752_BANDGAP_TSHUT_MPU_OFFSET 0x1b0
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET 0x1bc
|
||||||
|
#define DRA752_DTEMP_MPU_0_OFFSET 0x1e0
|
||||||
|
#define DRA752_DTEMP_MPU_1_OFFSET 0x1e4
|
||||||
|
#define DRA752_DTEMP_MPU_2_OFFSET 0x1e8
|
||||||
|
#define DRA752_DTEMP_MPU_3_OFFSET 0x1ec
|
||||||
|
#define DRA752_DTEMP_MPU_4_OFFSET 0x1f0
|
||||||
|
|
||||||
|
/* DRA752.dspeve register offsets */
|
||||||
|
#define DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET 0x384
|
||||||
|
#define DRA752_TEMP_SENSOR_DSPEVE_OFFSET 0x394
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET 0x3a0
|
||||||
|
#define DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET 0x3a8
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET 0x3b0
|
||||||
|
#define DRA752_DTEMP_DSPEVE_0_OFFSET 0x3bc
|
||||||
|
#define DRA752_DTEMP_DSPEVE_1_OFFSET 0x3c0
|
||||||
|
#define DRA752_DTEMP_DSPEVE_2_OFFSET 0x3c4
|
||||||
|
#define DRA752_DTEMP_DSPEVE_3_OFFSET 0x3c8
|
||||||
|
#define DRA752_DTEMP_DSPEVE_4_OFFSET 0x3cc
|
||||||
|
|
||||||
|
/* DRA752.gpu register offsets */
|
||||||
|
#define DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET 0x0
|
||||||
|
#define DRA752_TEMP_SENSOR_GPU_OFFSET 0x150
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_GPU_OFFSET 0x1a8
|
||||||
|
#define DRA752_BANDGAP_TSHUT_GPU_OFFSET 0x1b4
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET 0x1c0
|
||||||
|
#define DRA752_DTEMP_GPU_0_OFFSET 0x1f4
|
||||||
|
#define DRA752_DTEMP_GPU_1_OFFSET 0x1f8
|
||||||
|
#define DRA752_DTEMP_GPU_2_OFFSET 0x1fc
|
||||||
|
#define DRA752_DTEMP_GPU_3_OFFSET 0x200
|
||||||
|
#define DRA752_DTEMP_GPU_4_OFFSET 0x204
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register bitfields for DRA752
|
||||||
|
*
|
||||||
|
* All the macros bellow define the required bits for
|
||||||
|
* controlling temperature on DRA752. Bit defines are
|
||||||
|
* grouped by register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_STATUS_1 */
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_ALERT_MASK BIT(31)
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK BIT(5)
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_COLD_CORE_MASK BIT(4)
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK BIT(3)
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_COLD_GPU_MASK BIT(2)
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK BIT(1)
|
||||||
|
#define DRA752_BANDGAP_STATUS_1_COLD_MPU_MASK BIT(0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CTRL_2 */
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK BIT(22)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK BIT(21)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK BIT(19)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK BIT(18)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK BIT(16)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK BIT(15)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK BIT(3)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK BIT(2)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK BIT(1)
|
||||||
|
#define DRA752_BANDGAP_CTRL_2_MASK_COLD_DSPEVE_MASK BIT(0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_STATUS_2 */
|
||||||
|
#define DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK BIT(3)
|
||||||
|
#define DRA752_BANDGAP_STATUS_2_COLD_IVA_MASK BIT(2)
|
||||||
|
#define DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK BIT(1)
|
||||||
|
#define DRA752_BANDGAP_STATUS_2_COLD_DSPEVE_MASK BIT(0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CTRL_1 */
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK (0x3 << 30)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK (0x7 << 27)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK BIT(23)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK BIT(22)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK BIT(21)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK BIT(20)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK BIT(19)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK BIT(18)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK BIT(17)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK BIT(16)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK BIT(15)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK BIT(5)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK BIT(4)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK BIT(3)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_MASK_COLD_GPU_MASK BIT(2)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_MASK_HOT_MPU_MASK BIT(1)
|
||||||
|
#define DRA752_BANDGAP_CTRL_1_MASK_COLD_MPU_MASK BIT(0)
|
||||||
|
|
||||||
|
/* DRA752.TEMP_SENSOR */
|
||||||
|
#define DRA752_TEMP_SENSOR_TMPSOFF_MASK BIT(11)
|
||||||
|
#define DRA752_TEMP_SENSOR_EOCZ_MASK BIT(10)
|
||||||
|
#define DRA752_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_THRESHOLD */
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_HOT_MASK (0x3ff << 16)
|
||||||
|
#define DRA752_BANDGAP_THRESHOLD_COLD_MASK (0x3ff << 0)
|
||||||
|
|
||||||
|
/* DRA752.TSHUT_THRESHOLD */
|
||||||
|
#define DRA752_TSHUT_THRESHOLD_MUXCTRL_MASK BIT(31)
|
||||||
|
#define DRA752_TSHUT_THRESHOLD_HOT_MASK (0x3ff << 16)
|
||||||
|
#define DRA752_TSHUT_THRESHOLD_COLD_MASK (0x3ff << 0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CUMUL_DTEMP_CORE */
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CUMUL_DTEMP_IVA */
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_MASK (0xffffffff << 0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CUMUL_DTEMP_MPU */
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CUMUL_DTEMP_DSPEVE */
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_MASK (0xffffffff << 0)
|
||||||
|
|
||||||
|
/* DRA752.BANDGAP_CUMUL_DTEMP_GPU */
|
||||||
|
#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temperature limits and thresholds for DRA752
|
||||||
|
*
|
||||||
|
* All the macros bellow are definitions for handling the
|
||||||
|
* ADC conversions and representation of temperature limits
|
||||||
|
* and thresholds for DRA752. Definitions are grouped
|
||||||
|
* by temperature domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* DRA752.common temperature definitions */
|
||||||
|
/* ADC conversion table limits */
|
||||||
|
#define DRA752_ADC_START_VALUE 540
|
||||||
|
#define DRA752_ADC_END_VALUE 945
|
||||||
|
|
||||||
|
/* DRA752.GPU temperature definitions */
|
||||||
|
/* bandgap clock limits */
|
||||||
|
#define DRA752_GPU_MAX_FREQ 1500000
|
||||||
|
#define DRA752_GPU_MIN_FREQ 1000000
|
||||||
|
/* sensor limits */
|
||||||
|
#define DRA752_GPU_MIN_TEMP -40000
|
||||||
|
#define DRA752_GPU_MAX_TEMP 125000
|
||||||
|
#define DRA752_GPU_HYST_VAL 5000
|
||||||
|
/* interrupts thresholds */
|
||||||
|
#define DRA752_GPU_TSHUT_HOT 915
|
||||||
|
#define DRA752_GPU_TSHUT_COLD 900
|
||||||
|
#define DRA752_GPU_T_HOT 800
|
||||||
|
#define DRA752_GPU_T_COLD 795
|
||||||
|
|
||||||
|
/* DRA752.MPU temperature definitions */
|
||||||
|
/* bandgap clock limits */
|
||||||
|
#define DRA752_MPU_MAX_FREQ 1500000
|
||||||
|
#define DRA752_MPU_MIN_FREQ 1000000
|
||||||
|
/* sensor limits */
|
||||||
|
#define DRA752_MPU_MIN_TEMP -40000
|
||||||
|
#define DRA752_MPU_MAX_TEMP 125000
|
||||||
|
#define DRA752_MPU_HYST_VAL 5000
|
||||||
|
/* interrupts thresholds */
|
||||||
|
#define DRA752_MPU_TSHUT_HOT 915
|
||||||
|
#define DRA752_MPU_TSHUT_COLD 900
|
||||||
|
#define DRA752_MPU_T_HOT 800
|
||||||
|
#define DRA752_MPU_T_COLD 795
|
||||||
|
|
||||||
|
/* DRA752.CORE temperature definitions */
|
||||||
|
/* bandgap clock limits */
|
||||||
|
#define DRA752_CORE_MAX_FREQ 1500000
|
||||||
|
#define DRA752_CORE_MIN_FREQ 1000000
|
||||||
|
/* sensor limits */
|
||||||
|
#define DRA752_CORE_MIN_TEMP -40000
|
||||||
|
#define DRA752_CORE_MAX_TEMP 125000
|
||||||
|
#define DRA752_CORE_HYST_VAL 5000
|
||||||
|
/* interrupts thresholds */
|
||||||
|
#define DRA752_CORE_TSHUT_HOT 915
|
||||||
|
#define DRA752_CORE_TSHUT_COLD 900
|
||||||
|
#define DRA752_CORE_T_HOT 800
|
||||||
|
#define DRA752_CORE_T_COLD 795
|
||||||
|
|
||||||
|
/* DRA752.DSPEVE temperature definitions */
|
||||||
|
/* bandgap clock limits */
|
||||||
|
#define DRA752_DSPEVE_MAX_FREQ 1500000
|
||||||
|
#define DRA752_DSPEVE_MIN_FREQ 1000000
|
||||||
|
/* sensor limits */
|
||||||
|
#define DRA752_DSPEVE_MIN_TEMP -40000
|
||||||
|
#define DRA752_DSPEVE_MAX_TEMP 125000
|
||||||
|
#define DRA752_DSPEVE_HYST_VAL 5000
|
||||||
|
/* interrupts thresholds */
|
||||||
|
#define DRA752_DSPEVE_TSHUT_HOT 915
|
||||||
|
#define DRA752_DSPEVE_TSHUT_COLD 900
|
||||||
|
#define DRA752_DSPEVE_T_HOT 800
|
||||||
|
#define DRA752_DSPEVE_T_COLD 795
|
||||||
|
|
||||||
|
/* DRA752.IVA temperature definitions */
|
||||||
|
/* bandgap clock limits */
|
||||||
|
#define DRA752_IVA_MAX_FREQ 1500000
|
||||||
|
#define DRA752_IVA_MIN_FREQ 1000000
|
||||||
|
/* sensor limits */
|
||||||
|
#define DRA752_IVA_MIN_TEMP -40000
|
||||||
|
#define DRA752_IVA_MAX_TEMP 125000
|
||||||
|
#define DRA752_IVA_HYST_VAL 5000
|
||||||
|
/* interrupts thresholds */
|
||||||
|
#define DRA752_IVA_TSHUT_HOT 915
|
||||||
|
#define DRA752_IVA_TSHUT_COLD 900
|
||||||
|
#define DRA752_IVA_T_HOT 800
|
||||||
|
#define DRA752_IVA_T_COLD 795
|
||||||
|
|
||||||
|
#endif /* __DRA752_BANDGAP_H */
|
|
@ -0,0 +1,476 @@
|
||||||
|
/*
|
||||||
|
* DRA752 thermal data.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Texas Instruments Inc.
|
||||||
|
* Contact:
|
||||||
|
* Eduardo Valentin <eduardo.valentin@ti.com>
|
||||||
|
* Tero Kristo <t-kristo@ti.com>
|
||||||
|
*
|
||||||
|
* This file is partially autogenerated.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the GNU General Public
|
||||||
|
* License version 2, as published by the Free Software Foundation, and
|
||||||
|
* may be copied, distributed, and modified under those terms.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ti-thermal.h"
|
||||||
|
#include "ti-bandgap.h"
|
||||||
|
#include "dra752-bandgap.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 has five instances of thermal sensor: MPU, GPU, CORE,
|
||||||
|
* IVA and DSPEVE need to describe the individual registers and
|
||||||
|
* bit fields.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 CORE thermal sensor register offsets and bit-fields
|
||||||
|
*/
|
||||||
|
static struct temp_sensor_registers
|
||||||
|
dra752_core_temp_sensor_registers = {
|
||||||
|
.temp_sensor_ctrl = DRA752_TEMP_SENSOR_CORE_OFFSET,
|
||||||
|
.bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
|
||||||
|
.bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
|
||||||
|
.bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
|
||||||
|
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
|
||||||
|
.mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK,
|
||||||
|
.mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK,
|
||||||
|
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
|
||||||
|
.mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK,
|
||||||
|
.mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK,
|
||||||
|
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK,
|
||||||
|
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_CORE_OFFSET,
|
||||||
|
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
|
||||||
|
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
|
||||||
|
.tshut_threshold = DRA752_BANDGAP_TSHUT_CORE_OFFSET,
|
||||||
|
.tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
|
||||||
|
.tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
|
||||||
|
.bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
|
||||||
|
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
|
||||||
|
.status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK,
|
||||||
|
.status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_CORE_MASK,
|
||||||
|
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET,
|
||||||
|
.ctrl_dtemp_0 = DRA752_DTEMP_CORE_0_OFFSET,
|
||||||
|
.ctrl_dtemp_1 = DRA752_DTEMP_CORE_1_OFFSET,
|
||||||
|
.ctrl_dtemp_2 = DRA752_DTEMP_CORE_2_OFFSET,
|
||||||
|
.ctrl_dtemp_3 = DRA752_DTEMP_CORE_3_OFFSET,
|
||||||
|
.ctrl_dtemp_4 = DRA752_DTEMP_CORE_4_OFFSET,
|
||||||
|
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 IVA thermal sensor register offsets and bit-fields
|
||||||
|
*/
|
||||||
|
static struct temp_sensor_registers
|
||||||
|
dra752_iva_temp_sensor_registers = {
|
||||||
|
.temp_sensor_ctrl = DRA752_TEMP_SENSOR_IVA_OFFSET,
|
||||||
|
.bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
|
||||||
|
.bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
|
||||||
|
.bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
|
||||||
|
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_2_OFFSET,
|
||||||
|
.mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK,
|
||||||
|
.mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK,
|
||||||
|
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
|
||||||
|
.mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK,
|
||||||
|
.mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK,
|
||||||
|
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK,
|
||||||
|
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_IVA_OFFSET,
|
||||||
|
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
|
||||||
|
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
|
||||||
|
.tshut_threshold = DRA752_BANDGAP_TSHUT_IVA_OFFSET,
|
||||||
|
.tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
|
||||||
|
.tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
|
||||||
|
.bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
|
||||||
|
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
|
||||||
|
.status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK,
|
||||||
|
.status_cold_mask = DRA752_BANDGAP_STATUS_2_COLD_IVA_MASK,
|
||||||
|
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET,
|
||||||
|
.ctrl_dtemp_0 = DRA752_DTEMP_IVA_0_OFFSET,
|
||||||
|
.ctrl_dtemp_1 = DRA752_DTEMP_IVA_1_OFFSET,
|
||||||
|
.ctrl_dtemp_2 = DRA752_DTEMP_IVA_2_OFFSET,
|
||||||
|
.ctrl_dtemp_3 = DRA752_DTEMP_IVA_3_OFFSET,
|
||||||
|
.ctrl_dtemp_4 = DRA752_DTEMP_IVA_4_OFFSET,
|
||||||
|
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 MPU thermal sensor register offsets and bit-fields
|
||||||
|
*/
|
||||||
|
static struct temp_sensor_registers
|
||||||
|
dra752_mpu_temp_sensor_registers = {
|
||||||
|
.temp_sensor_ctrl = DRA752_TEMP_SENSOR_MPU_OFFSET,
|
||||||
|
.bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
|
||||||
|
.bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
|
||||||
|
.bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
|
||||||
|
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
|
||||||
|
.mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_MPU_MASK,
|
||||||
|
.mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_MPU_MASK,
|
||||||
|
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
|
||||||
|
.mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK,
|
||||||
|
.mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK,
|
||||||
|
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK,
|
||||||
|
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_MPU_OFFSET,
|
||||||
|
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
|
||||||
|
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
|
||||||
|
.tshut_threshold = DRA752_BANDGAP_TSHUT_MPU_OFFSET,
|
||||||
|
.tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
|
||||||
|
.tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
|
||||||
|
.bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
|
||||||
|
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
|
||||||
|
.status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK,
|
||||||
|
.status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_MPU_MASK,
|
||||||
|
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET,
|
||||||
|
.ctrl_dtemp_0 = DRA752_DTEMP_MPU_0_OFFSET,
|
||||||
|
.ctrl_dtemp_1 = DRA752_DTEMP_MPU_1_OFFSET,
|
||||||
|
.ctrl_dtemp_2 = DRA752_DTEMP_MPU_2_OFFSET,
|
||||||
|
.ctrl_dtemp_3 = DRA752_DTEMP_MPU_3_OFFSET,
|
||||||
|
.ctrl_dtemp_4 = DRA752_DTEMP_MPU_4_OFFSET,
|
||||||
|
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 DSPEVE thermal sensor register offsets and bit-fields
|
||||||
|
*/
|
||||||
|
static struct temp_sensor_registers
|
||||||
|
dra752_dspeve_temp_sensor_registers = {
|
||||||
|
.temp_sensor_ctrl = DRA752_TEMP_SENSOR_DSPEVE_OFFSET,
|
||||||
|
.bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
|
||||||
|
.bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
|
||||||
|
.bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
|
||||||
|
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_2_OFFSET,
|
||||||
|
.mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK,
|
||||||
|
.mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_DSPEVE_MASK,
|
||||||
|
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
|
||||||
|
.mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK,
|
||||||
|
.mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK,
|
||||||
|
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK,
|
||||||
|
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET,
|
||||||
|
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
|
||||||
|
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
|
||||||
|
.tshut_threshold = DRA752_BANDGAP_TSHUT_DSPEVE_OFFSET,
|
||||||
|
.tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
|
||||||
|
.tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
|
||||||
|
.bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
|
||||||
|
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
|
||||||
|
.status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK,
|
||||||
|
.status_cold_mask = DRA752_BANDGAP_STATUS_2_COLD_DSPEVE_MASK,
|
||||||
|
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET,
|
||||||
|
.ctrl_dtemp_0 = DRA752_DTEMP_DSPEVE_0_OFFSET,
|
||||||
|
.ctrl_dtemp_1 = DRA752_DTEMP_DSPEVE_1_OFFSET,
|
||||||
|
.ctrl_dtemp_2 = DRA752_DTEMP_DSPEVE_2_OFFSET,
|
||||||
|
.ctrl_dtemp_3 = DRA752_DTEMP_DSPEVE_3_OFFSET,
|
||||||
|
.ctrl_dtemp_4 = DRA752_DTEMP_DSPEVE_4_OFFSET,
|
||||||
|
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 GPU thermal sensor register offsets and bit-fields
|
||||||
|
*/
|
||||||
|
static struct temp_sensor_registers
|
||||||
|
dra752_gpu_temp_sensor_registers = {
|
||||||
|
.temp_sensor_ctrl = DRA752_TEMP_SENSOR_GPU_OFFSET,
|
||||||
|
.bgap_tempsoff_mask = DRA752_TEMP_SENSOR_TMPSOFF_MASK,
|
||||||
|
.bgap_eocz_mask = DRA752_TEMP_SENSOR_EOCZ_MASK,
|
||||||
|
.bgap_dtemp_mask = DRA752_TEMP_SENSOR_DTEMP_MASK,
|
||||||
|
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
|
||||||
|
.mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK,
|
||||||
|
.mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_GPU_MASK,
|
||||||
|
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
|
||||||
|
.mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK,
|
||||||
|
.mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK,
|
||||||
|
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK,
|
||||||
|
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_GPU_OFFSET,
|
||||||
|
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
|
||||||
|
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
|
||||||
|
.tshut_threshold = DRA752_BANDGAP_TSHUT_GPU_OFFSET,
|
||||||
|
.tshut_hot_mask = DRA752_TSHUT_THRESHOLD_HOT_MASK,
|
||||||
|
.tshut_cold_mask = DRA752_TSHUT_THRESHOLD_COLD_MASK,
|
||||||
|
.bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
|
||||||
|
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
|
||||||
|
.status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK,
|
||||||
|
.status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_GPU_MASK,
|
||||||
|
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET,
|
||||||
|
.ctrl_dtemp_0 = DRA752_DTEMP_GPU_0_OFFSET,
|
||||||
|
.ctrl_dtemp_1 = DRA752_DTEMP_GPU_1_OFFSET,
|
||||||
|
.ctrl_dtemp_2 = DRA752_DTEMP_GPU_2_OFFSET,
|
||||||
|
.ctrl_dtemp_3 = DRA752_DTEMP_GPU_3_OFFSET,
|
||||||
|
.ctrl_dtemp_4 = DRA752_DTEMP_GPU_4_OFFSET,
|
||||||
|
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thresholds and limits for DRA752 MPU temperature sensor */
|
||||||
|
static struct temp_sensor_data dra752_mpu_temp_sensor_data = {
|
||||||
|
.tshut_hot = DRA752_MPU_TSHUT_HOT,
|
||||||
|
.tshut_cold = DRA752_MPU_TSHUT_COLD,
|
||||||
|
.t_hot = DRA752_MPU_T_HOT,
|
||||||
|
.t_cold = DRA752_MPU_T_COLD,
|
||||||
|
.min_freq = DRA752_MPU_MIN_FREQ,
|
||||||
|
.max_freq = DRA752_MPU_MAX_FREQ,
|
||||||
|
.max_temp = DRA752_MPU_MAX_TEMP,
|
||||||
|
.min_temp = DRA752_MPU_MIN_TEMP,
|
||||||
|
.hyst_val = DRA752_MPU_HYST_VAL,
|
||||||
|
.update_int1 = 1000,
|
||||||
|
.update_int2 = 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thresholds and limits for DRA752 GPU temperature sensor */
|
||||||
|
static struct temp_sensor_data dra752_gpu_temp_sensor_data = {
|
||||||
|
.tshut_hot = DRA752_GPU_TSHUT_HOT,
|
||||||
|
.tshut_cold = DRA752_GPU_TSHUT_COLD,
|
||||||
|
.t_hot = DRA752_GPU_T_HOT,
|
||||||
|
.t_cold = DRA752_GPU_T_COLD,
|
||||||
|
.min_freq = DRA752_GPU_MIN_FREQ,
|
||||||
|
.max_freq = DRA752_GPU_MAX_FREQ,
|
||||||
|
.max_temp = DRA752_GPU_MAX_TEMP,
|
||||||
|
.min_temp = DRA752_GPU_MIN_TEMP,
|
||||||
|
.hyst_val = DRA752_GPU_HYST_VAL,
|
||||||
|
.update_int1 = 1000,
|
||||||
|
.update_int2 = 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thresholds and limits for DRA752 CORE temperature sensor */
|
||||||
|
static struct temp_sensor_data dra752_core_temp_sensor_data = {
|
||||||
|
.tshut_hot = DRA752_CORE_TSHUT_HOT,
|
||||||
|
.tshut_cold = DRA752_CORE_TSHUT_COLD,
|
||||||
|
.t_hot = DRA752_CORE_T_HOT,
|
||||||
|
.t_cold = DRA752_CORE_T_COLD,
|
||||||
|
.min_freq = DRA752_CORE_MIN_FREQ,
|
||||||
|
.max_freq = DRA752_CORE_MAX_FREQ,
|
||||||
|
.max_temp = DRA752_CORE_MAX_TEMP,
|
||||||
|
.min_temp = DRA752_CORE_MIN_TEMP,
|
||||||
|
.hyst_val = DRA752_CORE_HYST_VAL,
|
||||||
|
.update_int1 = 1000,
|
||||||
|
.update_int2 = 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thresholds and limits for DRA752 DSPEVE temperature sensor */
|
||||||
|
static struct temp_sensor_data dra752_dspeve_temp_sensor_data = {
|
||||||
|
.tshut_hot = DRA752_DSPEVE_TSHUT_HOT,
|
||||||
|
.tshut_cold = DRA752_DSPEVE_TSHUT_COLD,
|
||||||
|
.t_hot = DRA752_DSPEVE_T_HOT,
|
||||||
|
.t_cold = DRA752_DSPEVE_T_COLD,
|
||||||
|
.min_freq = DRA752_DSPEVE_MIN_FREQ,
|
||||||
|
.max_freq = DRA752_DSPEVE_MAX_FREQ,
|
||||||
|
.max_temp = DRA752_DSPEVE_MAX_TEMP,
|
||||||
|
.min_temp = DRA752_DSPEVE_MIN_TEMP,
|
||||||
|
.hyst_val = DRA752_DSPEVE_HYST_VAL,
|
||||||
|
.update_int1 = 1000,
|
||||||
|
.update_int2 = 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thresholds and limits for DRA752 IVA temperature sensor */
|
||||||
|
static struct temp_sensor_data dra752_iva_temp_sensor_data = {
|
||||||
|
.tshut_hot = DRA752_IVA_TSHUT_HOT,
|
||||||
|
.tshut_cold = DRA752_IVA_TSHUT_COLD,
|
||||||
|
.t_hot = DRA752_IVA_T_HOT,
|
||||||
|
.t_cold = DRA752_IVA_T_COLD,
|
||||||
|
.min_freq = DRA752_IVA_MIN_FREQ,
|
||||||
|
.max_freq = DRA752_IVA_MAX_FREQ,
|
||||||
|
.max_temp = DRA752_IVA_MAX_TEMP,
|
||||||
|
.min_temp = DRA752_IVA_MIN_TEMP,
|
||||||
|
.hyst_val = DRA752_IVA_HYST_VAL,
|
||||||
|
.update_int1 = 1000,
|
||||||
|
.update_int2 = 2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DRA752 : Temperature values in milli degree celsius
|
||||||
|
* ADC code values from 540 to 945
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int dra752_adc_to_temp[DRA752_ADC_END_VALUE - DRA752_ADC_START_VALUE + 1] = {
|
||||||
|
/* Index 540 - 549 */
|
||||||
|
-40000, -40000, -40000, -40000, -39800, -39400, -39000, -38600, -38200,
|
||||||
|
-37800,
|
||||||
|
/* Index 550 - 559 */
|
||||||
|
-37400, -37000, -36600, -36200, -35800, -35300, -34700, -34200, -33800,
|
||||||
|
-33400,
|
||||||
|
/* Index 560 - 569 */
|
||||||
|
-33000, -32600, -32200, -31800, -31400, -31000, -30600, -30200, -29800,
|
||||||
|
-29400,
|
||||||
|
/* Index 570 - 579 */
|
||||||
|
-29000, -28600, -28200, -27700, -27100, -26600, -26200, -25800, -25400,
|
||||||
|
-25000,
|
||||||
|
/* Index 580 - 589 */
|
||||||
|
-24600, -24200, -23800, -23400, -23000, -22600, -22200, -21800, -21400,
|
||||||
|
-21000,
|
||||||
|
/* Index 590 - 599 */
|
||||||
|
-20500, -19900, -19400, -19000, -18600, -18200, -17800, -17400, -17000,
|
||||||
|
-16600,
|
||||||
|
/* Index 600 - 609 */
|
||||||
|
-16200, -15800, -15400, -15000, -14600, -14200, -13800, -13400, -13000,
|
||||||
|
-12500,
|
||||||
|
/* Index 610 - 619 */
|
||||||
|
-11900, -11400, -11000, -10600, -10200, -9800, -9400, -9000, -8600,
|
||||||
|
-8200,
|
||||||
|
/* Index 620 - 629 */
|
||||||
|
-7800, -7400, -7000, -6600, -6200, -5800, -5400, -5000, -4500,
|
||||||
|
-3900,
|
||||||
|
/* Index 630 - 639 */
|
||||||
|
-3400, -3000, -2600, -2200, -1800, -1400, -1000, -600, -200,
|
||||||
|
200,
|
||||||
|
/* Index 640 - 649 */
|
||||||
|
600, 1000, 1400, 1800, 2200, 2600, 3000, 3400, 3900,
|
||||||
|
4500,
|
||||||
|
/* Index 650 - 659 */
|
||||||
|
5000, 5400, 5800, 6200, 6600, 7000, 7400, 7800, 8200,
|
||||||
|
8600,
|
||||||
|
/* Index 660 - 669 */
|
||||||
|
9000, 9400, 9800, 10200, 10600, 11000, 11400, 11800, 12200,
|
||||||
|
12700,
|
||||||
|
/* Index 670 - 679 */
|
||||||
|
13300, 13800, 14200, 14600, 15000, 15400, 15800, 16200, 16600,
|
||||||
|
17000,
|
||||||
|
/* Index 680 - 689 */
|
||||||
|
17400, 17800, 18200, 18600, 19000, 19400, 19800, 20200, 20600,
|
||||||
|
21000,
|
||||||
|
/* Index 690 - 699 */
|
||||||
|
21400, 21900, 22500, 23000, 23400, 23800, 24200, 24600, 25000,
|
||||||
|
25400,
|
||||||
|
/* Index 700 - 709 */
|
||||||
|
25800, 26200, 26600, 27000, 27400, 27800, 28200, 28600, 29000,
|
||||||
|
29400,
|
||||||
|
/* Index 710 - 719 */
|
||||||
|
29800, 30200, 30600, 31000, 31400, 31900, 32500, 33000, 33400,
|
||||||
|
33800,
|
||||||
|
/* Index 720 - 729 */
|
||||||
|
34200, 34600, 35000, 35400, 35800, 36200, 36600, 37000, 37400,
|
||||||
|
37800,
|
||||||
|
/* Index 730 - 739 */
|
||||||
|
38200, 38600, 39000, 39400, 39800, 40200, 40600, 41000, 41400,
|
||||||
|
41800,
|
||||||
|
/* Index 740 - 749 */
|
||||||
|
42200, 42600, 43100, 43700, 44200, 44600, 45000, 45400, 45800,
|
||||||
|
46200,
|
||||||
|
/* Index 750 - 759 */
|
||||||
|
46600, 47000, 47400, 47800, 48200, 48600, 49000, 49400, 49800,
|
||||||
|
50200,
|
||||||
|
/* Index 760 - 769 */
|
||||||
|
50600, 51000, 51400, 51800, 52200, 52600, 53000, 53400, 53800,
|
||||||
|
54200,
|
||||||
|
/* Index 770 - 779 */
|
||||||
|
54600, 55000, 55400, 55900, 56500, 57000, 57400, 57800, 58200,
|
||||||
|
58600,
|
||||||
|
/* Index 780 - 789 */
|
||||||
|
59000, 59400, 59800, 60200, 60600, 61000, 61400, 61800, 62200,
|
||||||
|
62600,
|
||||||
|
/* Index 790 - 799 */
|
||||||
|
63000, 63400, 63800, 64200, 64600, 65000, 65400, 65800, 66200,
|
||||||
|
66600,
|
||||||
|
/* Index 800 - 809 */
|
||||||
|
67000, 67400, 67800, 68200, 68600, 69000, 69400, 69800, 70200,
|
||||||
|
70600,
|
||||||
|
/* Index 810 - 819 */
|
||||||
|
71000, 71500, 72100, 72600, 73000, 73400, 73800, 74200, 74600,
|
||||||
|
75000,
|
||||||
|
/* Index 820 - 829 */
|
||||||
|
75400, 75800, 76200, 76600, 77000, 77400, 77800, 78200, 78600,
|
||||||
|
79000,
|
||||||
|
/* Index 830 - 839 */
|
||||||
|
79400, 79800, 80200, 80600, 81000, 81400, 81800, 82200, 82600,
|
||||||
|
83000,
|
||||||
|
/* Index 840 - 849 */
|
||||||
|
83400, 83800, 84200, 84600, 85000, 85400, 85800, 86200, 86600,
|
||||||
|
87000,
|
||||||
|
/* Index 850 - 859 */
|
||||||
|
87400, 87800, 88200, 88600, 89000, 89400, 89800, 90200, 90600,
|
||||||
|
91000,
|
||||||
|
/* Index 860 - 869 */
|
||||||
|
91400, 91800, 92200, 92600, 93000, 93400, 93800, 94200, 94600,
|
||||||
|
95000,
|
||||||
|
/* Index 870 - 879 */
|
||||||
|
95400, 95800, 96200, 96600, 97000, 97500, 98100, 98600, 99000,
|
||||||
|
99400,
|
||||||
|
/* Index 880 - 889 */
|
||||||
|
99800, 100200, 100600, 101000, 101400, 101800, 102200, 102600, 103000,
|
||||||
|
103400,
|
||||||
|
/* Index 890 - 899 */
|
||||||
|
103800, 104200, 104600, 105000, 105400, 105800, 106200, 106600, 107000,
|
||||||
|
107400,
|
||||||
|
/* Index 900 - 909 */
|
||||||
|
107800, 108200, 108600, 109000, 109400, 109800, 110200, 110600, 111000,
|
||||||
|
111400,
|
||||||
|
/* Index 910 - 919 */
|
||||||
|
111800, 112200, 112600, 113000, 113400, 113800, 114200, 114600, 115000,
|
||||||
|
115400,
|
||||||
|
/* Index 920 - 929 */
|
||||||
|
115800, 116200, 116600, 117000, 117400, 117800, 118200, 118600, 119000,
|
||||||
|
119400,
|
||||||
|
/* Index 930 - 939 */
|
||||||
|
119800, 120200, 120600, 121000, 121400, 121800, 122200, 122600, 123000,
|
||||||
|
123400,
|
||||||
|
/* Index 940 - 945 */
|
||||||
|
123800, 124200, 124600, 124900, 125000, 125000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* DRA752 data */
|
||||||
|
const struct ti_bandgap_data dra752_data = {
|
||||||
|
.features = TI_BANDGAP_FEATURE_TSHUT_CONFIG |
|
||||||
|
TI_BANDGAP_FEATURE_FREEZE_BIT |
|
||||||
|
TI_BANDGAP_FEATURE_TALERT |
|
||||||
|
TI_BANDGAP_FEATURE_COUNTER_DELAY |
|
||||||
|
TI_BANDGAP_FEATURE_HISTORY_BUFFER,
|
||||||
|
.fclock_name = "l3instr_ts_gclk_div",
|
||||||
|
.div_ck_name = "l3instr_ts_gclk_div",
|
||||||
|
.conv_table = dra752_adc_to_temp,
|
||||||
|
.adc_start_val = DRA752_ADC_START_VALUE,
|
||||||
|
.adc_end_val = DRA752_ADC_END_VALUE,
|
||||||
|
.expose_sensor = ti_thermal_expose_sensor,
|
||||||
|
.remove_sensor = ti_thermal_remove_sensor,
|
||||||
|
.sensors = {
|
||||||
|
{
|
||||||
|
.registers = &dra752_mpu_temp_sensor_registers,
|
||||||
|
.ts_data = &dra752_mpu_temp_sensor_data,
|
||||||
|
.domain = "cpu",
|
||||||
|
.register_cooling = ti_thermal_register_cpu_cooling,
|
||||||
|
.unregister_cooling = ti_thermal_unregister_cpu_cooling,
|
||||||
|
.slope = DRA752_GRADIENT_SLOPE,
|
||||||
|
.constant = DRA752_GRADIENT_CONST,
|
||||||
|
.slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
|
||||||
|
.constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.registers = &dra752_gpu_temp_sensor_registers,
|
||||||
|
.ts_data = &dra752_gpu_temp_sensor_data,
|
||||||
|
.domain = "gpu",
|
||||||
|
.slope = DRA752_GRADIENT_SLOPE,
|
||||||
|
.constant = DRA752_GRADIENT_CONST,
|
||||||
|
.slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
|
||||||
|
.constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.registers = &dra752_core_temp_sensor_registers,
|
||||||
|
.ts_data = &dra752_core_temp_sensor_data,
|
||||||
|
.domain = "core",
|
||||||
|
.slope = DRA752_GRADIENT_SLOPE,
|
||||||
|
.constant = DRA752_GRADIENT_CONST,
|
||||||
|
.slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
|
||||||
|
.constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.registers = &dra752_dspeve_temp_sensor_registers,
|
||||||
|
.ts_data = &dra752_dspeve_temp_sensor_data,
|
||||||
|
.domain = "dspeve",
|
||||||
|
.slope = DRA752_GRADIENT_SLOPE,
|
||||||
|
.constant = DRA752_GRADIENT_CONST,
|
||||||
|
.slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
|
||||||
|
.constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.registers = &dra752_iva_temp_sensor_registers,
|
||||||
|
.ts_data = &dra752_iva_temp_sensor_data,
|
||||||
|
.domain = "iva",
|
||||||
|
.slope = DRA752_GRADIENT_SLOPE,
|
||||||
|
.constant = DRA752_GRADIENT_CONST,
|
||||||
|
.slope_pcb = DRA752_GRADIENT_SLOPE_W_PCB,
|
||||||
|
.constant_pcb = DRA752_GRADIENT_CONST_W_PCB,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.sensor_count = 5,
|
||||||
|
};
|
|
@ -38,6 +38,7 @@
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
|
#include <linux/of_gpio.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
|
||||||
#include "ti-bandgap.h"
|
#include "ti-bandgap.h"
|
||||||
|
@ -469,7 +470,7 @@ static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(bgp)) {
|
if (!bgp || IS_ERR(bgp)) {
|
||||||
pr_err("%s: invalid bandgap pointer\n", __func__);
|
pr_err("%s: invalid bandgap pointer\n", __func__);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -992,9 +993,12 @@ int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock(&bgp->lock);
|
||||||
|
|
||||||
tsr = bgp->conf->sensors[id].registers;
|
tsr = bgp->conf->sensors[id].registers;
|
||||||
|
|
||||||
/* Freeze and read the last 2 valid readings */
|
/* Freeze and read the last 2 valid readings */
|
||||||
|
RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 1);
|
||||||
reg1 = tsr->ctrl_dtemp_1;
|
reg1 = tsr->ctrl_dtemp_1;
|
||||||
reg2 = tsr->ctrl_dtemp_2;
|
reg2 = tsr->ctrl_dtemp_2;
|
||||||
|
|
||||||
|
@ -1008,22 +1012,25 @@ int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
|
||||||
/* Convert from adc values to mCelsius temperature */
|
/* Convert from adc values to mCelsius temperature */
|
||||||
ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
|
ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto exit;
|
goto unfreeze;
|
||||||
|
|
||||||
ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
|
ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto exit;
|
goto unfreeze;
|
||||||
|
|
||||||
/* Fetch the update interval */
|
/* Fetch the update interval */
|
||||||
ret = ti_bandgap_read_update_interval(bgp, id, &interval);
|
ret = ti_bandgap_read_update_interval(bgp, id, &interval);
|
||||||
if (ret || !interval)
|
if (ret || !interval)
|
||||||
goto exit;
|
goto unfreeze;
|
||||||
|
|
||||||
*trend = (t1 - t2) / interval;
|
*trend = (t1 - t2) / interval;
|
||||||
|
|
||||||
dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
|
dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
|
||||||
t1, t2, *trend);
|
t1, t2, *trend);
|
||||||
|
|
||||||
|
unfreeze:
|
||||||
|
RMW_BITS(bgp, id, bgap_mask_ctrl, mask_freeze_mask, 0);
|
||||||
|
spin_unlock(&bgp->lock);
|
||||||
exit:
|
exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1123,7 +1130,6 @@ static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
|
||||||
const struct of_device_id *of_id;
|
const struct of_device_id *of_id;
|
||||||
struct ti_bandgap *bgp;
|
struct ti_bandgap *bgp;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
u32 prop;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* just for the sake */
|
/* just for the sake */
|
||||||
|
@ -1167,11 +1173,7 @@ static struct ti_bandgap *ti_bandgap_build(struct platform_device *pdev)
|
||||||
} while (res);
|
} while (res);
|
||||||
|
|
||||||
if (TI_BANDGAP_HAS(bgp, TSHUT)) {
|
if (TI_BANDGAP_HAS(bgp, TSHUT)) {
|
||||||
if (of_property_read_u32(node, "ti,tshut-gpio", &prop) < 0) {
|
bgp->tshut_gpio = of_get_gpio(node, 0);
|
||||||
dev_err(&pdev->dev, "missing tshut gpio in device tree\n");
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
bgp->tshut_gpio = prop;
|
|
||||||
if (!gpio_is_valid(bgp->tshut_gpio)) {
|
if (!gpio_is_valid(bgp->tshut_gpio)) {
|
||||||
dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
|
dev_err(&pdev->dev, "invalid gpio for tshut (%d)\n",
|
||||||
bgp->tshut_gpio);
|
bgp->tshut_gpio);
|
||||||
|
@ -1191,7 +1193,7 @@ int ti_bandgap_probe(struct platform_device *pdev)
|
||||||
int clk_rate, ret = 0, i;
|
int clk_rate, ret = 0, i;
|
||||||
|
|
||||||
bgp = ti_bandgap_build(pdev);
|
bgp = ti_bandgap_build(pdev);
|
||||||
if (IS_ERR_OR_NULL(bgp)) {
|
if (IS_ERR(bgp)) {
|
||||||
dev_err(&pdev->dev, "failed to fetch platform data\n");
|
dev_err(&pdev->dev, "failed to fetch platform data\n");
|
||||||
return PTR_ERR(bgp);
|
return PTR_ERR(bgp);
|
||||||
}
|
}
|
||||||
|
@ -1207,17 +1209,19 @@ int ti_bandgap_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
|
bgp->fclock = clk_get(NULL, bgp->conf->fclock_name);
|
||||||
ret = IS_ERR_OR_NULL(bgp->fclock);
|
ret = IS_ERR(bgp->fclock);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to request fclock reference\n");
|
dev_err(&pdev->dev, "failed to request fclock reference\n");
|
||||||
|
ret = PTR_ERR(bgp->fclock);
|
||||||
goto free_irqs;
|
goto free_irqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bgp->div_clk = clk_get(NULL, bgp->conf->div_ck_name);
|
bgp->div_clk = clk_get(NULL, bgp->conf->div_ck_name);
|
||||||
ret = IS_ERR_OR_NULL(bgp->div_clk);
|
ret = IS_ERR(bgp->div_clk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"failed to request div_ts_ck clock ref\n");
|
"failed to request div_ts_ck clock ref\n");
|
||||||
|
ret = PTR_ERR(bgp->div_clk);
|
||||||
goto free_irqs;
|
goto free_irqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1522,6 +1526,12 @@ static const struct of_device_id of_ti_bandgap_match[] = {
|
||||||
.compatible = "ti,omap5430-bandgap",
|
.compatible = "ti,omap5430-bandgap",
|
||||||
.data = (void *)&omap5430_data,
|
.data = (void *)&omap5430_data,
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_DRA752_THERMAL
|
||||||
|
{
|
||||||
|
.compatible = "ti,dra752-bandgap",
|
||||||
|
.data = (void *)&dra752_data,
|
||||||
|
},
|
||||||
#endif
|
#endif
|
||||||
/* Sentinel */
|
/* Sentinel */
|
||||||
{ },
|
{ },
|
|
@ -400,4 +400,9 @@ extern const struct ti_bandgap_data omap5430_data;
|
||||||
#define omap5430_data NULL
|
#define omap5430_data NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DRA752_THERMAL
|
||||||
|
extern const struct ti_bandgap_data dra752_data;
|
||||||
|
#else
|
||||||
|
#define dra752_data NULL
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
|
@ -101,7 +101,7 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
|
||||||
|
|
||||||
pcb_tz = data->pcb_tz;
|
pcb_tz = data->pcb_tz;
|
||||||
/* In case pcb zone is available, use the extrapolation rule with it */
|
/* In case pcb zone is available, use the extrapolation rule with it */
|
||||||
if (!IS_ERR_OR_NULL(pcb_tz)) {
|
if (!IS_ERR(pcb_tz)) {
|
||||||
ret = thermal_zone_get_temp(pcb_tz, &pcb_temp);
|
ret = thermal_zone_get_temp(pcb_tz, &pcb_temp);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
tmp -= pcb_temp; /* got a valid PCB temp */
|
tmp -= pcb_temp; /* got a valid PCB temp */
|
||||||
|
@ -124,7 +124,7 @@ static int ti_thermal_bind(struct thermal_zone_device *thermal,
|
||||||
struct ti_thermal_data *data = thermal->devdata;
|
struct ti_thermal_data *data = thermal->devdata;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(data))
|
if (!data || IS_ERR(data))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* check if this is the cooling device we registered */
|
/* check if this is the cooling device we registered */
|
||||||
|
@ -146,7 +146,7 @@ static int ti_thermal_unbind(struct thermal_zone_device *thermal,
|
||||||
{
|
{
|
||||||
struct ti_thermal_data *data = thermal->devdata;
|
struct ti_thermal_data *data = thermal->devdata;
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(data))
|
if (!data || IS_ERR(data))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* check if this is the cooling device we registered */
|
/* check if this is the cooling device we registered */
|
||||||
|
@ -282,6 +282,7 @@ static struct ti_thermal_data
|
||||||
data->sensor_id = id;
|
data->sensor_id = id;
|
||||||
data->bgp = bgp;
|
data->bgp = bgp;
|
||||||
data->mode = THERMAL_DEVICE_ENABLED;
|
data->mode = THERMAL_DEVICE_ENABLED;
|
||||||
|
/* pcb_tz will be either valid or PTR_ERR() */
|
||||||
data->pcb_tz = thermal_zone_get_zone_by_name("pcb");
|
data->pcb_tz = thermal_zone_get_zone_by_name("pcb");
|
||||||
INIT_WORK(&data->thermal_wq, ti_thermal_work);
|
INIT_WORK(&data->thermal_wq, ti_thermal_work);
|
||||||
|
|
||||||
|
@ -295,7 +296,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
|
||||||
|
|
||||||
data = ti_bandgap_get_sensor_data(bgp, id);
|
data = ti_bandgap_get_sensor_data(bgp, id);
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(data))
|
if (!data || IS_ERR(data))
|
||||||
data = ti_thermal_build_data(bgp, id);
|
data = ti_thermal_build_data(bgp, id);
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -306,7 +307,7 @@ int ti_thermal_expose_sensor(struct ti_bandgap *bgp, int id,
|
||||||
OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
|
OMAP_TRIP_NUMBER, 0, data, &ti_thermal_ops,
|
||||||
NULL, FAST_TEMP_MONITORING_RATE,
|
NULL, FAST_TEMP_MONITORING_RATE,
|
||||||
FAST_TEMP_MONITORING_RATE);
|
FAST_TEMP_MONITORING_RATE);
|
||||||
if (IS_ERR_OR_NULL(data->ti_thermal)) {
|
if (IS_ERR(data->ti_thermal)) {
|
||||||
dev_err(bgp->dev, "thermal zone device is NULL\n");
|
dev_err(bgp->dev, "thermal zone device is NULL\n");
|
||||||
return PTR_ERR(data->ti_thermal);
|
return PTR_ERR(data->ti_thermal);
|
||||||
}
|
}
|
||||||
|
@ -343,7 +344,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
|
||||||
struct ti_thermal_data *data;
|
struct ti_thermal_data *data;
|
||||||
|
|
||||||
data = ti_bandgap_get_sensor_data(bgp, id);
|
data = ti_bandgap_get_sensor_data(bgp, id);
|
||||||
if (IS_ERR_OR_NULL(data))
|
if (!data || IS_ERR(data))
|
||||||
data = ti_thermal_build_data(bgp, id);
|
data = ti_thermal_build_data(bgp, id);
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -356,7 +357,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id)
|
||||||
|
|
||||||
/* Register cooling device */
|
/* Register cooling device */
|
||||||
data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
|
data->cool_dev = cpufreq_cooling_register(cpu_present_mask);
|
||||||
if (IS_ERR_OR_NULL(data->cool_dev)) {
|
if (IS_ERR(data->cool_dev)) {
|
||||||
dev_err(bgp->dev,
|
dev_err(bgp->dev,
|
||||||
"Failed to register cpufreq cooling device\n");
|
"Failed to register cpufreq cooling device\n");
|
||||||
return PTR_ERR(data->cool_dev);
|
return PTR_ERR(data->cool_dev);
|
|
@ -38,6 +38,9 @@
|
||||||
#define OMAP_GRADIENT_SLOPE_5430_GPU 117
|
#define OMAP_GRADIENT_SLOPE_5430_GPU 117
|
||||||
#define OMAP_GRADIENT_CONST_5430_GPU -2992
|
#define OMAP_GRADIENT_CONST_5430_GPU -2992
|
||||||
|
|
||||||
|
#define DRA752_GRADIENT_SLOPE 0
|
||||||
|
#define DRA752_GRADIENT_CONST 2000
|
||||||
|
|
||||||
/* PCB sensor calculation constants */
|
/* PCB sensor calculation constants */
|
||||||
#define OMAP_GRADIENT_SLOPE_W_PCB_4430 0
|
#define OMAP_GRADIENT_SLOPE_W_PCB_4430 0
|
||||||
#define OMAP_GRADIENT_CONST_W_PCB_4430 20000
|
#define OMAP_GRADIENT_CONST_W_PCB_4430 20000
|
||||||
|
@ -51,6 +54,9 @@
|
||||||
#define OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU 464
|
#define OMAP_GRADIENT_SLOPE_W_PCB_5430_GPU 464
|
||||||
#define OMAP_GRADIENT_CONST_W_PCB_5430_GPU -5102
|
#define OMAP_GRADIENT_CONST_W_PCB_5430_GPU -5102
|
||||||
|
|
||||||
|
#define DRA752_GRADIENT_SLOPE_W_PCB 0
|
||||||
|
#define DRA752_GRADIENT_CONST_W_PCB 2000
|
||||||
|
|
||||||
/* trip points of interest in milicelsius (at hotspot level) */
|
/* trip points of interest in milicelsius (at hotspot level) */
|
||||||
#define OMAP_TRIP_COLD 100000
|
#define OMAP_TRIP_COLD 100000
|
||||||
#define OMAP_TRIP_HOT 110000
|
#define OMAP_TRIP_HOT 110000
|
|
@ -0,0 +1,642 @@
|
||||||
|
/*
|
||||||
|
* x86_pkg_temp_thermal driver
|
||||||
|
* Copyright (c) 2013, Intel Corporation.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/param.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/cpu.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/pm.h>
|
||||||
|
#include <linux/thermal.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <asm/cpu_device_id.h>
|
||||||
|
#include <asm/mce.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rate control delay: Idea is to introduce denounce effect
|
||||||
|
* This should be long enough to avoid reduce events, when
|
||||||
|
* threshold is set to a temperature, which is constantly
|
||||||
|
* violated, but at the short enough to take any action.
|
||||||
|
* The action can be remove threshold or change it to next
|
||||||
|
* interesting setting. Based on experiments, in around
|
||||||
|
* every 5 seconds under load will give us a significant
|
||||||
|
* temperature change.
|
||||||
|
*/
|
||||||
|
#define PKG_TEMP_THERMAL_NOTIFY_DELAY 5000
|
||||||
|
static int notify_delay_ms = PKG_TEMP_THERMAL_NOTIFY_DELAY;
|
||||||
|
module_param(notify_delay_ms, int, 0644);
|
||||||
|
MODULE_PARM_DESC(notify_delay_ms,
|
||||||
|
"User space notification delay in milli seconds.");
|
||||||
|
|
||||||
|
/* Number of trip points in thermal zone. Currently it can't
|
||||||
|
* be more than 2. MSR can allow setting and getting notifications
|
||||||
|
* for only 2 thresholds. This define enforces this, if there
|
||||||
|
* is some wrong values returned by cpuid for number of thresholds.
|
||||||
|
*/
|
||||||
|
#define MAX_NUMBER_OF_TRIPS 2
|
||||||
|
|
||||||
|
struct phy_dev_entry {
|
||||||
|
struct list_head list;
|
||||||
|
u16 phys_proc_id;
|
||||||
|
u16 first_cpu;
|
||||||
|
u32 tj_max;
|
||||||
|
int ref_cnt;
|
||||||
|
u32 start_pkg_therm_low;
|
||||||
|
u32 start_pkg_therm_high;
|
||||||
|
struct thermal_zone_device *tzone;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List maintaining number of package instances */
|
||||||
|
static LIST_HEAD(phy_dev_list);
|
||||||
|
static DEFINE_MUTEX(phy_dev_list_mutex);
|
||||||
|
|
||||||
|
/* Interrupt to work function schedule queue */
|
||||||
|
static DEFINE_PER_CPU(struct delayed_work, pkg_temp_thermal_threshold_work);
|
||||||
|
|
||||||
|
/* To track if the work is already scheduled on a package */
|
||||||
|
static u8 *pkg_work_scheduled;
|
||||||
|
|
||||||
|
/* Spin lock to prevent races with pkg_work_scheduled */
|
||||||
|
static spinlock_t pkg_work_lock;
|
||||||
|
static u16 max_phy_id;
|
||||||
|
|
||||||
|
/* Debug counters to show using debugfs */
|
||||||
|
static struct dentry *debugfs;
|
||||||
|
static unsigned int pkg_interrupt_cnt;
|
||||||
|
static unsigned int pkg_work_cnt;
|
||||||
|
|
||||||
|
static int pkg_temp_debugfs_init(void)
|
||||||
|
{
|
||||||
|
struct dentry *d;
|
||||||
|
|
||||||
|
debugfs = debugfs_create_dir("pkg_temp_thermal", NULL);
|
||||||
|
if (!debugfs)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs,
|
||||||
|
(u32 *)&pkg_interrupt_cnt);
|
||||||
|
if (!d)
|
||||||
|
goto err_out;
|
||||||
|
|
||||||
|
d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs,
|
||||||
|
(u32 *)&pkg_work_cnt);
|
||||||
|
if (!d)
|
||||||
|
goto err_out;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
debugfs_remove_recursive(debugfs);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct phy_dev_entry
|
||||||
|
*pkg_temp_thermal_get_phy_entry(unsigned int cpu)
|
||||||
|
{
|
||||||
|
u16 phys_proc_id = topology_physical_package_id(cpu);
|
||||||
|
struct phy_dev_entry *phy_ptr;
|
||||||
|
|
||||||
|
mutex_lock(&phy_dev_list_mutex);
|
||||||
|
|
||||||
|
list_for_each_entry(phy_ptr, &phy_dev_list, list)
|
||||||
|
if (phy_ptr->phys_proc_id == phys_proc_id) {
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
return phy_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tj-max is is interesting because threshold is set relative to this
|
||||||
|
* temperature.
|
||||||
|
*/
|
||||||
|
static int get_tj_max(int cpu, u32 *tj_max)
|
||||||
|
{
|
||||||
|
u32 eax, edx;
|
||||||
|
u32 val;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
|
||||||
|
if (err)
|
||||||
|
goto err_ret;
|
||||||
|
else {
|
||||||
|
val = (eax >> 16) & 0xff;
|
||||||
|
if (val)
|
||||||
|
*tj_max = val * 1000;
|
||||||
|
else {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto err_ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err_ret:
|
||||||
|
*tj_max = 0;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sys_get_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
|
||||||
|
{
|
||||||
|
u32 eax, edx;
|
||||||
|
struct phy_dev_entry *phy_dev_entry;
|
||||||
|
|
||||||
|
phy_dev_entry = tzd->devdata;
|
||||||
|
rdmsr_on_cpu(phy_dev_entry->first_cpu, MSR_IA32_PACKAGE_THERM_STATUS,
|
||||||
|
&eax, &edx);
|
||||||
|
if (eax & 0x80000000) {
|
||||||
|
*temp = phy_dev_entry->tj_max -
|
||||||
|
((eax >> 16) & 0x7f) * 1000;
|
||||||
|
pr_debug("sys_get_curr_temp %ld\n", *temp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sys_get_trip_temp(struct thermal_zone_device *tzd,
|
||||||
|
int trip, unsigned long *temp)
|
||||||
|
{
|
||||||
|
u32 eax, edx;
|
||||||
|
struct phy_dev_entry *phy_dev_entry;
|
||||||
|
u32 mask, shift;
|
||||||
|
unsigned long thres_reg_value;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (trip >= MAX_NUMBER_OF_TRIPS)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
phy_dev_entry = tzd->devdata;
|
||||||
|
|
||||||
|
if (trip) {
|
||||||
|
mask = THERM_MASK_THRESHOLD1;
|
||||||
|
shift = THERM_SHIFT_THRESHOLD1;
|
||||||
|
} else {
|
||||||
|
mask = THERM_MASK_THRESHOLD0;
|
||||||
|
shift = THERM_SHIFT_THRESHOLD0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = rdmsr_on_cpu(phy_dev_entry->first_cpu,
|
||||||
|
MSR_IA32_PACKAGE_THERM_INTERRUPT, &eax, &edx);
|
||||||
|
if (ret < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
thres_reg_value = (eax & mask) >> shift;
|
||||||
|
if (thres_reg_value)
|
||||||
|
*temp = phy_dev_entry->tj_max - thres_reg_value * 1000;
|
||||||
|
else
|
||||||
|
*temp = 0;
|
||||||
|
pr_debug("sys_get_trip_temp %ld\n", *temp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
|
||||||
|
unsigned long temp)
|
||||||
|
{
|
||||||
|
u32 l, h;
|
||||||
|
struct phy_dev_entry *phy_dev_entry;
|
||||||
|
u32 mask, shift, intr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
phy_dev_entry = tzd->devdata;
|
||||||
|
|
||||||
|
if (trip >= MAX_NUMBER_OF_TRIPS || temp >= phy_dev_entry->tj_max)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = rdmsr_on_cpu(phy_dev_entry->first_cpu,
|
||||||
|
MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||||
|
&l, &h);
|
||||||
|
if (ret < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (trip) {
|
||||||
|
mask = THERM_MASK_THRESHOLD1;
|
||||||
|
shift = THERM_SHIFT_THRESHOLD1;
|
||||||
|
intr = THERM_INT_THRESHOLD1_ENABLE;
|
||||||
|
} else {
|
||||||
|
mask = THERM_MASK_THRESHOLD0;
|
||||||
|
shift = THERM_SHIFT_THRESHOLD0;
|
||||||
|
intr = THERM_INT_THRESHOLD0_ENABLE;
|
||||||
|
}
|
||||||
|
l &= ~mask;
|
||||||
|
/*
|
||||||
|
* When users space sets a trip temperature == 0, which is indication
|
||||||
|
* that, it is no longer interested in receiving notifications.
|
||||||
|
*/
|
||||||
|
if (!temp)
|
||||||
|
l &= ~intr;
|
||||||
|
else {
|
||||||
|
l |= (phy_dev_entry->tj_max - temp)/1000 << shift;
|
||||||
|
l |= intr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrmsr_on_cpu(phy_dev_entry->first_cpu,
|
||||||
|
MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||||
|
l, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sys_get_trip_type(struct thermal_zone_device *thermal,
|
||||||
|
int trip, enum thermal_trip_type *type)
|
||||||
|
{
|
||||||
|
|
||||||
|
*type = THERMAL_TRIP_PASSIVE;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Thermal zone callback registry */
|
||||||
|
static struct thermal_zone_device_ops tzone_ops = {
|
||||||
|
.get_temp = sys_get_curr_temp,
|
||||||
|
.get_trip_temp = sys_get_trip_temp,
|
||||||
|
.get_trip_type = sys_get_trip_type,
|
||||||
|
.set_trip_temp = sys_set_trip_temp,
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool pkg_temp_thermal_platform_thermal_rate_control(void)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable threshold interrupt on local package/cpu */
|
||||||
|
static inline void enable_pkg_thres_interrupt(void)
|
||||||
|
{
|
||||||
|
u32 l, h;
|
||||||
|
u8 thres_0, thres_1;
|
||||||
|
|
||||||
|
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||||
|
/* only enable/disable if it had valid threshold value */
|
||||||
|
thres_0 = (l & THERM_MASK_THRESHOLD0) >> THERM_SHIFT_THRESHOLD0;
|
||||||
|
thres_1 = (l & THERM_MASK_THRESHOLD1) >> THERM_SHIFT_THRESHOLD1;
|
||||||
|
if (thres_0)
|
||||||
|
l |= THERM_INT_THRESHOLD0_ENABLE;
|
||||||
|
if (thres_1)
|
||||||
|
l |= THERM_INT_THRESHOLD1_ENABLE;
|
||||||
|
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable threshold interrupt on local package/cpu */
|
||||||
|
static inline void disable_pkg_thres_interrupt(void)
|
||||||
|
{
|
||||||
|
u32 l, h;
|
||||||
|
rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
|
||||||
|
wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||||
|
l & (~THERM_INT_THRESHOLD0_ENABLE) &
|
||||||
|
(~THERM_INT_THRESHOLD1_ENABLE), h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
|
||||||
|
{
|
||||||
|
__u64 msr_val;
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
int phy_id = topology_physical_package_id(cpu);
|
||||||
|
struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
|
||||||
|
bool notify = false;
|
||||||
|
|
||||||
|
if (!phdev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock(&pkg_work_lock);
|
||||||
|
++pkg_work_cnt;
|
||||||
|
if (unlikely(phy_id > max_phy_id)) {
|
||||||
|
spin_unlock(&pkg_work_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pkg_work_scheduled[phy_id] = 0;
|
||||||
|
spin_unlock(&pkg_work_lock);
|
||||||
|
|
||||||
|
enable_pkg_thres_interrupt();
|
||||||
|
rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
|
||||||
|
if (msr_val & THERM_LOG_THRESHOLD0) {
|
||||||
|
wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS,
|
||||||
|
msr_val & ~THERM_LOG_THRESHOLD0);
|
||||||
|
notify = true;
|
||||||
|
}
|
||||||
|
if (msr_val & THERM_LOG_THRESHOLD1) {
|
||||||
|
wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS,
|
||||||
|
msr_val & ~THERM_LOG_THRESHOLD1);
|
||||||
|
notify = true;
|
||||||
|
}
|
||||||
|
if (notify) {
|
||||||
|
pr_debug("thermal_zone_device_update\n");
|
||||||
|
thermal_zone_device_update(phdev->tzone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
int phy_id = topology_physical_package_id(cpu);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When a package is in interrupted state, all CPU's in that package
|
||||||
|
* are in the same interrupt state. So scheduling on any one CPU in
|
||||||
|
* the package is enough and simply return for others.
|
||||||
|
*/
|
||||||
|
spin_lock_irqsave(&pkg_work_lock, flags);
|
||||||
|
++pkg_interrupt_cnt;
|
||||||
|
if (unlikely(phy_id > max_phy_id) || unlikely(!pkg_work_scheduled) ||
|
||||||
|
pkg_work_scheduled[phy_id]) {
|
||||||
|
disable_pkg_thres_interrupt();
|
||||||
|
spin_unlock_irqrestore(&pkg_work_lock, flags);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
pkg_work_scheduled[phy_id] = 1;
|
||||||
|
spin_unlock_irqrestore(&pkg_work_lock, flags);
|
||||||
|
|
||||||
|
disable_pkg_thres_interrupt();
|
||||||
|
schedule_delayed_work_on(cpu,
|
||||||
|
&per_cpu(pkg_temp_thermal_threshold_work, cpu),
|
||||||
|
msecs_to_jiffies(notify_delay_ms));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int find_siblings_cpu(int cpu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int id = topology_physical_package_id(cpu);
|
||||||
|
|
||||||
|
for_each_online_cpu(i)
|
||||||
|
if (i != cpu && topology_physical_package_id(i) == id)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
u32 tj_max;
|
||||||
|
struct phy_dev_entry *phy_dev_entry;
|
||||||
|
char buffer[30];
|
||||||
|
int thres_count;
|
||||||
|
u32 eax, ebx, ecx, edx;
|
||||||
|
|
||||||
|
cpuid(6, &eax, &ebx, &ecx, &edx);
|
||||||
|
thres_count = ebx & 0x07;
|
||||||
|
if (!thres_count)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
|
||||||
|
|
||||||
|
err = get_tj_max(cpu, &tj_max);
|
||||||
|
if (err)
|
||||||
|
goto err_ret;
|
||||||
|
|
||||||
|
mutex_lock(&phy_dev_list_mutex);
|
||||||
|
|
||||||
|
phy_dev_entry = kzalloc(sizeof(*phy_dev_entry), GFP_KERNEL);
|
||||||
|
if (!phy_dev_entry) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_ret_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock(&pkg_work_lock);
|
||||||
|
if (topology_physical_package_id(cpu) > max_phy_id)
|
||||||
|
max_phy_id = topology_physical_package_id(cpu);
|
||||||
|
pkg_work_scheduled = krealloc(pkg_work_scheduled,
|
||||||
|
(max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
|
||||||
|
if (!pkg_work_scheduled) {
|
||||||
|
spin_unlock(&pkg_work_lock);
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_ret_free;
|
||||||
|
}
|
||||||
|
pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
|
||||||
|
spin_unlock(&pkg_work_lock);
|
||||||
|
|
||||||
|
phy_dev_entry->phys_proc_id = topology_physical_package_id(cpu);
|
||||||
|
phy_dev_entry->first_cpu = cpu;
|
||||||
|
phy_dev_entry->tj_max = tj_max;
|
||||||
|
phy_dev_entry->ref_cnt = 1;
|
||||||
|
snprintf(buffer, sizeof(buffer), "pkg-temp-%d\n",
|
||||||
|
phy_dev_entry->phys_proc_id);
|
||||||
|
phy_dev_entry->tzone = thermal_zone_device_register(buffer,
|
||||||
|
thres_count,
|
||||||
|
(thres_count == MAX_NUMBER_OF_TRIPS) ?
|
||||||
|
0x03 : 0x01,
|
||||||
|
phy_dev_entry, &tzone_ops, NULL, 0, 0);
|
||||||
|
if (IS_ERR(phy_dev_entry->tzone)) {
|
||||||
|
err = PTR_ERR(phy_dev_entry->tzone);
|
||||||
|
goto err_ret_free;
|
||||||
|
}
|
||||||
|
/* Store MSR value for package thermal interrupt, to restore at exit */
|
||||||
|
rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||||
|
&phy_dev_entry->start_pkg_therm_low,
|
||||||
|
&phy_dev_entry->start_pkg_therm_high);
|
||||||
|
|
||||||
|
list_add_tail(&phy_dev_entry->list, &phy_dev_list);
|
||||||
|
pr_debug("pkg_temp_thermal_device_add :phy_id %d cpu %d\n",
|
||||||
|
phy_dev_entry->phys_proc_id, cpu);
|
||||||
|
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_ret_free:
|
||||||
|
kfree(phy_dev_entry);
|
||||||
|
err_ret_unlock:
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
|
||||||
|
err_ret:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkg_temp_thermal_device_remove(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct phy_dev_entry *n;
|
||||||
|
u16 phys_proc_id = topology_physical_package_id(cpu);
|
||||||
|
struct phy_dev_entry *phdev =
|
||||||
|
pkg_temp_thermal_get_phy_entry(cpu);
|
||||||
|
|
||||||
|
if (!phdev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
mutex_lock(&phy_dev_list_mutex);
|
||||||
|
/* If we are loosing the first cpu for this package, we need change */
|
||||||
|
if (phdev->first_cpu == cpu) {
|
||||||
|
phdev->first_cpu = find_siblings_cpu(cpu);
|
||||||
|
pr_debug("thermal_device_remove: first cpu switched %d\n",
|
||||||
|
phdev->first_cpu);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* It is possible that no siblings left as this was the last cpu
|
||||||
|
* going offline. We don't need to worry about this assignment
|
||||||
|
* as the phydev entry will be removed in this case and
|
||||||
|
* thermal zone is removed.
|
||||||
|
*/
|
||||||
|
--phdev->ref_cnt;
|
||||||
|
pr_debug("thermal_device_remove: pkg: %d cpu %d ref_cnt %d\n",
|
||||||
|
phys_proc_id, cpu, phdev->ref_cnt);
|
||||||
|
if (!phdev->ref_cnt)
|
||||||
|
list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
|
||||||
|
if (phdev->phys_proc_id == phys_proc_id) {
|
||||||
|
thermal_zone_device_unregister(phdev->tzone);
|
||||||
|
list_del(&phdev->list);
|
||||||
|
kfree(phdev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_core_online(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||||
|
struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
|
||||||
|
|
||||||
|
/* Check if there is already an instance for this package */
|
||||||
|
if (!phdev) {
|
||||||
|
if (!cpu_has(c, X86_FEATURE_DTHERM) &&
|
||||||
|
!cpu_has(c, X86_FEATURE_PTS))
|
||||||
|
return -ENODEV;
|
||||||
|
if (pkg_temp_thermal_device_add(cpu))
|
||||||
|
return -ENODEV;
|
||||||
|
} else {
|
||||||
|
mutex_lock(&phy_dev_list_mutex);
|
||||||
|
++phdev->ref_cnt;
|
||||||
|
pr_debug("get_core_online: cpu %d ref_cnt %d\n",
|
||||||
|
cpu, phdev->ref_cnt);
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
}
|
||||||
|
INIT_DELAYED_WORK(&per_cpu(pkg_temp_thermal_threshold_work, cpu),
|
||||||
|
pkg_temp_thermal_threshold_work_fn);
|
||||||
|
|
||||||
|
pr_debug("get_core_online: cpu %d successful\n", cpu);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_core_offline(unsigned int cpu)
|
||||||
|
{
|
||||||
|
if (!pkg_temp_thermal_device_remove(cpu))
|
||||||
|
cancel_delayed_work_sync(
|
||||||
|
&per_cpu(pkg_temp_thermal_threshold_work, cpu));
|
||||||
|
|
||||||
|
pr_debug("put_core_offline: cpu %d\n", cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pkg_temp_thermal_cpu_callback(struct notifier_block *nfb,
|
||||||
|
unsigned long action, void *hcpu)
|
||||||
|
{
|
||||||
|
unsigned int cpu = (unsigned long) hcpu;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case CPU_ONLINE:
|
||||||
|
case CPU_DOWN_FAILED:
|
||||||
|
get_core_online(cpu);
|
||||||
|
break;
|
||||||
|
case CPU_DOWN_PREPARE:
|
||||||
|
put_core_offline(cpu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block pkg_temp_thermal_notifier __refdata = {
|
||||||
|
.notifier_call = pkg_temp_thermal_cpu_callback,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct x86_cpu_id __initconst pkg_temp_thermal_ids[] = {
|
||||||
|
{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids);
|
||||||
|
|
||||||
|
static int __init pkg_temp_thermal_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!x86_match_cpu(pkg_temp_thermal_ids))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
spin_lock_init(&pkg_work_lock);
|
||||||
|
platform_thermal_package_notify =
|
||||||
|
pkg_temp_thermal_platform_thermal_notify;
|
||||||
|
platform_thermal_package_rate_control =
|
||||||
|
pkg_temp_thermal_platform_thermal_rate_control;
|
||||||
|
|
||||||
|
get_online_cpus();
|
||||||
|
for_each_online_cpu(i)
|
||||||
|
if (get_core_online(i))
|
||||||
|
goto err_ret;
|
||||||
|
register_hotcpu_notifier(&pkg_temp_thermal_notifier);
|
||||||
|
put_online_cpus();
|
||||||
|
|
||||||
|
pkg_temp_debugfs_init(); /* Don't care if fails */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_ret:
|
||||||
|
get_online_cpus();
|
||||||
|
for_each_online_cpu(i)
|
||||||
|
put_core_offline(i);
|
||||||
|
put_online_cpus();
|
||||||
|
kfree(pkg_work_scheduled);
|
||||||
|
platform_thermal_package_notify = NULL;
|
||||||
|
platform_thermal_package_rate_control = NULL;
|
||||||
|
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit pkg_temp_thermal_exit(void)
|
||||||
|
{
|
||||||
|
struct phy_dev_entry *phdev, *n;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
get_online_cpus();
|
||||||
|
unregister_hotcpu_notifier(&pkg_temp_thermal_notifier);
|
||||||
|
mutex_lock(&phy_dev_list_mutex);
|
||||||
|
list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
|
||||||
|
/* Retore old MSR value for package thermal interrupt */
|
||||||
|
wrmsr_on_cpu(phdev->first_cpu,
|
||||||
|
MSR_IA32_PACKAGE_THERM_INTERRUPT,
|
||||||
|
phdev->start_pkg_therm_low,
|
||||||
|
phdev->start_pkg_therm_high);
|
||||||
|
thermal_zone_device_unregister(phdev->tzone);
|
||||||
|
list_del(&phdev->list);
|
||||||
|
kfree(phdev);
|
||||||
|
}
|
||||||
|
mutex_unlock(&phy_dev_list_mutex);
|
||||||
|
platform_thermal_package_notify = NULL;
|
||||||
|
platform_thermal_package_rate_control = NULL;
|
||||||
|
for_each_online_cpu(i)
|
||||||
|
cancel_delayed_work_sync(
|
||||||
|
&per_cpu(pkg_temp_thermal_threshold_work, i));
|
||||||
|
put_online_cpus();
|
||||||
|
|
||||||
|
kfree(pkg_work_scheduled);
|
||||||
|
|
||||||
|
debugfs_remove_recursive(debugfs);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(pkg_temp_thermal_init)
|
||||||
|
module_exit(pkg_temp_thermal_exit)
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver");
|
||||||
|
MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -41,7 +41,7 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus);
|
||||||
*/
|
*/
|
||||||
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev);
|
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev);
|
||||||
|
|
||||||
unsigned long cpufreq_cooling_get_level(unsigned int, unsigned int);
|
unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq);
|
||||||
#else /* !CONFIG_CPU_THERMAL */
|
#else /* !CONFIG_CPU_THERMAL */
|
||||||
static inline struct thermal_cooling_device *
|
static inline struct thermal_cooling_device *
|
||||||
cpufreq_cooling_register(const struct cpumask *clip_cpus)
|
cpufreq_cooling_register(const struct cpumask *clip_cpus)
|
||||||
|
@ -54,7 +54,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
unsigned long cpufreq_cooling_get_level(unsigned int, unsigned int)
|
unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq)
|
||||||
{
|
{
|
||||||
return THERMAL_CSTATE_INVALID;
|
return THERMAL_CSTATE_INVALID;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue