Skip to content

Commit

Permalink
rtc: add devm_rtc_device_{register,unregister}()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jingoo Han authored and Linus Torvalds committed Apr 30, 2013
1 parent 51b38c6 commit 3e217b6
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
70 changes: 70 additions & 0 deletions drivers/rtc/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,76 @@ void rtc_device_unregister(struct rtc_device *rtc)
}
EXPORT_SYMBOL_GPL(rtc_device_unregister);

static void devm_rtc_device_release(struct device *dev, void *res)
{
struct rtc_device *rtc = *(struct rtc_device **)res;

rtc_device_unregister(rtc);
}

static int devm_rtc_device_match(struct device *dev, void *res, void *data)
{
struct rtc **r = res;

return *r == data;
}

/**
* devm_rtc_device_register - resource managed rtc_device_register()
* @name: the name of the device
* @dev: the device to register
* @ops: the rtc operations structure
* @owner: the module owner
*
* @return a struct rtc on success, or an ERR_PTR on error
*
* Managed rtc_device_register(). The rtc_device returned from this function
* are automatically freed on driver detach. See rtc_device_register()
* for more information.
*/

struct rtc_device *devm_rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner)
{
struct rtc_device **ptr, *rtc;

ptr = devres_alloc(devm_rtc_device_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);

rtc = rtc_device_register(name, dev, ops, owner);
if (!IS_ERR(rtc)) {
*ptr = rtc;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}

return rtc;
}
EXPORT_SYMBOL_GPL(devm_rtc_device_register);

/**
* devm_rtc_device_unregister - resource managed devm_rtc_device_unregister()
* @dev: the device to unregister
* @rtc: the RTC class device to unregister
*
* Deallocated a rtc allocated with devm_rtc_device_register(). Normally this
* function will not need to be called and the resource management code will
* ensure that the resource is freed.
*/
void devm_rtc_device_unregister(struct device *dev, struct rtc_device *rtc)
{
int rc;

rc = devres_release(dev, devm_rtc_device_release,
devm_rtc_device_match, rtc);
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_rtc_device_unregister);

static int __init rtc_init(void)
{
rtc_class = class_create(THIS_MODULE, "rtc");
Expand Down
6 changes: 6 additions & 0 deletions include/linux/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,13 @@ extern struct rtc_device *rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner);
extern struct rtc_device *devm_rtc_device_register(const char *name,
struct device *dev,
const struct rtc_class_ops *ops,
struct module *owner);
extern void rtc_device_unregister(struct rtc_device *rtc);
extern void devm_rtc_device_unregister(struct device *dev,
struct rtc_device *rtc);

extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
Expand Down

0 comments on commit 3e217b6

Please sign in to comment.