diff options
author | David Brownell <david-b@pacbell.net> | 2007-02-28 23:12:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-01 17:53:37 -0500 |
commit | e109ebd1eed2b91e3c9bb3b42cc27961f0dc22b3 (patch) | |
tree | 402ca61d265c59d35282b0786363dfbe32659564 /drivers/rtc/class.c | |
parent | 0478e62e8a04154b7bdc0dfd33ffbcabc5446e9c (diff) |
[PATCH] rtc_cmos oops fix
Fix an oops on the rtc_device_unregister() path by waiting until the last
moment before nulling the rtc->ops vector. Fix some potential oopses by
having the rtc_class_open()/rtc_class_close() interface increase the RTC's
reference count while an RTC handle is available outside the RTC framework.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alessandro Zummo <a.zummo@towertech.it>
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 | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 7a0d8ee2de9c..04aaa6347234 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -113,10 +113,16 @@ EXPORT_SYMBOL_GPL(rtc_device_register); | |||
113 | */ | 113 | */ |
114 | void rtc_device_unregister(struct rtc_device *rtc) | 114 | void rtc_device_unregister(struct rtc_device *rtc) |
115 | { | 115 | { |
116 | mutex_lock(&rtc->ops_lock); | 116 | if (class_device_get(&rtc->class_dev) != NULL) { |
117 | rtc->ops = NULL; | 117 | mutex_lock(&rtc->ops_lock); |
118 | mutex_unlock(&rtc->ops_lock); | 118 | /* remove innards of this RTC, then disable it, before |
119 | class_device_unregister(&rtc->class_dev); | 119 | * letting any rtc_class_open() users access it again |
120 | */ | ||
121 | class_device_unregister(&rtc->class_dev); | ||
122 | rtc->ops = NULL; | ||
123 | mutex_unlock(&rtc->ops_lock); | ||
124 | class_device_put(&rtc->class_dev); | ||
125 | } | ||
120 | } | 126 | } |
121 | EXPORT_SYMBOL_GPL(rtc_device_unregister); | 127 | EXPORT_SYMBOL_GPL(rtc_device_unregister); |
122 | 128 | ||