123 lines
2.9 KiB
C
123 lines
2.9 KiB
C
|
/*
|
||
|
* /drivers/rtc/power-on-alarm.c
|
||
|
*
|
||
|
* Copyright (C) 2015 Samsung Electronics
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <linux/time.h>
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/device.h>
|
||
|
#include <linux/miscdevice.h>
|
||
|
#include <linux/fs.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/sched.h>
|
||
|
#include <linux/spinlock.h>
|
||
|
#include <linux/uaccess.h>
|
||
|
#include <linux/alarmtimer.h>
|
||
|
#include <linux/ioctl.h>
|
||
|
|
||
|
#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
|
||
|
#define ANDROID_ALARM_SET_ALARM_BOOT _IOW('a', 7, struct timespec)
|
||
|
#ifdef CONFIG_COMPAT
|
||
|
#define ANDROID_ALARM_SET_ALARM_BOOT_COMPAT _IOW('a', 7, \
|
||
|
struct compat_timespec)
|
||
|
#endif
|
||
|
|
||
|
static long power_on_alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||
|
{
|
||
|
int rv;
|
||
|
char bootalarm_data[14];
|
||
|
|
||
|
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||
|
case ANDROID_ALARM_SET_ALARM_BOOT:
|
||
|
if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) {
|
||
|
rv = -EFAULT;
|
||
|
printk("boot alarm param copy fail\n");
|
||
|
return rv;
|
||
|
}
|
||
|
printk("power_alarm_ioctl:%ld\n",arg);
|
||
|
rv = alarm_set_alarm_boot(bootalarm_data);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifdef CONFIG_COMPAT
|
||
|
static long power_alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||
|
{
|
||
|
int rv;
|
||
|
char bootalarm_data[14];
|
||
|
|
||
|
switch (ANDROID_ALARM_BASE_CMD(cmd)) {
|
||
|
case ANDROID_ALARM_SET_ALARM_BOOT_COMPAT:
|
||
|
if (copy_from_user(bootalarm_data, (void __user *)arg, 14)) {
|
||
|
rv = -EFAULT;
|
||
|
printk("boot alarm param copy fail\n");
|
||
|
return rv;
|
||
|
}
|
||
|
printk("power_alarm_compat_ioctl:%ld\n",arg);
|
||
|
rv = alarm_set_alarm_boot(bootalarm_data);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static int power_on_alarm_open(struct inode *inode, struct file *file)
|
||
|
{
|
||
|
file->private_data = NULL;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int power_on_alarm_release(struct inode *inode, struct file *file)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static const struct file_operations power_on_alarm_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.unlocked_ioctl = power_on_alarm_ioctl,
|
||
|
.open = power_on_alarm_open,
|
||
|
.release = power_on_alarm_release,
|
||
|
#ifdef CONFIG_COMPAT
|
||
|
.compat_ioctl = power_alarm_compat_ioctl,
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
static struct miscdevice power_on_alarm_device = {
|
||
|
.minor = MISC_DYNAMIC_MINOR,
|
||
|
.name = "power_on_alarm",
|
||
|
.fops = &power_on_alarm_fops,
|
||
|
};
|
||
|
|
||
|
static int __init power_on_alarm_dev_init(void)
|
||
|
{
|
||
|
int err;
|
||
|
|
||
|
err = misc_register(&power_on_alarm_device);
|
||
|
if (err)
|
||
|
return err;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void __exit power_on_alarm_dev_exit(void)
|
||
|
{
|
||
|
misc_deregister(&power_on_alarm_device);
|
||
|
}
|
||
|
|
||
|
module_init(power_on_alarm_dev_init);
|
||
|
module_exit(power_on_alarm_dev_exit);
|