mirror of https://github.com/OpenIPC/firmware.git
103 lines
3.4 KiB
Diff
103 lines
3.4 KiB
Diff
diff -drupN a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
|
|
--- a/kernel/time/alarmtimer.c 2018-08-06 17:23:04.000000000 +0300
|
|
+++ b/kernel/time/alarmtimer.c 2022-06-12 05:28:14.000000000 +0300
|
|
@@ -206,6 +206,18 @@ ktime_t alarm_expires_remaining(const st
|
|
EXPORT_SYMBOL_GPL(alarm_expires_remaining);
|
|
|
|
#ifdef CONFIG_RTC_CLASS
|
|
+static int boot_mode; //0:normal boot; 1:charger mode; 2:recovery mode
|
|
+static int __init boot_mode_setup(char *str)
|
|
+{
|
|
+ if (!str)
|
|
+ return -EINVAL;
|
|
+
|
|
+ // androidboot.mode=charger
|
|
+ if (!strncmp(str, "charger", strlen("charger")))
|
|
+ boot_mode = 1;
|
|
+ return 1;
|
|
+}
|
|
+__setup("androidboot.mode=", boot_mode_setup);
|
|
/**
|
|
* alarmtimer_suspend - Suspend time callback
|
|
* @dev: unused
|
|
@@ -280,6 +292,58 @@ static int alarmtimer_resume(struct devi
|
|
rtc_timer_cancel(rtc, &rtctimer);
|
|
return 0;
|
|
}
|
|
+static void alarmtimer_shutdown(struct platform_device *dev)
|
|
+{
|
|
+ struct rtc_time tm;
|
|
+ ktime_t min, now;
|
|
+ unsigned long flags;
|
|
+ struct rtc_device *rtc;
|
|
+ int ret;
|
|
+ struct alarm_base *base = &alarm_bases[ALARM_REALTIME_SHUTDOWN];
|
|
+ // struct alarm_base *base = &alarm_bases[ALARM_BOOTTIME];
|
|
+ struct timerqueue_node *next;
|
|
+ ktime_t delta;
|
|
+
|
|
+ spin_lock_irqsave(&freezer_delta_lock, flags);
|
|
+ min = freezer_delta;
|
|
+ freezer_delta = ktime_set(0, 0);
|
|
+ spin_unlock_irqrestore(&freezer_delta_lock, flags);
|
|
+
|
|
+ rtc = alarmtimer_get_rtcdev();
|
|
+ /* If we have no rtcdev, just return */
|
|
+ if (!rtc)
|
|
+ return;
|
|
+
|
|
+ /* Find the soonest timer to expire*/
|
|
+ spin_lock_irqsave(&base->lock, flags);
|
|
+ next = timerqueue_getnext(&base->timerqueue);
|
|
+ spin_unlock_irqrestore(&base->lock, flags);
|
|
+ if (!next) {
|
|
+ printk("[alarmtimer] have no shutdown alarm! %s %d\n", __FUNCTION__, __LINE__);
|
|
+ return;
|
|
+ }
|
|
+ delta = ktime_sub(next->expires, base->gettime());
|
|
+ if (!min.tv64 || (delta.tv64 < min.tv64))
|
|
+ min = delta;
|
|
+
|
|
+ /*if the current time is less 50 seconds than the alarm time, the alarm should turn off*/
|
|
+ if (ktime_to_ms(min) < 50 * MSEC_PER_SEC) {
|
|
+ printk("[alarmtimer] shutdown alarm interval is too short, less than 50s! %s %d\n", __FUNCTION__, __LINE__);
|
|
+ return;
|
|
+ }
|
|
+ /* Setup an rtc timer to fire that far in the future */
|
|
+ rtc_timer_cancel(rtc, &rtctimer);
|
|
+ rtc_read_time(rtc, &tm);
|
|
+ now = rtc_tm_to_ktime(tm);
|
|
+ /* make the alarm trigger ahead of the alarm time, because the power on spend about 50s */
|
|
+ min = ktime_sub(min, ktime_set(50, 0));
|
|
+ printk("[alarmtimer] add shutdown alarm interval=%lldms, %s %d\n", ktime_to_ms(min), __FUNCTION__, __LINE__);
|
|
+ now = ktime_add(now, min);
|
|
+
|
|
+ /* Set alarm, if in the past reject suspend briefly to handle */
|
|
+ ret = rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0));
|
|
+ return;
|
|
+}
|
|
|
|
#else
|
|
static int alarmtimer_suspend(struct device *dev)
|
|
@@ -829,7 +893,10 @@ static struct platform_driver alarmtimer
|
|
.driver = {
|
|
.name = "alarmtimer",
|
|
.pm = &alarmtimer_pm_ops,
|
|
- }
|
|
+ },
|
|
+#ifdef CONFIG_RTC_CLASS
|
|
+ .shutdown = alarmtimer_shutdown,
|
|
+#endif
|
|
};
|
|
|
|
/**
|
|
@@ -863,6 +930,8 @@ static int __init alarmtimer_init(void)
|
|
alarm_bases[ALARM_REALTIME].gettime = &ktime_get_real;
|
|
alarm_bases[ALARM_BOOTTIME].base_clockid = CLOCK_BOOTTIME;
|
|
alarm_bases[ALARM_BOOTTIME].gettime = &ktime_get_boottime;
|
|
+ alarm_bases[ALARM_REALTIME_SHUTDOWN].base_clockid = CLOCK_REALTIME;
|
|
+ alarm_bases[ALARM_REALTIME_SHUTDOWN].gettime = &ktime_get_real;
|
|
for (i = 0; i < ALARM_NUMTYPE; i++) {
|
|
timerqueue_init_head(&alarm_bases[i].timerqueue);
|
|
spin_lock_init(&alarm_bases[i].lock);
|