Merge branch 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
Pull thermal management fixes from Zhang Rui: "These includes several commits that are necessary to properly fix regression for TMU test MUX address setting after reset, for exynos thermal driver. Specifics: - fix a regression that the removal of setting a certain field at TMU configuration setting results in immediately shutdown after reset on Exynos4412 SoC. - revert a patch which tries to link the thermal_zone device and its hwmon node but breaks libsensors. - fix a deadlock/lockdep warning issue in x86_pkg_temp thermal driver, which can be reproduced on a buggy platform only. - fix ti-soc-thermal driver to fall back on bandgap reading when reading from PCB temperature sensor fails" * 'for-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux: Revert "drivers: thermal: parent virtual hwmon with thermal zone" drivers: thermal: allow ti-soc-thermal run without pcb zone thermal: exynos: Provide initial setting for TMU's test MUX address at Exynos4412 thermal: exynos: Provide separate TMU data for Exynos4412 thermal: exynos: Remove check for thermal device pointer at exynos_report_trigger() Thermal: x86_pkg_temp: change spin lock
This commit is contained in:
Коммит
90338325a9
|
@ -310,8 +310,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
th_zone = conf->pzone_data;
|
th_zone = conf->pzone_data;
|
||||||
if (th_zone->therm_dev)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (th_zone->bind == false) {
|
if (th_zone->bind == false) {
|
||||||
for (i = 0; i < th_zone->cool_dev_size; i++) {
|
for (i = 0; i < th_zone->cool_dev_size; i++) {
|
||||||
|
|
|
@ -317,6 +317,9 @@ static void exynos_tmu_control(struct platform_device *pdev, bool on)
|
||||||
|
|
||||||
con = readl(data->base + reg->tmu_ctrl);
|
con = readl(data->base + reg->tmu_ctrl);
|
||||||
|
|
||||||
|
if (pdata->test_mux)
|
||||||
|
con |= (pdata->test_mux << reg->test_mux_addr_shift);
|
||||||
|
|
||||||
if (pdata->reference_voltage) {
|
if (pdata->reference_voltage) {
|
||||||
con &= ~(reg->buf_vref_sel_mask << reg->buf_vref_sel_shift);
|
con &= ~(reg->buf_vref_sel_mask << reg->buf_vref_sel_shift);
|
||||||
con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
|
con |= pdata->reference_voltage << reg->buf_vref_sel_shift;
|
||||||
|
@ -488,7 +491,7 @@ static const struct of_device_id exynos_tmu_match[] = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.compatible = "samsung,exynos4412-tmu",
|
.compatible = "samsung,exynos4412-tmu",
|
||||||
.data = (void *)EXYNOS5250_TMU_DRV_DATA,
|
.data = (void *)EXYNOS4412_TMU_DRV_DATA,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.compatible = "samsung,exynos5250-tmu",
|
.compatible = "samsung,exynos5250-tmu",
|
||||||
|
@ -629,8 +632,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (pdata->type == SOC_ARCH_EXYNOS ||
|
if (pdata->type == SOC_ARCH_EXYNOS4210 ||
|
||||||
pdata->type == SOC_ARCH_EXYNOS4210 ||
|
pdata->type == SOC_ARCH_EXYNOS4412 ||
|
||||||
|
pdata->type == SOC_ARCH_EXYNOS5250 ||
|
||||||
pdata->type == SOC_ARCH_EXYNOS5440)
|
pdata->type == SOC_ARCH_EXYNOS5440)
|
||||||
data->soc = pdata->type;
|
data->soc = pdata->type;
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -41,7 +41,8 @@ enum calibration_mode {
|
||||||
|
|
||||||
enum soc_type {
|
enum soc_type {
|
||||||
SOC_ARCH_EXYNOS4210 = 1,
|
SOC_ARCH_EXYNOS4210 = 1,
|
||||||
SOC_ARCH_EXYNOS,
|
SOC_ARCH_EXYNOS4412,
|
||||||
|
SOC_ARCH_EXYNOS5250,
|
||||||
SOC_ARCH_EXYNOS5440,
|
SOC_ARCH_EXYNOS5440,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@ enum soc_type {
|
||||||
* @triminfo_reload_shift: shift of triminfo reload enable bit in triminfo_ctrl
|
* @triminfo_reload_shift: shift of triminfo reload enable bit in triminfo_ctrl
|
||||||
reg.
|
reg.
|
||||||
* @tmu_ctrl: TMU main controller register.
|
* @tmu_ctrl: TMU main controller register.
|
||||||
|
* @test_mux_addr_shift: shift bits of test mux address.
|
||||||
* @buf_vref_sel_shift: shift bits of reference voltage in tmu_ctrl register.
|
* @buf_vref_sel_shift: shift bits of reference voltage in tmu_ctrl register.
|
||||||
* @buf_vref_sel_mask: mask bits of reference voltage in tmu_ctrl register.
|
* @buf_vref_sel_mask: mask bits of reference voltage in tmu_ctrl register.
|
||||||
* @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register.
|
* @therm_trip_mode_shift: shift bits of tripping mode in tmu_ctrl register.
|
||||||
|
@ -150,6 +152,7 @@ struct exynos_tmu_registers {
|
||||||
u32 triminfo_reload_shift;
|
u32 triminfo_reload_shift;
|
||||||
|
|
||||||
u32 tmu_ctrl;
|
u32 tmu_ctrl;
|
||||||
|
u32 test_mux_addr_shift;
|
||||||
u32 buf_vref_sel_shift;
|
u32 buf_vref_sel_shift;
|
||||||
u32 buf_vref_sel_mask;
|
u32 buf_vref_sel_mask;
|
||||||
u32 therm_trip_mode_shift;
|
u32 therm_trip_mode_shift;
|
||||||
|
@ -257,6 +260,7 @@ struct exynos_tmu_registers {
|
||||||
* @first_point_trim: temp value of the first point trimming
|
* @first_point_trim: temp value of the first point trimming
|
||||||
* @second_point_trim: temp value of the second point trimming
|
* @second_point_trim: temp value of the second point trimming
|
||||||
* @default_temp_offset: default temperature offset in case of no trimming
|
* @default_temp_offset: default temperature offset in case of no trimming
|
||||||
|
* @test_mux; information if SoC supports test MUX
|
||||||
* @cal_type: calibration type for temperature
|
* @cal_type: calibration type for temperature
|
||||||
* @cal_mode: calibration mode for temperature
|
* @cal_mode: calibration mode for temperature
|
||||||
* @freq_clip_table: Table representing frequency reduction percentage.
|
* @freq_clip_table: Table representing frequency reduction percentage.
|
||||||
|
@ -286,6 +290,7 @@ struct exynos_tmu_platform_data {
|
||||||
u8 first_point_trim;
|
u8 first_point_trim;
|
||||||
u8 second_point_trim;
|
u8 second_point_trim;
|
||||||
u8 default_temp_offset;
|
u8 default_temp_offset;
|
||||||
|
u8 test_mux;
|
||||||
|
|
||||||
enum calibration_type cal_type;
|
enum calibration_type cal_type;
|
||||||
enum calibration_mode cal_mode;
|
enum calibration_mode cal_mode;
|
||||||
|
|
|
@ -90,14 +90,15 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
|
#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
|
||||||
static const struct exynos_tmu_registers exynos5250_tmu_registers = {
|
static const struct exynos_tmu_registers exynos4412_tmu_registers = {
|
||||||
.triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
|
.triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
|
||||||
.triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
|
.triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
|
||||||
.triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
|
.triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
|
||||||
.triminfo_ctrl = EXYNOS_TMU_TRIMINFO_CON,
|
.triminfo_ctrl = EXYNOS_TMU_TRIMINFO_CON,
|
||||||
.triminfo_reload_shift = EXYNOS_TRIMINFO_RELOAD_SHIFT,
|
.triminfo_reload_shift = EXYNOS_TRIMINFO_RELOAD_SHIFT,
|
||||||
.tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
|
.tmu_ctrl = EXYNOS_TMU_REG_CONTROL,
|
||||||
|
.test_mux_addr_shift = EXYNOS4412_MUX_ADDR_SHIFT,
|
||||||
.buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
|
.buf_vref_sel_shift = EXYNOS_TMU_REF_VOLTAGE_SHIFT,
|
||||||
.buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
|
.buf_vref_sel_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
|
||||||
.therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
|
.therm_trip_mode_shift = EXYNOS_TMU_TRIP_MODE_SHIFT,
|
||||||
|
@ -128,7 +129,7 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
|
||||||
.emul_time_mask = EXYNOS_EMUL_TIME_MASK,
|
.emul_time_mask = EXYNOS_EMUL_TIME_MASK,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EXYNOS5250_TMU_DATA \
|
#define EXYNOS4412_TMU_DATA \
|
||||||
.threshold_falling = 10, \
|
.threshold_falling = 10, \
|
||||||
.trigger_levels[0] = 85, \
|
.trigger_levels[0] = 85, \
|
||||||
.trigger_levels[1] = 103, \
|
.trigger_levels[1] = 103, \
|
||||||
|
@ -162,15 +163,32 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
|
||||||
.temp_level = 103, \
|
.temp_level = 103, \
|
||||||
}, \
|
}, \
|
||||||
.freq_tab_count = 2, \
|
.freq_tab_count = 2, \
|
||||||
.type = SOC_ARCH_EXYNOS, \
|
.registers = &exynos4412_tmu_registers, \
|
||||||
.registers = &exynos5250_tmu_registers, \
|
|
||||||
.features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
|
.features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
|
||||||
TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
|
TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
|
||||||
TMU_SUPPORT_EMUL_TIME)
|
TMU_SUPPORT_EMUL_TIME)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_EXYNOS4412)
|
||||||
|
struct exynos_tmu_init_data const exynos4412_default_tmu_data = {
|
||||||
|
.tmu_data = {
|
||||||
|
{
|
||||||
|
EXYNOS4412_TMU_DATA,
|
||||||
|
.type = SOC_ARCH_EXYNOS4412,
|
||||||
|
.test_mux = EXYNOS4412_MUX_ADDR_VALUE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.tmu_count = 1,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_EXYNOS5250)
|
||||||
struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
|
struct exynos_tmu_init_data const exynos5250_default_tmu_data = {
|
||||||
.tmu_data = {
|
.tmu_data = {
|
||||||
{ EXYNOS5250_TMU_DATA },
|
{
|
||||||
|
EXYNOS4412_TMU_DATA,
|
||||||
|
.type = SOC_ARCH_EXYNOS5250,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.tmu_count = 1,
|
.tmu_count = 1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,6 +95,10 @@
|
||||||
|
|
||||||
#define EXYNOS_MAX_TRIGGER_PER_REG 4
|
#define EXYNOS_MAX_TRIGGER_PER_REG 4
|
||||||
|
|
||||||
|
/* Exynos4412 specific */
|
||||||
|
#define EXYNOS4412_MUX_ADDR_VALUE 6
|
||||||
|
#define EXYNOS4412_MUX_ADDR_SHIFT 20
|
||||||
|
|
||||||
/*exynos5440 specific registers*/
|
/*exynos5440 specific registers*/
|
||||||
#define EXYNOS5440_TMU_S0_7_TRIM 0x000
|
#define EXYNOS5440_TMU_S0_7_TRIM 0x000
|
||||||
#define EXYNOS5440_TMU_S0_7_CTRL 0x020
|
#define EXYNOS5440_TMU_S0_7_CTRL 0x020
|
||||||
|
@ -138,7 +142,14 @@ extern struct exynos_tmu_init_data const exynos4210_default_tmu_data;
|
||||||
#define EXYNOS4210_TMU_DRV_DATA (NULL)
|
#define EXYNOS4210_TMU_DRV_DATA (NULL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412))
|
#if defined(CONFIG_SOC_EXYNOS4412)
|
||||||
|
extern struct exynos_tmu_init_data const exynos4412_default_tmu_data;
|
||||||
|
#define EXYNOS4412_TMU_DRV_DATA (&exynos4412_default_tmu_data)
|
||||||
|
#else
|
||||||
|
#define EXYNOS4412_TMU_DRV_DATA (NULL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_EXYNOS5250)
|
||||||
extern struct exynos_tmu_init_data const exynos5250_default_tmu_data;
|
extern struct exynos_tmu_init_data const exynos5250_default_tmu_data;
|
||||||
#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
|
#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -159,7 +159,7 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
|
||||||
|
|
||||||
INIT_LIST_HEAD(&hwmon->tz_list);
|
INIT_LIST_HEAD(&hwmon->tz_list);
|
||||||
strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
|
strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
|
||||||
hwmon->device = hwmon_device_register(&tz->device);
|
hwmon->device = hwmon_device_register(NULL);
|
||||||
if (IS_ERR(hwmon->device)) {
|
if (IS_ERR(hwmon->device)) {
|
||||||
result = PTR_ERR(hwmon->device);
|
result = PTR_ERR(hwmon->device);
|
||||||
goto free_mem;
|
goto free_mem;
|
||||||
|
|
|
@ -110,6 +110,7 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
|
||||||
} else {
|
} else {
|
||||||
dev_err(bgp->dev,
|
dev_err(bgp->dev,
|
||||||
"Failed to read PCB state. Using defaults\n");
|
"Failed to read PCB state. Using defaults\n");
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*temp = ti_thermal_hotspot_temperature(tmp, slope, constant);
|
*temp = ti_thermal_hotspot_temperature(tmp, slope, constant);
|
||||||
|
|
|
@ -316,18 +316,19 @@ static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
|
||||||
int phy_id = topology_physical_package_id(cpu);
|
int phy_id = topology_physical_package_id(cpu);
|
||||||
struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
|
struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!phdev)
|
if (!phdev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
spin_lock(&pkg_work_lock);
|
spin_lock_irqsave(&pkg_work_lock, flags);
|
||||||
++pkg_work_cnt;
|
++pkg_work_cnt;
|
||||||
if (unlikely(phy_id > max_phy_id)) {
|
if (unlikely(phy_id > max_phy_id)) {
|
||||||
spin_unlock(&pkg_work_lock);
|
spin_unlock_irqrestore(&pkg_work_lock, flags);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pkg_work_scheduled[phy_id] = 0;
|
pkg_work_scheduled[phy_id] = 0;
|
||||||
spin_unlock(&pkg_work_lock);
|
spin_unlock_irqrestore(&pkg_work_lock, flags);
|
||||||
|
|
||||||
enable_pkg_thres_interrupt();
|
enable_pkg_thres_interrupt();
|
||||||
rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
|
rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
|
||||||
|
@ -397,6 +398,7 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||||
int thres_count;
|
int thres_count;
|
||||||
u32 eax, ebx, ecx, edx;
|
u32 eax, ebx, ecx, edx;
|
||||||
u8 *temp;
|
u8 *temp;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
cpuid(6, &eax, &ebx, &ecx, &edx);
|
cpuid(6, &eax, &ebx, &ecx, &edx);
|
||||||
thres_count = ebx & 0x07;
|
thres_count = ebx & 0x07;
|
||||||
|
@ -420,19 +422,19 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
|
||||||
goto err_ret_unlock;
|
goto err_ret_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock(&pkg_work_lock);
|
spin_lock_irqsave(&pkg_work_lock, flags);
|
||||||
if (topology_physical_package_id(cpu) > max_phy_id)
|
if (topology_physical_package_id(cpu) > max_phy_id)
|
||||||
max_phy_id = topology_physical_package_id(cpu);
|
max_phy_id = topology_physical_package_id(cpu);
|
||||||
temp = krealloc(pkg_work_scheduled,
|
temp = krealloc(pkg_work_scheduled,
|
||||||
(max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
|
(max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
spin_unlock(&pkg_work_lock);
|
spin_unlock_irqrestore(&pkg_work_lock, flags);
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_ret_free;
|
goto err_ret_free;
|
||||||
}
|
}
|
||||||
pkg_work_scheduled = temp;
|
pkg_work_scheduled = temp;
|
||||||
pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
|
pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
|
||||||
spin_unlock(&pkg_work_lock);
|
spin_unlock_irqrestore(&pkg_work_lock, flags);
|
||||||
|
|
||||||
phy_dev_entry->phys_proc_id = topology_physical_package_id(cpu);
|
phy_dev_entry->phys_proc_id = topology_physical_package_id(cpu);
|
||||||
phy_dev_entry->first_cpu = cpu;
|
phy_dev_entry->first_cpu = cpu;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче