diff options
| -rw-r--r-- | drivers/hwmon/gl520sm.c | 91 |
1 files changed, 43 insertions, 48 deletions
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index 8984ef141627..19616f2242b0 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
| @@ -79,26 +79,37 @@ static const u8 GL520_REG_TEMP_MAX_HYST[] = { 0x06, 0x18 }; | |||
| 79 | * Function declarations | 79 | * Function declarations |
| 80 | */ | 80 | */ |
| 81 | 81 | ||
| 82 | static int gl520_attach_adapter(struct i2c_adapter *adapter); | 82 | static int gl520_probe(struct i2c_client *client, |
| 83 | static int gl520_detect(struct i2c_adapter *adapter, int address, int kind); | 83 | const struct i2c_device_id *id); |
| 84 | static int gl520_detect(struct i2c_client *client, int kind, | ||
| 85 | struct i2c_board_info *info); | ||
| 84 | static void gl520_init_client(struct i2c_client *client); | 86 | static void gl520_init_client(struct i2c_client *client); |
| 85 | static int gl520_detach_client(struct i2c_client *client); | 87 | static int gl520_remove(struct i2c_client *client); |
| 86 | static int gl520_read_value(struct i2c_client *client, u8 reg); | 88 | static int gl520_read_value(struct i2c_client *client, u8 reg); |
| 87 | static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value); | 89 | static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value); |
| 88 | static struct gl520_data *gl520_update_device(struct device *dev); | 90 | static struct gl520_data *gl520_update_device(struct device *dev); |
| 89 | 91 | ||
| 90 | /* Driver data */ | 92 | /* Driver data */ |
| 93 | static const struct i2c_device_id gl520_id[] = { | ||
| 94 | { "gl520sm", gl520sm }, | ||
| 95 | { } | ||
| 96 | }; | ||
| 97 | MODULE_DEVICE_TABLE(i2c, gl520_id); | ||
| 98 | |||
| 91 | static struct i2c_driver gl520_driver = { | 99 | static struct i2c_driver gl520_driver = { |
| 100 | .class = I2C_CLASS_HWMON, | ||
| 92 | .driver = { | 101 | .driver = { |
| 93 | .name = "gl520sm", | 102 | .name = "gl520sm", |
| 94 | }, | 103 | }, |
| 95 | .attach_adapter = gl520_attach_adapter, | 104 | .probe = gl520_probe, |
| 96 | .detach_client = gl520_detach_client, | 105 | .remove = gl520_remove, |
| 106 | .id_table = gl520_id, | ||
| 107 | .detect = gl520_detect, | ||
| 108 | .address_data = &addr_data, | ||
| 97 | }; | 109 | }; |
| 98 | 110 | ||
| 99 | /* Client data */ | 111 | /* Client data */ |
| 100 | struct gl520_data { | 112 | struct gl520_data { |
| 101 | struct i2c_client client; | ||
| 102 | struct device *hwmon_dev; | 113 | struct device *hwmon_dev; |
| 103 | struct mutex update_lock; | 114 | struct mutex update_lock; |
| 104 | char valid; /* zero until the following fields are valid */ | 115 | char valid; /* zero until the following fields are valid */ |
| @@ -669,37 +680,15 @@ static const struct attribute_group gl520_group_opt = { | |||
| 669 | * Real code | 680 | * Real code |
| 670 | */ | 681 | */ |
| 671 | 682 | ||
| 672 | static int gl520_attach_adapter(struct i2c_adapter *adapter) | 683 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 673 | { | 684 | static int gl520_detect(struct i2c_client *client, int kind, |
| 674 | if (!(adapter->class & I2C_CLASS_HWMON)) | 685 | struct i2c_board_info *info) |
| 675 | return 0; | ||
| 676 | return i2c_probe(adapter, &addr_data, gl520_detect); | ||
| 677 | } | ||
| 678 | |||
| 679 | static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) | ||
| 680 | { | 686 | { |
| 681 | struct i2c_client *client; | 687 | struct i2c_adapter *adapter = client->adapter; |
| 682 | struct gl520_data *data; | ||
| 683 | int err = 0; | ||
| 684 | 688 | ||
| 685 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 689 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
| 686 | I2C_FUNC_SMBUS_WORD_DATA)) | 690 | I2C_FUNC_SMBUS_WORD_DATA)) |
| 687 | goto exit; | 691 | return -ENODEV; |
| 688 | |||
| 689 | /* OK. For now, we presume we have a valid client. We now create the | ||
| 690 | client structure, even though we cannot fill it completely yet. | ||
| 691 | But it allows us to access gl520_{read,write}_value. */ | ||
| 692 | |||
| 693 | if (!(data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL))) { | ||
| 694 | err = -ENOMEM; | ||
| 695 | goto exit; | ||
| 696 | } | ||
| 697 | |||
| 698 | client = &data->client; | ||
| 699 | i2c_set_clientdata(client, data); | ||
| 700 | client->addr = address; | ||
| 701 | client->adapter = adapter; | ||
| 702 | client->driver = &gl520_driver; | ||
| 703 | 692 | ||
| 704 | /* Determine the chip type. */ | 693 | /* Determine the chip type. */ |
| 705 | if (kind < 0) { | 694 | if (kind < 0) { |
| @@ -707,24 +696,36 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 707 | ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) || | 696 | ((gl520_read_value(client, GL520_REG_REVISION) & 0x7f) != 0x00) || |
| 708 | ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) { | 697 | ((gl520_read_value(client, GL520_REG_CONF) & 0x80) != 0x00)) { |
| 709 | dev_dbg(&client->dev, "Unknown chip type, skipping\n"); | 698 | dev_dbg(&client->dev, "Unknown chip type, skipping\n"); |
| 710 | goto exit_free; | 699 | return -ENODEV; |
| 711 | } | 700 | } |
| 712 | } | 701 | } |
| 713 | 702 | ||
| 714 | /* Fill in the remaining client fields */ | 703 | strlcpy(info->type, "gl520sm", I2C_NAME_SIZE); |
| 715 | strlcpy(client->name, "gl520sm", I2C_NAME_SIZE); | ||
| 716 | mutex_init(&data->update_lock); | ||
| 717 | 704 | ||
| 718 | /* Tell the I2C layer a new client has arrived */ | 705 | return 0; |
| 719 | if ((err = i2c_attach_client(client))) | 706 | } |
| 720 | goto exit_free; | 707 | |
| 708 | static int gl520_probe(struct i2c_client *client, | ||
| 709 | const struct i2c_device_id *id) | ||
| 710 | { | ||
| 711 | struct gl520_data *data; | ||
| 712 | int err; | ||
| 713 | |||
| 714 | data = kzalloc(sizeof(struct gl520_data), GFP_KERNEL); | ||
| 715 | if (!data) { | ||
| 716 | err = -ENOMEM; | ||
| 717 | goto exit; | ||
| 718 | } | ||
| 719 | |||
| 720 | i2c_set_clientdata(client, data); | ||
| 721 | mutex_init(&data->update_lock); | ||
| 721 | 722 | ||
| 722 | /* Initialize the GL520SM chip */ | 723 | /* Initialize the GL520SM chip */ |
| 723 | gl520_init_client(client); | 724 | gl520_init_client(client); |
| 724 | 725 | ||
| 725 | /* Register sysfs hooks */ | 726 | /* Register sysfs hooks */ |
| 726 | if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group))) | 727 | if ((err = sysfs_create_group(&client->dev.kobj, &gl520_group))) |
| 727 | goto exit_detach; | 728 | goto exit_free; |
| 728 | 729 | ||
| 729 | if (data->two_temps) { | 730 | if (data->two_temps) { |
| 730 | if ((err = device_create_file(&client->dev, | 731 | if ((err = device_create_file(&client->dev, |
| @@ -764,8 +765,6 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 764 | exit_remove_files: | 765 | exit_remove_files: |
| 765 | sysfs_remove_group(&client->dev.kobj, &gl520_group); | 766 | sysfs_remove_group(&client->dev.kobj, &gl520_group); |
| 766 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); | 767 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); |
| 767 | exit_detach: | ||
| 768 | i2c_detach_client(client); | ||
| 769 | exit_free: | 768 | exit_free: |
| 770 | kfree(data); | 769 | kfree(data); |
| 771 | exit: | 770 | exit: |
| @@ -811,18 +810,14 @@ static void gl520_init_client(struct i2c_client *client) | |||
| 811 | gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); | 810 | gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); |
| 812 | } | 811 | } |
| 813 | 812 | ||
| 814 | static int gl520_detach_client(struct i2c_client *client) | 813 | static int gl520_remove(struct i2c_client *client) |
| 815 | { | 814 | { |
| 816 | struct gl520_data *data = i2c_get_clientdata(client); | 815 | struct gl520_data *data = i2c_get_clientdata(client); |
| 817 | int err; | ||
| 818 | 816 | ||
| 819 | hwmon_device_unregister(data->hwmon_dev); | 817 | hwmon_device_unregister(data->hwmon_dev); |
| 820 | sysfs_remove_group(&client->dev.kobj, &gl520_group); | 818 | sysfs_remove_group(&client->dev.kobj, &gl520_group); |
| 821 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); | 819 | sysfs_remove_group(&client->dev.kobj, &gl520_group_opt); |
| 822 | 820 | ||
| 823 | if ((err = i2c_detach_client(client))) | ||
| 824 | return err; | ||
| 825 | |||
| 826 | kfree(data); | 821 | kfree(data); |
| 827 | return 0; | 822 | return 0; |
| 828 | } | 823 | } |
