Skip to content

Commit fdf4f2f

Browse files
spandruvadazhang-rui
authored andcommitted
drivers: thermal: processor_thermal_device: Export sysfs interface for TCC offset
This change exports an interface to read tcc offset and allow writing if the platform is not locked. Refer to Intel SDM for details on the MSR: MSR_TEMPERATURE_TARGET. Here TCC Activation Offset (R/W) bits allow temperature offset in degrees in relation to TjMAX. This change will be useful for improving performance from user space for some platforms, if the current offset is not optimal. Signed-off-by: Srinivas Pandruvada <[email protected]> Tested-by: Benjamin Berg <[email protected]> Signed-off-by: Zhang Rui <[email protected]>
1 parent d1abaeb commit fdf4f2f

File tree

1 file changed

+87
-4
lines changed

1 file changed

+87
-4
lines changed

drivers/thermal/intel/int340x_thermal/processor_thermal_device.c

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,72 @@ static const struct attribute_group power_limit_attribute_group = {
137137
.name = "power_limits"
138138
};
139139

140+
static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
141+
struct device_attribute *attr, char *buf)
142+
{
143+
u64 val;
144+
int err;
145+
146+
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
147+
if (err)
148+
return err;
149+
150+
val = (val >> 24) & 0xff;
151+
return sprintf(buf, "%d\n", (int)val);
152+
}
153+
154+
static int tcc_offset_update(int tcc)
155+
{
156+
u64 val;
157+
int err;
158+
159+
if (!tcc)
160+
return -EINVAL;
161+
162+
err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
163+
if (err)
164+
return err;
165+
166+
val &= ~GENMASK_ULL(31, 24);
167+
val |= (tcc & 0xff) << 24;
168+
169+
err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
170+
if (err)
171+
return err;
172+
173+
return 0;
174+
}
175+
176+
static int tcc_offset_save;
177+
178+
static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
179+
struct device_attribute *attr, const char *buf,
180+
size_t count)
181+
{
182+
u64 val;
183+
int tcc, err;
184+
185+
err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
186+
if (err)
187+
return err;
188+
189+
if (!(val & BIT(30)))
190+
return -EACCES;
191+
192+
if (kstrtoint(buf, 0, &tcc))
193+
return -EINVAL;
194+
195+
err = tcc_offset_update(tcc);
196+
if (err)
197+
return err;
198+
199+
tcc_offset_save = tcc;
200+
201+
return count;
202+
}
203+
204+
static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
205+
140206
static int stored_tjmax; /* since it is fixed, we can have local storage */
141207

142208
static int get_tjmax(void)
@@ -332,6 +398,7 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
332398
acpi_remove_notify_handler(proc_priv->adev->handle,
333399
ACPI_DEVICE_NOTIFY, proc_thermal_notify);
334400
int340x_thermal_zone_remove(proc_priv->int340x_zone);
401+
sysfs_remove_file(&proc_priv->dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
335402
sysfs_remove_group(&proc_priv->dev->kobj,
336403
&power_limit_attribute_group);
337404
}
@@ -355,8 +422,15 @@ static int int3401_add(struct platform_device *pdev)
355422

356423
dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
357424

358-
return sysfs_create_group(&pdev->dev.kobj,
359-
&power_limit_attribute_group);
425+
ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
426+
if (ret)
427+
return ret;
428+
429+
ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
430+
if (ret)
431+
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
432+
433+
return ret;
360434
}
361435

362436
static int int3401_remove(struct platform_device *pdev)
@@ -588,8 +662,15 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev,
588662

589663
dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
590664

591-
return sysfs_create_group(&pdev->dev.kobj,
592-
&power_limit_attribute_group);
665+
ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
666+
if (ret)
667+
return ret;
668+
669+
ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
670+
if (ret)
671+
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
672+
673+
return ret;
593674
}
594675

595676
static void proc_thermal_pci_remove(struct pci_dev *pdev)
@@ -615,6 +696,8 @@ static int proc_thermal_resume(struct device *dev)
615696
proc_dev = dev_get_drvdata(dev);
616697
proc_thermal_read_ppcc(proc_dev);
617698

699+
tcc_offset_update(tcc_offset_save);
700+
618701
return 0;
619702
}
620703
#else

0 commit comments

Comments
 (0)