diff options
Diffstat (limited to 'drivers/hwmon')
-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 | } |