blob: 111256ccfe1246c3e931627106dcff7761ecacd1 [file] [log] [blame]
/*
* Copyright (C) 2012-2017 Samsung Electronics, 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.
*/
#include <linux/kthread.h>
#include <linux/module.h>
#include "tz_iwsock.h"
#include "tz_ree_time.h"
MODULE_AUTHOR("Konstantin Karasev");
MODULE_DESCRIPTION("REE Time service");
MODULE_LICENSE("GPL");
#define ERR(...) pr_alert("[ree_time] ERR : " __VA_ARGS__)
#define TZ_REE_TIME_SOCK_NAME "ree_time_socket"
static struct task_struct *ree_time_kthread;
static int tz_ree_time_kthread(void *data)
{
struct sock_desc *ree_time_listen;
struct sock_desc *ree_time_conn;
ssize_t len;
int req;
int ret;
struct timespec ts;
struct tz_ree_time ree_time;
(void)data;
/* Create socket */
ree_time_listen = tz_iwsock_socket(1);
if (IS_ERR(ree_time_listen))
return PTR_ERR(ree_time_listen);
ret = tz_iwsock_listen(ree_time_listen, TZ_REE_TIME_SOCK_NAME);
if (ret)
goto out;
while (!kthread_should_stop()) {
/* Accept connection */
ree_time_conn = tz_iwsock_accept(ree_time_listen);
if (IS_ERR(ree_time_conn)) {
ret = PTR_ERR(ree_time_conn);
goto out;
}
/* Process REE time requests from SWd */
while (!kthread_should_stop()) {
if ((len = tz_iwsock_read(ree_time_conn, &req,
sizeof(req), 0))
!= sizeof(req)) {
ERR("failed to fetch request, err = %zd\n", len);
break;
}
getnstimeofday(&ts);
ree_time.sec = ts.tv_sec;
ree_time.nsec = (unsigned int)ts.tv_nsec;
if ((len = tz_iwsock_write(ree_time_conn, &ree_time,
sizeof(ree_time), 0))
!= sizeof(ree_time)) {
ERR("failed to send time, err = %zd\n", len);
break;
}
}
tz_iwsock_release(ree_time_conn);
}
out:
tz_iwsock_release(ree_time_listen);
return ret;
}
static int __init tz_ree_time_init(void)
{
ree_time_kthread = kthread_run(tz_ree_time_kthread, NULL, "ree_time");
if (IS_ERR(ree_time_kthread))
return PTR_ERR(ree_time_kthread);
return 0;
}
static void __init tz_ree_time_fini(void)
{
kthread_stop(ree_time_kthread);
}
module_init(tz_ree_time_init);
module_exit(tz_ree_time_fini);