rtc: alarm: Add power-on alarm feature

Android does not support powering up of phone through alarm.
Adding shutdown hook in alarm driver which will set alarm while phone
is going down so as to power-up the phone after alarm expiration.

CRs-Fixed: 432312
Change-Id: I21786d264b93f7c0c660823a0a1a221c1b4df7b2
Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
This commit is contained in:
Ashay Jaiswal
2013-05-27 11:59:12 +05:30
parent d06d3f026f
commit c1b2e47058
3 changed files with 54 additions and 0 deletions
+6
View File
@@ -98,6 +98,8 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
wake_unlock(&alarm_wake_lock);
}
alarm_enabled &= ~alarm_type_mask;
if (alarm_type == ANDROID_ALARM_RTC_WAKEUP)
set_power_on_alarm(0);
spin_unlock_irqrestore(&alarm_slock, flags);
break;
@@ -125,6 +127,10 @@ from_old_alarm_set:
alarm_start_range(&alarms[alarm_type],
timespec_to_ktime(new_alarm_time),
timespec_to_ktime(new_alarm_time));
if ((alarm_type == ANDROID_ALARM_RTC_WAKEUP) &&
(ANDROID_ALARM_BASE_CMD(cmd) ==
ANDROID_ALARM_SET(0)))
set_power_on_alarm(new_alarm_time.tv_sec);
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)
+47
View File
@@ -68,6 +68,13 @@ static struct wake_lock alarm_rtc_wake_lock;
static struct platform_device *alarm_platform_dev;
struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT];
static bool suspended;
static long power_on_alarm;
void set_power_on_alarm(long secs)
{
power_on_alarm = secs;
}
static void update_timer_locked(struct alarm_queue *base, bool head_removed)
{
@@ -486,6 +493,45 @@ static int alarm_resume(struct platform_device *pdev)
return 0;
}
static void alarm_shutdown(struct platform_device *dev)
{
struct timespec wall_time;
struct rtc_time rtc_time;
struct rtc_wkalrm alarm;
unsigned long flags;
long rtc_secs, alarm_delta, alarm_time;
int rc;
spin_lock_irqsave(&alarm_slock, flags);
if (!power_on_alarm)
goto disable_alarm;
rtc_read_time(alarm_rtc_dev, &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;
if (alarm_time <= rtc_secs)
goto disable_alarm;
rtc_time_to_tm(alarm_time, &alarm.time);
alarm.enabled = 1;
rc = rtc_set_alarm(alarm_rtc_dev, &alarm);
if (rc)
pr_alarm(ERROR, "Unable to set power-on alarm\n");
else
pr_alarm(FLOW, "Power-on alarm set to %lu\n",
alarm_time);
spin_unlock_irqrestore(&alarm_slock, flags);
return;
disable_alarm:
rtc_alarm_irq_enable(alarm_rtc_dev, 0);
spin_unlock_irqrestore(&alarm_slock, flags);
}
static struct rtc_task alarm_rtc_task = {
.func = alarm_triggered_func
};
@@ -545,6 +591,7 @@ static struct class_interface rtc_alarm_interface = {
static struct platform_driver alarm_driver = {
.suspend = alarm_suspend,
.resume = alarm_resume,
.shutdown = alarm_shutdown,
.driver = {
.name = "alarm"
}
+1
View File
@@ -70,6 +70,7 @@ void alarm_init(struct alarm *alarm,
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);
ktime_t alarm_get_elapsed_realtime(void);
/* set rtc while preserving elapsed realtime */