diff --git a/patchForKernel/ubuntu_20.04/kernel_5.10.27/0007.add_android_alarm_driver.patch b/patchForKernel/ubuntu_20.04/kernel_5.10.27/0007.add_android_alarm_driver.patch index 57ce69ff554f103f3e6385235667b4c4ca7fd982..d230435de08e73bee191dce3bd32ab123d0a235c 100755 --- a/patchForKernel/ubuntu_20.04/kernel_5.10.27/0007.add_android_alarm_driver.patch +++ b/patchForKernel/ubuntu_20.04/kernel_5.10.27/0007.add_android_alarm_driver.patch @@ -9,4 +9,1000 @@ index 53b22e262..e33b6ae96 100644 +source "drivers/android/alarm/Kconfig" endif # if ANDROID - \ No newline at end of file + +diff --git a/drivers/android/Makefile b/drivers/android/Makefile +index c9d3d0c99..7422be9e5 100644 +--- a/drivers/android/Makefile ++++ b/drivers/android/Makefile +@@ -4,3 +4,4 @@ ccflags-y += -I$(src) # needed for trace events + obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o + obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o + obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o ++obj-$(CONFIG_ANDROID_ALARM) += alarm/ +\ No newline at end of file +diff --git a/drivers/android/alarm/Kconfig b/drivers/android/alarm/Kconfig +new file mode 100755 +index 000000000..1e17949eb +--- /dev/null ++++ b/drivers/android/alarm/Kconfig +@@ -0,0 +1,3 @@ ++config ANDROID_ALARM ++ tristate "Android Alarm Driver" ++ default m +diff --git a/drivers/android/alarm/Makefile b/drivers/android/alarm/Makefile +new file mode 100755 +index 000000000..2e81dea9e +--- /dev/null ++++ b/drivers/android/alarm/Makefile +@@ -0,0 +1,3 @@ ++flags-y += -I$(src) -Wno-error=implicit-int -Wno-int-conversion -g3 -O3 ++alarm_linux-y := alarm.o ++obj-$(CONFIG_ANDROID_ALARM) += alarm_linux.o +diff --git a/drivers/android/alarm/alarm.c b/drivers/android/alarm/alarm.c +new file mode 100755 +index 000000000..2647c9df4 +--- /dev/null ++++ b/drivers/android/alarm/alarm.c +@@ -0,0 +1,559 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "android_alarm.h" ++ ++ ++#define ANDROID_ALARM_PRINT_INFO (1U << 0) ++#define ANDROID_ALARM_PRINT_IO (1U << 1) ++#define ANDROID_ALARM_PRINT_INT (1U << 2) ++ ++#define ALARM_DKMS_MAJOR 508 ++#define ALARM_DKMS_MAX_MINOR 256 ++ ++static DEFINE_MUTEX(alarm_devices_mtx); ++static HLIST_HEAD(alarm_devices); ++ ++static int debug_mask = ANDROID_ALARM_PRINT_INFO; ++module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++#define alarm_dbg(debug_level_mask, fmt, ...) \ ++do { \ ++ if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) \ ++ pr_info(fmt, ##__VA_ARGS__); \ ++} while (0) ++ ++struct devalarm { ++ union { ++ struct hrtimer hrt; ++ struct alarm alrm; ++ } u; ++ enum android_alarm_type type; ++ struct alarm_context* context; ++}; ++ ++static int alarm_devices_param = 1; ++module_param_named(num_devices, alarm_devices_param, int, 0444); ++static struct class *alarm_class; ++ ++struct alarm_context { ++ const char *name; ++ ++ int alarm_opened; ++ spinlock_t alarm_slock; ++ struct wakeup_source* alarm_wake_lock; ++ wait_queue_head_t alarm_wait_queue; ++ uint32_t alarm_pending; ++ uint32_t alarm_enabled; ++ uint32_t wait_pending; ++ ++ struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; ++}; ++ ++struct alarm_device { ++ struct hlist_node hlist; ++ struct cdev cdev; ++ struct device class_dev; ++ struct alarm_context context; ++}; ++ ++static int is_wakeup(enum android_alarm_type type) ++{ ++ return (type == ANDROID_ALARM_RTC_WAKEUP || ++ type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); ++} ++ ++static int devalarm_try_to_cancel(struct devalarm *alrm) ++{ ++ if (is_wakeup(alrm->type)) ++ return alarm_try_to_cancel(&alrm->u.alrm); ++ return hrtimer_try_to_cancel(&alrm->u.hrt); ++} ++ ++ ++static void alarm_clear(struct alarm_context* context, enum android_alarm_type alarm_type) ++{ ++ uint32_t alarm_type_mask = 1U << alarm_type; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ alarm_dbg(IO, "alarm %d clear\n", alarm_type); ++ devalarm_try_to_cancel(&context->alarms[alarm_type]); ++ if (context->alarm_pending) { ++ context->alarm_pending &= ~alarm_type_mask; ++ if (!context->alarm_pending && !context->wait_pending) ++ __pm_relax(context->alarm_wake_lock); ++ } ++ context->alarm_enabled &= ~alarm_type_mask; ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++ ++} ++ ++static void devalarm_start(struct devalarm *alrm, ktime_t exp) ++{ ++ if (is_wakeup(alrm->type)) ++ alarm_start(&alrm->u.alrm, exp); ++ else ++ hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS); ++} ++ ++static void alarm_set(struct alarm_context* context, enum android_alarm_type alarm_type, ++ struct timespec *ts) ++{ ++ uint32_t alarm_type_mask = 1U << alarm_type; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ alarm_dbg(IO, "alarm %d set %ld.%09ld\n", ++ alarm_type, ts->tv_sec, ts->tv_nsec); ++ context->alarm_enabled |= alarm_type_mask; ++ devalarm_start(&context->alarms[alarm_type], timespec_to_ktime(*ts)); ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++} ++ ++static int alarm_wait(struct alarm_context* context) ++{ ++ unsigned long flags; ++ int rv = 0; ++ ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ alarm_dbg(IO, "alarm wait\n"); ++ if (!context->alarm_pending && context->wait_pending) { ++ __pm_relax(context->alarm_wake_lock); ++ context->wait_pending = 0; ++ } ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++ ++ rv = wait_event_interruptible(context->alarm_wait_queue, context->alarm_pending); ++ if (rv) ++ return rv; ++ ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ rv = context->alarm_pending; ++ context->wait_pending = 1; ++ context->alarm_pending = 0; ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++ ++ return rv; ++} ++ ++static int alarm_set_rtc(struct alarm_context* context, struct timespec *ts) ++{ ++ struct rtc_time new_rtc_tm; ++ struct rtc_device *rtc_dev; ++ unsigned long flags; ++ struct timespec64 ts64; ++ int rv = 0; ++ ++ rtc_time64_to_tm(ts->tv_sec, &new_rtc_tm); ++ rtc_dev = alarmtimer_get_rtcdev(); ++ rv = do_settimeofday64(&ts64); ++ if (rv < 0) ++ return rv; ++ ts->tv_sec = (time_t)ts64.tv_sec; ++ ts->tv_nsec = ts64.tv_nsec; ++ if (rtc_dev) ++ rv = rtc_set_time(rtc_dev, &new_rtc_tm); ++ ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ context->alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; ++ wake_up(&context->alarm_wait_queue); ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++ ++ return rv; ++} ++ ++static int alarm_get_time(enum android_alarm_type alarm_type, ++ struct timespec *ts) ++{ ++ int rv = 0; ++ ++ switch (alarm_type) { ++ case ANDROID_ALARM_RTC_WAKEUP: ++ case ANDROID_ALARM_RTC: ++ getnstimeofday(ts); ++ break; ++ case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: ++ case ANDROID_ALARM_ELAPSED_REALTIME: ++ { ++ struct timespec64 ts64; ++ ktime_get_boottime_ts64(&ts64); ++ ts->tv_sec = (time_t)ts64.tv_sec; ++ ts->tv_nsec = ts64.tv_nsec; ++ } ++ break; ++ case ANDROID_ALARM_SYSTEMTIME: ++ ktime_get_ts(ts); ++ break; ++ default: ++ rv = -EINVAL; ++ } ++ return rv; ++} ++ ++static long alarm_do_ioctl(struct file *file, unsigned int cmd, ++ struct timespec *ts) ++{ ++ int rv = 0; ++ struct alarm_device* alarm_dev = NULL; ++ struct alarm_context* context = NULL; ++ alarm_dev = file->private_data; ++ context = &alarm_dev->context; ++ ++ enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); ++ ++ if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) ++ return -EINVAL; ++ ++ if(alarm_dev == NULL){ ++ return -EBUSY; ++ } ++ ++ if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { ++ if ((file->f_flags & O_ACCMODE) == O_RDONLY) ++ return -EPERM; ++ } ++ ++ switch (ANDROID_ALARM_BASE_CMD(cmd)) { ++ case ANDROID_ALARM_CLEAR(0): ++ alarm_clear(context, alarm_type); ++ break; ++ case ANDROID_ALARM_SET(0): ++ alarm_set(context, alarm_type, ts); ++ break; ++ case ANDROID_ALARM_SET_AND_WAIT(0): ++ alarm_set(context, alarm_type, ts); ++ /* fall though */ ++ case ANDROID_ALARM_WAIT: ++ rv = alarm_wait(context); ++ break; ++ case ANDROID_ALARM_SET_RTC: ++ rv = alarm_set_rtc(context, ts); ++ break; ++ case ANDROID_ALARM_GET_TIME(0): ++ rv = alarm_get_time(alarm_type, ts); ++ break; ++ ++ default: ++ rv = -EINVAL; ++ } ++ return rv; ++} ++ ++static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct timespec ts; ++ int rv; ++ ++ switch (ANDROID_ALARM_BASE_CMD(cmd)) { ++ case ANDROID_ALARM_SET_AND_WAIT(0): ++ case ANDROID_ALARM_SET(0): ++ case ANDROID_ALARM_SET_RTC: ++ if (copy_from_user(&ts, (void __user *)arg, sizeof(ts))) ++ return -EFAULT; ++ break; ++ } ++ ++ rv = alarm_do_ioctl(file, cmd, &ts); ++ if (rv) ++ return rv; ++ ++ switch (ANDROID_ALARM_BASE_CMD(cmd)) { ++ case ANDROID_ALARM_GET_TIME(0): ++ if (copy_to_user((void __user *)arg, &ts, sizeof(ts))) ++ return -EFAULT; ++ break; ++ } ++ ++ return 0; ++} ++ ++static int alarm_open(struct inode *inode, struct file *file) ++{ ++ int minor = iminor(inode); ++ struct hlist_node *tmp; ++ struct alarm_device *alarm_dev; ++ file->private_data = NULL; ++ ++ printk("alarm_open minor: %d\n", minor); ++ ++ mutex_lock(&alarm_devices_mtx); ++ hlist_for_each_entry_safe(alarm_dev, tmp, &alarm_devices, hlist) { ++ if (MINOR(alarm_dev->cdev.dev) == minor) ++ break; ++ alarm_dev = NULL; ++ } ++ mutex_unlock(&alarm_devices_mtx); ++ ++ file->private_data = alarm_dev; ++ ++ return 0; ++} ++ ++static void devalarm_cancel(struct devalarm *alrm) ++{ ++ if (is_wakeup(alrm->type)) ++ alarm_cancel(&alrm->u.alrm); ++ else ++ hrtimer_cancel(&alrm->u.hrt); ++} ++ ++static int alarm_release(struct inode *inode, struct file *file) ++{ ++ int i; ++ unsigned long flags; ++ struct alarm_device* alarm_dev = NULL; ++ struct alarm_context* context = NULL; ++ alarm_dev = file->private_data; ++ ++ if (alarm_dev) { ++ context = &alarm_dev->context; ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { ++ uint32_t alarm_type_mask = 1U << i; ++ if (context->alarm_enabled & alarm_type_mask) { ++ alarm_dbg(INFO, ++ "%s: clear alarm, pending %d\n", ++ __func__, ++ !!(context->alarm_pending & alarm_type_mask)); ++ context->alarm_enabled &= ~alarm_type_mask; ++ } ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++ devalarm_cancel(&context->alarms[i]); ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ } ++ if (context->alarm_pending | context->wait_pending) { ++ if (context->alarm_pending) ++ alarm_dbg(INFO, "%s: clear pending alarms %x\n", ++ __func__, context->alarm_pending); ++ __pm_relax(context->alarm_wake_lock); ++ context->wait_pending = 0; ++ context->alarm_pending = 0; ++ } ++ context->alarm_opened = 0; ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++ } ++ return 0; ++} ++ ++static const struct file_operations alarm_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = alarm_ioctl, ++ .open = alarm_open, ++ .release = alarm_release, ++}; ++ ++static void alarm_device_release(struct device *dev) ++{ ++} ++ ++static void devalarm_triggered(struct devalarm *alarm) ++{ ++ unsigned long flags; ++ uint32_t alarm_type_mask = 1U << alarm->type; ++ struct alarm_context* context = alarm->context; ++ ++ alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type); ++ spin_lock_irqsave(&context->alarm_slock, flags); ++ if (context->alarm_enabled & alarm_type_mask) { ++ __pm_wakeup_event(context->alarm_wake_lock, 5000); /* 5secs */ ++ context->alarm_enabled &= ~alarm_type_mask; ++ context->alarm_pending |= alarm_type_mask; ++ wake_up(&context->alarm_wait_queue); ++ } ++ spin_unlock_irqrestore(&context->alarm_slock, flags); ++} ++ ++static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) ++{ ++ struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); ++ ++ devalarm_triggered(devalrm); ++ return HRTIMER_NORESTART; ++} ++ ++static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm, ++ ktime_t now) ++{ ++ struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm); ++ ++ devalarm_triggered(devalrm); ++ return ALARMTIMER_NORESTART; ++} ++ ++static int __init init_alarm_device(int idx) ++{ ++ int ret; ++ int i; ++ char *name; ++ dev_t devnr; ++ struct alarm_device *alarm_device; ++ /* strlen("binder") ++ * + ++ * maximum length of 64 bit int as string ++ */ ++ char numstr[6 + 21] = "alarm"; ++ ++ alarm_device = kzalloc(sizeof(*alarm_device), GFP_KERNEL); ++ if (!alarm_device) ++ return -ENOMEM; ++ ++ cdev_init(&alarm_device->cdev, &alarm_fops); ++ alarm_device->cdev.owner = THIS_MODULE; ++ ++ devnr = MKDEV(ALARM_DKMS_MAJOR, idx); ++ ret = cdev_add(&alarm_device->cdev, devnr, 1); ++ if (ret) { ++ kfree(alarm_device); ++ return ret; ++ } ++ ++ if (alarm_devices_param > 1) ++ ret = snprintf(numstr, sizeof(numstr), "alarm%d", idx); ++ if (ret < 0 || (size_t)ret >= sizeof(numstr)) { ++ cdev_del(&alarm_device->cdev); ++ kfree(alarm_device); ++ return -EIO; ++ } ++ ++ name = kzalloc(strlen(numstr) + 1, GFP_KERNEL); ++ if (!name) { ++ cdev_del(&alarm_device->cdev); ++ kfree(alarm_device); ++ return -ENOMEM; ++ } ++ strcpy(name, numstr); ++ alarm_device->context.name = name; ++ alarm_device->context.alarm_slock = __SPIN_LOCK_UNLOCKED(alarm_slock); ++ init_waitqueue_head(&alarm_device->context.alarm_wait_queue); ++ ++ alarm_device->class_dev.devt = alarm_device->cdev.dev; ++ alarm_device->class_dev.class = alarm_class; ++ alarm_device->class_dev.release = alarm_device_release; ++ dev_set_name(&alarm_device->class_dev, "%s", name); ++ ret = device_register(&alarm_device->class_dev); ++ if (ret) { ++ cdev_del(&alarm_device->cdev); ++ kfree(alarm_device); ++ kfree(name); ++ return ret; ++ } ++ ++ for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { ++ alarm_device->context.alarms[i].context = &alarm_device->context; ++ } ++ ++ alarm_init(&alarm_device->context.alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm, ++ ALARM_REALTIME, devalarm_alarmhandler); ++ hrtimer_init(&alarm_device->context.alarms[ANDROID_ALARM_RTC].u.hrt, ++ CLOCK_REALTIME, HRTIMER_MODE_ABS); ++ alarm_init(&alarm_device->context.alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm, ++ ALARM_BOOTTIME, devalarm_alarmhandler); ++ hrtimer_init(&alarm_device->context.alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt, ++ CLOCK_BOOTTIME, HRTIMER_MODE_ABS); ++ hrtimer_init(&alarm_device->context.alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt, ++ CLOCK_MONOTONIC, HRTIMER_MODE_ABS); ++ ++ for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { ++ alarm_device->context.alarms[i].type = i; ++ if (!is_wakeup(i)) ++ alarm_device->context.alarms[i].u.hrt.function = devalarm_hrthandler; ++ } ++ ++ alarm_device->context.alarm_wake_lock = wakeup_source_create(name); ++ wakeup_source_add(alarm_device->context.alarm_wake_lock); ++ ++ mutex_lock(&alarm_devices_mtx); ++ hlist_add_head(&alarm_device->hlist, &alarm_devices); ++ mutex_unlock(&alarm_devices_mtx); ++ ++ return 0; ++} ++ ++static int __init alarm_dev_init(void) ++{ ++ int i, ret; ++ struct alarm_device *device; ++ struct hlist_node *tmp; ++ ++ ret = register_chrdev_region(MKDEV(ALARM_DKMS_MAJOR, 0), ALARM_DKMS_MAX_MINOR, "alarm"); ++ if (ret){ ++ printk("register_chrdev_region %d\n", ret); ++ return ret; ++ } ++ ++ alarm_class = class_create(THIS_MODULE, "alarm"); ++ if (IS_ERR(alarm_class)) ++ goto on_error_unregister_chrdev_region; ++ ++ for (i = 1; i <= alarm_devices_param; i++) { ++ ret = init_alarm_device(i); ++ if (ret) ++ goto err_init_device_failed; ++ } ++ ++ return ret; ++ ++err_init_device_failed: ++ mutex_lock(&alarm_devices_mtx); ++ hlist_for_each_entry_safe(device, tmp, &alarm_devices, hlist) { ++ cdev_del(&device->cdev); ++ device_unregister(&device->class_dev); ++ kfree(device->context.name); ++ hlist_del(&device->hlist); ++ kfree(device); ++ } ++ mutex_unlock(&alarm_devices_mtx); ++ class_destroy(alarm_class); ++ ++on_error_unregister_chrdev_region: ++ unregister_chrdev_region(MKDEV(ALARM_DKMS_MAJOR, 0), ++ ALARM_DKMS_MAX_MINOR); ++ ++ ++ return -1; ++} ++ ++ ++ ++static void __exit alarm_dev_exit(void) ++{ ++ struct alarm_device *device; ++ struct hlist_node *tmp; ++ ++ mutex_lock(&alarm_devices_mtx); ++ hlist_for_each_entry_safe(device, tmp, &alarm_devices, hlist) { ++ wakeup_source_remove(device->context.alarm_wake_lock); ++ wakeup_source_destroy(device->context.alarm_wake_lock); ++ cdev_del(&device->cdev); ++ device_unregister(&device->class_dev); ++ kfree(device->context.name); ++ hlist_del(&device->hlist); ++ kfree(device); ++ } ++ mutex_unlock(&alarm_devices_mtx); ++ ++ class_destroy(alarm_class); ++ ++ unregister_chrdev_region(MKDEV(ALARM_DKMS_MAJOR, 0), ++ ALARM_DKMS_MAX_MINOR); ++} ++ ++ ++ ++module_init(alarm_dev_init); ++module_exit(alarm_dev_exit); ++ ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/android/alarm/android_alarm.h b/drivers/android/alarm/android_alarm.h +new file mode 100755 +index 000000000..89a593b36 +--- /dev/null ++++ b/drivers/android/alarm/android_alarm.h +@@ -0,0 +1,126 @@ ++/* include/linux/android_alarm.h ++ * ++ * Copyright (C) 2006-2007 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LINUX_ANDROID_ALARM_H ++#define _LINUX_ANDROID_ALARM_H ++ ++#include ++#include ++ ++#ifndef _STRUCT_TIMESPEC ++#define _STRUCT_TIMESPEC ++struct timespec { ++ __kernel_old_time_t tv_sec; /* seconds */ ++ long tv_nsec; /* nanoseconds */ ++}; ++#endif ++ ++#ifndef _TIME_T ++#define _TIME_T ++typedef __kernel_long_t __kernel_time_t; ++typedef __kernel_time_t time_t; ++#endif ++ ++#if __BITS_PER_LONG == 64 ++ ++/* timespec64 is defined as timespec here */ ++static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) ++{ ++ return *(const struct timespec *)&ts64; ++} ++ ++static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) ++{ ++ return *(const struct timespec64 *)&ts; ++} ++ ++#else ++static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) ++{ ++ struct timespec ret; ++ ++ ret.tv_sec = (time_t)ts64.tv_sec; ++ ret.tv_nsec = ts64.tv_nsec; ++ return ret; ++} ++ ++static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) ++{ ++ struct timespec64 ret; ++ ++ ret.tv_sec = ts.tv_sec; ++ ret.tv_nsec = ts.tv_nsec; ++ return ret; ++} ++#endif ++ ++ ++static inline void getnstimeofday(struct timespec *ts) ++{ ++ struct timespec64 ts64; ++ ++ ktime_get_real_ts64(&ts64); ++ *ts = timespec64_to_timespec(ts64); ++} ++ ++static inline void ktime_get_ts(struct timespec *ts) ++{ ++ struct timespec64 ts64; ++ ++ ktime_get_ts64(&ts64); ++ *ts = timespec64_to_timespec(ts64); ++} ++ ++static inline void getrawmonotonic(struct timespec *ts) ++{ ++ struct timespec64 ts64; ++ ++ ktime_get_raw_ts64(&ts64); ++ *ts = timespec64_to_timespec(ts64); ++} ++ ++static inline void getboottime(struct timespec *ts) ++{ ++ struct timespec64 ts64; ++ ++ getboottime64(&ts64); ++ *ts = timespec64_to_timespec(ts64); ++} ++ ++static inline ktime_t timespec_to_ktime(struct timespec ts) ++{ ++ return ktime_set(ts.tv_sec, ts.tv_nsec); ++} ++ ++#include "uapi/android_alarm.h" ++ ++#ifdef CONFIG_COMPAT ++#define ANDROID_ALARM_SET_COMPAT(type) ALARM_IOW(2, type, \ ++ struct compat_timespec) ++#define ANDROID_ALARM_SET_AND_WAIT_COMPAT(type) ALARM_IOW(3, type, \ ++ struct compat_timespec) ++#define ANDROID_ALARM_GET_TIME_COMPAT(type) ALARM_IOW(4, type, \ ++ struct compat_timespec) ++#define ANDROID_ALARM_SET_RTC_COMPAT _IOW('a', 5, \ ++ struct compat_timespec) ++#define ANDROID_ALARM_IOCTL_NR(cmd) (_IOC_NR(cmd) & ((1<<4)-1)) ++#define ANDROID_ALARM_COMPAT_TO_NORM(cmd) \ ++ ALARM_IOW(ANDROID_ALARM_IOCTL_NR(cmd), \ ++ ANDROID_ALARM_IOCTL_TO_TYPE(cmd), \ ++ struct timespec) ++ ++#endif ++ ++#endif +diff --git a/drivers/android/alarm/deps.c b/drivers/android/alarm/deps.c +new file mode 100755 +index 000000000..abb55ded8 +--- /dev/null ++++ b/drivers/android/alarm/deps.c +@@ -0,0 +1,181 @@ ++#include ++#include ++#include ++ ++int (*alarm_cancel_ptr)(struct alarm *alarm) = NULL; ++int alarm_cancel(struct alarm *alarm) ++{ ++ if (!alarm_cancel_ptr) ++ alarm_cancel_ptr = kallsyms_lookup_name("alarm_cancel"); ++ return alarm_cancel_ptr(alarm); ++ ++} ++ ++struct rtc_device* (*alarmtimer_get_rtcdev_ptr)(void) = NULL; ++struct rtc_device *alarmtimer_get_rtcdev(void) ++{ ++ if (!alarmtimer_get_rtcdev_ptr) ++ alarmtimer_get_rtcdev_ptr = kallsyms_lookup_name("alarmtimer_get_rtcdev"); ++ return alarmtimer_get_rtcdev_ptr(); ++} ++ ++ ++void (*alarm_init_ptr)(struct alarm *alarm, enum alarmtimer_type type, ++ enum alarmtimer_restart (*function)(struct alarm *, ktime_t)) = NULL; ++ ++void alarm_init(struct alarm *alarm, enum alarmtimer_type type, ++ enum alarmtimer_restart (*function)(struct alarm *, ktime_t)) ++{ ++ if(!alarm_init_ptr) ++ alarm_init_ptr = kallsyms_lookup_name("alarm_init"); ++ alarm_init_ptr(alarm, type, function); ++} ++ ++ ++void (*alarm_start_ptr)(struct alarm *alarm, ktime_t start) = NULL; ++void alarm_start(struct alarm *alarm, ktime_t start) ++{ ++ if(!alarm_start_ptr) ++ alarm_start_ptr = kallsyms_lookup_name("alarm_start"); ++ alarm_start_ptr(alarm, start); ++} ++ ++ ++int (*alarm_try_to_cancel_ptr)(struct alarm *alarm) = NULL; ++int alarm_try_to_cancel(struct alarm *alarm) ++{ ++ if(!alarm_try_to_cancel_ptr) ++ alarm_try_to_cancel_ptr = kallsyms_lookup_name("alarm_try_to_cancel"); ++ return alarm_try_to_cancel_ptr(alarm); ++} ++ ++ ++void (*wakeup_source_remove_ptr)(struct wakeup_source *ws) = NULL; ++void wakeup_source_remove(struct wakeup_source *ws) ++{ ++ if(!wakeup_source_remove_ptr) ++ wakeup_source_remove_ptr = kallsyms_lookup_name("wakeup_source_remove"); ++ wakeup_source_remove_ptr(ws); ++} ++ ++void (*wakeup_source_drop_ptr)(struct wakeup_source *ws) = NULL; ++void wakeup_source_drop(struct wakeup_source *ws) ++{ ++ if(!wakeup_source_drop_ptr) ++ wakeup_source_drop_ptr = kallsyms_lookup_name("wakeup_source_drop"); ++ wakeup_source_drop_ptr(ws); ++} ++ ++ ++void (*ktime_get_ts64_ptr)(struct timespec64 *ts) = NULL; ++void ktime_get_ts64(struct timespec64 *ts) ++{ ++ if(!ktime_get_ts64_ptr) ++ ktime_get_ts64_ptr = kallsyms_lookup_name("ktime_get_ts64"); ++ ktime_get_ts64_ptr(ts); ++} ++ ++int (*hrtimer_try_to_cancel_ptr)(struct hrtimer *timer) = NULL; ++int hrtimer_try_to_cancel(struct hrtimer *timer) ++{ ++ if(!hrtimer_try_to_cancel_ptr) ++ hrtimer_try_to_cancel_ptr = kallsyms_lookup_name("hrtimer_try_to_cancel"); ++ return hrtimer_try_to_cancel_ptr(timer); ++ ++} ++ ++void (*hrtimer_init_ptr)(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode) = NULL; ++void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode) ++{ ++ if(!hrtimer_init_ptr) ++ hrtimer_init_ptr = kallsyms_lookup_name("hrtimer_init"); ++ hrtimer_init_ptr(timer, clock_id, mode); ++} ++ ++void (*hrtimer_start_range_ns_ptr)(struct hrtimer *timer, ktime_t tim, u64 range_ns, const enum hrtimer_mode mode) = NULL; ++void hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, u64 range_ns, const enum hrtimer_mode mode) ++{ ++ if(!hrtimer_start_range_ns_ptr) ++ hrtimer_start_range_ns_ptr = kallsyms_lookup_name("hrtimer_start_range_ns"); ++ hrtimer_start_range_ns_ptr(timer, tim, range_ns, mode); ++} ++ ++void (*wakeup_source_prepare_ptr)(struct wakeup_source *ws, const char *name) = NULL; ++void wakeup_source_prepare(struct wakeup_source *ws, const char *name) ++{ ++ if(!wakeup_source_prepare_ptr) ++ wakeup_source_prepare_ptr = kallsyms_lookup_name("wakeup_source_prepare"); ++ wakeup_source_prepare_ptr(ws, name); ++ ++} ++ ++ ++void (*wakeup_source_add_ptr)(struct wakeup_source *ws) = NULL; ++void wakeup_source_add(struct wakeup_source *ws) ++{ ++ if(!wakeup_source_add_ptr) ++ wakeup_source_add_ptr = kallsyms_lookup_name("wakeup_source_add"); ++ wakeup_source_add_ptr(ws); ++ ++} ++ ++int (*hrtimer_cancel_ptr)(struct hrtimer *timer) = NULL; ++int hrtimer_cancel(struct hrtimer *timer) ++{ ++ if(!hrtimer_cancel_ptr) ++ hrtimer_cancel_ptr = kallsyms_lookup_name("hrtimer_cancel"); ++ return hrtimer_cancel_ptr(timer); ++} ++ ++int (*compat_put_timespec_ptr)(const struct timespec *ts, void __user *uts) = NULL; ++int compat_put_timespec(const struct timespec *ts, void __user *uts) ++{ ++ if(!compat_put_timespec_ptr) ++ compat_put_timespec_ptr = kallsyms_lookup_name("compat_put_timespec"); ++ return compat_put_timespec_ptr(ts, uts); ++ ++} ++ ++int (*compat_get_timespec_ptr)(struct timespec *ts, const void __user *uts) = NULL; ++int compat_get_timespec(struct timespec *ts, const void __user *uts) ++{ ++ if(!compat_get_timespec_ptr) ++ compat_get_timespec_ptr = kallsyms_lookup_name("compat_get_timespec"); ++ return compat_get_timespec_ptr(ts, uts); ++} ++ ++ ++int (*rtc_set_time_ptr)(struct rtc_device *rtc, struct rtc_time *tm) = NULL; ++int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) ++{ ++ if(!rtc_set_time_ptr) ++ rtc_set_time_ptr = kallsyms_lookup_name("rtc_set_time"); ++ return rtc_set_time_ptr(rtc, tm); ++} ++ ++ktime_t (*ktime_get_with_offset_ptr)(enum tk_offsets offs); ++ktime_t ktime_get_with_offset(enum tk_offsets offs) ++{ ++ if(!ktime_get_with_offset_ptr) ++ ktime_get_with_offset_ptr = kallsyms_lookup_name("ktime_get_with_offset"); ++ return ktime_get_with_offset_ptr(offs); ++ ++} ++ ++void (*__pm_relax_ptr)(struct wakeup_source *ws) = NULL; ++void __pm_relax(struct wakeup_source *ws) ++{ ++ if(!__pm_relax_ptr) ++ __pm_relax_ptr = kallsyms_lookup_name("__pm_relax"); ++ __pm_relax_ptr(ws); ++} ++ ++void (*pm_wakeup_ws_event_ptr)(struct wakeup_source *ws, unsigned int msec, bool hard) = NULL; ++void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard) ++{ ++ if(!pm_wakeup_ws_event_ptr) ++ pm_wakeup_ws_event_ptr = kallsyms_lookup_name("pm_wakeup_ws_event"); ++ pm_wakeup_ws_event_ptr(ws, msec, hard); ++ ++} ++ +diff --git a/drivers/android/alarm/dkms.conf b/drivers/android/alarm/dkms.conf +new file mode 100755 +index 000000000..a48358be4 +--- /dev/null ++++ b/drivers/android/alarm/dkms.conf +@@ -0,0 +1,7 @@ ++PACKAGE_NAME="anbox-alarm" ++PACKAGE_VERSION="1" ++CLEAN="make clean" ++MAKE[0]="make all KERNEL_SRC=/lib/modules/$kernelver/build" ++BUILT_MODULE_NAME[0]="alarm_linux" ++DEST_MODULE_LOCATION[0]="/updates" ++AUTOINSTALL="yes" +diff --git a/drivers/android/alarm/uapi/android_alarm.h b/drivers/android/alarm/uapi/android_alarm.h +new file mode 100755 +index 000000000..aa013f6f5 +--- /dev/null ++++ b/drivers/android/alarm/uapi/android_alarm.h +@@ -0,0 +1,62 @@ ++/* drivers/staging/android/uapi/android_alarm.h ++ * ++ * Copyright (C) 2006-2007 Google, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _UAPI_LINUX_ANDROID_ALARM_H ++#define _UAPI_LINUX_ANDROID_ALARM_H ++ ++#include ++#include ++ ++enum android_alarm_type { ++ /* return code bit numbers or set alarm arg */ ++ ANDROID_ALARM_RTC_WAKEUP, ++ ANDROID_ALARM_RTC, ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ++ ANDROID_ALARM_ELAPSED_REALTIME, ++ ANDROID_ALARM_SYSTEMTIME, ++ ++ ANDROID_ALARM_TYPE_COUNT, ++ ++ /* return code bit numbers */ ++ /* ANDROID_ALARM_TIME_CHANGE = 16 */ ++}; ++ ++enum android_alarm_return_flags { ++ ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP, ++ ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC, ++ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = ++ 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ++ ANDROID_ALARM_ELAPSED_REALTIME_MASK = ++ 1U << ANDROID_ALARM_ELAPSED_REALTIME, ++ ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME, ++ ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16 ++}; ++ ++/* Disable alarm */ ++#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4)) ++ ++/* Ack last alarm and wait for next */ ++#define ANDROID_ALARM_WAIT _IO('a', 1) ++ ++#define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) ++/* Set alarm */ ++#define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) ++#define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) ++#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) ++#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) ++#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) ++#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) ++ ++#endif +-- +2.25.1 +