diff options
Diffstat (limited to 'drivers/hwmon/it87.c')
-rw-r--r-- | drivers/hwmon/it87.c | 56 |
1 files changed, 13 insertions, 43 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 53cc2b6d6385..6c41e25e670b 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -2,7 +2,7 @@ | |||
2 | it87.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | it87.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | monitoring. | 3 | monitoring. |
4 | 4 | ||
5 | Supports: IT8705F Super I/O chip w/LPC interface & SMBus | 5 | Supports: IT8705F Super I/O chip w/LPC interface |
6 | IT8712F Super I/O chip w/LPC interface & SMBus | 6 | IT8712F Super I/O chip w/LPC interface & SMBus |
7 | Sis950 A clone of the IT8705F | 7 | Sis950 A clone of the IT8705F |
8 | 8 | ||
@@ -47,7 +47,7 @@ | |||
47 | /* Addresses to scan */ | 47 | /* Addresses to scan */ |
48 | static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, | 48 | static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, |
49 | 0x2e, 0x2f, I2C_CLIENT_END }; | 49 | 0x2e, 0x2f, I2C_CLIENT_END }; |
50 | static unsigned short isa_address = 0x290; | 50 | static unsigned short isa_address; |
51 | 51 | ||
52 | /* Insmod parameters */ | 52 | /* Insmod parameters */ |
53 | I2C_CLIENT_INSMOD_2(it87, it8712); | 53 | I2C_CLIENT_INSMOD_2(it87, it8712); |
@@ -706,7 +706,7 @@ static int it87_isa_attach_adapter(struct i2c_adapter *adapter) | |||
706 | } | 706 | } |
707 | 707 | ||
708 | /* SuperIO detection - will change isa_address if a chip is found */ | 708 | /* SuperIO detection - will change isa_address if a chip is found */ |
709 | static int __init it87_find(int *address) | 709 | static int __init it87_find(unsigned short *address) |
710 | { | 710 | { |
711 | int err = -ENODEV; | 711 | int err = -ENODEV; |
712 | 712 | ||
@@ -738,7 +738,7 @@ exit: | |||
738 | } | 738 | } |
739 | 739 | ||
740 | /* This function is called by i2c_probe */ | 740 | /* This function is called by i2c_probe */ |
741 | int it87_detect(struct i2c_adapter *adapter, int address, int kind) | 741 | static int it87_detect(struct i2c_adapter *adapter, int address, int kind) |
742 | { | 742 | { |
743 | int i; | 743 | int i; |
744 | struct i2c_client *new_client; | 744 | struct i2c_client *new_client; |
@@ -757,42 +757,14 @@ int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
757 | if (!request_region(address, IT87_EXTENT, it87_isa_driver.name)) | 757 | if (!request_region(address, IT87_EXTENT, it87_isa_driver.name)) |
758 | goto ERROR0; | 758 | goto ERROR0; |
759 | 759 | ||
760 | /* Probe whether there is anything available on this address. Already | 760 | /* For now, we presume we have a valid client. We create the |
761 | done for SMBus and Super-I/O clients */ | ||
762 | if (kind < 0) { | ||
763 | if (is_isa && !chip_type) { | ||
764 | #define REALLY_SLOW_IO | ||
765 | /* We need the timeouts for at least some IT87-like chips. But only | ||
766 | if we read 'undefined' registers. */ | ||
767 | i = inb_p(address + 1); | ||
768 | if (inb_p(address + 2) != i | ||
769 | || inb_p(address + 3) != i | ||
770 | || inb_p(address + 7) != i) { | ||
771 | err = -ENODEV; | ||
772 | goto ERROR1; | ||
773 | } | ||
774 | #undef REALLY_SLOW_IO | ||
775 | |||
776 | /* Let's just hope nothing breaks here */ | ||
777 | i = inb_p(address + 5) & 0x7f; | ||
778 | outb_p(~i & 0x7f, address + 5); | ||
779 | if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { | ||
780 | outb_p(i, address + 5); | ||
781 | err = -ENODEV; | ||
782 | goto ERROR1; | ||
783 | } | ||
784 | } | ||
785 | } | ||
786 | |||
787 | /* OK. For now, we presume we have a valid client. We now create the | ||
788 | client structure, even though we cannot fill it completely yet. | 761 | client structure, even though we cannot fill it completely yet. |
789 | But it allows us to access it87_{read,write}_value. */ | 762 | But it allows us to access it87_{read,write}_value. */ |
790 | 763 | ||
791 | if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) { | 764 | if (!(data = kzalloc(sizeof(struct it87_data), GFP_KERNEL))) { |
792 | err = -ENOMEM; | 765 | err = -ENOMEM; |
793 | goto ERROR1; | 766 | goto ERROR1; |
794 | } | 767 | } |
795 | memset(data, 0, sizeof(struct it87_data)); | ||
796 | 768 | ||
797 | new_client = &data->client; | 769 | new_client = &data->client; |
798 | if (is_isa) | 770 | if (is_isa) |
@@ -1182,20 +1154,18 @@ static struct it87_data *it87_update_device(struct device *dev) | |||
1182 | 1154 | ||
1183 | static int __init sm_it87_init(void) | 1155 | static int __init sm_it87_init(void) |
1184 | { | 1156 | { |
1185 | int addr, res; | 1157 | int res; |
1186 | |||
1187 | if (!it87_find(&addr)) { | ||
1188 | isa_address = addr; | ||
1189 | } | ||
1190 | 1158 | ||
1191 | res = i2c_add_driver(&it87_driver); | 1159 | res = i2c_add_driver(&it87_driver); |
1192 | if (res) | 1160 | if (res) |
1193 | return res; | 1161 | return res; |
1194 | 1162 | ||
1195 | res = i2c_isa_add_driver(&it87_isa_driver); | 1163 | if (!it87_find(&isa_address)) { |
1196 | if (res) { | 1164 | res = i2c_isa_add_driver(&it87_isa_driver); |
1197 | i2c_del_driver(&it87_driver); | 1165 | if (res) { |
1198 | return res; | 1166 | i2c_del_driver(&it87_driver); |
1167 | return res; | ||
1168 | } | ||
1199 | } | 1169 | } |
1200 | 1170 | ||
1201 | return 0; | 1171 | return 0; |