diff options
author | Jingoo Han <jg1.han@samsung.com> | 2013-04-29 19:18:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 21:28:21 -0400 |
commit | 3e217b660281bbdf2db7e58725a4934b5635cb46 (patch) | |
tree | b9e9d6d2cb27e947d2fe3f56c7b04685b7311d68 /drivers/rtc/class.c | |
parent | 51b38c62aa89c8747c350dac2515b8899ff8f4d7 (diff) |
rtc: add devm_rtc_device_{register,unregister}()
These functions allow the driver core to automatically clean up any
allocation made by rtc drivers. Thus it simplifies the error paths.
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/class.c')
-rw-r--r-- | drivers/rtc/class.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 9b742d3ffb94..b72b40bd7805 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -259,6 +259,76 @@ void rtc_device_unregister(struct rtc_device *rtc) | |||
259 | } | 259 | } |
260 | EXPORT_SYMBOL_GPL(rtc_device_unregister); | 260 | EXPORT_SYMBOL_GPL(rtc_device_unregister); |
261 | 261 | ||
262 | static void devm_rtc_device_release(struct device *dev, void *res) | ||
263 | { | ||
264 | struct rtc_device *rtc = *(struct rtc_device **)res; | ||
265 | |||
266 | rtc_device_unregister(rtc); | ||
267 | } | ||
268 | |||
269 | static int devm_rtc_device_match(struct device *dev, void *res, void *data) | ||
270 | { | ||
271 | struct rtc **r = res; | ||
272 | |||
273 | return *r == data; | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * devm_rtc_device_register - resource managed rtc_device_register() | ||
278 | * @name: the name of the device | ||
279 | * @dev: the device to register | ||
280 | * @ops: the rtc operations structure | ||
281 | * @owner: the module owner | ||
282 | * | ||
283 | * @return a struct rtc on success, or an ERR_PTR on error | ||
284 | * | ||
285 | * Managed rtc_device_register(). The rtc_device returned from this function | ||
286 | * are automatically freed on driver detach. See rtc_device_register() | ||
287 | * for more information. | ||
288 | */ | ||
289 | |||
290 | struct rtc_device *devm_rtc_device_register(const char *name, | ||
291 | struct device *dev, | ||
292 | const struct rtc_class_ops *ops, | ||
293 | struct module *owner) | ||
294 | { | ||
295 | struct rtc_device **ptr, *rtc; | ||
296 | |||
297 | ptr = devres_alloc(devm_rtc_device_release, sizeof(*ptr), GFP_KERNEL); | ||
298 | if (!ptr) | ||
299 | return ERR_PTR(-ENOMEM); | ||
300 | |||
301 | rtc = rtc_device_register(name, dev, ops, owner); | ||
302 | if (!IS_ERR(rtc)) { | ||
303 | *ptr = rtc; | ||
304 | devres_add(dev, ptr); | ||
305 | } else { | ||
306 | devres_free(ptr); | ||
307 | } | ||
308 | |||
309 | return rtc; | ||
310 | } | ||
311 | EXPORT_SYMBOL_GPL(devm_rtc_device_register); | ||
312 | |||
313 | /** | ||
314 | * devm_rtc_device_unregister - resource managed devm_rtc_device_unregister() | ||
315 | * @dev: the device to unregister | ||
316 | * @rtc: the RTC class device to unregister | ||
317 | * | ||
318 | * Deallocated a rtc allocated with devm_rtc_device_register(). Normally this | ||
319 | * function will not need to be called and the resource management code will | ||
320 | * ensure that the resource is freed. | ||
321 | */ | ||
322 | void devm_rtc_device_unregister(struct device *dev, struct rtc_device *rtc) | ||
323 | { | ||
324 | int rc; | ||
325 | |||
326 | rc = devres_release(dev, devm_rtc_device_release, | ||
327 | devm_rtc_device_match, rtc); | ||
328 | WARN_ON(rc); | ||
329 | } | ||
330 | EXPORT_SYMBOL_GPL(devm_rtc_device_unregister); | ||
331 | |||
262 | static int __init rtc_init(void) | 332 | static int __init rtc_init(void) |
263 | { | 333 | { |
264 | rtc_class = class_create(THIS_MODULE, "rtc"); | 334 | rtc_class = class_create(THIS_MODULE, "rtc"); |