Commit 90338325 authored by Linus Torvalds's avatar Linus Torvalds

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
parents ea89e1d3 167c3ad2
...@@ -310,8 +310,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf) ...@@ -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) ...@@ -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[] = { ...@@ -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,9 +632,10 @@ static int exynos_tmu_probe(struct platform_device *pdev) ...@@ -629,9 +632,10 @@ 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_EXYNOS5440) pdata->type == SOC_ARCH_EXYNOS5250 ||
pdata->type == SOC_ARCH_EXYNOS5440)
data->soc = pdata->type; data->soc = pdata->type;
else { else {
ret = -EINVAL; ret = -EINVAL;
......
...@@ -41,7 +41,8 @@ enum calibration_mode { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 = { ...@@ -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 = { ...@@ -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 = { ...@@ -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 @@ ...@@ -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; ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment