All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Courbot <acourbot@nvidia.com>
To: Wei Ni <wni@nvidia.com>
Cc: "durgadoss.r@intel.com" <durgadoss.r@intel.com>,
	"rui.zhang@intel.com" <rui.zhang@intel.com>,
	Matthew Longnecker <MLongnecker@nvidia.com>,
	"khali@linux-fr.org" <khali@linux-fr.org>,
	"devicetree-discuss@lists.ozlabs.org"
	<devicetree-discuss@lists.ozlabs.org>,
	"linux-tegra@vger.kernel.org" <linux-tegra@vger.kernel.org>,
	"lm-sensors@lm-sensors.org" <lm-sensors@lm-sensors.org>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"linux-kernel@vger.kernel.orgrs.org"
	<linux-kernel@vger.kernel.orgrs.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [RFC PATCH 6/9] hwmon: (lm90) Register to the thermal framework
Date: Tue, 19 Feb 2013 14:22:44 +0900	[thread overview]
Message-ID: <51230C24.5090707@nvidia.com> (raw)
In-Reply-To: <1361187031-3679-7-git-send-email-wni@nvidia.com>

On 02/18/2013 08:30 PM, Wei Ni wrote:
> Register the remote sensor to the thermal framework.
> It can support to show the temperature and read/write threshold.
>
> Signed-off-by: Wei Ni <wni@nvidia.com>
> ---
>   arch/arm/boot/dts/tegra30-cardhu.dtsi |    1 +
>   drivers/hwmon/lm90.c                  |  182 ++++++++++++++++++++++++++++++++-
>   2 files changed, 182 insertions(+), 1 deletion(-)

Making changes to a driver *and* a board file in the same patch? I think 
this should be separated, and the board file change preferably squashed 
with the first patch of this series, and moved right after this one.

>
> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> index 15ad1ad..3f6ab89 100644
> --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
> +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> @@ -279,6 +279,7 @@
>   			reg = <0x4c>;
>   			interrupt-parent = <&gpio>;
>   			interrupts = <226 0x08>; /* gpio PCC2 */
> +			#sensor-cells = <1>;
>   		};
>   	};
>
> diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
> index de5a476..0abdedc 100644
> --- a/drivers/hwmon/lm90.c
> +++ b/drivers/hwmon/lm90.c
> @@ -91,6 +91,7 @@
>   #include <linux/sysfs.h>
>   #include <linux/interrupt.h>
>   #include <linux/of_irq.h>
> +#include <linux/thermal.h>
>
>   /*
>    * Addresses to scan
> @@ -182,6 +183,15 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
>   #define LM90_HAVE_BROKEN_ALERT	(1 << 7) /* Broken alert		*/
>
>   /*
> + * Thermal framework
> + */
> +enum lm90_thresholds {
> +	LM90_LOW_THRESHOLDS = 0,	/* threshold 0: low limits */
> +	LM90_HIGH_THRESHOLDS,		/* threshold 1: high limits */
> +	LM90_NUM_THRESHOLDS
> +};
> +
> +/*
>    * Driver data (common to all clients)
>    */
>
> @@ -377,6 +387,9 @@ struct lm90_data {
>   	s16 temp11[TEMP11_REG_NUM];
>   	u8 temp_hyst;
>   	u16 alarms; /* bitvector (upper 8 bits for max6695/96) */
> +
> +	struct thermal_sensor *ts_remote;
> +	struct thermal_sensor *ts_local;
>   };
>
>   /*
> @@ -1493,12 +1506,151 @@ static irqreturn_t lm90_irq(int irq, void *dev_id)
>   	return IRQ_HANDLED;
>   }
>
> +static int lm90_read_remote_temp(struct thermal_sensor *ts, long *temp)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +
> +	_show_temp11(dev, TEMP11_REMOTE_TEMP, (int *)temp);

As Guenter pointed, this might break. Since you introduced _show_temp11 
in a previous patch, you should revise it to take a long * as third 
argument (or even better, return a long). Or if you cannot do that for 
some reason, use a temporary int and affect temp properly (*temp = 
temp_int).

> +
> +	return 0;
> +}
> +
> +static int lm90_read_remote_threshold(struct thermal_sensor *ts, int th_index,
> +					long *val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* remote low limit */
> +		index = TEMP11_REMOTE_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* remote high limit */
> +		index = TEMP11_REMOTE_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "read remote threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_show_temp11(dev, index, (int *)val);
> +
> +	return 0;
> +}
> +
> +static int lm90_write_remote_threshold(struct thermal_sensor *ts, int th_index,
> +					long val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int nr, index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* remote low limit */
> +		nr = NR_CHAN_0_REMOTE_LOW;
> +		index = TEMP11_REMOTE_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* remote high limit */
> +		nr = NR_CHAN_0_REMOTE_HIGH;
> +		index = TEMP11_REMOTE_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "write remote threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_set_temp11(dev, nr, index, val);
> +
> +	return 0;
> +}
> +
> +static struct thermal_sensor_ops remote_ops = {
> +	.get_temp = lm90_read_remote_temp,
> +	.get_threshold = lm90_read_remote_threshold,
> +	.set_threshold = lm90_write_remote_threshold,
> +};
> +
> +static int lm90_read_local_temp(struct thermal_sensor *ts, long *temp)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +
> +	_show_temp11(dev, TEMP11_LOCAL_TEMP, (int *)temp);
> +
> +	return 0;
> +}
> +
> +static int lm90_read_local_threshold(struct thermal_sensor *ts, int th_index,
> +					long *val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* local low limit */
> +		index = TEMP8_LOCAL_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* local high limit */
> +		index = TEMP8_LOCAL_HIGH;
> +		break;

I think the comments are unneeded here, the macro name should be 
explicit enough.

> +	default:
> +		dev_err(dev, "read local threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_show_temp8(dev, index, (int *)val);
> +
> +	return 0;
> +}
> +
> +static int lm90_write_local_threshold(struct thermal_sensor *ts, int th_index,
> +					long val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* local low limit */
> +		index = TEMP8_LOCAL_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* local high limit */
> +		index = TEMP8_LOCAL_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "write local threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_set_temp8(dev, index, val);
> +
> +	return 0;
> +}
> +
> +static struct thermal_sensor_ops local_ops = {
> +	.get_temp = lm90_read_local_temp,
> +	.get_threshold = lm90_read_local_threshold,
> +	.set_threshold = lm90_write_local_threshold,
> +};
> +
>   static int lm90_probe(struct i2c_client *client,
>   		      const struct i2c_device_id *id)
>   {
>   	struct device *dev = &client->dev;
>   	struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
>   	struct lm90_data *data;
> +	struct node_args np_args;
>   	int err;
>
>   	data = devm_kzalloc(&client->dev, sizeof(struct lm90_data), GFP_KERNEL);
> @@ -1576,12 +1728,38 @@ static int lm90_probe(struct i2c_client *client,
>   				       "lm90", data);
>   		if (err < 0) {
>   			dev_err(dev, "cannot request interrupt\n");
> -			goto exit_remove_files;
> +			goto exit_unregister_hwmon;
>   		}
>   	}
>
> +	np_args.np = dev->of_node;
> +	np_args.index = 0;
> +	data->ts_remote = thermal_sensor_register("lm90_remote",
> +						LM90_NUM_THRESHOLDS,
> +						&np_args,
> +						&remote_ops, client);
> +	if (IS_ERR(data->ts_remote)) {
> +		dev_err(dev, "cannot register sensor to thermal framework\n");
> +		err = -EINVAL;

When don't you return the error code provided by 
thermal_sensor_register, e.g. err = PTR_ERR(data->ts_remote) ?

> +		goto exit_unregister_hwmon;
> +	}
> +
> +	np_args.index = 1;
> +	data->ts_local = thermal_sensor_register("lm90_local",
> +						LM90_NUM_THRESHOLDS,
> +						&np_args,
> +						&local_ops, client);
> +
> +	if (IS_ERR(data->ts_local)) {
> +		dev_err(dev, "cannot register sensor to thermal framework\n");
> +		err = -EINVAL;

Same thing here.

> +		goto exit_unregister_hwmon;
> +	}
> +
>   	return 0;
>
> +exit_unregister_hwmon:
> +	hwmon_device_unregister(data->hwmon_dev);
>   exit_remove_files:
>   	lm90_remove_files(client, data);
>   exit_restore:
> @@ -1594,6 +1772,8 @@ static int lm90_remove(struct i2c_client *client)
>   	struct lm90_data *data = i2c_get_clientdata(client);
>
>   	free_irq(client->irq, data);
> +	thermal_sensor_unregister(data->ts_remote);
> +	thermal_sensor_unregister(data->ts_local);

Ideally you would unregister your sensors in the reverse order they have 
been registered, but I'm being picky here.

Alex.


WARNING: multiple messages have this Message-ID (diff)
From: Alex Courbot <acourbot@nvidia.com>
To: Wei Ni <wni@nvidia.com>
Cc: "durgadoss.r@intel.com" <durgadoss.r@intel.com>,
	"rui.zhang@intel.com" <rui.zhang@intel.com>,
	Matthew Longnecker <MLongnecker@nvidia.com>,
	"khali@linux-fr.org" <khali@linux-fr.org>,
	"devicetree-discuss@lists.ozlabs.org"
	<devicetree-discuss@lists.ozlabs.org>,
	"linux-tegra@vger.kernel.org" <linux-tegra@vger.kernel.org>,
	"lm-sensors@lm-sensors.org" <lm-sensors@lm-sensors.org>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"linux-kernel@vger.kernel.orgrs.org"
	<linux-kernel@vger.kernel.orgrs.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [lm-sensors] [RFC PATCH 6/9] hwmon: (lm90) Register to the thermal framework
Date: Tue, 19 Feb 2013 05:22:44 +0000	[thread overview]
Message-ID: <51230C24.5090707@nvidia.com> (raw)
In-Reply-To: <1361187031-3679-7-git-send-email-wni@nvidia.com>

On 02/18/2013 08:30 PM, Wei Ni wrote:
> Register the remote sensor to the thermal framework.
> It can support to show the temperature and read/write threshold.
>
> Signed-off-by: Wei Ni <wni@nvidia.com>
> ---
>   arch/arm/boot/dts/tegra30-cardhu.dtsi |    1 +
>   drivers/hwmon/lm90.c                  |  182 ++++++++++++++++++++++++++++++++-
>   2 files changed, 182 insertions(+), 1 deletion(-)

Making changes to a driver *and* a board file in the same patch? I think 
this should be separated, and the board file change preferably squashed 
with the first patch of this series, and moved right after this one.

>
> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> index 15ad1ad..3f6ab89 100644
> --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
> +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> @@ -279,6 +279,7 @@
>   			reg = <0x4c>;
>   			interrupt-parent = <&gpio>;
>   			interrupts = <226 0x08>; /* gpio PCC2 */
> +			#sensor-cells = <1>;
>   		};
>   	};
>
> diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
> index de5a476..0abdedc 100644
> --- a/drivers/hwmon/lm90.c
> +++ b/drivers/hwmon/lm90.c
> @@ -91,6 +91,7 @@
>   #include <linux/sysfs.h>
>   #include <linux/interrupt.h>
>   #include <linux/of_irq.h>
> +#include <linux/thermal.h>
>
>   /*
>    * Addresses to scan
> @@ -182,6 +183,15 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
>   #define LM90_HAVE_BROKEN_ALERT	(1 << 7) /* Broken alert		*/
>
>   /*
> + * Thermal framework
> + */
> +enum lm90_thresholds {
> +	LM90_LOW_THRESHOLDS = 0,	/* threshold 0: low limits */
> +	LM90_HIGH_THRESHOLDS,		/* threshold 1: high limits */
> +	LM90_NUM_THRESHOLDS
> +};
> +
> +/*
>    * Driver data (common to all clients)
>    */
>
> @@ -377,6 +387,9 @@ struct lm90_data {
>   	s16 temp11[TEMP11_REG_NUM];
>   	u8 temp_hyst;
>   	u16 alarms; /* bitvector (upper 8 bits for max6695/96) */
> +
> +	struct thermal_sensor *ts_remote;
> +	struct thermal_sensor *ts_local;
>   };
>
>   /*
> @@ -1493,12 +1506,151 @@ static irqreturn_t lm90_irq(int irq, void *dev_id)
>   	return IRQ_HANDLED;
>   }
>
> +static int lm90_read_remote_temp(struct thermal_sensor *ts, long *temp)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +
> +	_show_temp11(dev, TEMP11_REMOTE_TEMP, (int *)temp);

As Guenter pointed, this might break. Since you introduced _show_temp11 
in a previous patch, you should revise it to take a long * as third 
argument (or even better, return a long). Or if you cannot do that for 
some reason, use a temporary int and affect temp properly (*temp = 
temp_int).

> +
> +	return 0;
> +}
> +
> +static int lm90_read_remote_threshold(struct thermal_sensor *ts, int th_index,
> +					long *val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* remote low limit */
> +		index = TEMP11_REMOTE_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* remote high limit */
> +		index = TEMP11_REMOTE_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "read remote threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_show_temp11(dev, index, (int *)val);
> +
> +	return 0;
> +}
> +
> +static int lm90_write_remote_threshold(struct thermal_sensor *ts, int th_index,
> +					long val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int nr, index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* remote low limit */
> +		nr = NR_CHAN_0_REMOTE_LOW;
> +		index = TEMP11_REMOTE_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* remote high limit */
> +		nr = NR_CHAN_0_REMOTE_HIGH;
> +		index = TEMP11_REMOTE_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "write remote threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_set_temp11(dev, nr, index, val);
> +
> +	return 0;
> +}
> +
> +static struct thermal_sensor_ops remote_ops = {
> +	.get_temp = lm90_read_remote_temp,
> +	.get_threshold = lm90_read_remote_threshold,
> +	.set_threshold = lm90_write_remote_threshold,
> +};
> +
> +static int lm90_read_local_temp(struct thermal_sensor *ts, long *temp)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +
> +	_show_temp11(dev, TEMP11_LOCAL_TEMP, (int *)temp);
> +
> +	return 0;
> +}
> +
> +static int lm90_read_local_threshold(struct thermal_sensor *ts, int th_index,
> +					long *val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* local low limit */
> +		index = TEMP8_LOCAL_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* local high limit */
> +		index = TEMP8_LOCAL_HIGH;
> +		break;

I think the comments are unneeded here, the macro name should be 
explicit enough.

> +	default:
> +		dev_err(dev, "read local threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_show_temp8(dev, index, (int *)val);
> +
> +	return 0;
> +}
> +
> +static int lm90_write_local_threshold(struct thermal_sensor *ts, int th_index,
> +					long val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* local low limit */
> +		index = TEMP8_LOCAL_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* local high limit */
> +		index = TEMP8_LOCAL_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "write local threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_set_temp8(dev, index, val);
> +
> +	return 0;
> +}
> +
> +static struct thermal_sensor_ops local_ops = {
> +	.get_temp = lm90_read_local_temp,
> +	.get_threshold = lm90_read_local_threshold,
> +	.set_threshold = lm90_write_local_threshold,
> +};
> +
>   static int lm90_probe(struct i2c_client *client,
>   		      const struct i2c_device_id *id)
>   {
>   	struct device *dev = &client->dev;
>   	struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
>   	struct lm90_data *data;
> +	struct node_args np_args;
>   	int err;
>
>   	data = devm_kzalloc(&client->dev, sizeof(struct lm90_data), GFP_KERNEL);
> @@ -1576,12 +1728,38 @@ static int lm90_probe(struct i2c_client *client,
>   				       "lm90", data);
>   		if (err < 0) {
>   			dev_err(dev, "cannot request interrupt\n");
> -			goto exit_remove_files;
> +			goto exit_unregister_hwmon;
>   		}
>   	}
>
> +	np_args.np = dev->of_node;
> +	np_args.index = 0;
> +	data->ts_remote = thermal_sensor_register("lm90_remote",
> +						LM90_NUM_THRESHOLDS,
> +						&np_args,
> +						&remote_ops, client);
> +	if (IS_ERR(data->ts_remote)) {
> +		dev_err(dev, "cannot register sensor to thermal framework\n");
> +		err = -EINVAL;

When don't you return the error code provided by 
thermal_sensor_register, e.g. err = PTR_ERR(data->ts_remote) ?

> +		goto exit_unregister_hwmon;
> +	}
> +
> +	np_args.index = 1;
> +	data->ts_local = thermal_sensor_register("lm90_local",
> +						LM90_NUM_THRESHOLDS,
> +						&np_args,
> +						&local_ops, client);
> +
> +	if (IS_ERR(data->ts_local)) {
> +		dev_err(dev, "cannot register sensor to thermal framework\n");
> +		err = -EINVAL;

Same thing here.

> +		goto exit_unregister_hwmon;
> +	}
> +
>   	return 0;
>
> +exit_unregister_hwmon:
> +	hwmon_device_unregister(data->hwmon_dev);
>   exit_remove_files:
>   	lm90_remove_files(client, data);
>   exit_restore:
> @@ -1594,6 +1772,8 @@ static int lm90_remove(struct i2c_client *client)
>   	struct lm90_data *data = i2c_get_clientdata(client);
>
>   	free_irq(client->irq, data);
> +	thermal_sensor_unregister(data->ts_remote);
> +	thermal_sensor_unregister(data->ts_local);

Ideally you would unregister your sensors in the reverse order they have 
been registered, but I'm being picky here.

Alex.


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

WARNING: multiple messages have this Message-ID (diff)
From: acourbot@nvidia.com (Alex Courbot)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 6/9] hwmon: (lm90) Register to the thermal framework
Date: Tue, 19 Feb 2013 14:22:44 +0900	[thread overview]
Message-ID: <51230C24.5090707@nvidia.com> (raw)
In-Reply-To: <1361187031-3679-7-git-send-email-wni@nvidia.com>

On 02/18/2013 08:30 PM, Wei Ni wrote:
> Register the remote sensor to the thermal framework.
> It can support to show the temperature and read/write threshold.
>
> Signed-off-by: Wei Ni <wni@nvidia.com>
> ---
>   arch/arm/boot/dts/tegra30-cardhu.dtsi |    1 +
>   drivers/hwmon/lm90.c                  |  182 ++++++++++++++++++++++++++++++++-
>   2 files changed, 182 insertions(+), 1 deletion(-)

Making changes to a driver *and* a board file in the same patch? I think 
this should be separated, and the board file change preferably squashed 
with the first patch of this series, and moved right after this one.

>
> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> index 15ad1ad..3f6ab89 100644
> --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
> +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> @@ -279,6 +279,7 @@
>   			reg = <0x4c>;
>   			interrupt-parent = <&gpio>;
>   			interrupts = <226 0x08>; /* gpio PCC2 */
> +			#sensor-cells = <1>;
>   		};
>   	};
>
> diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
> index de5a476..0abdedc 100644
> --- a/drivers/hwmon/lm90.c
> +++ b/drivers/hwmon/lm90.c
> @@ -91,6 +91,7 @@
>   #include <linux/sysfs.h>
>   #include <linux/interrupt.h>
>   #include <linux/of_irq.h>
> +#include <linux/thermal.h>
>
>   /*
>    * Addresses to scan
> @@ -182,6 +183,15 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680,
>   #define LM90_HAVE_BROKEN_ALERT	(1 << 7) /* Broken alert		*/
>
>   /*
> + * Thermal framework
> + */
> +enum lm90_thresholds {
> +	LM90_LOW_THRESHOLDS = 0,	/* threshold 0: low limits */
> +	LM90_HIGH_THRESHOLDS,		/* threshold 1: high limits */
> +	LM90_NUM_THRESHOLDS
> +};
> +
> +/*
>    * Driver data (common to all clients)
>    */
>
> @@ -377,6 +387,9 @@ struct lm90_data {
>   	s16 temp11[TEMP11_REG_NUM];
>   	u8 temp_hyst;
>   	u16 alarms; /* bitvector (upper 8 bits for max6695/96) */
> +
> +	struct thermal_sensor *ts_remote;
> +	struct thermal_sensor *ts_local;
>   };
>
>   /*
> @@ -1493,12 +1506,151 @@ static irqreturn_t lm90_irq(int irq, void *dev_id)
>   	return IRQ_HANDLED;
>   }
>
> +static int lm90_read_remote_temp(struct thermal_sensor *ts, long *temp)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +
> +	_show_temp11(dev, TEMP11_REMOTE_TEMP, (int *)temp);

As Guenter pointed, this might break. Since you introduced _show_temp11 
in a previous patch, you should revise it to take a long * as third 
argument (or even better, return a long). Or if you cannot do that for 
some reason, use a temporary int and affect temp properly (*temp = 
temp_int).

> +
> +	return 0;
> +}
> +
> +static int lm90_read_remote_threshold(struct thermal_sensor *ts, int th_index,
> +					long *val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* remote low limit */
> +		index = TEMP11_REMOTE_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* remote high limit */
> +		index = TEMP11_REMOTE_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "read remote threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_show_temp11(dev, index, (int *)val);
> +
> +	return 0;
> +}
> +
> +static int lm90_write_remote_threshold(struct thermal_sensor *ts, int th_index,
> +					long val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int nr, index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* remote low limit */
> +		nr = NR_CHAN_0_REMOTE_LOW;
> +		index = TEMP11_REMOTE_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* remote high limit */
> +		nr = NR_CHAN_0_REMOTE_HIGH;
> +		index = TEMP11_REMOTE_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "write remote threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_set_temp11(dev, nr, index, val);
> +
> +	return 0;
> +}
> +
> +static struct thermal_sensor_ops remote_ops = {
> +	.get_temp = lm90_read_remote_temp,
> +	.get_threshold = lm90_read_remote_threshold,
> +	.set_threshold = lm90_write_remote_threshold,
> +};
> +
> +static int lm90_read_local_temp(struct thermal_sensor *ts, long *temp)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +
> +	_show_temp11(dev, TEMP11_LOCAL_TEMP, (int *)temp);
> +
> +	return 0;
> +}
> +
> +static int lm90_read_local_threshold(struct thermal_sensor *ts, int th_index,
> +					long *val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* local low limit */
> +		index = TEMP8_LOCAL_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* local high limit */
> +		index = TEMP8_LOCAL_HIGH;
> +		break;

I think the comments are unneeded here, the macro name should be 
explicit enough.

> +	default:
> +		dev_err(dev, "read local threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_show_temp8(dev, index, (int *)val);
> +
> +	return 0;
> +}
> +
> +static int lm90_write_local_threshold(struct thermal_sensor *ts, int th_index,
> +					long val)
> +{
> +	struct i2c_client *client = ts->devdata;
> +	struct device *dev = &client->dev;
> +	int index;
> +
> +	switch (th_index) {
> +	case LM90_LOW_THRESHOLDS:
> +		/* local low limit */
> +		index = TEMP8_LOCAL_LOW;
> +		break;
> +	case LM90_HIGH_THRESHOLDS:
> +		/* local high limit */
> +		index = TEMP8_LOCAL_HIGH;
> +		break;
> +	default:
> +		dev_err(dev, "write local threshold failed.\n");
> +		return -EINVAL;
> +	}
> +
> +	_set_temp8(dev, index, val);
> +
> +	return 0;
> +}
> +
> +static struct thermal_sensor_ops local_ops = {
> +	.get_temp = lm90_read_local_temp,
> +	.get_threshold = lm90_read_local_threshold,
> +	.set_threshold = lm90_write_local_threshold,
> +};
> +
>   static int lm90_probe(struct i2c_client *client,
>   		      const struct i2c_device_id *id)
>   {
>   	struct device *dev = &client->dev;
>   	struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
>   	struct lm90_data *data;
> +	struct node_args np_args;
>   	int err;
>
>   	data = devm_kzalloc(&client->dev, sizeof(struct lm90_data), GFP_KERNEL);
> @@ -1576,12 +1728,38 @@ static int lm90_probe(struct i2c_client *client,
>   				       "lm90", data);
>   		if (err < 0) {
>   			dev_err(dev, "cannot request interrupt\n");
> -			goto exit_remove_files;
> +			goto exit_unregister_hwmon;
>   		}
>   	}
>
> +	np_args.np = dev->of_node;
> +	np_args.index = 0;
> +	data->ts_remote = thermal_sensor_register("lm90_remote",
> +						LM90_NUM_THRESHOLDS,
> +						&np_args,
> +						&remote_ops, client);
> +	if (IS_ERR(data->ts_remote)) {
> +		dev_err(dev, "cannot register sensor to thermal framework\n");
> +		err = -EINVAL;

When don't you return the error code provided by 
thermal_sensor_register, e.g. err = PTR_ERR(data->ts_remote) ?

> +		goto exit_unregister_hwmon;
> +	}
> +
> +	np_args.index = 1;
> +	data->ts_local = thermal_sensor_register("lm90_local",
> +						LM90_NUM_THRESHOLDS,
> +						&np_args,
> +						&local_ops, client);
> +
> +	if (IS_ERR(data->ts_local)) {
> +		dev_err(dev, "cannot register sensor to thermal framework\n");
> +		err = -EINVAL;

Same thing here.

> +		goto exit_unregister_hwmon;
> +	}
> +
>   	return 0;
>
> +exit_unregister_hwmon:
> +	hwmon_device_unregister(data->hwmon_dev);
>   exit_remove_files:
>   	lm90_remove_files(client, data);
>   exit_restore:
> @@ -1594,6 +1772,8 @@ static int lm90_remove(struct i2c_client *client)
>   	struct lm90_data *data = i2c_get_clientdata(client);
>
>   	free_irq(client->irq, data);
> +	thermal_sensor_unregister(data->ts_remote);
> +	thermal_sensor_unregister(data->ts_local);

Ideally you would unregister your sensors in the reverse order they have 
been registered, but I'm being picky here.

Alex.

  parent reply	other threads:[~2013-02-19  5:22 UTC|newest]

Thread overview: 135+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-18 11:30 [RFC PATCH 0/9] Support for tegra30 thermal Wei Ni
2013-02-18 11:30 ` Wei Ni
2013-02-18 11:30 ` [lm-sensors] " Wei Ni
2013-02-18 11:30 ` [RFC PATCH 2/9] hwmon: (lm90) split set&show temp as common codes Wei Ni
2013-02-18 11:30   ` Wei Ni
2013-02-18 11:30   ` [lm-sensors] " Wei Ni
2013-02-18 22:29   ` Matthew Longnecker
2013-02-18 22:29     ` Matthew Longnecker
2013-02-18 22:29     ` [lm-sensors] " Matthew Longnecker
2013-02-19  9:48     ` Wei Ni
2013-02-19  9:48       ` Wei Ni
2013-02-19  9:48       ` [lm-sensors] " Wei Ni
2013-02-19  3:31   ` Guenter Roeck
2013-02-19  3:31     ` Guenter Roeck
2013-02-19  3:31     ` Guenter Roeck
     [not found]     ` <20130219033144.GA25610-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
2013-02-19 10:00       ` Wei Ni
2013-02-19 10:00         ` Wei Ni
2013-02-19 10:00         ` Wei Ni
2013-02-19 22:56   ` Stephen Warren
2013-02-19 22:56     ` Stephen Warren
2013-02-19 22:56     ` [lm-sensors] " Stephen Warren
     [not found]     ` <51240331.7080604-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-02-20 12:31       ` Wei Ni
2013-02-20 12:31         ` Wei Ni
2013-02-20 12:31         ` [lm-sensors] " Wei Ni
2013-02-18 11:30 ` [RFC PATCH 4/9] hwmon: (lm90) use macros for the indexes of temp8 and temp11 Wei Ni
2013-02-18 11:30   ` Wei Ni
2013-02-18 11:30   ` [lm-sensors] " Wei Ni
2013-02-19  5:39   ` Alex Courbot
2013-02-19  5:39     ` Alex Courbot
2013-02-19  5:39     ` [lm-sensors] " Alex Courbot
     [not found]     ` <5123100A.9050604-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19  9:58       ` Wei Ni
2013-02-19  9:58         ` Wei Ni
2013-02-19  9:58         ` [lm-sensors] " Wei Ni
2013-02-19 23:02   ` Stephen Warren
2013-02-19 23:02     ` Stephen Warren
2013-02-19 23:02     ` [lm-sensors] " Stephen Warren
     [not found]     ` <51240497.8010909-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-02-20 10:29       ` Wei Ni
2013-02-20 10:29         ` Wei Ni
2013-02-20 10:29         ` [lm-sensors] " Wei Ni
     [not found] ` <1361187031-3679-1-git-send-email-wni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-18 11:30   ` [RFC PATCH 1/9] ARM: dt: t30 cardhu: add dt entry for lm90 Wei Ni
2013-02-18 11:30     ` Wei Ni
2013-02-18 11:30     ` [lm-sensors] " Wei Ni
     [not found]     ` <1361187031-3679-2-git-send-email-wni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19  3:28       ` Alex Courbot
2013-02-19  3:28         ` Alex Courbot
2013-02-19  3:28         ` [lm-sensors] " Alex Courbot
2013-02-19  9:52         ` Wei Ni
2013-02-19  9:52           ` Wei Ni
2013-02-19  9:52           ` [lm-sensors] " Wei Ni
     [not found]         ` <5122F162.9030103-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19 22:48           ` Stephen Warren
2013-02-19 22:48             ` Stephen Warren
2013-02-19 22:48             ` [lm-sensors] " Stephen Warren
2013-02-18 11:30   ` [RFC PATCH 3/9] hwmon: (lm90) add support to handle irq Wei Ni
2013-02-18 11:30     ` Wei Ni
2013-02-18 11:30     ` [lm-sensors] " Wei Ni
     [not found]     ` <1361187031-3679-4-git-send-email-wni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19  3:34       ` Guenter Roeck
2013-02-19  3:34         ` Guenter Roeck
2013-02-19  3:34         ` Guenter Roeck
2013-02-19 10:43         ` Wei Ni
2013-02-19 10:43           ` Wei Ni
2013-02-19 10:43           ` Wei Ni
2013-02-19 23:00     ` Stephen Warren
2013-02-19 23:00       ` Stephen Warren
2013-02-19 23:00       ` [lm-sensors] " Stephen Warren
2013-02-20  3:27       ` Alex Courbot
2013-02-20  3:27         ` Alex Courbot
2013-02-20  3:27         ` [lm-sensors] " Alex Courbot
     [not found]         ` <5124429B.2000404-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-20 10:27           ` Wei Ni
2013-02-20 10:27             ` Wei Ni
2013-02-20 10:27             ` [lm-sensors] " Wei Ni
2013-02-18 11:30   ` [RFC PATCH 5/9] Thermal: Support using dt node to get sensor Wei Ni
2013-02-18 11:30     ` Wei Ni
2013-02-18 11:30     ` [lm-sensors] " Wei Ni
     [not found]     ` <1361187031-3679-6-git-send-email-wni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19 23:12       ` Stephen Warren
2013-02-19 23:12         ` Stephen Warren
2013-02-19 23:12         ` [lm-sensors] " Stephen Warren
     [not found]         ` <512406F0.4080708-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2013-02-20 10:36           ` Wei Ni
2013-02-20 10:36             ` Wei Ni
2013-02-20 10:36             ` [lm-sensors] " Wei Ni
2013-02-18 11:30   ` [RFC PATCH 6/9] hwmon: (lm90) Register to the thermal framework Wei Ni
2013-02-18 11:30     ` Wei Ni
2013-02-18 11:30     ` [lm-sensors] " Wei Ni
2013-02-19  3:42     ` Guenter Roeck
2013-02-19  3:42       ` Guenter Roeck
2013-02-19  3:42       ` Guenter Roeck
     [not found]       ` <20130219034205.GC25610-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>
2013-02-19 10:47         ` Wei Ni
2013-02-19 10:47           ` Wei Ni
2013-02-19 10:47           ` Wei Ni
2013-02-19  5:22     ` Alex Courbot [this message]
2013-02-19  5:22       ` Alex Courbot
2013-02-19  5:22       ` [lm-sensors] " Alex Courbot
2013-02-19 10:58       ` Wei Ni
2013-02-19 10:58         ` Wei Ni
2013-02-19 10:58         ` [lm-sensors] " Wei Ni
     [not found]     ` <1361187031-3679-7-git-send-email-wni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19 23:18       ` Stephen Warren
2013-02-19 23:18         ` Stephen Warren
2013-02-19 23:18         ` [lm-sensors] " Stephen Warren
2013-02-20 10:40         ` Wei Ni
2013-02-20 10:40           ` Wei Ni
2013-02-20 10:40           ` [lm-sensors] " Wei Ni
2013-02-18 11:30   ` [RFC PATCH 8/9] ARM: dt: t30 cardhu: add dt entry for thermal driver Wei Ni
2013-02-18 11:30     ` Wei Ni
2013-02-18 11:30     ` [lm-sensors] " Wei Ni
2013-02-19  3:42     ` Alex Courbot
2013-02-19  3:42       ` Alex Courbot
2013-02-19  3:42       ` [lm-sensors] " Alex Courbot
2013-02-19  9:56       ` Wei Ni
2013-02-19  9:56         ` Wei Ni
2013-02-19  9:56         ` [lm-sensors] " Wei Ni
     [not found]     ` <1361187031-3679-9-git-send-email-wni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-19 23:28       ` Stephen Warren
2013-02-19 23:28         ` Stephen Warren
2013-02-19 23:28         ` [lm-sensors] " Stephen Warren
2013-02-20 11:53         ` Wei Ni
2013-02-20 11:53           ` Wei Ni
2013-02-20 11:53           ` [lm-sensors] " Wei Ni
     [not found]           ` <5124B934.3020900-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2013-02-20 17:18             ` Stephen Warren
2013-02-20 17:18               ` Stephen Warren
2013-02-20 17:18               ` [lm-sensors] " Stephen Warren
2013-02-18 11:30   ` [RFC PATCH 9/9] ARM: tegra: defconfig: enable thermal framework Wei Ni
2013-02-18 11:30     ` Wei Ni
2013-02-18 11:30     ` [lm-sensors] " Wei Ni
2013-02-18 11:30 ` [RFC PATCH 7/9] thermal: tegra30: add tegra30 thermal driver Wei Ni
2013-02-18 11:30   ` Wei Ni
2013-02-18 11:30   ` [lm-sensors] " Wei Ni
2013-02-19 23:48   ` Stephen Warren
2013-02-19 23:48     ` Stephen Warren
2013-02-19 23:48     ` [lm-sensors] " Stephen Warren
2013-02-20 12:23     ` Wei Ni
2013-02-20 12:23       ` Wei Ni
2013-02-20 12:23       ` [lm-sensors] " Wei Ni
2013-02-19 23:56   ` Russell King - ARM Linux
2013-02-19 23:56     ` Russell King - ARM Linux
2013-02-19 23:56     ` [lm-sensors] " Russell King - ARM Linux
     [not found]     ` <20130219235629.GU17833-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>
2013-02-20 12:29       ` Wei Ni
2013-02-20 12:29         ` Wei Ni
2013-02-20 12:29         ` [lm-sensors] " Wei Ni

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=51230C24.5090707@nvidia.com \
    --to=acourbot@nvidia.com \
    --cc=MLongnecker@nvidia.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=durgadoss.r@intel.com \
    --cc=khali@linux-fr.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.orgrs.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=lm-sensors@lm-sensors.org \
    --cc=rui.zhang@intel.com \
    --cc=wni@nvidia.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.