
From: Yu Liao <liaoyu15@huawei.com> Offering: HULK hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBV6W4 -------------------------------- Split out a function that does not acquire ops_lock from rtc_update_irq_enable, in preparation for fixing RTC_RD_TIME and RTC_UIE_ON race problem. Signed-off-by: Yu Liao <liaoyu15@huawei.com> Conflicts: drivers/rtc/interface.c [wxf: Backport from OLK-5.10. Fix context conflicts] Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com> --- drivers/rtc/interface.c | 30 ++++++++++++++++++++---------- include/linux/rtc.h | 1 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 1ab619fb978a..f5ff99ca1088 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -554,18 +554,10 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) } EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); -int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) +int __rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) { - int err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return err; + int err = 0; -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - if (enabled == 0 && rtc->uie_irq_active) { - mutex_unlock(&rtc->ops_lock); - return rtc_dev_update_irq_enable_emul(rtc, 0); - } -#endif /* make sure we're changing state */ if (rtc->uie_rtctimer.enabled == enabled) goto out; @@ -589,6 +581,24 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) rtc_timer_remove(rtc, &rtc->uie_rtctimer); out: + return err; + +} + +int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) +{ + int err = mutex_lock_interruptible(&rtc->ops_lock); + if (err) + return err; + +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + if (enabled == 0 && rtc->uie_irq_active) { + mutex_unlock(&rtc->ops_lock); + return rtc_dev_update_irq_enable_emul(rtc, 0); + } +#endif + + err = __rtc_update_irq_enable(rtc, enabled); mutex_unlock(&rtc->ops_lock); #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL /* diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 5a34f59941fb..54a63198e3cb 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -200,6 +200,7 @@ extern void rtc_class_close(struct rtc_device *rtc); extern int rtc_irq_set_state(struct rtc_device *rtc, int enabled); extern int rtc_irq_set_freq(struct rtc_device *rtc, int freq); extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled); +extern int __rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled); extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled); -- 2.20.1