firmware/br-ext-chip-allwinner/board/v83x/kernel/patches/00000-kernel_time_alarmtime...

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);