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

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

Merge "qpnp-rtc: clear alarm register when rtc irq is disabled"

parents ce71070e cb1505c0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ qpnp_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
	unsigned long irq_flags;
	struct qpnp_rtc *rtc_dd = dev_get_drvdata(dev);
	u8 ctrl_reg;
	u8 value[4] = {0};

	spin_lock_irqsave(&rtc_dd->alarm_ctrl_lock, irq_flags);
	ctrl_reg = rtc_dd->alarm_ctrl_reg1;
@@ -370,6 +371,15 @@ qpnp_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)

	rtc_dd->alarm_ctrl_reg1 = ctrl_reg;

	/* Clear Alarm register */
	if (!enabled) {
		rc = qpnp_write_wrapper(rtc_dd, value,
			rtc_dd->alarm_base + REG_OFFSET_ALARM_RW,
			NUM_8_BIT_RTC_REGS);
		if (rc)
			dev_err(dev, "Clear ALARM value reg failed\n");
	}

rtc_rw_fail:
	spin_unlock_irqrestore(&rtc_dd->alarm_ctrl_lock, irq_flags);
	return rc;
+5 −4
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ static void devalarm_cancel(struct devalarm *alrm)
		hrtimer_cancel(&alrm->u.hrt);
}

static void alarm_clear(enum android_alarm_type alarm_type)
static void alarm_clear(enum android_alarm_type alarm_type, struct timespec *ts)
{
	uint32_t alarm_type_mask = 1U << alarm_type;
	unsigned long flags;
@@ -111,7 +111,7 @@ static void alarm_clear(enum android_alarm_type alarm_type)
	spin_unlock_irqrestore(&alarm_slock, flags);

	if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)
		set_power_on_alarm(0);
		set_power_on_alarm(ts->tv_sec, 0);
}

static void alarm_set(enum android_alarm_type alarm_type,
@@ -128,7 +128,7 @@ static void alarm_set(enum android_alarm_type alarm_type,
	spin_unlock_irqrestore(&alarm_slock, flags);

	if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)
		set_power_on_alarm(ts->tv_sec);
		set_power_on_alarm(ts->tv_sec, 1);
}

static int alarm_wait(void)
@@ -232,7 +232,7 @@ static long alarm_do_ioctl(struct file *file, unsigned int cmd,

	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
	case ANDROID_ALARM_CLEAR(0):
		alarm_clear(alarm_type);
		alarm_clear(alarm_type, ts);
		break;
	case ANDROID_ALARM_SET(0):
		alarm_set(alarm_type, ts);
@@ -266,6 +266,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
	case ANDROID_ALARM_SET_AND_WAIT(0):
	case ANDROID_ALARM_SET(0):
	case ANDROID_ALARM_SET_RTC:
	case ANDROID_ALARM_CLEAR(0):
		if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
			return -EFAULT;
		break;
+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ int alarm_start_relative(struct alarm *alarm, ktime_t start);
void alarm_restart(struct alarm *alarm);
int alarm_try_to_cancel(struct alarm *alarm);
int alarm_cancel(struct alarm *alarm);
void set_power_on_alarm(long secs);
void set_power_on_alarm(long secs, bool enable);

u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval);
u64 alarm_forward_now(struct alarm *alarm, ktime_t interval);
+20 −10
Original line number Diff line number Diff line
@@ -57,10 +57,11 @@ static DEFINE_SPINLOCK(rtcdev_lock);
static unsigned long power_on_alarm;
static struct mutex power_on_alarm_lock;

void set_power_on_alarm(long secs)
void set_power_on_alarm(long secs, bool enable)
{
	int rc;
	long rtc_secs, alarm_time;
	struct timespec wall_time;
	long rtc_secs, alarm_time, alarm_delta;
	struct rtc_time rtc_time;
	struct rtc_wkalrm alarm;

@@ -68,15 +69,23 @@ void set_power_on_alarm(long secs)
	if (rc != 0)
		return;

	rtc_read_time(rtcdev, &rtc_time);
	rtc_tm_to_time(&rtc_time, &rtc_secs);
	if (enable) {
			power_on_alarm = secs;
	} else {
		if (power_on_alarm == secs)
			power_on_alarm = 0;
		else
			goto exit;
	}

	if (!secs)
	if (!power_on_alarm)
		goto disable_alarm;
	else
		power_on_alarm = secs + rtc_secs;

	alarm_time = power_on_alarm;
	rtc_read_time(rtcdev, &rtc_time);
	getnstimeofday(&wall_time);
	rtc_tm_to_time(&rtc_time, &rtc_secs);
	alarm_delta = wall_time.tv_sec - rtc_secs;
	alarm_time = power_on_alarm - alarm_delta;

	/*
	 *Substract ALARM_DELTA from actual alarm time
@@ -85,8 +94,7 @@ void set_power_on_alarm(long secs)
	 */
	if ((alarm_time - ALARM_DELTA) > rtc_secs)
		alarm_time -= ALARM_DELTA;

	if (alarm_time <= rtc_secs)
	else
		goto disable_alarm;

	rtc_time_to_tm(alarm_time, &alarm.time);
@@ -99,7 +107,9 @@ void set_power_on_alarm(long secs)
	return;

disable_alarm:
	power_on_alarm = 0;
	rtc_alarm_irq_enable(rtcdev, 0);
exit:
	mutex_unlock(&power_on_alarm_lock);
}