aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/f75375s.c109
1 files changed, 83 insertions, 26 deletions
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 59a3470d6cf9..19b3427b5e9e 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -86,7 +86,7 @@ I2C_CLIENT_INSMOD_2(f75373, f75375);
86 86
87struct f75375_data { 87struct f75375_data {
88 unsigned short addr; 88 unsigned short addr;
89 struct i2c_client client; 89 struct i2c_client *client;
90 struct device *hwmon_dev; 90 struct device *hwmon_dev;
91 91
92 const char *name; 92 const char *name;
@@ -116,15 +116,25 @@ struct f75375_data {
116static int f75375_attach_adapter(struct i2c_adapter *adapter); 116static int f75375_attach_adapter(struct i2c_adapter *adapter);
117static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); 117static int f75375_detect(struct i2c_adapter *adapter, int address, int kind);
118static int f75375_detach_client(struct i2c_client *client); 118static int f75375_detach_client(struct i2c_client *client);
119static int f75375_probe(struct i2c_client *client);
120static int f75375_remove(struct i2c_client *client);
119 121
120static struct i2c_driver f75375_driver = { 122static struct i2c_driver f75375_legacy_driver = {
121 .driver = { 123 .driver = {
122 .name = "f75375", 124 .name = "f75375_legacy",
123 }, 125 },
124 .attach_adapter = f75375_attach_adapter, 126 .attach_adapter = f75375_attach_adapter,
125 .detach_client = f75375_detach_client, 127 .detach_client = f75375_detach_client,
126}; 128};
127 129
130static struct i2c_driver f75375_driver = {
131 .driver = {
132 .name = "f75375",
133 },
134 .probe = f75375_probe,
135 .remove = f75375_remove,
136};
137
128static inline int f75375_read8(struct i2c_client *client, u8 reg) 138static inline int f75375_read8(struct i2c_client *client, u8 reg)
129{ 139{
130 return i2c_smbus_read_byte_data(client, reg); 140 return i2c_smbus_read_byte_data(client, reg);
@@ -580,12 +590,9 @@ static const struct attribute_group f75375_group = {
580 590
581static int f75375_detach_client(struct i2c_client *client) 591static int f75375_detach_client(struct i2c_client *client)
582{ 592{
583 struct f75375_data *data = i2c_get_clientdata(client);
584 int err; 593 int err;
585 594
586 hwmon_device_unregister(data->hwmon_dev); 595 f75375_remove(client);
587 sysfs_remove_group(&client->dev.kobj, &f75375_group);
588
589 err = i2c_detach_client(client); 596 err = i2c_detach_client(client);
590 if (err) { 597 if (err) {
591 dev_err(&client->dev, 598 dev_err(&client->dev,
@@ -593,7 +600,60 @@ static int f75375_detach_client(struct i2c_client *client)
593 "client not detached.\n"); 600 "client not detached.\n");
594 return err; 601 return err;
595 } 602 }
603 kfree(client);
604 return 0;
605}
606
607static int f75375_probe(struct i2c_client *client)
608{
609 struct f75375_data *data = i2c_get_clientdata(client);
610 int err;
611
612 if (!i2c_check_functionality(client->adapter,
613 I2C_FUNC_SMBUS_BYTE_DATA))
614 return -EIO;
615 if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL)))
616 return -ENOMEM;
617
618 i2c_set_clientdata(client, data);
619 data->client = client;
620 mutex_init(&data->update_lock);
621
622 if (strcmp(client->name, "f75375") == 0)
623 data->kind = f75375;
624 else if (strcmp(client->name, "f75373") == 0)
625 data->kind = f75373;
626 else {
627 dev_err(&client->dev, "Unsupported device: %s\n", client->name);
628 return -ENODEV;
629 }
630
631 if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group)))
632 goto exit_free;
633
634 data->hwmon_dev = hwmon_device_register(&client->dev);
635 if (IS_ERR(data->hwmon_dev)) {
636 err = PTR_ERR(data->hwmon_dev);
637 goto exit_remove;
638 }
639
640 return 0;
641
642exit_remove:
643 sysfs_remove_group(&client->dev.kobj, &f75375_group);
644exit_free:
645 kfree(data);
646 i2c_set_clientdata(client, NULL);
647 return err;
648}
649
650static int f75375_remove(struct i2c_client *client)
651{
652 struct f75375_data *data = i2c_get_clientdata(client);
653 hwmon_device_unregister(data->hwmon_dev);
654 sysfs_remove_group(&client->dev.kobj, &f75375_group);
596 kfree(data); 655 kfree(data);
656 i2c_set_clientdata(client, NULL);
597 return 0; 657 return 0;
598} 658}
599 659
@@ -608,20 +668,17 @@ static int f75375_attach_adapter(struct i2c_adapter *adapter)
608static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) 668static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
609{ 669{
610 struct i2c_client *client; 670 struct i2c_client *client;
611 struct f75375_data *data;
612 u8 version = 0; 671 u8 version = 0;
613 int err = 0; 672 int err = 0;
614 const char *name = ""; 673 const char *name = "";
615 674
616 if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) { 675 if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) {
617 err = -ENOMEM; 676 err = -ENOMEM;
618 goto exit; 677 goto exit;
619 } 678 }
620 client = &data->client;
621 i2c_set_clientdata(client, data);
622 client->addr = address; 679 client->addr = address;
623 client->adapter = adapter; 680 client->adapter = adapter;
624 client->driver = &f75375_driver; 681 client->driver = &f75375_legacy_driver;
625 682
626 if (kind < 0) { 683 if (kind < 0) {
627 u16 vendid = f75375_read16(client, F75375_REG_VENDOR); 684 u16 vendid = f75375_read16(client, F75375_REG_VENDOR);
@@ -644,42 +701,42 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind)
644 } else if (kind == f75373) { 701 } else if (kind == f75373) {
645 name = "f75373"; 702 name = "f75373";
646 } 703 }
647
648 dev_info(&adapter->dev, "found %s version: %02X\n", name, version); 704 dev_info(&adapter->dev, "found %s version: %02X\n", name, version);
649 strlcpy(client->name, name, I2C_NAME_SIZE); 705 strlcpy(client->name, name, I2C_NAME_SIZE);
650 data->kind = kind; 706
651 mutex_init(&data->update_lock);
652 if ((err = i2c_attach_client(client))) 707 if ((err = i2c_attach_client(client)))
653 goto exit_free; 708 goto exit_free;
654 709
655 if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) 710 if ((err = f75375_probe(client)) < 0)
656 goto exit_detach; 711 goto exit_detach;
657 712
658 data->hwmon_dev = hwmon_device_register(&client->dev);
659 if (IS_ERR(data->hwmon_dev)) {
660 err = PTR_ERR(data->hwmon_dev);
661 goto exit_remove;
662 }
663
664 return 0; 713 return 0;
665 714
666exit_remove:
667 sysfs_remove_group(&client->dev.kobj, &f75375_group);
668exit_detach: 715exit_detach:
669 i2c_detach_client(client); 716 i2c_detach_client(client);
670exit_free: 717exit_free:
671 kfree(data); 718 kfree(client);
672exit: 719exit:
673 return err; 720 return err;
674} 721}
675 722
676static int __init sensors_f75375_init(void) 723static int __init sensors_f75375_init(void)
677{ 724{
678 return i2c_add_driver(&f75375_driver); 725 int status;
726 status = i2c_add_driver(&f75375_driver);
727 if (status)
728 return status;
729
730 status = i2c_add_driver(&f75375_legacy_driver);
731 if (status)
732 i2c_del_driver(&f75375_driver);
733
734 return status;
679} 735}
680 736
681static void __exit sensors_f75375_exit(void) 737static void __exit sensors_f75375_exit(void)
682{ 738{
739 i2c_del_driver(&f75375_legacy_driver);
683 i2c_del_driver(&f75375_driver); 740 i2c_del_driver(&f75375_driver);
684} 741}
685 742