aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/class.c
diff options
context:
space:
mode:
authorJingoo Han <jg1.han@samsung.com>2013-04-29 19:18:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 21:28:21 -0400
commit3e217b660281bbdf2db7e58725a4934b5635cb46 (patch)
treeb9e9d6d2cb27e947d2fe3f56c7b04685b7311d68 /drivers/rtc/class.c
parent51b38c62aa89c8747c350dac2515b8899ff8f4d7 (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.c70
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}
260EXPORT_SYMBOL_GPL(rtc_device_unregister); 260EXPORT_SYMBOL_GPL(rtc_device_unregister);
261 261
262static 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
269static 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
290struct 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}
311EXPORT_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 */
322void 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}
330EXPORT_SYMBOL_GPL(devm_rtc_device_unregister);
331
262static int __init rtc_init(void) 332static int __init rtc_init(void)
263{ 333{
264 rtc_class = class_create(THIS_MODULE, "rtc"); 334 rtc_class = class_create(THIS_MODULE, "rtc");