Commit 86c725e3c5a6baa5316787e0b017d8ac8b0facd8
Committed by
Jean Delvare
1 parent
aef64d0d38
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
hwmon: (i5500_temp) Convert to use ATTRIBUTE_GROUPS macro
Use ATTRIBUTE_GROUPS macro to simplify the code a bit. Signed-off-by: Axel Lin <axel.lin@ingics.com> Signed-off-by: Jean Delvare <jdelvare@suse.de>
Showing 1 changed file with 3 additions and 10 deletions Inline Diff
drivers/hwmon/i5500_temp.c
1 | /* | 1 | /* |
2 | * i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor | 2 | * i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor |
3 | * | 3 | * |
4 | * Copyright (C) 2012, 2014 Jean Delvare <jdelvare@suse.de> | 4 | * Copyright (C) 2012, 2014 Jean Delvare <jdelvare@suse.de> |
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 as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/jiffies.h> | 20 | #include <linux/jiffies.h> |
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
23 | #include <linux/hwmon.h> | 23 | #include <linux/hwmon.h> |
24 | #include <linux/hwmon-sysfs.h> | 24 | #include <linux/hwmon-sysfs.h> |
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | 27 | ||
28 | /* Register definitions from datasheet */ | 28 | /* Register definitions from datasheet */ |
29 | #define REG_TSTHRCATA 0xE2 | 29 | #define REG_TSTHRCATA 0xE2 |
30 | #define REG_TSCTRL 0xE8 | 30 | #define REG_TSCTRL 0xE8 |
31 | #define REG_TSTHRRPEX 0xEB | 31 | #define REG_TSTHRRPEX 0xEB |
32 | #define REG_TSTHRLO 0xEC | 32 | #define REG_TSTHRLO 0xEC |
33 | #define REG_TSTHRHI 0xEE | 33 | #define REG_TSTHRHI 0xEE |
34 | #define REG_CTHINT 0xF0 | 34 | #define REG_CTHINT 0xF0 |
35 | #define REG_TSFSC 0xF3 | 35 | #define REG_TSFSC 0xF3 |
36 | #define REG_CTSTS 0xF4 | 36 | #define REG_CTSTS 0xF4 |
37 | #define REG_TSTHRRQPI 0xF5 | 37 | #define REG_TSTHRRQPI 0xF5 |
38 | #define REG_CTCTRL 0xF7 | 38 | #define REG_CTCTRL 0xF7 |
39 | #define REG_TSTIMER 0xF8 | 39 | #define REG_TSTIMER 0xF8 |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * Sysfs stuff | 42 | * Sysfs stuff |
43 | */ | 43 | */ |
44 | 44 | ||
45 | /* Sensor resolution : 0.5 degree C */ | 45 | /* Sensor resolution : 0.5 degree C */ |
46 | static ssize_t show_temp(struct device *dev, | 46 | static ssize_t show_temp(struct device *dev, |
47 | struct device_attribute *devattr, char *buf) | 47 | struct device_attribute *devattr, char *buf) |
48 | { | 48 | { |
49 | struct pci_dev *pdev = to_pci_dev(dev->parent); | 49 | struct pci_dev *pdev = to_pci_dev(dev->parent); |
50 | long temp; | 50 | long temp; |
51 | u16 tsthrhi; | 51 | u16 tsthrhi; |
52 | s8 tsfsc; | 52 | s8 tsfsc; |
53 | 53 | ||
54 | pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi); | 54 | pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi); |
55 | pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); | 55 | pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); |
56 | temp = ((long)tsthrhi - tsfsc) * 500; | 56 | temp = ((long)tsthrhi - tsfsc) * 500; |
57 | 57 | ||
58 | return sprintf(buf, "%ld\n", temp); | 58 | return sprintf(buf, "%ld\n", temp); |
59 | } | 59 | } |
60 | 60 | ||
61 | static ssize_t show_thresh(struct device *dev, | 61 | static ssize_t show_thresh(struct device *dev, |
62 | struct device_attribute *devattr, char *buf) | 62 | struct device_attribute *devattr, char *buf) |
63 | { | 63 | { |
64 | struct pci_dev *pdev = to_pci_dev(dev->parent); | 64 | struct pci_dev *pdev = to_pci_dev(dev->parent); |
65 | int reg = to_sensor_dev_attr(devattr)->index; | 65 | int reg = to_sensor_dev_attr(devattr)->index; |
66 | long temp; | 66 | long temp; |
67 | u16 tsthr; | 67 | u16 tsthr; |
68 | 68 | ||
69 | pci_read_config_word(pdev, reg, &tsthr); | 69 | pci_read_config_word(pdev, reg, &tsthr); |
70 | temp = tsthr * 500; | 70 | temp = tsthr * 500; |
71 | 71 | ||
72 | return sprintf(buf, "%ld\n", temp); | 72 | return sprintf(buf, "%ld\n", temp); |
73 | } | 73 | } |
74 | 74 | ||
75 | static ssize_t show_alarm(struct device *dev, | 75 | static ssize_t show_alarm(struct device *dev, |
76 | struct device_attribute *devattr, char *buf) | 76 | struct device_attribute *devattr, char *buf) |
77 | { | 77 | { |
78 | struct pci_dev *pdev = to_pci_dev(dev->parent); | 78 | struct pci_dev *pdev = to_pci_dev(dev->parent); |
79 | int nr = to_sensor_dev_attr(devattr)->index; | 79 | int nr = to_sensor_dev_attr(devattr)->index; |
80 | u8 ctsts; | 80 | u8 ctsts; |
81 | 81 | ||
82 | pci_read_config_byte(pdev, REG_CTSTS, &ctsts); | 82 | pci_read_config_byte(pdev, REG_CTSTS, &ctsts); |
83 | return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); | 83 | return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); |
84 | } | 84 | } |
85 | 85 | ||
86 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); | 86 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); |
87 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); | 87 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); |
88 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); | 88 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); |
89 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); | 89 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); |
90 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | 90 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); |
91 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); | 91 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); |
92 | 92 | ||
93 | static struct attribute *i5500_temp_attributes[] = { | 93 | static struct attribute *i5500_temp_attrs[] = { |
94 | &dev_attr_temp1_input.attr, | 94 | &dev_attr_temp1_input.attr, |
95 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | 95 | &sensor_dev_attr_temp1_crit.dev_attr.attr, |
96 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | 96 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, |
97 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 97 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
98 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | 98 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, |
99 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | 99 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, |
100 | NULL | 100 | NULL |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static const struct attribute_group i5500_temp_group = { | 103 | ATTRIBUTE_GROUPS(i5500_temp); |
104 | .attrs = i5500_temp_attributes, | ||
105 | }; | ||
106 | 104 | ||
107 | static const struct attribute_group *i5500_temp_groups[] = { | ||
108 | &i5500_temp_group, | ||
109 | NULL | ||
110 | }; | ||
111 | |||
112 | static const struct pci_device_id i5500_temp_ids[] = { | 105 | static const struct pci_device_id i5500_temp_ids[] = { |
113 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, | 106 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, |
114 | { 0 }, | 107 | { 0 }, |
115 | }; | 108 | }; |
116 | 109 | ||
117 | MODULE_DEVICE_TABLE(pci, i5500_temp_ids); | 110 | MODULE_DEVICE_TABLE(pci, i5500_temp_ids); |
118 | 111 | ||
119 | static int i5500_temp_probe(struct pci_dev *pdev, | 112 | static int i5500_temp_probe(struct pci_dev *pdev, |
120 | const struct pci_device_id *id) | 113 | const struct pci_device_id *id) |
121 | { | 114 | { |
122 | int err; | 115 | int err; |
123 | struct device *hwmon_dev; | 116 | struct device *hwmon_dev; |
124 | u32 tstimer; | 117 | u32 tstimer; |
125 | s8 tsfsc; | 118 | s8 tsfsc; |
126 | 119 | ||
127 | err = pci_enable_device(pdev); | 120 | err = pci_enable_device(pdev); |
128 | if (err) { | 121 | if (err) { |
129 | dev_err(&pdev->dev, "Failed to enable device\n"); | 122 | dev_err(&pdev->dev, "Failed to enable device\n"); |
130 | return err; | 123 | return err; |
131 | } | 124 | } |
132 | 125 | ||
133 | pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); | 126 | pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); |
134 | pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); | 127 | pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); |
135 | if (tsfsc == 0x7F && tstimer == 0x07D30D40) { | 128 | if (tsfsc == 0x7F && tstimer == 0x07D30D40) { |
136 | dev_warn(&pdev->dev, "Sensor seems to be disabled\n"); | 129 | dev_notice(&pdev->dev, "Sensor seems to be disabled\n"); |
137 | return -ENODEV; | 130 | return -ENODEV; |
138 | } | 131 | } |
139 | 132 | ||
140 | hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, | 133 | hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, |
141 | "intel5500", NULL, | 134 | "intel5500", NULL, |
142 | i5500_temp_groups); | 135 | i5500_temp_groups); |
143 | return PTR_ERR_OR_ZERO(hwmon_dev); | 136 | return PTR_ERR_OR_ZERO(hwmon_dev); |
144 | } | 137 | } |
145 | 138 | ||
146 | static struct pci_driver i5500_temp_driver = { | 139 | static struct pci_driver i5500_temp_driver = { |
147 | .name = "i5500_temp", | 140 | .name = "i5500_temp", |
148 | .id_table = i5500_temp_ids, | 141 | .id_table = i5500_temp_ids, |
149 | .probe = i5500_temp_probe, | 142 | .probe = i5500_temp_probe, |
150 | }; | 143 | }; |
151 | 144 | ||
152 | module_pci_driver(i5500_temp_driver); | 145 | module_pci_driver(i5500_temp_driver); |
153 | 146 | ||
154 | MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); | 147 | MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); |
155 | MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); | 148 | MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); |
156 | MODULE_LICENSE("GPL"); | 149 | MODULE_LICENSE("GPL"); |
157 | 150 |