aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-08-14 15:08:59 -0400
committerJean Delvare <khali@linux-fr.org>2010-08-14 15:08:59 -0400
commit008e5f3350e0a474baff3ed3eb4f79653a6b6745 (patch)
treeb2a2b27fd68b6071bbe3f2560df477d39d2ddb24
parent9d32df192d2e4db4d59f26a3ea73601bd1a733e5 (diff)
hwmon: (pc87427) Add temperature monitoring support
Add support for the 6 temperature monitoring channels of the PC87427. Note that the sensors resolution can vary, and I couldn't find a way to figure it out, so we might have to compensate in user-space. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
-rw-r--r--Documentation/hwmon/pc8742714
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/pc87427.c368
3 files changed, 379 insertions, 7 deletions
diff --git a/Documentation/hwmon/pc87427 b/Documentation/hwmon/pc87427
index 3282bf39d67d..8fdd08c9e48b 100644
--- a/Documentation/hwmon/pc87427
+++ b/Documentation/hwmon/pc87427
@@ -18,7 +18,8 @@ Description
18 18
19The National Semiconductor Super I/O chip includes complete hardware 19The National Semiconductor Super I/O chip includes complete hardware
20monitoring capabilities. It can monitor up to 18 voltages, 8 fans and 20monitoring capabilities. It can monitor up to 18 voltages, 8 fans and
216 temperature sensors. Only the fans are supported at the moment. 216 temperature sensors. Only the fans and temperatures are supported at
22the moment, voltages aren't.
22 23
23This chip also has fan controlling features (up to 4 PWM outputs), 24This chip also has fan controlling features (up to 4 PWM outputs),
24which are partly supported by this driver. 25which are partly supported by this driver.
@@ -45,3 +46,14 @@ Fan speed can be controlled by PWM outputs. There are 4 possible modes:
45always off, always on, manual and automatic. The latter isn't supported 46always off, always on, manual and automatic. The latter isn't supported
46by the driver: you can only return to that mode if it was the original 47by the driver: you can only return to that mode if it was the original
47setting, and the configuration interface is missing. 48setting, and the configuration interface is missing.
49
50
51Temperature Monitoring
52----------------------
53
54The PC87427 relies on external sensors (following the SensorPath
55standard), so the resolution and range depend on the type of sensor
56connected. The integer part can be 8-bit or 9-bit, and can be signed or
57not. I couldn't find a way to figure out the external sensor data
58temperature format, so user-space adjustment (typically by a factor 2)
59may be required.
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ea3d8dff684b..3c4dd849b075 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -711,8 +711,8 @@ config SENSORS_PC87427
711 functions of the National Semiconductor PC87427 Super-I/O chip. 711 functions of the National Semiconductor PC87427 Super-I/O chip.
712 The chip has two distinct logical devices, one for fan speed 712 The chip has two distinct logical devices, one for fan speed
713 monitoring and control, and one for voltage and temperature 713 monitoring and control, and one for voltage and temperature
714 monitoring. Only fan speed monitoring and control is supported 714 monitoring. Fan speed monitoring and control are supported, as
715 right now. 715 well as temperature monitoring. Voltages aren't supported yet.
716 716
717 This driver can also be built as a module. If so, the module 717 This driver can also be built as a module. If so, the module
718 will be called pc87427. 718 will be called pc87427.
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 129a33ce3fe4..189dad428ac2 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * pc87427.c - hardware monitoring driver for the 2 * pc87427.c - hardware monitoring driver for the
3 * National Semiconductor PC87427 Super-I/O chip 3 * National Semiconductor PC87427 Super-I/O chip
4 * Copyright (C) 2006, 2008 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2006, 2008, 2010 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -15,10 +15,11 @@
15 * Supports the following chips: 15 * Supports the following chips:
16 * 16 *
17 * Chip #vin #fan #pwm #temp devid 17 * Chip #vin #fan #pwm #temp devid
18 * PC87427 - 8 4 - 0xF2 18 * PC87427 - 8 4 6 0xF2
19 * 19 *
20 * This driver assumes that no more than one chip is present. 20 * This driver assumes that no more than one chip is present.
21 * Only fans are supported so far, although the chip can do much more. 21 * Only fans are fully supported so far. Temperatures are in read-only
22 * mode, and voltages aren't supported at all.
22 */ 23 */
23 24
24#include <linux/module.h> 25#include <linux/module.h>
@@ -62,6 +63,14 @@ struct pc87427_data {
62 u8 pwm_auto_ok; /* bit vector */ 63 u8 pwm_auto_ok; /* bit vector */
63 u8 pwm_enable[4]; /* register values */ 64 u8 pwm_enable[4]; /* register values */
64 u8 pwm[4]; /* register values */ 65 u8 pwm[4]; /* register values */
66
67 u8 temp_enabled; /* bit vector */
68 s16 temp[6]; /* register values */
69 s8 temp_min[6]; /* register values */
70 s8 temp_max[6]; /* register values */
71 s8 temp_crit[6]; /* register values */
72 u8 temp_status[6]; /* register values */
73 u8 temp_type[6]; /* register values */
65}; 74};
66 75
67struct pc87427_sio_data { 76struct pc87427_sio_data {
@@ -120,6 +129,8 @@ static inline void superio_exit(int sioaddr)
120#define BANK_FM(nr) (nr) 129#define BANK_FM(nr) (nr)
121#define BANK_FT(nr) (0x08 + (nr)) 130#define BANK_FT(nr) (0x08 + (nr))
122#define BANK_FC(nr) (0x10 + (nr) * 2) 131#define BANK_FC(nr) (0x10 + (nr) * 2)
132#define BANK_TM(nr) (nr)
133#define BANK_VM(nr) (0x08 + (nr))
123 134
124/* 135/*
125 * I/O access functions 136 * I/O access functions
@@ -252,6 +263,72 @@ static inline u8 pwm_enable_to_reg(unsigned long val, u8 pwmval)
252} 263}
253 264
254/* 265/*
266 * Temperature registers and conversions
267 */
268
269#define PC87427_REG_TEMP_STATUS 0x10
270#define PC87427_REG_TEMP 0x14
271#define PC87427_REG_TEMP_MAX 0x18
272#define PC87427_REG_TEMP_MIN 0x19
273#define PC87427_REG_TEMP_CRIT 0x1a
274#define PC87427_REG_TEMP_TYPE 0x1d
275
276#define TEMP_STATUS_CHANEN (1 << 0)
277#define TEMP_STATUS_LOWFLG (1 << 1)
278#define TEMP_STATUS_HIGHFLG (1 << 2)
279#define TEMP_STATUS_CRITFLG (1 << 3)
280#define TEMP_STATUS_SENSERR (1 << 5)
281#define TEMP_TYPE_MASK (3 << 5)
282
283#define TEMP_TYPE_THERMISTOR (1 << 5)
284#define TEMP_TYPE_REMOTE_DIODE (2 << 5)
285#define TEMP_TYPE_LOCAL_DIODE (3 << 5)
286
287/* Dedicated function to read all registers related to a given temperature
288 input. This saves us quite a few locks and bank selections.
289 Must be called with data->lock held.
290 nr is from 0 to 5 */
291static void pc87427_readall_temp(struct pc87427_data *data, u8 nr)
292{
293 int iobase = data->address[LD_TEMP];
294
295 outb(BANK_TM(nr), iobase + PC87427_REG_BANK);
296 data->temp[nr] = le16_to_cpu(inw(iobase + PC87427_REG_TEMP));
297 data->temp_max[nr] = inb(iobase + PC87427_REG_TEMP_MAX);
298 data->temp_min[nr] = inb(iobase + PC87427_REG_TEMP_MIN);
299 data->temp_crit[nr] = inb(iobase + PC87427_REG_TEMP_CRIT);
300 data->temp_type[nr] = inb(iobase + PC87427_REG_TEMP_TYPE);
301 data->temp_status[nr] = inb(iobase + PC87427_REG_TEMP_STATUS);
302 /* Clear fan alarm bits */
303 outb(data->temp_status[nr], iobase + PC87427_REG_TEMP_STATUS);
304}
305
306static inline unsigned int temp_type_from_reg(u8 reg)
307{
308 switch (reg & TEMP_TYPE_MASK) {
309 case TEMP_TYPE_THERMISTOR:
310 return 4;
311 case TEMP_TYPE_REMOTE_DIODE:
312 case TEMP_TYPE_LOCAL_DIODE:
313 return 3;
314 default:
315 return 0;
316 }
317}
318
319/* We assume 8-bit thermal sensors; 9-bit thermal sensors are possible
320 too, but I have no idea how to figure out when they are used. */
321static inline long temp_from_reg(s16 reg)
322{
323 return reg * 1000 / 256;
324}
325
326static inline long temp_from_reg8(s8 reg)
327{
328 return reg * 1000;
329}
330
331/*
255 * Data interface 332 * Data interface
256 */ 333 */
257 334
@@ -279,6 +356,13 @@ static struct pc87427_data *pc87427_update_device(struct device *dev)
279 pc87427_readall_pwm(data, i); 356 pc87427_readall_pwm(data, i);
280 } 357 }
281 358
359 /* Temperature channels */
360 for (i = 0; i < 6; i++) {
361 if (!(data->temp_enabled & (1 << i)))
362 continue;
363 pc87427_readall_temp(data, i);
364 }
365
282 data->last_updated = jiffies; 366 data->last_updated = jiffies;
283 367
284done: 368done:
@@ -595,6 +679,251 @@ static const struct attribute_group pc87427_group_pwm[4] = {
595 { .attrs = pc87427_attributes_pwm[3] }, 679 { .attrs = pc87427_attributes_pwm[3] },
596}; 680};
597 681
682static ssize_t show_temp_input(struct device *dev, struct device_attribute
683 *devattr, char *buf)
684{
685 struct pc87427_data *data = pc87427_update_device(dev);
686 int nr = to_sensor_dev_attr(devattr)->index;
687
688 return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
689}
690
691static ssize_t show_temp_min(struct device *dev, struct device_attribute
692 *devattr, char *buf)
693{
694 struct pc87427_data *data = pc87427_update_device(dev);
695 int nr = to_sensor_dev_attr(devattr)->index;
696
697 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_min[nr]));
698}
699
700static ssize_t show_temp_max(struct device *dev, struct device_attribute
701 *devattr, char *buf)
702{
703 struct pc87427_data *data = pc87427_update_device(dev);
704 int nr = to_sensor_dev_attr(devattr)->index;
705
706 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_max[nr]));
707}
708
709static ssize_t show_temp_crit(struct device *dev, struct device_attribute
710 *devattr, char *buf)
711{
712 struct pc87427_data *data = pc87427_update_device(dev);
713 int nr = to_sensor_dev_attr(devattr)->index;
714
715 return sprintf(buf, "%ld\n", temp_from_reg8(data->temp_crit[nr]));
716}
717
718static ssize_t show_temp_type(struct device *dev, struct device_attribute
719 *devattr, char *buf)
720{
721 struct pc87427_data *data = pc87427_update_device(dev);
722 int nr = to_sensor_dev_attr(devattr)->index;
723
724 return sprintf(buf, "%u\n", temp_type_from_reg(data->temp_type[nr]));
725}
726
727static ssize_t show_temp_min_alarm(struct device *dev, struct device_attribute
728 *devattr, char *buf)
729{
730 struct pc87427_data *data = pc87427_update_device(dev);
731 int nr = to_sensor_dev_attr(devattr)->index;
732
733 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
734 & TEMP_STATUS_LOWFLG));
735}
736
737static ssize_t show_temp_max_alarm(struct device *dev, struct device_attribute
738 *devattr, char *buf)
739{
740 struct pc87427_data *data = pc87427_update_device(dev);
741 int nr = to_sensor_dev_attr(devattr)->index;
742
743 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
744 & TEMP_STATUS_HIGHFLG));
745}
746
747static ssize_t show_temp_crit_alarm(struct device *dev, struct device_attribute
748 *devattr, char *buf)
749{
750 struct pc87427_data *data = pc87427_update_device(dev);
751 int nr = to_sensor_dev_attr(devattr)->index;
752
753 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
754 & TEMP_STATUS_CRITFLG));
755}
756
757static ssize_t show_temp_fault(struct device *dev, struct device_attribute
758 *devattr, char *buf)
759{
760 struct pc87427_data *data = pc87427_update_device(dev);
761 int nr = to_sensor_dev_attr(devattr)->index;
762
763 return sprintf(buf, "%d\n", !!(data->temp_status[nr]
764 & TEMP_STATUS_SENSERR));
765}
766
767static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0);
768static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1);
769static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2);
770static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_input, NULL, 3);
771static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp_input, NULL, 4);
772static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp_input, NULL, 5);
773
774static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp_min, NULL, 0);
775static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO, show_temp_min, NULL, 1);
776static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO, show_temp_min, NULL, 2);
777static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO, show_temp_min, NULL, 3);
778static SENSOR_DEVICE_ATTR(temp5_min, S_IRUGO, show_temp_min, NULL, 4);
779static SENSOR_DEVICE_ATTR(temp6_min, S_IRUGO, show_temp_min, NULL, 5);
780
781static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, NULL, 0);
782static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_max, NULL, 1);
783static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_max, NULL, 2);
784static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_max, NULL, 3);
785static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_max, NULL, 4);
786static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_max, NULL, 5);
787
788static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0);
789static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 1);
790static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 2);
791static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 3);
792static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 4);
793static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 5);
794
795static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0);
796static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1);
797static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2);
798static SENSOR_DEVICE_ATTR(temp4_type, S_IRUGO, show_temp_type, NULL, 3);
799static SENSOR_DEVICE_ATTR(temp5_type, S_IRUGO, show_temp_type, NULL, 4);
800static SENSOR_DEVICE_ATTR(temp6_type, S_IRUGO, show_temp_type, NULL, 5);
801
802static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO,
803 show_temp_min_alarm, NULL, 0);
804static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO,
805 show_temp_min_alarm, NULL, 1);
806static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO,
807 show_temp_min_alarm, NULL, 2);
808static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO,
809 show_temp_min_alarm, NULL, 3);
810static SENSOR_DEVICE_ATTR(temp5_min_alarm, S_IRUGO,
811 show_temp_min_alarm, NULL, 4);
812static SENSOR_DEVICE_ATTR(temp6_min_alarm, S_IRUGO,
813 show_temp_min_alarm, NULL, 5);
814
815static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
816 show_temp_max_alarm, NULL, 0);
817static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO,
818 show_temp_max_alarm, NULL, 1);
819static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO,
820 show_temp_max_alarm, NULL, 2);
821static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO,
822 show_temp_max_alarm, NULL, 3);
823static SENSOR_DEVICE_ATTR(temp5_max_alarm, S_IRUGO,
824 show_temp_max_alarm, NULL, 4);
825static SENSOR_DEVICE_ATTR(temp6_max_alarm, S_IRUGO,
826 show_temp_max_alarm, NULL, 5);
827
828static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO,
829 show_temp_crit_alarm, NULL, 0);
830static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO,
831 show_temp_crit_alarm, NULL, 1);
832static SENSOR_DEVICE_ATTR(temp3_crit_alarm, S_IRUGO,
833 show_temp_crit_alarm, NULL, 2);
834static SENSOR_DEVICE_ATTR(temp4_crit_alarm, S_IRUGO,
835 show_temp_crit_alarm, NULL, 3);
836static SENSOR_DEVICE_ATTR(temp5_crit_alarm, S_IRUGO,
837 show_temp_crit_alarm, NULL, 4);
838static SENSOR_DEVICE_ATTR(temp6_crit_alarm, S_IRUGO,
839 show_temp_crit_alarm, NULL, 5);
840
841static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0);
842static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1);
843static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2);
844static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_temp_fault, NULL, 3);
845static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_temp_fault, NULL, 4);
846static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_temp_fault, NULL, 5);
847
848static struct attribute *pc87427_attributes_temp[6][10] = {
849 {
850 &sensor_dev_attr_temp1_input.dev_attr.attr,
851 &sensor_dev_attr_temp1_min.dev_attr.attr,
852 &sensor_dev_attr_temp1_max.dev_attr.attr,
853 &sensor_dev_attr_temp1_crit.dev_attr.attr,
854 &sensor_dev_attr_temp1_type.dev_attr.attr,
855 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
856 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
857 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
858 &sensor_dev_attr_temp1_fault.dev_attr.attr,
859 NULL
860 }, {
861 &sensor_dev_attr_temp2_input.dev_attr.attr,
862 &sensor_dev_attr_temp2_min.dev_attr.attr,
863 &sensor_dev_attr_temp2_max.dev_attr.attr,
864 &sensor_dev_attr_temp2_crit.dev_attr.attr,
865 &sensor_dev_attr_temp2_type.dev_attr.attr,
866 &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
867 &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
868 &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
869 &sensor_dev_attr_temp2_fault.dev_attr.attr,
870 NULL
871 }, {
872 &sensor_dev_attr_temp3_input.dev_attr.attr,
873 &sensor_dev_attr_temp3_min.dev_attr.attr,
874 &sensor_dev_attr_temp3_max.dev_attr.attr,
875 &sensor_dev_attr_temp3_crit.dev_attr.attr,
876 &sensor_dev_attr_temp3_type.dev_attr.attr,
877 &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
878 &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
879 &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
880 &sensor_dev_attr_temp3_fault.dev_attr.attr,
881 NULL
882 }, {
883 &sensor_dev_attr_temp4_input.dev_attr.attr,
884 &sensor_dev_attr_temp4_min.dev_attr.attr,
885 &sensor_dev_attr_temp4_max.dev_attr.attr,
886 &sensor_dev_attr_temp4_crit.dev_attr.attr,
887 &sensor_dev_attr_temp4_type.dev_attr.attr,
888 &sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
889 &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
890 &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
891 &sensor_dev_attr_temp4_fault.dev_attr.attr,
892 NULL
893 }, {
894 &sensor_dev_attr_temp5_input.dev_attr.attr,
895 &sensor_dev_attr_temp5_min.dev_attr.attr,
896 &sensor_dev_attr_temp5_max.dev_attr.attr,
897 &sensor_dev_attr_temp5_crit.dev_attr.attr,
898 &sensor_dev_attr_temp5_type.dev_attr.attr,
899 &sensor_dev_attr_temp5_min_alarm.dev_attr.attr,
900 &sensor_dev_attr_temp5_max_alarm.dev_attr.attr,
901 &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr,
902 &sensor_dev_attr_temp5_fault.dev_attr.attr,
903 NULL
904 }, {
905 &sensor_dev_attr_temp6_input.dev_attr.attr,
906 &sensor_dev_attr_temp6_min.dev_attr.attr,
907 &sensor_dev_attr_temp6_max.dev_attr.attr,
908 &sensor_dev_attr_temp6_crit.dev_attr.attr,
909 &sensor_dev_attr_temp6_type.dev_attr.attr,
910 &sensor_dev_attr_temp6_min_alarm.dev_attr.attr,
911 &sensor_dev_attr_temp6_max_alarm.dev_attr.attr,
912 &sensor_dev_attr_temp6_crit_alarm.dev_attr.attr,
913 &sensor_dev_attr_temp6_fault.dev_attr.attr,
914 NULL
915 }
916};
917
918static const struct attribute_group pc87427_group_temp[6] = {
919 { .attrs = pc87427_attributes_temp[0] },
920 { .attrs = pc87427_attributes_temp[1] },
921 { .attrs = pc87427_attributes_temp[2] },
922 { .attrs = pc87427_attributes_temp[3] },
923 { .attrs = pc87427_attributes_temp[4] },
924 { .attrs = pc87427_attributes_temp[5] },
925};
926
598static ssize_t show_name(struct device *dev, struct device_attribute 927static ssize_t show_name(struct device *dev, struct device_attribute
599 *devattr, char *buf) 928 *devattr, char *buf)
600{ 929{
@@ -659,7 +988,7 @@ static void __devinit pc87427_init_device(struct device *dev)
659 /* The FMC module should be ready */ 988 /* The FMC module should be ready */
660 reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK); 989 reg = pc87427_read8(data, LD_FAN, PC87427_REG_BANK);
661 if (!(reg & 0x80)) 990 if (!(reg & 0x80))
662 dev_warn(dev, "FMC module not ready!\n"); 991 dev_warn(dev, "%s module not ready!\n", "FMC");
663 992
664 /* Check which fans are enabled */ 993 /* Check which fans are enabled */
665 for (i = 0; i < 8; i++) { 994 for (i = 0; i < 8; i++) {
@@ -701,6 +1030,19 @@ static void __devinit pc87427_init_device(struct device *dev)
701 data->pwm_auto_ok |= (1 << i); 1030 data->pwm_auto_ok |= (1 << i);
702 } 1031 }
703 } 1032 }
1033
1034 /* The HMC module should be ready */
1035 reg = pc87427_read8(data, LD_TEMP, PC87427_REG_BANK);
1036 if (!(reg & 0x80))
1037 dev_warn(dev, "%s module not ready!\n", "HMC");
1038
1039 /* Check which temperature channels are enabled */
1040 for (i = 0; i < 6; i++) {
1041 reg = pc87427_read8_bank(data, LD_TEMP, BANK_TM(i),
1042 PC87427_REG_TEMP_STATUS);
1043 if (reg & TEMP_STATUS_CHANEN)
1044 data->temp_enabled |= (1 << i);
1045 }
704} 1046}
705 1047
706static int __devinit pc87427_probe(struct platform_device *pdev) 1048static int __devinit pc87427_probe(struct platform_device *pdev)
@@ -749,6 +1091,14 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
749 if (err) 1091 if (err)
750 goto exit_remove_files; 1092 goto exit_remove_files;
751 } 1093 }
1094 for (i = 0; i < 6; i++) {
1095 if (!(data->temp_enabled & (1 << i)))
1096 continue;
1097 err = sysfs_create_group(&pdev->dev.kobj,
1098 &pc87427_group_temp[i]);
1099 if (err)
1100 goto exit_remove_files;
1101 }
752 1102
753 data->hwmon_dev = hwmon_device_register(&pdev->dev); 1103 data->hwmon_dev = hwmon_device_register(&pdev->dev);
754 if (IS_ERR(data->hwmon_dev)) { 1104 if (IS_ERR(data->hwmon_dev)) {
@@ -770,6 +1120,11 @@ exit_remove_files:
770 continue; 1120 continue;
771 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_pwm[i]); 1121 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_pwm[i]);
772 } 1122 }
1123 for (i = 0; i < 6; i++) {
1124 if (!(data->temp_enabled & (1 << i)))
1125 continue;
1126 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_temp[i]);
1127 }
773exit_release_region: 1128exit_release_region:
774 pc87427_release_regions(pdev, res_count); 1129 pc87427_release_regions(pdev, res_count);
775exit_kfree: 1130exit_kfree:
@@ -798,6 +1153,11 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
798 continue; 1153 continue;
799 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_pwm[i]); 1154 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_pwm[i]);
800 } 1155 }
1156 for (i = 0; i < 6; i++) {
1157 if (!(data->temp_enabled & (1 << i)))
1158 continue;
1159 sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_temp[i]);
1160 }
801 platform_set_drvdata(pdev, NULL); 1161 platform_set_drvdata(pdev, NULL);
802 kfree(data); 1162 kfree(data);
803 1163