public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Chen Gong <gong.chen@linux.intel.com>
To: "R, Durgadoss" <durgadoss.r@intel.com>
Cc: "Yu, Fenghua" <fenghua.yu@intel.com>,
	"khali@linux-fr.org" <khali@linux-fr.org>,
	"linux-acpi@vger.kernel.org" <linux-acpi@vger.kernel.org>,
	"lm-sensors@lm-sensors.org" <lm-sensors@lm-sensors.org>,
	"lenb@kernel.org" <lenb@kernel.org>
Subject: Re: [lm-sensors] Patch[1/1] Adding Core Thermal Threshold Support to	Coretemp
Date: Mon, 13 Dec 2010 11:25:11 +0800	[thread overview]
Message-ID: <4D059217.9070905@linux.intel.com> (raw)
In-Reply-To: <D6D887BA8C9DFF48B5233887EF04654105C1077008@bgsmsx502.gar.corp.intel.com>

于 12/10/2010 5:30 PM, R, Durgadoss 写道:
> Hi Fenghua/Jean,
>
> I am submitting a patch to enable core thermal threshold
> Support to coretemp.c. There are two core thermal thresholds
> available through sysfs interfaces temp1_core_thresh[0/1].
>
> The expectation is that thresh0 is lesser than the current temperature
> and thresh1 is higher than the current temperature. Whenever the current
> temperature crosses these limits, an interrupt is generated.
> This interrupt is handles by the user space to do power
> Management via CPU throttling, etc..
>
> This patch is generated against stable Linux-2.6 kernel.
>
> Kindly review and merge.
> -------------------------------------------------------------------------
> From: Durgadoss R<durgadoss.r@intel.com>
>
> Date: Fri, 10 Dec 2010 02:16:36 +0530
> Subject: [PATCH] Adding_Threshold_support_to_coretemp
>
> This patch adds the core thermal threshold support to coretemp.c.
> These thresholds can be read/written using the sysfs interface
> temp1_core_thresh[0/1]. These can be used to generate interrupts,
> to do dynamic power management.
>
> Signed-off-by: Durgadoss R<durgadoss.r@intel.com>
>
> ---
>   arch/x86/include/asm/msr-index.h |   12 ++++
>   drivers/hwmon/coretemp.c         |  122 ++++++++++++++++++++++++++++++++++++++
>   2 files changed, 134 insertions(+), 0 deletions(-)
>
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 3ea3dc4..31cefad 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -253,6 +253,18 @@
>   #define PACKAGE_THERM_INT_LOW_ENABLE		(1<<  1)
>   #define PACKAGE_THERM_INT_PLN_ENABLE		(1<<  24)
>
> +/* Thermal Thresholds Support */
> +#define THERM_INT_THRESHOLD0_ENABLE    (1<<  15)
> +#define THERM_OFFSET_THRESHOLD0        8
> +#define THERM_MASK_THRESHOLD0          (0x7f<<  THERM_OFFSET_THRESHOLD0)
> +#define THERM_INT_THRESHOLD1_ENABLE    (1<<  23)
> +#define THERM_OFFSET_THRESHOLD1        16
> +#define THERM_MASK_THRESHOLD1          (0x7f<<  THERM_OFFSET_THRESHOLD1)
> +#define THERM_STATUS_THRESHOLD0        (1<<  6)
> +#define THERM_LOG_THRESHOLD0           (1<<  7)
> +#define THERM_STATUS_THRESHOLD1        (1<<  8)
> +#define THERM_LOG_THRESHOLD1           (1<<  9)
> +
>   /* MISC_ENABLE bits: architectural */
>   #define MSR_IA32_MISC_ENABLE_FAST_STRING	(1ULL<<  0)
>   #define MSR_IA32_MISC_ENABLE_TCC		(1ULL<<  1)
> diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
> index 42de98d..fe0699f 100644
> --- a/drivers/hwmon/coretemp.c
> +++ b/drivers/hwmon/coretemp.c
> @@ -42,6 +42,9 @@
>   typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL,
>   		SHOW_NAME } SHOW;
>
> +/* C indicates core thermal thresholds */
> +enum thresholds { C_TTHRESH0, C_TTHRESH1} THRESH;
> +
>   /*
>    * Functions declaration
>    */
> @@ -59,9 +62,13 @@ struct coretemp_data {
>   	int temp;
>   	int tjmax;
>   	int ttarget;
> +	int c_tthresh0;
> +	int c_tthresh1;
>   	u8 alarm;
>   };
>
> +static int set_core_threshold(struct coretemp_data *data, int val,
> +						enum thresholds thresh);
>   /*
>    * Sysfs stuff
>    */
> @@ -104,6 +111,41 @@ static ssize_t show_temp(struct device *dev,
>   	return err;
>   }
>
> +static ssize_t show_threshold(struct device *dev,
> +				struct device_attribute *devattr, char *buf)
> +{
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
> +	struct coretemp_data *data = coretemp_update_device(dev);
> +
> +	if (!data->valid)
> +		return -EINVAL;
> +
> +	switch (attr->index) {
> +	case C_TTHRESH0:
> +		return sprintf(buf, "%d\n", data->c_tthresh0);
> +	case C_TTHRESH1:
> +		return sprintf(buf, "%d\n", data->c_tthresh1);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static ssize_t set_threshold(struct device *dev,
> +		struct device_attribute *devattr, const char *buf, size_t count)
> +{
> +	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
> +	struct coretemp_data *data = coretemp_update_device(dev);
> +	unsigned long val;
> +	int err;
> +
> +	if (strict_strtoul(buf, 10,&val))
> +		return -EINVAL;
> +
> +	err = set_core_threshold(data, val, attr->index);
> +
> +	return (err) ? -EINVAL : count;
> +}
> +
>   static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
>   			  SHOW_TEMP);
>   static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
> @@ -114,12 +156,19 @@ static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
>   static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
>   static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
>
> +static SENSOR_DEVICE_ATTR(temp1_core_thresh0, S_IWUSR | S_IRUGO,
> +				show_threshold,	set_threshold, C_TTHRESH0);
> +static SENSOR_DEVICE_ATTR(temp1_core_thresh1, S_IWUSR | S_IRUGO,
> +				show_threshold, set_threshold, C_TTHRESH1);
> +
>   static struct attribute *coretemp_attributes[] = {
>   	&sensor_dev_attr_name.dev_attr.attr,
>   	&sensor_dev_attr_temp1_label.dev_attr.attr,
>   	&dev_attr_temp1_crit_alarm.attr,
>   	&sensor_dev_attr_temp1_input.dev_attr.attr,
>   	&sensor_dev_attr_temp1_crit.dev_attr.attr,
> +	&sensor_dev_attr_temp1_core_thresh0.dev_attr.attr,
> +	&sensor_dev_attr_temp1_core_thresh1.dev_attr.attr,
>   	NULL
>   };
>
> @@ -298,6 +347,66 @@ static void __devinit get_ucode_rev_on_cpu(void *edx)
>   	rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx);
>   }
>
> +static int set_core_threshold(struct coretemp_data *data, int temp,
> +						enum thresholds thresh)
> +{
> +	u32 eax, edx, l;
> +	int diff;
> +
> +	if (temp>  data->tjmax)
> +		return -EINVAL;
> +
> +	mutex_lock(&data->update_lock);
> +
> +	diff = (data->tjmax - temp)/1000;
> +
> +	/* Mask the thermal vector in the lapic */
> +	l = apic_read(APIC_LVTTHMR);
> +	apic_write(APIC_LVTTHMR, l | APIC_LVT_MASKED);
> +
> +	rdmsr_on_cpu(data->id, MSR_IA32_THERM_INTERRUPT,&eax,&edx);

apic_write and rdmsr_on_cpu maybe don't point to the same CPU.
Maybe it is a potential issue. The below apic_xxx etc. are same situations.

> +
> +	if (thresh == C_TTHRESH0) {
> +		eax = (eax&  ~THERM_MASK_THRESHOLD0) |
> +					(diff<<  THERM_OFFSET_THRESHOLD0);
> +		data->c_tthresh0 = temp;
> +	} else {
> +		eax = (eax&  ~THERM_MASK_THRESHOLD1) |
> +					(diff<<  THERM_OFFSET_THRESHOLD1);
> +		data->c_tthresh1 = temp;
> +	}
> +
> +	wrmsr_on_cpu(data->id, MSR_IA32_THERM_INTERRUPT, eax, edx);
> +
> +	/* Unmask the thermal vector */
> +	l = apic_read(APIC_LVTTHMR);
> +	apic_write(APIC_LVTTHMR, l&  ~APIC_LVT_MASKED);
> +
> +	mutex_unlock(&data->update_lock);
> +	return 0;
> +}
> +
> +static int __devinit enable_thresh_support(struct coretemp_data *data)
> +{
> +	u32 eax, edx, l;
> +
> +	/* Mask the thermal vector in the lapic */
> +	l = apic_read(APIC_LVTTHMR);
> +	apic_write(APIC_LVTTHMR, l | APIC_LVT_MASKED);
> +
> +	rdmsr_on_cpu(data->id, MSR_IA32_THERM_INTERRUPT,&eax,&edx);
> +
> +	eax |= (THERM_INT_THRESHOLD0_ENABLE | THERM_INT_THRESHOLD1_ENABLE);
> +
> +	wrmsr_on_cpu(data->id, MSR_IA32_THERM_INTERRUPT, eax, edx);
> +
> +	/* Unmask the thermal vector */
> +	l = apic_read(APIC_LVTTHMR);
> +	apic_write(APIC_LVTTHMR, l&  ~APIC_LVT_MASKED);
> +
> +	return 0;
> +}
> +
>   static int __devinit coretemp_probe(struct platform_device *pdev)
>   {
>   	struct coretemp_data *data;
> @@ -353,6 +462,15 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
>   	data->tjmax = get_tjmax(c, data->id,&pdev->dev);
>   	platform_set_drvdata(pdev, data);
>
> +	/* Enable threshold support */
> +	enable_thresh_support(data);
> +
> +	/* Set Initial Core thresholds.
> +	 * The lower and upper threshold values here are assumed
> +	 */
> +	set_core_threshold(data, 0, C_TTHRESH0);
> +	set_core_threshold(data, 90000, C_TTHRESH1);
> +
>   	/*
>   	 * read the still undocumented IA32_TEMPERATURE_TARGET. It exists
>   	 * on older CPUs but not in this register,
> @@ -405,6 +523,10 @@ static int __devexit coretemp_remove(struct platform_device *pdev)
>   	hwmon_device_unregister(data->hwmon_dev);
>   	sysfs_remove_group(&pdev->dev.kobj,&coretemp_group);
>   	device_remove_file(&pdev->dev,&sensor_dev_attr_temp1_max.dev_attr);
> +	device_remove_file(&pdev->dev,
> +				&sensor_dev_attr_temp1_core_thresh0.dev_attr);
> +	device_remove_file(&pdev->dev,
> +				&sensor_dev_attr_temp1_core_thresh1.dev_attr);
>   	platform_set_drvdata(pdev, NULL);
>   	kfree(data);
>   	return 0;
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2010-12-13  3:25 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-10  9:30 Patch[1/1] Adding Core Thermal Threshold Support to Coretemp R, Durgadoss
2010-12-13  3:25 ` Chen Gong [this message]
2010-12-14 10:06   ` [lm-sensors] Patch[1/1] Adding Core Thermal Threshold Support to_Coretemp R, Durgadoss

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D059217.9070905@linux.intel.com \
    --to=gong.chen@linux.intel.com \
    --cc=durgadoss.r@intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=khali@linux-fr.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=lm-sensors@lm-sensors.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox