diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 39db12f267cc6..0a242c75b6ca2 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -398,6 +398,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } else { memset(alarm, 0, sizeof(struct rtc_wkalrm)); alarm->enabled = rtc->aie_timer.enabled; + alarm->pending = test_bit(RTC_PENDING_ALARM, &rtc->flags); alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); } mutex_unlock(&rtc->ops_lock); @@ -504,6 +505,7 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) rtc->aie_timer.node.expires = alarm_time; rtc->aie_timer.period = 0; + clear_bit(RTC_PENDING_ALARM, &rtc->flags); if (alarm->enabled) err = rtc_timer_enqueue(rtc, &rtc->aie_timer); @@ -533,6 +535,8 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.period = 0; + if (alarm->pending) + set_bit(RTC_PENDING_ALARM, &rtc->flags); /* Alarm has to be enabled & in the future for us to enqueue it */ if (alarm->enabled && (rtc_tm_to_ktime(now) < diff --git a/drivers/rtc/rtc-rpi.c b/drivers/rtc/rtc-rpi.c index 006012333e789..a6d99927c0f9c 100644 --- a/drivers/rtc/rtc-rpi.c +++ b/drivers/rtc/rtc-rpi.c @@ -99,6 +99,13 @@ static int rpi_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) &data, sizeof(data)); rtc_time64_to_tm(data[1], &alarm->time); + data[0] = RTC_ALARM_PENDING; + data[1] = 0; + if (!err) + err = rpi_firmware_property(vrtc->fw, RPI_FIRMWARE_GET_RTC_REG, + &data, sizeof(data)); + alarm->pending = data[1] & 1; + return err; } @@ -243,8 +250,6 @@ static int rpi_rtc_probe(struct platform_device *pdev) if (ret) return ret; - rpi_rtc_alarm_clear_pending(dev); - /* * Optionally enable trickle charging - if the property isn't * present (or set to zero), trickle charging is disabled. @@ -254,7 +259,12 @@ static int rpi_rtc_probe(struct platform_device *pdev) rpi_rtc_set_charge_voltage(dev); - return devm_rtc_register_device(vrtc->rtc); + ret = devm_rtc_register_device(vrtc->rtc); + + if (!ret) + rpi_rtc_alarm_clear_pending(dev); + + return ret; } static const struct of_device_id rpi_rtc_dt_match[] = { diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 3f4d315aaec9e..7dcdb6b3f75e4 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -83,6 +83,7 @@ struct rtc_timer { /* flags */ #define RTC_DEV_BUSY 0 #define RTC_NO_CDEV 1 +#define RTC_PENDING_ALARM 2 struct rtc_device { struct device dev;