Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+68
+63
drivers/hwmon/hwmon.c
··· 163 163 } 164 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 229 static void __init hwmon_pci_quirks(void) 167 230 { 168 231 #if defined CONFIG_X86 && defined CONFIG_PCI
+5
include/linux/hwmon.h
··· 22 22 hwmon_device_register_with_groups(struct device *dev, const char *name, 23 23 void *drvdata, 24 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 30 void hwmon_device_unregister(struct device *dev); 31 + void devm_hwmon_device_unregister(struct device *dev); 27 32 28 33 #endif