aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-06-09 10:11:16 -0400
committerMark M. Hoffman <mhoffman@lightlink.com>2007-07-19 14:22:12 -0400
commitf641b588fdfd25e73c73f6e4977cd2daf8a5e363 (patch)
tree0380dab553d7ffc72a6aa6add488656586d1cb08 /drivers
parentb825037d185549825d4f35504f2085ec86037110 (diff)
hwmon/pc87360: Convert to a platform driver
Convert the pc87360 driver from the nonsensical i2c-isa hack to a regular platform driver. This is a direct conversion, other cleanups could happen on top of that. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Jim Cromie <jim.cromie@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/pc87360.c232
2 files changed, 137 insertions, 97 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index f848e343b6ab..1d9be07c3c1d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -405,8 +405,6 @@ config SENSORS_MAX6650
405 405
406config SENSORS_PC87360 406config SENSORS_PC87360
407 tristate "National Semiconductor PC87360 family" 407 tristate "National Semiconductor PC87360 family"
408 depends on I2C && EXPERIMENTAL
409 select I2C_ISA
410 select HWMON_VID 408 select HWMON_VID
411 help 409 help
412 If you say yes here you get access to the hardware monitoring 410 If you say yes here you get access to the hardware monitoring
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index c8a21be09d87..cb72526c346a 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * pc87360.c - Part of lm_sensors, Linux kernel modules 2 * pc87360.c - Part of lm_sensors, Linux kernel modules
3 * for hardware monitoring 3 * for hardware monitoring
4 * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2004, 2007 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * Copied from smsc47m1.c: 6 * Copied from smsc47m1.c:
7 * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> 7 * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
@@ -37,8 +37,7 @@
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/i2c.h> 40#include <linux/platform_device.h>
41#include <linux/i2c-isa.h>
42#include <linux/hwmon.h> 41#include <linux/hwmon.h>
43#include <linux/hwmon-sysfs.h> 42#include <linux/hwmon-sysfs.h>
44#include <linux/hwmon-vid.h> 43#include <linux/hwmon-vid.h>
@@ -47,12 +46,10 @@
47#include <asm/io.h> 46#include <asm/io.h>
48 47
49static u8 devid; 48static u8 devid;
50static unsigned short address; 49static struct platform_device *pdev;
51static unsigned short extra_isa[3]; 50static unsigned short extra_isa[3];
52static u8 confreg[4]; 51static u8 confreg[4];
53 52
54enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 };
55
56static int init = 1; 53static int init = 1;
57module_param(init, int, 0); 54module_param(init, int, 0);
58MODULE_PARM_DESC(init, 55MODULE_PARM_DESC(init,
@@ -178,11 +175,11 @@ static inline u8 PWM_TO_REG(int val, int inv)
178 ((val) + 500) / 1000) 175 ((val) + 500) / 1000)
179 176
180/* 177/*
181 * Client data (each client gets its own) 178 * Device data
182 */ 179 */
183 180
184struct pc87360_data { 181struct pc87360_data {
185 struct i2c_client client; 182 const char *name;
186 struct class_device *class_dev; 183 struct class_device *class_dev;
187 struct mutex lock; 184 struct mutex lock;
188 struct mutex update_lock; 185 struct mutex update_lock;
@@ -222,27 +219,28 @@ struct pc87360_data {
222 * Functions declaration 219 * Functions declaration
223 */ 220 */
224 221
225static int pc87360_detect(struct i2c_adapter *adapter); 222static int pc87360_probe(struct platform_device *pdev);
226static int pc87360_detach_client(struct i2c_client *client); 223static int pc87360_remove(struct platform_device *pdev);
227 224
228static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank, 225static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
229 u8 reg); 226 u8 reg);
230static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, 227static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
231 u8 reg, u8 value); 228 u8 reg, u8 value);
232static void pc87360_init_client(struct i2c_client *client, int use_thermistors); 229static void pc87360_init_device(struct platform_device *pdev,
230 int use_thermistors);
233static struct pc87360_data *pc87360_update_device(struct device *dev); 231static struct pc87360_data *pc87360_update_device(struct device *dev);
234 232
235/* 233/*
236 * Driver data (common to all clients) 234 * Driver data
237 */ 235 */
238 236
239static struct i2c_driver pc87360_driver = { 237static struct platform_driver pc87360_driver = {
240 .driver = { 238 .driver = {
241 .owner = THIS_MODULE, 239 .owner = THIS_MODULE,
242 .name = "pc87360", 240 .name = "pc87360",
243 }, 241 },
244 .attach_adapter = pc87360_detect, 242 .probe = pc87360_probe,
245 .detach_client = pc87360_detach_client, 243 .remove = __devexit_p(pc87360_remove),
246}; 244};
247 245
248/* 246/*
@@ -281,8 +279,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr,
281 size_t count) 279 size_t count)
282{ 280{
283 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 281 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
284 struct i2c_client *client = to_i2c_client(dev); 282 struct pc87360_data *data = dev_get_drvdata(dev);
285 struct pc87360_data *data = i2c_get_clientdata(client);
286 long fan_min = simple_strtol(buf, NULL, 10); 283 long fan_min = simple_strtol(buf, NULL, 10);
287 284
288 mutex_lock(&data->update_lock); 285 mutex_lock(&data->update_lock);
@@ -347,8 +344,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, con
347 size_t count) 344 size_t count)
348{ 345{
349 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 346 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
350 struct i2c_client *client = to_i2c_client(dev); 347 struct pc87360_data *data = dev_get_drvdata(dev);
351 struct pc87360_data *data = i2c_get_clientdata(client);
352 long val = simple_strtol(buf, NULL, 10); 348 long val = simple_strtol(buf, NULL, 10);
353 349
354 mutex_lock(&data->update_lock); 350 mutex_lock(&data->update_lock);
@@ -410,8 +406,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr,
410 size_t count) 406 size_t count)
411{ 407{
412 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 408 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
413 struct i2c_client *client = to_i2c_client(dev); 409 struct pc87360_data *data = dev_get_drvdata(dev);
414 struct pc87360_data *data = i2c_get_clientdata(client);
415 long val = simple_strtol(buf, NULL, 10); 410 long val = simple_strtol(buf, NULL, 10);
416 411
417 mutex_lock(&data->update_lock); 412 mutex_lock(&data->update_lock);
@@ -425,8 +420,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr,
425 size_t count) 420 size_t count)
426{ 421{
427 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 422 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
428 struct i2c_client *client = to_i2c_client(dev); 423 struct pc87360_data *data = dev_get_drvdata(dev);
429 struct pc87360_data *data = i2c_get_clientdata(client);
430 long val = simple_strtol(buf, NULL, 10); 424 long val = simple_strtol(buf, NULL, 10);
431 425
432 mutex_lock(&data->update_lock); 426 mutex_lock(&data->update_lock);
@@ -511,8 +505,7 @@ static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char
511} 505}
512static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 506static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
513{ 507{
514 struct i2c_client *client = to_i2c_client(dev); 508 struct pc87360_data *data = dev_get_drvdata(dev);
515 struct pc87360_data *data = i2c_get_clientdata(client);
516 data->vrm = simple_strtoul(buf, NULL, 10); 509 data->vrm = simple_strtoul(buf, NULL, 10);
517 return count; 510 return count;
518} 511}
@@ -584,8 +577,7 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt
584 size_t count) 577 size_t count)
585{ 578{
586 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 579 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
587 struct i2c_client *client = to_i2c_client(dev); 580 struct pc87360_data *data = dev_get_drvdata(dev);
588 struct pc87360_data *data = i2c_get_clientdata(client);
589 long val = simple_strtol(buf, NULL, 10); 581 long val = simple_strtol(buf, NULL, 10);
590 582
591 mutex_lock(&data->update_lock); 583 mutex_lock(&data->update_lock);
@@ -599,8 +591,7 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt
599 size_t count) 591 size_t count)
600{ 592{
601 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 593 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
602 struct i2c_client *client = to_i2c_client(dev); 594 struct pc87360_data *data = dev_get_drvdata(dev);
603 struct pc87360_data *data = i2c_get_clientdata(client);
604 long val = simple_strtol(buf, NULL, 10); 595 long val = simple_strtol(buf, NULL, 10);
605 596
606 mutex_lock(&data->update_lock); 597 mutex_lock(&data->update_lock);
@@ -614,8 +605,7 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat
614 size_t count) 605 size_t count)
615{ 606{
616 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 607 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
617 struct i2c_client *client = to_i2c_client(dev); 608 struct pc87360_data *data = dev_get_drvdata(dev);
618 struct pc87360_data *data = i2c_get_clientdata(client);
619 long val = simple_strtol(buf, NULL, 10); 609 long val = simple_strtol(buf, NULL, 10);
620 610
621 mutex_lock(&data->update_lock); 611 mutex_lock(&data->update_lock);
@@ -715,8 +705,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr
715 size_t count) 705 size_t count)
716{ 706{
717 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 707 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
718 struct i2c_client *client = to_i2c_client(dev); 708 struct pc87360_data *data = dev_get_drvdata(dev);
719 struct pc87360_data *data = i2c_get_clientdata(client);
720 long val = simple_strtol(buf, NULL, 10); 709 long val = simple_strtol(buf, NULL, 10);
721 710
722 mutex_lock(&data->update_lock); 711 mutex_lock(&data->update_lock);
@@ -730,8 +719,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr
730 size_t count) 719 size_t count)
731{ 720{
732 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 721 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
733 struct i2c_client *client = to_i2c_client(dev); 722 struct pc87360_data *data = dev_get_drvdata(dev);
734 struct pc87360_data *data = i2c_get_clientdata(client);
735 long val = simple_strtol(buf, NULL, 10); 723 long val = simple_strtol(buf, NULL, 10);
736 724
737 mutex_lock(&data->update_lock); 725 mutex_lock(&data->update_lock);
@@ -745,8 +733,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devatt
745 size_t count) 733 size_t count)
746{ 734{
747 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 735 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
748 struct i2c_client *client = to_i2c_client(dev); 736 struct pc87360_data *data = dev_get_drvdata(dev);
749 struct pc87360_data *data = i2c_get_clientdata(client);
750 long val = simple_strtol(buf, NULL, 10); 737 long val = simple_strtol(buf, NULL, 10);
751 738
752 mutex_lock(&data->update_lock); 739 mutex_lock(&data->update_lock);
@@ -818,6 +805,14 @@ static const struct attribute_group pc8736x_temp_group = {
818 .attrs = pc8736x_temp_attr_array, 805 .attrs = pc8736x_temp_attr_array,
819}; 806};
820 807
808static ssize_t show_name(struct device *dev, struct device_attribute
809 *devattr, char *buf)
810{
811 struct pc87360_data *data = dev_get_drvdata(dev);
812 return sprintf(buf, "%s\n", data->name);
813}
814static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
815
821/* 816/*
822 * Device detection, registration and update 817 * Device detection, registration and update
823 */ 818 */
@@ -912,28 +907,18 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
912 return 0; 907 return 0;
913} 908}
914 909
915static int pc87360_detect(struct i2c_adapter *adapter) 910static int __devinit pc87360_probe(struct platform_device *pdev)
916{ 911{
917 int i; 912 int i;
918 struct i2c_client *client;
919 struct pc87360_data *data; 913 struct pc87360_data *data;
920 int err = 0; 914 int err = 0;
921 const char *name = "pc87360"; 915 const char *name = "pc87360";
922 int use_thermistors = 0; 916 int use_thermistors = 0;
923 struct device *dev; 917 struct device *dev = &pdev->dev;
924 918
925 if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL))) 919 if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
926 return -ENOMEM; 920 return -ENOMEM;
927 921
928 client = &data->client;
929 dev = &client->dev;
930 i2c_set_clientdata(client, data);
931 client->addr = address;
932 mutex_init(&data->lock);
933 client->adapter = adapter;
934 client->driver = &pc87360_driver;
935 client->flags = 0;
936
937 data->fannr = 2; 922 data->fannr = 2;
938 data->innr = 0; 923 data->innr = 0;
939 data->tempnr = 0; 924 data->tempnr = 0;
@@ -960,15 +945,17 @@ static int pc87360_detect(struct i2c_adapter *adapter)
960 break; 945 break;
961 } 946 }
962 947
963 strlcpy(client->name, name, sizeof(client->name)); 948 data->name = name;
964 data->valid = 0; 949 data->valid = 0;
950 mutex_init(&data->lock);
965 mutex_init(&data->update_lock); 951 mutex_init(&data->update_lock);
952 platform_set_drvdata(pdev, data);
966 953
967 for (i = 0; i < 3; i++) { 954 for (i = 0; i < 3; i++) {
968 if (((data->address[i] = extra_isa[i])) 955 if (((data->address[i] = extra_isa[i]))
969 && !request_region(extra_isa[i], PC87360_EXTENT, 956 && !request_region(extra_isa[i], PC87360_EXTENT,
970 pc87360_driver.driver.name)) { 957 pc87360_driver.driver.name)) {
971 dev_err(&client->dev, "Region 0x%x-0x%x already " 958 dev_err(dev, "Region 0x%x-0x%x already "
972 "in use!\n", extra_isa[i], 959 "in use!\n", extra_isa[i],
973 extra_isa[i]+PC87360_EXTENT-1); 960 extra_isa[i]+PC87360_EXTENT-1);
974 for (i--; i >= 0; i--) 961 for (i--; i >= 0; i--)
@@ -982,9 +969,6 @@ static int pc87360_detect(struct i2c_adapter *adapter)
982 if (data->fannr) 969 if (data->fannr)
983 data->fan_conf = confreg[0] | (confreg[1] << 8); 970 data->fan_conf = confreg[0] | (confreg[1] << 8);
984 971
985 if ((err = i2c_attach_client(client)))
986 goto ERROR2;
987
988 /* Use the correct reference voltage 972 /* Use the correct reference voltage
989 Unless both the VLM and the TMS logical devices agree to 973 Unless both the VLM and the TMS logical devices agree to
990 use an external Vref, the internal one is used. */ 974 use an external Vref, the internal one is used. */
@@ -996,7 +980,7 @@ static int pc87360_detect(struct i2c_adapter *adapter)
996 PC87365_REG_TEMP_CONFIG); 980 PC87365_REG_TEMP_CONFIG);
997 } 981 }
998 data->in_vref = (i&0x02) ? 3025 : 2966; 982 data->in_vref = (i&0x02) ? 3025 : 2966;
999 dev_dbg(&client->dev, "Using %s reference voltage\n", 983 dev_dbg(dev, "Using %s reference voltage\n",
1000 (i&0x02) ? "external" : "internal"); 984 (i&0x02) ? "external" : "internal");
1001 985
1002 data->vid_conf = confreg[3]; 986 data->vid_conf = confreg[3];
@@ -1015,18 +999,18 @@ static int pc87360_detect(struct i2c_adapter *adapter)
1015 if (devid == 0xe9 && data->address[1]) /* PC87366 */ 999 if (devid == 0xe9 && data->address[1]) /* PC87366 */
1016 use_thermistors = confreg[2] & 0x40; 1000 use_thermistors = confreg[2] & 0x40;
1017 1001
1018 pc87360_init_client(client, use_thermistors); 1002 pc87360_init_device(pdev, use_thermistors);
1019 } 1003 }
1020 1004
1021 /* Register all-or-nothing sysfs groups */ 1005 /* Register all-or-nothing sysfs groups */
1022 1006
1023 if (data->innr && 1007 if (data->innr &&
1024 (err = sysfs_create_group(&client->dev.kobj, 1008 (err = sysfs_create_group(&dev->kobj,
1025 &pc8736x_vin_group))) 1009 &pc8736x_vin_group)))
1026 goto ERROR3; 1010 goto ERROR3;
1027 1011
1028 if (data->innr == 14 && 1012 if (data->innr == 14 &&
1029 (err = sysfs_create_group(&client->dev.kobj, 1013 (err = sysfs_create_group(&dev->kobj,
1030 &pc8736x_therm_group))) 1014 &pc8736x_therm_group)))
1031 goto ERROR3; 1015 goto ERROR3;
1032 1016
@@ -1067,7 +1051,10 @@ static int pc87360_detect(struct i2c_adapter *adapter)
1067 goto ERROR3; 1051 goto ERROR3;
1068 } 1052 }
1069 1053
1070 data->class_dev = hwmon_device_register(&client->dev); 1054 if ((err = device_create_file(dev, &dev_attr_name)))
1055 goto ERROR3;
1056
1057 data->class_dev = hwmon_device_register(dev);
1071 if (IS_ERR(data->class_dev)) { 1058 if (IS_ERR(data->class_dev)) {
1072 err = PTR_ERR(data->class_dev); 1059 err = PTR_ERR(data->class_dev);
1073 goto ERROR3; 1060 goto ERROR3;
@@ -1075,14 +1062,12 @@ static int pc87360_detect(struct i2c_adapter *adapter)
1075 return 0; 1062 return 0;
1076 1063
1077ERROR3: 1064ERROR3:
1065 device_remove_file(dev, &dev_attr_name);
1078 /* can still remove groups whose members were added individually */ 1066 /* can still remove groups whose members were added individually */
1079 sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); 1067 sysfs_remove_group(&dev->kobj, &pc8736x_temp_group);
1080 sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); 1068 sysfs_remove_group(&dev->kobj, &pc8736x_fan_group);
1081 sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); 1069 sysfs_remove_group(&dev->kobj, &pc8736x_therm_group);
1082 sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); 1070 sysfs_remove_group(&dev->kobj, &pc8736x_vin_group);
1083
1084 i2c_detach_client(client);
1085ERROR2:
1086 for (i = 0; i < 3; i++) { 1071 for (i = 0; i < 3; i++) {
1087 if (data->address[i]) { 1072 if (data->address[i]) {
1088 release_region(data->address[i], PC87360_EXTENT); 1073 release_region(data->address[i], PC87360_EXTENT);
@@ -1093,20 +1078,18 @@ ERROR1:
1093 return err; 1078 return err;
1094} 1079}
1095 1080
1096static int pc87360_detach_client(struct i2c_client *client) 1081static int __devexit pc87360_remove(struct platform_device *pdev)
1097{ 1082{
1098 struct pc87360_data *data = i2c_get_clientdata(client); 1083 struct pc87360_data *data = platform_get_drvdata(pdev);
1099 int i; 1084 int i;
1100 1085
1101 hwmon_device_unregister(data->class_dev); 1086 hwmon_device_unregister(data->class_dev);
1102 1087
1103 sysfs_remove_group(&client->dev.kobj, &pc8736x_temp_group); 1088 device_remove_file(&pdev->dev, &dev_attr_name);
1104 sysfs_remove_group(&client->dev.kobj, &pc8736x_fan_group); 1089 sysfs_remove_group(&pdev->dev.kobj, &pc8736x_temp_group);
1105 sysfs_remove_group(&client->dev.kobj, &pc8736x_therm_group); 1090 sysfs_remove_group(&pdev->dev.kobj, &pc8736x_fan_group);
1106 sysfs_remove_group(&client->dev.kobj, &pc8736x_vin_group); 1091 sysfs_remove_group(&pdev->dev.kobj, &pc8736x_therm_group);
1107 1092 sysfs_remove_group(&pdev->dev.kobj, &pc8736x_vin_group);
1108 if ((i = i2c_detach_client(client)))
1109 return i;
1110 1093
1111 for (i = 0; i < 3; i++) { 1094 for (i = 0; i < 3; i++) {
1112 if (data->address[i]) { 1095 if (data->address[i]) {
@@ -1144,9 +1127,10 @@ static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
1144 mutex_unlock(&(data->lock)); 1127 mutex_unlock(&(data->lock));
1145} 1128}
1146 1129
1147static void pc87360_init_client(struct i2c_client *client, int use_thermistors) 1130static void pc87360_init_device(struct platform_device *pdev,
1131 int use_thermistors)
1148{ 1132{
1149 struct pc87360_data *data = i2c_get_clientdata(client); 1133 struct pc87360_data *data = platform_get_drvdata(pdev);
1150 int i, nr; 1134 int i, nr;
1151 const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 }; 1135 const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
1152 const u8 init_temp[3] = { 2, 2, 1 }; 1136 const u8 init_temp[3] = { 2, 2, 1 };
@@ -1155,7 +1139,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1155 if (init >= 2 && data->innr) { 1139 if (init >= 2 && data->innr) {
1156 reg = pc87360_read_value(data, LD_IN, NO_BANK, 1140 reg = pc87360_read_value(data, LD_IN, NO_BANK,
1157 PC87365_REG_IN_CONVRATE); 1141 PC87365_REG_IN_CONVRATE);
1158 dev_info(&client->dev, "VLM conversion set to " 1142 dev_info(&pdev->dev, "VLM conversion set to "
1159 "1s period, 160us delay\n"); 1143 "1s period, 160us delay\n");
1160 pc87360_write_value(data, LD_IN, NO_BANK, 1144 pc87360_write_value(data, LD_IN, NO_BANK,
1161 PC87365_REG_IN_CONVRATE, 1145 PC87365_REG_IN_CONVRATE,
@@ -1169,7 +1153,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1169 reg = pc87360_read_value(data, LD_IN, i, 1153 reg = pc87360_read_value(data, LD_IN, i,
1170 PC87365_REG_IN_STATUS); 1154 PC87365_REG_IN_STATUS);
1171 if (!(reg & 0x01)) { 1155 if (!(reg & 0x01)) {
1172 dev_dbg(&client->dev, "Forcibly " 1156 dev_dbg(&pdev->dev, "Forcibly "
1173 "enabling in%d\n", i); 1157 "enabling in%d\n", i);
1174 pc87360_write_value(data, LD_IN, i, 1158 pc87360_write_value(data, LD_IN, i,
1175 PC87365_REG_IN_STATUS, 1159 PC87365_REG_IN_STATUS,
@@ -1193,7 +1177,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1193 reg = pc87360_read_value(data, LD_TEMP, i, 1177 reg = pc87360_read_value(data, LD_TEMP, i,
1194 PC87365_REG_TEMP_STATUS); 1178 PC87365_REG_TEMP_STATUS);
1195 if (!(reg & 0x01)) { 1179 if (!(reg & 0x01)) {
1196 dev_dbg(&client->dev, "Forcibly " 1180 dev_dbg(&pdev->dev, "Forcibly "
1197 "enabling temp%d\n", i+1); 1181 "enabling temp%d\n", i+1);
1198 pc87360_write_value(data, LD_TEMP, i, 1182 pc87360_write_value(data, LD_TEMP, i,
1199 PC87365_REG_TEMP_STATUS, 1183 PC87365_REG_TEMP_STATUS,
@@ -1210,7 +1194,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1210 reg = pc87360_read_value(data, LD_TEMP, 1194 reg = pc87360_read_value(data, LD_TEMP,
1211 (i-11)/2, PC87365_REG_TEMP_STATUS); 1195 (i-11)/2, PC87365_REG_TEMP_STATUS);
1212 if (reg & 0x01) { 1196 if (reg & 0x01) {
1213 dev_dbg(&client->dev, "Skipping " 1197 dev_dbg(&pdev->dev, "Skipping "
1214 "temp%d, pin already in use " 1198 "temp%d, pin already in use "
1215 "by temp%d\n", i-7, (i-11)/2); 1199 "by temp%d\n", i-7, (i-11)/2);
1216 continue; 1200 continue;
@@ -1220,7 +1204,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1220 reg = pc87360_read_value(data, LD_IN, i, 1204 reg = pc87360_read_value(data, LD_IN, i,
1221 PC87365_REG_IN_STATUS); 1205 PC87365_REG_IN_STATUS);
1222 if (!(reg & 0x01)) { 1206 if (!(reg & 0x01)) {
1223 dev_dbg(&client->dev, "Forcibly " 1207 dev_dbg(&pdev->dev, "Forcibly "
1224 "enabling temp%d\n", i-7); 1208 "enabling temp%d\n", i-7);
1225 pc87360_write_value(data, LD_IN, i, 1209 pc87360_write_value(data, LD_IN, i,
1226 PC87365_REG_TEMP_STATUS, 1210 PC87365_REG_TEMP_STATUS,
@@ -1234,7 +1218,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1234 reg = pc87360_read_value(data, LD_IN, NO_BANK, 1218 reg = pc87360_read_value(data, LD_IN, NO_BANK,
1235 PC87365_REG_IN_CONFIG); 1219 PC87365_REG_IN_CONFIG);
1236 if (reg & 0x01) { 1220 if (reg & 0x01) {
1237 dev_dbg(&client->dev, "Forcibly " 1221 dev_dbg(&pdev->dev, "Forcibly "
1238 "enabling monitoring (VLM)\n"); 1222 "enabling monitoring (VLM)\n");
1239 pc87360_write_value(data, LD_IN, NO_BANK, 1223 pc87360_write_value(data, LD_IN, NO_BANK,
1240 PC87365_REG_IN_CONFIG, 1224 PC87365_REG_IN_CONFIG,
@@ -1246,7 +1230,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1246 reg = pc87360_read_value(data, LD_TEMP, NO_BANK, 1230 reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
1247 PC87365_REG_TEMP_CONFIG); 1231 PC87365_REG_TEMP_CONFIG);
1248 if (reg & 0x01) { 1232 if (reg & 0x01) {
1249 dev_dbg(&client->dev, "Forcibly enabling " 1233 dev_dbg(&pdev->dev, "Forcibly enabling "
1250 "monitoring (TMS)\n"); 1234 "monitoring (TMS)\n");
1251 pc87360_write_value(data, LD_TEMP, NO_BANK, 1235 pc87360_write_value(data, LD_TEMP, NO_BANK,
1252 PC87365_REG_TEMP_CONFIG, 1236 PC87365_REG_TEMP_CONFIG,
@@ -1268,9 +1252,9 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
1268 } 1252 }
1269} 1253}
1270 1254
1271static void pc87360_autodiv(struct i2c_client *client, int nr) 1255static void pc87360_autodiv(struct device *dev, int nr)
1272{ 1256{
1273 struct pc87360_data *data = i2c_get_clientdata(client); 1257 struct pc87360_data *data = dev_get_drvdata(dev);
1274 u8 old_min = data->fan_min[nr]; 1258 u8 old_min = data->fan_min[nr];
1275 1259
1276 /* Increase clock divider if needed and possible */ 1260 /* Increase clock divider if needed and possible */
@@ -1280,7 +1264,7 @@ static void pc87360_autodiv(struct i2c_client *client, int nr)
1280 data->fan_status[nr] += 0x20; 1264 data->fan_status[nr] += 0x20;
1281 data->fan_min[nr] >>= 1; 1265 data->fan_min[nr] >>= 1;
1282 data->fan[nr] >>= 1; 1266 data->fan[nr] >>= 1;
1283 dev_dbg(&client->dev, "Increasing " 1267 dev_dbg(dev, "Increasing "
1284 "clock divider to %d for fan %d\n", 1268 "clock divider to %d for fan %d\n",
1285 FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1); 1269 FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1);
1286 } 1270 }
@@ -1292,7 +1276,7 @@ static void pc87360_autodiv(struct i2c_client *client, int nr)
1292 data->fan_status[nr] -= 0x20; 1276 data->fan_status[nr] -= 0x20;
1293 data->fan_min[nr] <<= 1; 1277 data->fan_min[nr] <<= 1;
1294 data->fan[nr] <<= 1; 1278 data->fan[nr] <<= 1;
1295 dev_dbg(&client->dev, "Decreasing " 1279 dev_dbg(dev, "Decreasing "
1296 "clock divider to %d for fan %d\n", 1280 "clock divider to %d for fan %d\n",
1297 FAN_DIV_FROM_REG(data->fan_status[nr]), 1281 FAN_DIV_FROM_REG(data->fan_status[nr]),
1298 nr+1); 1282 nr+1);
@@ -1309,14 +1293,13 @@ static void pc87360_autodiv(struct i2c_client *client, int nr)
1309 1293
1310static struct pc87360_data *pc87360_update_device(struct device *dev) 1294static struct pc87360_data *pc87360_update_device(struct device *dev)
1311{ 1295{
1312 struct i2c_client *client = to_i2c_client(dev); 1296 struct pc87360_data *data = dev_get_drvdata(dev);
1313 struct pc87360_data *data = i2c_get_clientdata(client);
1314 u8 i; 1297 u8 i;
1315 1298
1316 mutex_lock(&data->update_lock); 1299 mutex_lock(&data->update_lock);
1317 1300
1318 if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { 1301 if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
1319 dev_dbg(&client->dev, "Data update\n"); 1302 dev_dbg(dev, "Data update\n");
1320 1303
1321 /* Fans */ 1304 /* Fans */
1322 for (i = 0; i < data->fannr; i++) { 1305 for (i = 0; i < data->fannr; i++) {
@@ -1330,7 +1313,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
1330 LD_FAN, NO_BANK, 1313 LD_FAN, NO_BANK,
1331 PC87360_REG_FAN_MIN(i)); 1314 PC87360_REG_FAN_MIN(i));
1332 /* Change clock divider if needed */ 1315 /* Change clock divider if needed */
1333 pc87360_autodiv(client, i); 1316 pc87360_autodiv(dev, i);
1334 /* Clear bits and write new divider */ 1317 /* Clear bits and write new divider */
1335 pc87360_write_value(data, LD_FAN, NO_BANK, 1318 pc87360_write_value(data, LD_FAN, NO_BANK,
1336 PC87360_REG_FAN_STATUS(i), 1319 PC87360_REG_FAN_STATUS(i),
@@ -1418,9 +1401,53 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
1418 return data; 1401 return data;
1419} 1402}
1420 1403
1404static int __init pc87360_device_add(unsigned short address)
1405{
1406 struct resource res = {
1407 .name = "pc87360",
1408 .flags = IORESOURCE_IO,
1409 };
1410 int err, i;
1411
1412 pdev = platform_device_alloc("pc87360", address);
1413 if (!pdev) {
1414 err = -ENOMEM;
1415 printk(KERN_ERR "pc87360: Device allocation failed\n");
1416 goto exit;
1417 }
1418
1419 for (i = 0; i < 3; i++) {
1420 if (!extra_isa[i])
1421 continue;
1422 res.start = extra_isa[i];
1423 res.end = extra_isa[i] + PC87360_EXTENT - 1;
1424 err = platform_device_add_resources(pdev, &res, 1);
1425 if (err) {
1426 printk(KERN_ERR "pc87360: Device resource[%d] "
1427 "addition failed (%d)\n", i, err);
1428 goto exit_device_put;
1429 }
1430 }
1431
1432 err = platform_device_add(pdev);
1433 if (err) {
1434 printk(KERN_ERR "pc87360: Device addition failed (%d)\n",
1435 err);
1436 goto exit_device_put;
1437 }
1438
1439 return 0;
1440
1441exit_device_put:
1442 platform_device_put(pdev);
1443exit:
1444 return err;
1445}
1446
1421static int __init pc87360_init(void) 1447static int __init pc87360_init(void)
1422{ 1448{
1423 int i; 1449 int err, i;
1450 unsigned short address = 0;
1424 1451
1425 if (pc87360_find(0x2e, &devid, extra_isa) 1452 if (pc87360_find(0x2e, &devid, extra_isa)
1426 && pc87360_find(0x4e, &devid, extra_isa)) { 1453 && pc87360_find(0x4e, &devid, extra_isa)) {
@@ -1443,12 +1470,27 @@ static int __init pc87360_init(void)
1443 return -ENODEV; 1470 return -ENODEV;
1444 } 1471 }
1445 1472
1446 return i2c_isa_add_driver(&pc87360_driver); 1473 err = platform_driver_register(&pc87360_driver);
1474 if (err)
1475 goto exit;
1476
1477 /* Sets global pdev as a side effect */
1478 err = pc87360_device_add(address);
1479 if (err)
1480 goto exit_driver;
1481
1482 return 0;
1483
1484 exit_driver:
1485 platform_driver_unregister(&pc87360_driver);
1486 exit:
1487 return err;
1447} 1488}
1448 1489
1449static void __exit pc87360_exit(void) 1490static void __exit pc87360_exit(void)
1450{ 1491{
1451 i2c_isa_del_driver(&pc87360_driver); 1492 platform_device_unregister(pdev);
1493 platform_driver_unregister(&pc87360_driver);
1452} 1494}
1453 1495
1454 1496