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)
}
th_zone = conf->pzone_data;
if (th_zone->therm_dev)
return;
if (th_zone->bind == false) {
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);
if (pdata->test_mux)
con |= (pdata->test_mux << reg->test_mux_addr_shift);
if (pdata->reference_voltage) {
con &= ~(reg->buf_vref_sel_mask << 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",
.data = (void *)EXYNOS5250_TMU_DRV_DATA,
.data = (void *)EXYNOS4412_TMU_DRV_DATA,
},
{
.compatible = "samsung,exynos5250-tmu",
......@@ -629,9 +632,10 @@ static int exynos_tmu_probe(struct platform_device *pdev)
if (ret)
return ret;
if (pdata->type == SOC_ARCH_EXYNOS ||
pdata->type == SOC_ARCH_EXYNOS4210 ||
pdata->type == SOC_ARCH_EXYNOS5440)
if (pdata->type == SOC_ARCH_EXYNOS4210 ||
pdata->type == SOC_ARCH_EXYNOS4412 ||
pdata->type == SOC_ARCH_EXYNOS5250 ||
pdata->type == SOC_ARCH_EXYNOS5440)
data->soc = pdata->type;
else {
ret = -EINVAL;
......
......@@ -41,7 +41,8 @@ enum calibration_mode {
enum soc_type {
SOC_ARCH_EXYNOS4210 = 1,
SOC_ARCH_EXYNOS,
SOC_ARCH_EXYNOS4412,
SOC_ARCH_EXYNOS5250,
SOC_ARCH_EXYNOS5440,
};
......@@ -84,6 +85,7 @@ enum soc_type {
* @triminfo_reload_shift: shift of triminfo reload enable bit in triminfo_ctrl
reg.
* @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_mask: mask bits of reference voltage 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 tmu_ctrl;
u32 test_mux_addr_shift;
u32 buf_vref_sel_shift;
u32 buf_vref_sel_mask;
u32 therm_trip_mode_shift;
......@@ -257,6 +260,7 @@ struct exynos_tmu_registers {
* @first_point_trim: temp value of the first point trimming
* @second_point_trim: temp value of the second point 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_mode: calibration mode for temperature
* @freq_clip_table: Table representing frequency reduction percentage.
......@@ -286,6 +290,7 @@ struct exynos_tmu_platform_data {
u8 first_point_trim;
u8 second_point_trim;
u8 default_temp_offset;
u8 test_mux;
enum calibration_type cal_type;
enum calibration_mode cal_mode;
......
......@@ -90,14 +90,15 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = {
};
#endif
#if defined(CONFIG_SOC_EXYNOS5250) || defined(CONFIG_SOC_EXYNOS4412)
static const struct exynos_tmu_registers exynos5250_tmu_registers = {
#if defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250)
static const struct exynos_tmu_registers exynos4412_tmu_registers = {
.triminfo_data = EXYNOS_TMU_REG_TRIMINFO,
.triminfo_25_shift = EXYNOS_TRIMINFO_25_SHIFT,
.triminfo_85_shift = EXYNOS_TRIMINFO_85_SHIFT,
.triminfo_ctrl = EXYNOS_TMU_TRIMINFO_CON,
.triminfo_reload_shift = EXYNOS_TRIMINFO_RELOAD_SHIFT,
.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_mask = EXYNOS_TMU_REF_VOLTAGE_MASK,
.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,
};
#define EXYNOS5250_TMU_DATA \
#define EXYNOS4412_TMU_DATA \
.threshold_falling = 10, \
.trigger_levels[0] = 85, \
.trigger_levels[1] = 103, \
......@@ -162,15 +163,32 @@ static const struct exynos_tmu_registers exynos5250_tmu_registers = {
.temp_level = 103, \
}, \
.freq_tab_count = 2, \
.type = SOC_ARCH_EXYNOS, \
.registers = &exynos5250_tmu_registers, \
.registers = &exynos4412_tmu_registers, \
.features = (TMU_SUPPORT_EMULATION | TMU_SUPPORT_TRIM_RELOAD | \
TMU_SUPPORT_FALLING_TRIP | TMU_SUPPORT_READY_STATUS | \
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 = {
.tmu_data = {
{ EXYNOS5250_TMU_DATA },
{
EXYNOS4412_TMU_DATA,
.type = SOC_ARCH_EXYNOS5250,
},
},
.tmu_count = 1,
};
......
......@@ -95,6 +95,10 @@
#define EXYNOS_MAX_TRIGGER_PER_REG 4
/* Exynos4412 specific */
#define EXYNOS4412_MUX_ADDR_VALUE 6
#define EXYNOS4412_MUX_ADDR_SHIFT 20
/*exynos5440 specific registers*/
#define EXYNOS5440_TMU_S0_7_TRIM 0x000
#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)
#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;
#define EXYNOS5250_TMU_DRV_DATA (&exynos5250_default_tmu_data)
#else
......
......@@ -159,7 +159,7 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
INIT_LIST_HEAD(&hwmon->tz_list);
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)) {
result = PTR_ERR(hwmon->device);
goto free_mem;
......
......@@ -110,6 +110,7 @@ static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal,
} else {
dev_err(bgp->dev,
"Failed to read PCB state. Using defaults\n");
ret = 0;
}
}
*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);
struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
bool notify = false;
unsigned long flags;
if (!phdev)
return;
spin_lock(&pkg_work_lock);
spin_lock_irqsave(&pkg_work_lock, flags);
++pkg_work_cnt;
if (unlikely(phy_id > max_phy_id)) {
spin_unlock(&pkg_work_lock);
spin_unlock_irqrestore(&pkg_work_lock, flags);
return;
}
pkg_work_scheduled[phy_id] = 0;
spin_unlock(&pkg_work_lock);
spin_unlock_irqrestore(&pkg_work_lock, flags);
enable_pkg_thres_interrupt();
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;
u32 eax, ebx, ecx, edx;
u8 *temp;
unsigned long flags;
cpuid(6, &eax, &ebx, &ecx, &edx);
thres_count = ebx & 0x07;
......@@ -420,19 +422,19 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
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)
max_phy_id = topology_physical_package_id(cpu);
temp = krealloc(pkg_work_scheduled,
(max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
if (!temp) {
spin_unlock(&pkg_work_lock);
spin_unlock_irqrestore(&pkg_work_lock, flags);
err = -ENOMEM;
goto err_ret_free;
}
pkg_work_scheduled = temp;
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->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