[PATCH 2/2] lm87: Add support for configuration through platform_data

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ben,

On Tue, 19 Aug 2008 16:02:29 +0100, Ben Hutchings wrote:
> The lm87 driver normally assumes that firmware configured the chip
> correctly.  Since this is not always the case, alllow platform code to
> set the channel register value via platform_data.  All other
> configuration registers can be changed after driver initialisation.

Sounds almost sane to me, except...

> 
> Signed-off-by: Ben Hutchings <bhutchings at solarflare.com>
> ---
>  drivers/hwmon/lm87.c |   33 ++++++++++++++++++++++++---------
>  1 files changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
> index ddad6fc..1f5cac5 100644
> --- a/drivers/hwmon/lm87.c
> +++ b/drivers/hwmon/lm87.c
> @@ -21,11 +21,12 @@
>   *   http://www.national.com/pf/LM/LM87.html
>   *
>   * Some functions share pins, so not all functions are available at the same
> - * time. Which are depends on the hardware setup. This driver assumes that
> - * the BIOS configured the chip correctly. In that respect, it  differs from
> - * the original driver (from lm_sensors for Linux 2.4), which would force the
> - * LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
> - * chipset wiring.
> + * time. Which are depends on the hardware setup. This driver normally
> + * assumes that firmware configured the chip correctly. Where this is not
> + * the case, platform code must set the I2C client's platform_data to point
> + * to a u8 value to be written to the channel register. In that case the
> + * driver will assume that it is the only user of the chip and will reset
> + * it in the probe and remove functions.

I fail to see how setting the channel mode is related to resetting the
chip. Not that I really get the point of resetting the chip in the
first place, but if you want to do that, it should be independent of
setting the channel mode.

>   * For reference, here is the list of exclusive functions:
>   *  - in0+in5 (default) or temp3
>   *  - fan1 (default) or in6
> @@ -731,7 +732,7 @@ static int lm87_probe(struct i2c_client *new_client,
>  
>  	/* Register sysfs hooks */
>  	if ((err = sysfs_create_group(&new_client->dev.kobj, &lm87_group)))
> -		goto exit_free;
> +		goto exit_reset;
>  
>  	if (data->channel & CHAN_NO_FAN(0)) {
>  		if ((err = device_create_file(&new_client->dev,
> @@ -831,7 +832,10 @@ static int lm87_probe(struct i2c_client *new_client,
>  exit_remove:
>  	sysfs_remove_group(&new_client->dev.kobj, &lm87_group);
>  	sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt);
> -exit_free:
> +exit_reset:
> +	if (new_client->dev.platform_data)
> +		lm87_write_value(new_client, LM87_REG_CONFIG, 0x80);
> +
>  	kfree(data);
>  exit:
>  	return err;
> @@ -842,9 +846,17 @@ static void lm87_init_client(struct i2c_client *client)
>  	struct lm87_data *data = i2c_get_clientdata(client);
>  	u8 config;
>  
> -	data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
> +	if (client->dev.platform_data) {
> +		config = 0x80;
> +		lm87_write_value(client, LM87_REG_CONFIG, config);
> +		data->channel = *(u8 *)client->dev.platform_data;

I'm not fond of that kind of cast. Which leads me to the following
porposal: define a proper structure controlling the LM87 device
initialization.

struct lm87_platform_data {
	u8 channel_mode;
	unsigned int reset:1;
}

So that the caller has control over the channel mode and the resetting
of the chip, in a clear and independent way. This is much better than
(ab)using the platform_data pointer for everything.

> +		lm87_write_value(client,
> +				 LM87_REG_CHANNEL_MODE, data->channel);
> +	} else {
> +		data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
> +		config = lm87_read_value(client, LM87_REG_CONFIG);
> +	}
>  
> -	config = lm87_read_value(client, LM87_REG_CONFIG);
>  	if (!(config & 0x01)) {
>  		int i;
>  
> @@ -882,6 +894,9 @@ static int lm87_remove(struct i2c_client *client)
>  	sysfs_remove_group(&client->dev.kobj, &lm87_group);
>  	sysfs_remove_group(&client->dev.kobj, &lm87_group_opt);
>  
> +	if (client->dev.platform_data)
> +		lm87_write_value(client, LM87_REG_CONFIG, 0x80);
> +
>  	kfree(data);
>  	return 0;
>  }


-- 
Jean Delvare




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux