diff options
author | Guenter Roeck <linux@roeck-us.net> | 2013-07-11 23:00:12 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2013-10-13 19:16:28 -0400 |
commit | 74188cba088192e14cd7fd5433876e8c947bcdd8 (patch) | |
tree | a57d582ea4a75155a169b0dede83f5eed3c2e9b1 | |
parent | 615fc8cb0f900c91ee50f0da0a1821a7c6823671 (diff) |
hwmon: Provide managed hwmon registration
Drivers using the new hwmon_device_register_with_groups API often have a
remove function which consists solely of a call hwmon_device_unregister().
Provide support for devm_hwmon_device_register_with_groups and
devm_hwmon_device_unregister to allow this repeated code to be removed
and help eliminate error handling code.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r-- | drivers/hwmon/hwmon.c | 63 | ||||
-rw-r--r-- | include/linux/hwmon.h | 5 |
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index a982528293ea..e176a43af63d 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
@@ -163,6 +163,69 @@ void hwmon_device_unregister(struct device *dev) | |||
163 | } | 163 | } |
164 | EXPORT_SYMBOL_GPL(hwmon_device_unregister); | 164 | EXPORT_SYMBOL_GPL(hwmon_device_unregister); |
165 | 165 | ||
166 | static void devm_hwmon_release(struct device *dev, void *res) | ||
167 | { | ||
168 | struct device *hwdev = *(struct device **)res; | ||
169 | |||
170 | hwmon_device_unregister(hwdev); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * devm_hwmon_device_register_with_groups - register w/ hwmon | ||
175 | * @dev: the parent device | ||
176 | * @name: hwmon name attribute | ||
177 | * @drvdata: driver data to attach to created device | ||
178 | * @groups: List of attribute groups to create | ||
179 | * | ||
180 | * Returns the pointer to the new device. The new device is automatically | ||
181 | * unregistered with the parent device. | ||
182 | */ | ||
183 | struct device * | ||
184 | devm_hwmon_device_register_with_groups(struct device *dev, const char *name, | ||
185 | void *drvdata, | ||
186 | const struct attribute_group **groups) | ||
187 | { | ||
188 | struct device **ptr, *hwdev; | ||
189 | |||
190 | if (!dev) | ||
191 | return ERR_PTR(-EINVAL); | ||
192 | |||
193 | ptr = devres_alloc(devm_hwmon_release, sizeof(*ptr), GFP_KERNEL); | ||
194 | if (!ptr) | ||
195 | return ERR_PTR(-ENOMEM); | ||
196 | |||
197 | hwdev = hwmon_device_register_with_groups(dev, name, drvdata, groups); | ||
198 | if (IS_ERR(hwdev)) | ||
199 | goto error; | ||
200 | |||
201 | *ptr = hwdev; | ||
202 | devres_add(dev, ptr); | ||
203 | return hwdev; | ||
204 | |||
205 | error: | ||
206 | devres_free(ptr); | ||
207 | return hwdev; | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups); | ||
210 | |||
211 | static int devm_hwmon_match(struct device *dev, void *res, void *data) | ||
212 | { | ||
213 | struct device **hwdev = res; | ||
214 | |||
215 | return *hwdev == data; | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * devm_hwmon_device_unregister - removes a previously registered hwmon device | ||
220 | * | ||
221 | * @dev: the parent device of the device to unregister | ||
222 | */ | ||
223 | void devm_hwmon_device_unregister(struct device *dev) | ||
224 | { | ||
225 | WARN_ON(devres_release(dev, devm_hwmon_release, devm_hwmon_match, dev)); | ||
226 | } | ||
227 | EXPORT_SYMBOL_GPL(devm_hwmon_device_unregister); | ||
228 | |||
166 | static void __init hwmon_pci_quirks(void) | 229 | static void __init hwmon_pci_quirks(void) |
167 | { | 230 | { |
168 | #if defined CONFIG_X86 && defined CONFIG_PCI | 231 | #if defined CONFIG_X86 && defined CONFIG_PCI |
diff --git a/include/linux/hwmon.h b/include/linux/hwmon.h index 6d02ff77ae1a..09354f6c1d63 100644 --- a/include/linux/hwmon.h +++ b/include/linux/hwmon.h | |||
@@ -22,7 +22,12 @@ struct device * | |||
22 | hwmon_device_register_with_groups(struct device *dev, const char *name, | 22 | hwmon_device_register_with_groups(struct device *dev, const char *name, |
23 | void *drvdata, | 23 | void *drvdata, |
24 | const struct attribute_group **groups); | 24 | const struct attribute_group **groups); |
25 | struct device * | ||
26 | devm_hwmon_device_register_with_groups(struct device *dev, const char *name, | ||
27 | void *drvdata, | ||
28 | const struct attribute_group **groups); | ||
25 | 29 | ||
26 | void hwmon_device_unregister(struct device *dev); | 30 | void hwmon_device_unregister(struct device *dev); |
31 | void devm_hwmon_device_unregister(struct device *dev); | ||
27 | 32 | ||
28 | #endif | 33 | #endif |