+static int cmos_aie_poweroff(struct device *dev)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ struct rtc_time now;
+ time64_t t_now;
+ int retval = 0;
+ unsigned char rtc_control;
+
+ if (!cmos->alarm_expires)
+ return -EINVAL;
+
+ spin_lock_irq(&rtc_lock);
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ spin_unlock_irq(&rtc_lock);
+
+ /* We only care about the situation where AIE is disabled. */
+ if (rtc_control & RTC_AIE)
+ return -EBUSY;
+
+ cmos_read_time(dev, &now);
+ t_now = rtc_tm_to_time64(&now);
+
+ /*
+ * When enabling "RTC wake-up" in BIOS setup, the machine reboots
+ * automatically right after shutdown on some buggy boxes.
+ * This automatic rebooting issue won't happen when the alarm
+ * time is larger than now+1 seconds.
+ *
+ * If the alarm time is equal to now+1 seconds, the issue can be
+ * prevented by cancelling the alarm.
+ */
+ if (cmos->alarm_expires == t_now + 1) {
+ struct rtc_wkalrm alarm;
+
+ /* Cancel the AIE timer by configuring the past time. */
+ rtc_time64_to_tm(t_now - 1, &alarm.time);
+ alarm.enabled = 0;
+ retval = cmos_set_alarm(dev, &alarm);
+ } else if (cmos->alarm_expires > t_now + 1) {
+ retval = -EBUSY;
+ }
+
+ return retval;
+}
+