aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2013-11-26 02:15:23 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-12-10 04:27:35 -0500
commite3670b81954ab1247341a08514aa4df09f0b495e (patch)
tree1173cb2ec884b3d23acb50003a6affe9769669ca
parent56cec249167b44ee2ba7a3cbf4431bee937e08e3 (diff)
igb: Convert to use devm_hwmon_device_register_with_groups
Simplify the code. Attach hwmon sysfs attributes to hwmon device instead of pci device. Avoid race conditions caused by attributes being created after registration and provide mandatory 'name' attribute by using new hwmon API. Other cleanup: Instead of allocating memory for hwmon attributes, move attributes and all other hwmon related data into struct hwmon_buff and allocate the entire structure using devm_kzalloc. Check return value from calls to igb_add_hwmon_attr() one by one instead of logically combining them all together. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h8
-rw-r--r--drivers/net/ethernet/intel/igb/igb_hwmon.c100
2 files changed, 53 insertions, 55 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 11173f46f436..8aaca0a1dca0 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -337,8 +337,10 @@ struct hwmon_attr {
337 }; 337 };
338 338
339struct hwmon_buff { 339struct hwmon_buff {
340 struct device *device; 340 struct attribute_group group;
341 struct hwmon_attr *hwmon_list; 341 const struct attribute_group *groups[2];
342 struct attribute *attrs[E1000_MAX_SENSORS * 4 + 1];
343 struct hwmon_attr hwmon_list[E1000_MAX_SENSORS * 4];
342 unsigned int n_hwmon; 344 unsigned int n_hwmon;
343 }; 345 };
344#endif 346#endif
@@ -440,7 +442,7 @@ struct igb_adapter {
440 442
441 char fw_version[32]; 443 char fw_version[32];
442#ifdef CONFIG_IGB_HWMON 444#ifdef CONFIG_IGB_HWMON
443 struct hwmon_buff igb_hwmon_buff; 445 struct hwmon_buff *igb_hwmon_buff;
444 bool ets; 446 bool ets;
445#endif 447#endif
446 struct i2c_algo_bit_data i2c_algo; 448 struct i2c_algo_bit_data i2c_algo;
diff --git a/drivers/net/ethernet/intel/igb/igb_hwmon.c b/drivers/net/ethernet/intel/igb/igb_hwmon.c
index 58f1ce967aeb..2e7ef2d0711f 100644
--- a/drivers/net/ethernet/intel/igb/igb_hwmon.c
+++ b/drivers/net/ethernet/intel/igb/igb_hwmon.c
@@ -117,8 +117,8 @@ static int igb_add_hwmon_attr(struct igb_adapter *adapter,
117 unsigned int n_attr; 117 unsigned int n_attr;
118 struct hwmon_attr *igb_attr; 118 struct hwmon_attr *igb_attr;
119 119
120 n_attr = adapter->igb_hwmon_buff.n_hwmon; 120 n_attr = adapter->igb_hwmon_buff->n_hwmon;
121 igb_attr = &adapter->igb_hwmon_buff.hwmon_list[n_attr]; 121 igb_attr = &adapter->igb_hwmon_buff->hwmon_list[n_attr];
122 122
123 switch (type) { 123 switch (type) {
124 case IGB_HWMON_TYPE_LOC: 124 case IGB_HWMON_TYPE_LOC:
@@ -154,30 +154,16 @@ static int igb_add_hwmon_attr(struct igb_adapter *adapter,
154 igb_attr->dev_attr.attr.mode = S_IRUGO; 154 igb_attr->dev_attr.attr.mode = S_IRUGO;
155 igb_attr->dev_attr.attr.name = igb_attr->name; 155 igb_attr->dev_attr.attr.name = igb_attr->name;
156 sysfs_attr_init(&igb_attr->dev_attr.attr); 156 sysfs_attr_init(&igb_attr->dev_attr.attr);
157 rc = device_create_file(&adapter->pdev->dev,
158 &igb_attr->dev_attr);
159 if (rc == 0)
160 ++adapter->igb_hwmon_buff.n_hwmon;
161 157
162 return rc; 158 adapter->igb_hwmon_buff->attrs[n_attr] = &igb_attr->dev_attr.attr;
159
160 ++adapter->igb_hwmon_buff->n_hwmon;
161
162 return 0;
163} 163}
164 164
165static void igb_sysfs_del_adapter(struct igb_adapter *adapter) 165static void igb_sysfs_del_adapter(struct igb_adapter *adapter)
166{ 166{
167 int i;
168
169 if (adapter == NULL)
170 return;
171
172 for (i = 0; i < adapter->igb_hwmon_buff.n_hwmon; i++) {
173 device_remove_file(&adapter->pdev->dev,
174 &adapter->igb_hwmon_buff.hwmon_list[i].dev_attr);
175 }
176
177 kfree(adapter->igb_hwmon_buff.hwmon_list);
178
179 if (adapter->igb_hwmon_buff.device)
180 hwmon_device_unregister(adapter->igb_hwmon_buff.device);
181} 167}
182 168
183/* called from igb_main.c */ 169/* called from igb_main.c */
@@ -189,11 +175,11 @@ void igb_sysfs_exit(struct igb_adapter *adapter)
189/* called from igb_main.c */ 175/* called from igb_main.c */
190int igb_sysfs_init(struct igb_adapter *adapter) 176int igb_sysfs_init(struct igb_adapter *adapter)
191{ 177{
192 struct hwmon_buff *igb_hwmon = &adapter->igb_hwmon_buff; 178 struct hwmon_buff *igb_hwmon;
179 struct i2c_client *client;
180 struct device *hwmon_dev;
193 unsigned int i; 181 unsigned int i;
194 int n_attrs;
195 int rc = 0; 182 int rc = 0;
196 struct i2c_client *client = NULL;
197 183
198 /* If this method isn't defined we don't support thermals */ 184 /* If this method isn't defined we don't support thermals */
199 if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) 185 if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
@@ -201,34 +187,16 @@ int igb_sysfs_init(struct igb_adapter *adapter)
201 187
202 /* Don't create thermal hwmon interface if no sensors present */ 188 /* Don't create thermal hwmon interface if no sensors present */
203 rc = (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw)); 189 rc = (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw));
204 if (rc) 190 if (rc)
205 goto exit;
206
207 /* init i2c_client */
208 client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info);
209 if (client == NULL) {
210 dev_info(&adapter->pdev->dev,
211 "Failed to create new i2c device..\n");
212 goto exit; 191 goto exit;
213 }
214 adapter->i2c_client = client;
215 192
216 /* Allocation space for max attributes 193 igb_hwmon = devm_kzalloc(&adapter->pdev->dev, sizeof(*igb_hwmon),
217 * max num sensors * values (loc, temp, max, caution) 194 GFP_KERNEL);
218 */ 195 if (!igb_hwmon) {
219 n_attrs = E1000_MAX_SENSORS * 4;
220 igb_hwmon->hwmon_list = kcalloc(n_attrs, sizeof(struct hwmon_attr),
221 GFP_KERNEL);
222 if (!igb_hwmon->hwmon_list) {
223 rc = -ENOMEM; 196 rc = -ENOMEM;
224 goto err; 197 goto exit;
225 }
226
227 igb_hwmon->device = hwmon_device_register(&adapter->pdev->dev);
228 if (IS_ERR(igb_hwmon->device)) {
229 rc = PTR_ERR(igb_hwmon->device);
230 goto err;
231 } 198 }
199 adapter->igb_hwmon_buff = igb_hwmon;
232 200
233 for (i = 0; i < E1000_MAX_SENSORS; i++) { 201 for (i = 0; i < E1000_MAX_SENSORS; i++) {
234 202
@@ -240,11 +208,39 @@ int igb_sysfs_init(struct igb_adapter *adapter)
240 208
241 /* Bail if any hwmon attr struct fails to initialize */ 209 /* Bail if any hwmon attr struct fails to initialize */
242 rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_CAUTION); 210 rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_CAUTION);
243 rc |= igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_LOC);
244 rc |= igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_TEMP);
245 rc |= igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_MAX);
246 if (rc) 211 if (rc)
247 goto err; 212 goto exit;
213 rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_LOC);
214 if (rc)
215 goto exit;
216 rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_TEMP);
217 if (rc)
218 goto exit;
219 rc = igb_add_hwmon_attr(adapter, i, IGB_HWMON_TYPE_MAX);
220 if (rc)
221 goto exit;
222 }
223
224 /* init i2c_client */
225 client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info);
226 if (client == NULL) {
227 dev_info(&adapter->pdev->dev,
228 "Failed to create new i2c device.\n");
229 rc = -ENODEV;
230 goto exit;
231 }
232 adapter->i2c_client = client;
233
234 igb_hwmon->groups[0] = &igb_hwmon->group;
235 igb_hwmon->group.attrs = igb_hwmon->attrs;
236
237 hwmon_dev = devm_hwmon_device_register_with_groups(&adapter->pdev->dev,
238 client->name,
239 igb_hwmon,
240 igb_hwmon->groups);
241 if (IS_ERR(hwmon_dev)) {
242 rc = PTR_ERR(hwmon_dev);
243 goto err;
248 } 244 }
249 245
250 goto exit; 246 goto exit;