rtc: alarm: update power_on alarm setting logic

The previous power_on alarm value should be checked to avoid
cancelling the alarm by mistake.

CRs-fixed: 551966
Change-Id: I4de12265416fab41a9c591d09961c9fef0d25917
Signed-off-by: Xiaocheng Li <lix@codeaurora.org>
diff --git a/drivers/rtc/alarm-dev.c b/drivers/rtc/alarm-dev.c
index 4682e9c..1e13ce1 100644
--- a/drivers/rtc/alarm-dev.c
+++ b/drivers/rtc/alarm-dev.c
@@ -99,7 +99,9 @@
 		}
 		alarm_enabled &= ~alarm_type_mask;
 		if (alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP)
-			set_power_on_alarm(0);
+			if (!copy_from_user(&new_alarm_time,
+				(void __user *)arg, sizeof(new_alarm_time)))
+				set_power_on_alarm(new_alarm_time.tv_sec, 0);
 		spin_unlock_irqrestore(&alarm_slock, flags);
 		break;
 
@@ -130,7 +132,7 @@
 		if ((alarm_type == ANDROID_ALARM_RTC_POWEROFF_WAKEUP) &&
 				(ANDROID_ALARM_BASE_CMD(cmd) ==
 				 ANDROID_ALARM_SET(0)))
-			set_power_on_alarm(new_alarm_time.tv_sec);
+			set_power_on_alarm(new_alarm_time.tv_sec, 1);
 		spin_unlock_irqrestore(&alarm_slock, flags);
 		if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0)
 		    && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)
diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c
index fb97329..2cf1158 100644
--- a/drivers/rtc/alarm.c
+++ b/drivers/rtc/alarm.c
@@ -72,9 +72,19 @@
 static long power_on_alarm;
 
 static void alarm_shutdown(struct platform_device *dev);
-void set_power_on_alarm(long secs)
+void set_power_on_alarm(long secs, bool enable)
 {
-	power_on_alarm = secs;
+	if (enable) {
+		power_on_alarm = secs;
+	} else {
+		if (power_on_alarm && power_on_alarm != secs) {
+			pr_alarm(FLOW, "power-off alarm mismatch: \
+				previous=%ld, now=%ld\n",
+				power_on_alarm, secs);
+		}
+		else
+			power_on_alarm = 0;
+	}
 	alarm_shutdown(NULL);
 }
 
diff --git a/include/linux/android_alarm.h b/include/linux/android_alarm.h
index b017caa..65227ad 100644
--- a/include/linux/android_alarm.h
+++ b/include/linux/android_alarm.h
@@ -71,7 +71,7 @@
 void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end);
 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);
 ktime_t alarm_get_elapsed_realtime(void);
 
 /* set rtc while preserving elapsed realtime */