All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Pandruvada, Srinivas" <srinivas.pandruvada@intel.com>
To: "matthewgarrett@google.com" <matthewgarrett@google.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: "Zhang, Rui" <rui.zhang@intel.com>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"Aram, Nisha" <nisha.aram@intel.com>,
	"mjg59@google.com" <mjg59@google.com>
Subject: Re: [PATCH V2 2/3] thermal/int340x_thermal: Export OEM vendor variables
Date: Mon, 18 May 2020 23:18:23 +0000	[thread overview]
Message-ID: <29ac489ff4d184c142ad62b56352ad9d5ef019b5.camel@intel.com> (raw)
In-Reply-To: <20200414020953.255364-2-matthewgarrett@google.com>

On Mon, 2020-04-13 at 19:09 -0700, Matthew Garrett wrote:
> From: Matthew Garrett <mjg59@google.com>
> 
> The platform vendor may expose an array of OEM-specific values to be
> used
> in determining DPTF policy. These are obtained via the ODVP method,
> and
> then simply exposed in sysfs. In addition, they are updated when a
> notification is received or when the DPTF policy is changed by
> userland.
> 
> Signed-off-by: Matthew Garrett <mjg59@google.com>
Tested-by: Pandruvada, Srinivas <srinivas.pandruvada@linux.intel.com>

> ---
>  .../intel/int340x_thermal/int3400_thermal.c   | 132
> +++++++++++++++++-
>  1 file changed, 131 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
> b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
> index 00a7732724cd0..3919098a73b47 100644
> --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
> +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c
> @@ -13,6 +13,7 @@
>  #include "acpi_thermal_rel.h"
>  
>  #define INT3400_THERMAL_TABLE_CHANGED 0x83
> +#define INT3400_ODVP_CHANGED 0x88
>  
>  enum int3400_thermal_uuid {
>  	INT3400_THERMAL_PASSIVE_1,
> @@ -41,8 +42,11 @@ static char
> *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = {
>  	"BE84BABF-C4D4-403D-B495-3128FD44dAC1",
>  };
>  
> +struct odvp_attr;
> +
>  struct int3400_thermal_priv {
>  	struct acpi_device *adev;
> +	struct platform_device *pdev;
>  	struct thermal_zone_device *thermal;
>  	int mode;
>  	int art_count;
> @@ -53,6 +57,17 @@ struct int3400_thermal_priv {
>  	int rel_misc_dev_res;
>  	int current_uuid_index;
>  	char *data_vault;
> +	int odvp_count;
> +	int *odvp;
> +	struct odvp_attr *odvp_attrs;
> +};
> +
> +static int evaluate_odvp(struct int3400_thermal_priv *priv);
> +
> +struct odvp_attr {
> +	int odvp;
> +	struct int3400_thermal_priv *priv;
> +	struct kobj_attribute attr;
>  };
>  
>  static ssize_t data_vault_read(struct file *file, struct kobject
> *kobj,
> @@ -210,9 +225,110 @@ static int int3400_thermal_run_osc(acpi_handle
> handle,
>  		result = -EPERM;
>  
>  	kfree(context.ret.pointer);
> +
>  	return result;
>  }
>  
> +static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute
> *attr,
> +			 char *buf)
> +{
> +	struct odvp_attr *odvp_attr;
> +
> +	odvp_attr = container_of(attr, struct odvp_attr, attr);
> +
> +	return sprintf(buf, "%d\n", odvp_attr->priv->odvp[odvp_attr-
> >odvp]);
> +}
> +
> +static void cleanup_odvp(struct int3400_thermal_priv *priv)
> +{
> +	int i;
> +
> +	if (priv->odvp_attrs) {
> +		for (i = 0; i < priv->odvp_count; i++) {
> +			sysfs_remove_file(&priv->pdev->dev.kobj,
> +					  &priv-
> >odvp_attrs[i].attr.attr);
> +			kfree(priv->odvp_attrs[i].attr.attr.name);
> +		}
> +		kfree(priv->odvp_attrs);
> +	}
> +	kfree(priv->odvp);
> +	priv->odvp_count = 0;
> +}
> +
> +static int evaluate_odvp(struct int3400_thermal_priv *priv)
> +{
> +	struct acpi_buffer odvp = { ACPI_ALLOCATE_BUFFER, NULL };
> +	union acpi_object *obj = NULL;
> +	acpi_status status;
> +	int i, ret;
> +
> +	status = acpi_evaluate_object(priv->adev->handle, "ODVP", NULL,
> &odvp);
> +	if (ACPI_FAILURE(status)) {
> +		ret = -EINVAL;
> +		goto out_err;
> +	}
> +
> +	obj = odvp.pointer;
> +	if (obj->type != ACPI_TYPE_PACKAGE) {
> +		ret = -EINVAL;
> +		goto out_err;
> +	}
> +
> +	if (priv->odvp == NULL) {
> +		priv->odvp_count = obj->package.count;
> +		priv->odvp = kmalloc_array(priv->odvp_count,
> sizeof(int),
> +				     GFP_KERNEL);
> +		if (!priv->odvp) {
> +			ret = -ENOMEM;
> +			goto out_err;
> +		}
> +	}
> +
> +	if (priv->odvp_attrs == NULL) {
> +		priv->odvp_attrs = kcalloc(priv->odvp_count,
> +					   sizeof(struct odvp_attr),
> +					   GFP_KERNEL);
> +		if (!priv->odvp_attrs) {
> +			ret = -ENOMEM;
> +			goto out_err;
> +		}
> +		for (i = 0; i < priv->odvp_count; i++) {
> +			struct odvp_attr *odvp = &priv->odvp_attrs[i];
> +
> +			sysfs_attr_init(&odvp->attr.attr);
> +			odvp->priv = priv;
> +			odvp->odvp = i;
> +			odvp->attr.attr.name = kasprintf(GFP_KERNEL,
> +							 "odvp%d", i);
> +
> +			if (!odvp->attr.attr.name) {
> +				ret = -ENOMEM;
> +				goto out_err;
> +			}
> +			odvp->attr.attr.mode = 0444;
> +			odvp->attr.show = odvp_show;
> +			odvp->attr.store = NULL;
> +			ret = sysfs_create_file(&priv->pdev->dev.kobj,
> +						&odvp->attr.attr);
> +			if (ret)
> +				goto out_err;
> +		}
> +	}
> +
> +	for (i = 0; i < obj->package.count; i++) {
> +		if (obj->package.elements[i].type == ACPI_TYPE_INTEGER)
> +			priv->odvp[i] = obj-
> >package.elements[i].integer.value;
> +	}
> +
> +	kfree(obj);
> +	return 0;
> +
> +out_err:
> +	cleanup_odvp(priv);
> +	kfree(obj);
> +	return ret;
> +}
> +
>  static void int3400_notify(acpi_handle handle,
>  			u32 event,
>  			void *data)
> @@ -236,6 +352,9 @@ static void int3400_notify(acpi_handle handle,
>  		kobject_uevent_env(&priv->thermal->device.kobj,
> KOBJ_CHANGE,
>  				thermal_prop);
>  		break;
> +	case INT3400_ODVP_CHANGED:
> +		evaluate_odvp(priv);
> +		break;
>  	default:
>  		/* Ignore unknown notification codes sent to INT3400
> device */
>  		break;
> @@ -285,6 +404,9 @@ static int int3400_thermal_set_mode(struct
> thermal_zone_device *thermal,
>  						 priv-
> >current_uuid_index,
>  						 enable);
>  	}
> +
> +	evaluate_odvp(priv);
> +
>  	return result;
>  }
>  
> @@ -336,6 +458,7 @@ static int int3400_thermal_probe(struct
> platform_device *pdev)
>  	if (!priv)
>  		return -ENOMEM;
>  
> +	priv->pdev = pdev;
>  	priv->adev = adev;
>  
>  	result = int3400_thermal_get_uuids(priv);
> @@ -356,6 +479,8 @@ static int int3400_thermal_probe(struct
> platform_device *pdev)
>  
>  	int3400_setup_gddv(priv);
>  
> +	evaluate_odvp(priv);
> +
>  	int3400_thermal_ops.get_mode = int3400_thermal_get_mode;
>  	int3400_thermal_ops.set_mode = int3400_thermal_set_mode;
>  
> @@ -390,8 +515,11 @@ static int int3400_thermal_probe(struct
> platform_device *pdev)
>  	return 0;
>  
>  free_sysfs:
> -	if (priv->data_vault)
> +	cleanup_odvp(priv);
> +	if (priv->data_vault) {
>  		sysfs_remove_group(&pdev->dev.kobj,
> &data_attribute_group);
> +		kfree(priv->data_vault);
> +	}
>  free_uuid:
>  	sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
>  free_rel_misc:
> @@ -414,6 +542,8 @@ static int int3400_thermal_remove(struct
> platform_device *pdev)
>  			priv->adev->handle, ACPI_DEVICE_NOTIFY,
>  			int3400_notify);
>  
> +	cleanup_odvp(priv);
> +
>  	if (!priv->rel_misc_dev_res)
>  		acpi_thermal_rel_misc_device_remove(priv->adev-
> >handle);
>  

  reply	other threads:[~2020-05-18 23:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-14  2:09 [PATCH V2 1/3] thermal/int340x_thermal: Export GDDV Matthew Garrett
2020-04-14  2:09 ` [PATCH V2 2/3] thermal/int340x_thermal: Export OEM vendor variables Matthew Garrett
2020-05-18 23:18   ` Pandruvada, Srinivas [this message]
2020-04-14  2:09 ` [PATCH V2 3/3] thermal/int340x_thermal: Don't require IDSP to exist Matthew Garrett
2020-05-18 23:18   ` Pandruvada, Srinivas
2020-04-14  3:33 ` [PATCH V2 1/3] thermal/int340x_thermal: Export GDDV Pandruvada, Srinivas
2020-04-14  3:53   ` Matthew Garrett
2020-04-14  3:58     ` Pandruvada, Srinivas
2020-05-18 23:18 ` Pandruvada, Srinivas
2020-05-29  6:00   ` Pandruvada, Srinivas
2020-05-29  6:02     ` Zhang Rui

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=29ac489ff4d184c142ad62b56352ad9d5ef019b5.camel@intel.com \
    --to=srinivas.pandruvada@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=matthewgarrett@google.com \
    --cc=mjg59@google.com \
    --cc=nisha.aram@intel.com \
    --cc=rui.zhang@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.