Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4fb1fa1 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "rtc: alarm: Change wake-up source"

parents 6c8a133e 08a82251
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -46,9 +46,10 @@
							(arr[3] << 24))

/* Module parameter to control power-on-alarm */
static bool poweron_alarm;
bool poweron_alarm;
module_param(poweron_alarm, bool, 0644);
MODULE_PARM_DESC(poweron_alarm, "Enable/Disable power-on alarm");
EXPORT_SYMBOL(poweron_alarm);

/* rtc driver internal structure */
struct qpnp_rtc {
+3 −0
Original line number Diff line number Diff line
@@ -55,5 +55,8 @@ ktime_t alarm_expires_remaining(const struct alarm *alarm);

/* Provide way to access the rtc device being used by alarmtimers */
struct rtc_device *alarmtimer_get_rtcdev(void);
#ifdef CONFIG_RTC_DRV_QPNP
extern bool poweron_alarm;
#endif

#endif
+1 −0
Original line number Diff line number Diff line
@@ -31,3 +31,4 @@ targets += timeconst.h
$(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
	$(call if_changed,bc)

ccflags-y += -Idrivers/cpuidle
+66 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/posix-timers.h>
#include <linux/workqueue.h>
#include <linux/freezer.h>
#include "lpm-levels.h"

/**
 * struct alarm_base - Alarm timer bases
@@ -242,6 +243,70 @@ EXPORT_SYMBOL_GPL(alarm_expires_remaining);
 * set an rtc timer to fire that far into the future, which
 * will wake us from suspend.
 */
#if defined(CONFIG_RTC_DRV_QPNP) && defined(CONFIG_MSM_PM)
static int alarmtimer_suspend(struct device *dev)
{
	struct rtc_time tm;
	ktime_t min, now;
	unsigned long flags;
	struct rtc_device *rtc;
	int i;
	int ret = 0;

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

	/* Find the soonest timer to expire*/
	for (i = 0; i < ALARM_NUMTYPE; i++) {
		struct alarm_base *base = &alarm_bases[i];
		struct timerqueue_node *next;
		ktime_t delta;

		spin_lock_irqsave(&base->lock, flags);
		next = timerqueue_getnext(&base->timerqueue);
		spin_unlock_irqrestore(&base->lock, flags);
		if (!next)
			continue;
		delta = ktime_sub(next->expires, base->gettime());
		if (!min.tv64 || (delta.tv64 < min.tv64))
			min = delta;
	}
	if (min.tv64 == 0)
		return 0;

	if (ktime_to_ns(min) < 2 * NSEC_PER_SEC) {
		__pm_wakeup_event(ws, 2 * MSEC_PER_SEC);
		return -EBUSY;
	}

	/* Setup a timer to fire that far in the future */
	rtc_timer_cancel(rtc, &rtctimer);
	rtc_read_time(rtc, &tm);
	now = rtc_tm_to_ktime(tm);
	now = ktime_add(now, min);
	if (poweron_alarm) {
		struct rtc_time tm_val;
		unsigned long secs;

		tm_val = rtc_ktime_to_tm(min);
		rtc_tm_to_time(&tm_val, &secs);
		lpm_suspend_wake_time(secs);
	} else {
		/* Set alarm, if in the past reject suspend briefly to handle */
		ret = rtc_timer_start(rtc, &rtctimer, now, ktime_set(0, 0));
		if (ret < 0)
			__pm_wakeup_event(ws, MSEC_PER_SEC);
	}
	return ret;
}
#else
static int alarmtimer_suspend(struct device *dev)
{
	struct rtc_time tm;
@@ -296,7 +361,7 @@ static int alarmtimer_suspend(struct device *dev)
		__pm_wakeup_event(ws, MSEC_PER_SEC);
	return ret;
}

#endif
static int alarmtimer_resume(struct device *dev)
{
	struct rtc_device *rtc;