summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Boyd <swboyd@chromium.org>2020-01-09 07:59:07 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-02-11 04:33:59 -0800
commitb522ff023e2daf109de25c94695b400bd217b3aa (patch)
tree61b48b83219ea265f627320bd3c173509042cc84
parent70435409cee45e60d70dbb961c0d88f88bfbb10d (diff)
alarmtimer: Unregister wakeup source when module get fails
commit 6b6d188aae79a630957aefd88ff5c42af6553ee3 upstream. The alarmtimer_rtc_add_device() function creates a wakeup source and then tries to grab a module reference. If that fails the function returns early with an error code, but fails to remove the wakeup source. Cleanup this exit path so there is no dangling wakeup source, which is named 'alarmtime' left allocated which will conflict with another RTC device that may be registered later. Fixes: 51218298a25e ("alarmtimer: Ensure RTC module is not unloaded") Signed-off-by: Stephen Boyd <swboyd@chromium.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Douglas Anderson <dianders@chromium.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200109155910.907-2-swboyd@chromium.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--kernel/time/alarmtimer.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index f4255a65c44b..9eece67f29f3 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -91,6 +91,7 @@ static int alarmtimer_rtc_add_device(struct device *dev,
unsigned long flags;
struct rtc_device *rtc = to_rtc_device(dev);
struct wakeup_source *__ws;
+ int ret = 0;
if (rtcdev)
return -EBUSY;
@@ -105,8 +106,8 @@ static int alarmtimer_rtc_add_device(struct device *dev,
spin_lock_irqsave(&rtcdev_lock, flags);
if (!rtcdev) {
if (!try_module_get(rtc->owner)) {
- spin_unlock_irqrestore(&rtcdev_lock, flags);
- return -1;
+ ret = -1;
+ goto unlock;
}
rtcdev = rtc;
@@ -115,11 +116,12 @@ static int alarmtimer_rtc_add_device(struct device *dev,
ws = __ws;
__ws = NULL;
}
+unlock:
spin_unlock_irqrestore(&rtcdev_lock, flags);
wakeup_source_unregister(__ws);
- return 0;
+ return ret;
}
static inline void alarmtimer_rtc_timer_init(void)