Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/um/drivers/rtc_user.c
26486 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Copyright (C) 2020 Intel Corporation
4
* Author: Johannes Berg <[email protected]>
5
*/
6
#include <stdbool.h>
7
#include <os.h>
8
#include <errno.h>
9
#include <sched.h>
10
#include <unistd.h>
11
#include <kern_util.h>
12
#include <sys/select.h>
13
#include <stdio.h>
14
#include <sys/timerfd.h>
15
#include "rtc.h"
16
17
static int uml_rtc_irq_fds[2];
18
19
void uml_rtc_send_timetravel_alarm(void)
20
{
21
unsigned long long c = 1;
22
23
CATCH_EINTR(write(uml_rtc_irq_fds[1], &c, sizeof(c)));
24
}
25
26
int uml_rtc_start(bool timetravel)
27
{
28
int err;
29
30
if (timetravel) {
31
err = os_pipe(uml_rtc_irq_fds, 1, 1);
32
if (err)
33
goto fail;
34
} else {
35
uml_rtc_irq_fds[0] = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
36
if (uml_rtc_irq_fds[0] < 0) {
37
err = -errno;
38
goto fail;
39
}
40
41
/* apparently timerfd won't send SIGIO, use workaround */
42
sigio_broken();
43
err = add_sigio_fd(uml_rtc_irq_fds[0]);
44
if (err < 0) {
45
close(uml_rtc_irq_fds[0]);
46
goto fail;
47
}
48
}
49
50
return uml_rtc_irq_fds[0];
51
fail:
52
uml_rtc_stop(timetravel);
53
return err;
54
}
55
56
int uml_rtc_enable_alarm(unsigned long long delta_seconds)
57
{
58
struct itimerspec it = {
59
.it_value = {
60
.tv_sec = delta_seconds,
61
},
62
};
63
64
if (timerfd_settime(uml_rtc_irq_fds[0], 0, &it, NULL))
65
return -errno;
66
return 0;
67
}
68
69
void uml_rtc_disable_alarm(void)
70
{
71
uml_rtc_enable_alarm(0);
72
}
73
74
void uml_rtc_stop(bool timetravel)
75
{
76
if (timetravel)
77
os_close_file(uml_rtc_irq_fds[1]);
78
else
79
ignore_sigio_fd(uml_rtc_irq_fds[0]);
80
os_close_file(uml_rtc_irq_fds[0]);
81
}
82
83