Jean Delvare wrote:
> The new-style fschmd driver implements the optional detect() callback
> to cover the use cases of the legacy driver.
> 
> Signed-off-by: Jean Delvare <[EMAIL PROTECTED]>
> Cc: Hans de Goede <[EMAIL PROTECTED]>

Tested as promised, still works fine.

Signed-off-by: Hans de Goede <[EMAIL PROTECTED]>

Regards,

Hans



> ---
>  drivers/hwmon/fschmd.c |  112 
> ++++++++++++++++++++++++------------------------
>  1 file changed, 57 insertions(+), 55 deletions(-)
> 
> --- linux-2.6.26-rc9.orig/drivers/hwmon/fschmd.c      2008-07-12 
> 09:20:30.000000000 +0200
> +++ linux-2.6.26-rc9/drivers/hwmon/fschmd.c   2008-07-12 10:27:23.000000000 
> +0200
> @@ -171,20 +171,37 @@ static const int FSCHMD_NO_TEMP_SENSORS[
>   * Functions declarations
>   */
>  
> -static int fschmd_attach_adapter(struct i2c_adapter *adapter);
> -static int fschmd_detach_client(struct i2c_client *client);
> +static int fschmd_probe(struct i2c_client *client,
> +                     const struct i2c_device_id *id);
> +static int fschmd_detect(struct i2c_client *client, int kind,
> +                      struct i2c_board_info *info);
> +static int fschmd_remove(struct i2c_client *client);
>  static struct fschmd_data *fschmd_update_device(struct device *dev);
>  
>  /*
>   * Driver data (common to all clients)
>   */
>  
> +static const struct i2c_device_id fschmd_id[] = {
> +     { "fscpos", fscpos },
> +     { "fscher", fscher },
> +     { "fscscy", fscscy },
> +     { "fschrc", fschrc },
> +     { "fschmd", fschmd },
> +     { }
> +};
> +MODULE_DEVICE_TABLE(i2c, fschmd_id);
> +
>  static struct i2c_driver fschmd_driver = {
> +     .class          = I2C_CLASS_HWMON,
>       .driver = {
>               .name   = FSCHMD_NAME,
>       },
> -     .attach_adapter = fschmd_attach_adapter,
> -     .detach_client  = fschmd_detach_client,
> +     .probe          = fschmd_probe,
> +     .remove         = fschmd_remove,
> +     .id_table       = fschmd_id,
> +     .detect         = fschmd_detect,
> +     .address_data   = &addr_data,
>  };
>  
>  /*
> @@ -192,7 +209,6 @@ static struct i2c_driver fschmd_driver =
>   */
>  
>  struct fschmd_data {
> -     struct i2c_client client;
>       struct device *hwmon_dev;
>       struct mutex update_lock;
>       int kind;
> @@ -269,7 +285,7 @@ static ssize_t store_temp_max(struct dev
>       v = SENSORS_LIMIT(v, -128, 127) + 128;
>  
>       mutex_lock(&data->update_lock);
> -     i2c_smbus_write_byte_data(&data->client,
> +     i2c_smbus_write_byte_data(to_i2c_client(dev),
>               FSCHMD_REG_TEMP_LIMIT[data->kind][index], v);
>       data->temp_max[index] = v;
>       mutex_unlock(&data->update_lock);
> @@ -346,14 +362,14 @@ static ssize_t store_fan_div(struct devi
>  
>       mutex_lock(&data->update_lock);
>  
> -     reg = i2c_smbus_read_byte_data(&data->client,
> +     reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
>               FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
>  
>       /* bits 2..7 reserved => mask with 0x03 */
>       reg &= ~0x03;
>       reg |= v;
>  
> -     i2c_smbus_write_byte_data(&data->client,
> +     i2c_smbus_write_byte_data(to_i2c_client(dev),
>               FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg);
>  
>       data->fan_ripple[index] = reg;
> @@ -416,7 +432,7 @@ static ssize_t store_pwm_auto_point1_pwm
>  
>       mutex_lock(&data->update_lock);
>  
> -     i2c_smbus_write_byte_data(&data->client,
> +     i2c_smbus_write_byte_data(to_i2c_client(dev),
>               FSCHMD_REG_FAN_MIN[data->kind][index], v);
>       data->fan_min[index] = v;
>  
> @@ -448,14 +464,14 @@ static ssize_t store_alert_led(struct de
>  
>       mutex_lock(&data->update_lock);
>  
> -     reg = i2c_smbus_read_byte_data(&data->client, FSCHMD_REG_CONTROL);
> +     reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
>  
>       if (v)
>               reg |= FSCHMD_CONTROL_ALERT_LED_MASK;
>       else
>               reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK;
>  
> -     i2c_smbus_write_byte_data(&data->client, FSCHMD_REG_CONTROL, reg);
> +     i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
>  
>       data->global_control = reg;
>  
> @@ -600,32 +616,15 @@ static void fschmd_dmi_decode(const stru
>       }
>  }
>  
> -static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
> +static int fschmd_detect(struct i2c_client *client, int kind,
> +                      struct i2c_board_info *info)
>  {
> -     struct i2c_client *client;
> -     struct fschmd_data *data;
> -     u8 revision;
> -     const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
> -                                     "Heracles", "Heimdall" };
> +     struct i2c_adapter *adapter = client->adapter;
>       const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
>                                               "fschrc", "fschmd" };
> -     int i, err = 0;
>  
>       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
> -             return 0;
> -
> -     /* OK. For now, we presume we have a valid client. We now create the
> -      * client structure, even though we cannot fill it completely yet.
> -      * But it allows us to access i2c_smbus_read_byte_data. */
> -     if (!(data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL)))
> -             return -ENOMEM;
> -
> -     client = &data->client;
> -     i2c_set_clientdata(client, data);
> -     client->addr = address;
> -     client->adapter = adapter;
> -     client->driver = &fschmd_driver;
> -     mutex_init(&data->update_lock);
> +             return -ENODEV;
>  
>       /* Detect & Identify the chip */
>       if (kind <= 0) {
> @@ -650,9 +649,31 @@ static int fschmd_detect(struct i2c_adap
>               else if (!strcmp(id, "HMD"))
>                       kind = fschmd;
>               else
> -                     goto exit_free;
> +                     return -ENODEV;
>       }
>  
> +     strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
> +
> +     return 0;
> +}
> +
> +static int fschmd_probe(struct i2c_client *client,
> +                     const struct i2c_device_id *id)
> +{
> +     struct fschmd_data *data;
> +     u8 revision;
> +     const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
> +                                     "Heracles", "Heimdall" };
> +     int i, err;
> +     enum chips kind = id->driver_data;
> +
> +     data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL);
> +     if (!data)
> +             return -ENOMEM;
> +
> +     i2c_set_clientdata(client, data);
> +     mutex_init(&data->update_lock);
> +
>       if (kind == fscpos) {
>               /* The Poseidon has hardwired temp limits, fill these
>                  in for the alarm resetting code */
> @@ -674,11 +695,6 @@ static int fschmd_detect(struct i2c_adap
>  
>       /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
>       data->kind = kind - 1;
> -     strlcpy(client->name, client_names[data->kind], I2C_NAME_SIZE);
> -
> -     /* Tell the I2C layer a new client has arrived */
> -     if ((err = i2c_attach_client(client)))
> -             goto exit_free;
>  
>       for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
>               err = device_create_file(&client->dev,
> @@ -726,25 +742,14 @@ static int fschmd_detect(struct i2c_adap
>       return 0;
>  
>  exit_detach:
> -     fschmd_detach_client(client); /* will also free data for us */
> -     return err;
> -
> -exit_free:
> -     kfree(data);
> +     fschmd_remove(client); /* will also free data for us */
>       return err;
>  }
>  
> -static int fschmd_attach_adapter(struct i2c_adapter *adapter)
> -{
> -     if (!(adapter->class & I2C_CLASS_HWMON))
> -             return 0;
> -     return i2c_probe(adapter, &addr_data, fschmd_detect);
> -}
> -
> -static int fschmd_detach_client(struct i2c_client *client)
> +static int fschmd_remove(struct i2c_client *client)
>  {
>       struct fschmd_data *data = i2c_get_clientdata(client);
> -     int i, err;
> +     int i;
>  
>       /* Check if registered in case we're called from fschmd_detect
>          to cleanup after an error */
> @@ -760,9 +765,6 @@ static int fschmd_detach_client(struct i
>               device_remove_file(&client->dev,
>                                       &fschmd_fan_attr[i].dev_attr);
>  
> -     if ((err = i2c_detach_client(client)))
> -             return err;
> -
>       kfree(data);
>       return 0;
>  }
> 
> 



_______________________________________________
i2c mailing list
[email protected]
http://lists.lm-sensors.org/mailman/listinfo/i2c

Reply via email to