Merge "Find wall clock RTC through sysfs"
automerge: 41ef80e
* commit '41ef80e7ff739d863ea5df0e129e54f953545212':
Find wall clock RTC through sysfs
This commit is contained in:
@@ -21,7 +21,9 @@
|
|||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
#include <utils/misc.h>
|
#include <utils/misc.h>
|
||||||
|
#include <utils/String8.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -80,8 +82,8 @@ public:
|
|||||||
class AlarmImplTimerFd : public AlarmImpl
|
class AlarmImplTimerFd : public AlarmImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd) :
|
AlarmImplTimerFd(int fds[N_ANDROID_TIMERFDS], int epollfd, int rtc_id) :
|
||||||
AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd) { }
|
AlarmImpl(fds, N_ANDROID_TIMERFDS), epollfd(epollfd), rtc_id(rtc_id) { }
|
||||||
~AlarmImplTimerFd();
|
~AlarmImplTimerFd();
|
||||||
|
|
||||||
int set(int type, struct timespec *ts);
|
int set(int type, struct timespec *ts);
|
||||||
@@ -90,6 +92,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int epollfd;
|
int epollfd;
|
||||||
|
int rtc_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
AlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]),
|
AlarmImpl::AlarmImpl(int *fds_, size_t n_fds) : fds(new int[n_fds]),
|
||||||
@@ -170,9 +173,16 @@ int AlarmImplTimerFd::setTime(struct timeval *tv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open("/dev/rtc0", O_RDWR);
|
if (rtc_id < 0) {
|
||||||
|
ALOGV("Not setting RTC because wall clock RTC was not found");
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
android::String8 rtc_dev = String8::format("/dev/rtc%d", rtc_id);
|
||||||
|
fd = open(rtc_dev.string(), O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ALOGV("Unable to open RTC driver: %s\n", strerror(errno));
|
ALOGV("Unable to open %s: %s\n", rtc_dev.string(), strerror(errno));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +293,66 @@ static jlong init_alarm_driver()
|
|||||||
return reinterpret_cast<jlong>(ret);
|
return reinterpret_cast<jlong>(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char rtc_sysfs[] = "/sys/class/rtc";
|
||||||
|
|
||||||
|
static bool rtc_is_hctosys(unsigned int rtc_id)
|
||||||
|
{
|
||||||
|
android::String8 hctosys_path = String8::format("%s/rtc%u/hctosys",
|
||||||
|
rtc_sysfs, rtc_id);
|
||||||
|
|
||||||
|
FILE *file = fopen(hctosys_path.string(), "re");
|
||||||
|
if (!file) {
|
||||||
|
ALOGE("failed to open %s: %s", hctosys_path.string(), strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int hctosys;
|
||||||
|
bool ret = false;
|
||||||
|
int err = fscanf(file, "%u", &hctosys);
|
||||||
|
if (err == EOF)
|
||||||
|
ALOGE("failed to read from %s: %s", hctosys_path.string(),
|
||||||
|
strerror(errno));
|
||||||
|
else if (err == 0)
|
||||||
|
ALOGE("%s did not have expected contents", hctosys_path.string());
|
||||||
|
else
|
||||||
|
ret = hctosys;
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wall_clock_rtc()
|
||||||
|
{
|
||||||
|
DIR *dir = opendir(rtc_sysfs);
|
||||||
|
if (!dir) {
|
||||||
|
ALOGE("failed to open %s: %s", rtc_sysfs, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *dirent;
|
||||||
|
while (errno = 0, dirent = readdir(dir)) {
|
||||||
|
unsigned int rtc_id;
|
||||||
|
int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id);
|
||||||
|
|
||||||
|
if (matched < 0)
|
||||||
|
break;
|
||||||
|
else if (matched != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (rtc_is_hctosys(rtc_id)) {
|
||||||
|
ALOGV("found wall clock RTC %u", rtc_id);
|
||||||
|
return rtc_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno == 0)
|
||||||
|
ALOGW("no wall clock RTC found");
|
||||||
|
else
|
||||||
|
ALOGE("failed to enumerate RTCs: %s", strerror(errno));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static jlong init_timerfd()
|
static jlong init_timerfd()
|
||||||
{
|
{
|
||||||
int epollfd;
|
int epollfd;
|
||||||
@@ -308,7 +378,7 @@ static jlong init_timerfd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd);
|
AlarmImpl *ret = new AlarmImplTimerFd(fds, epollfd, wall_clock_rtc());
|
||||||
|
|
||||||
for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) {
|
for (size_t i = 0; i < N_ANDROID_TIMERFDS; i++) {
|
||||||
epoll_event event;
|
epoll_event event;
|
||||||
|
|||||||
Reference in New Issue
Block a user