PageRenderTime 35ms CodeModel.GetById 19ms app.highlight 14ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/arm/mach-msm/rpc_server_time_remote.c

https://bitbucket.org/sammyz/iscream_thunderc-2.6.35-rebase
C | 167 lines | 126 code | 22 blank | 19 comment | 11 complexity | 9863dfc31605e78af150661802e5761b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1/* arch/arm/mach-msm/rpc_server_time_remote.c
  2 *
  3 * Copyright (C) 2007 Google, Inc.
  4 * Copyright (c) 2009-2010 Code Aurora Forum. All rights reserved.
  5 * Author: Iliyan Malchev <ibm@android.com>
  6 *
  7 * This software is licensed under the terms of the GNU General Public
  8 * License version 2, as published by the Free Software Foundation, and
  9 * may be copied, distributed, and modified under those terms.
 10 *
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 *
 16 */
 17
 18#include <linux/module.h>
 19#include <linux/kernel.h>
 20#include <linux/err.h>
 21#include <mach/msm_rpcrouter.h>
 22#include "rpc_server_time_remote.h"
 23#include <linux/rtc.h>
 24#include <linux/android_alarm.h>
 25
 26/* time_remote_mtoa server definitions. */
 27
 28#define TIME_REMOTE_MTOA_PROG 0x3000005d
 29#define TIME_REMOTE_MTOA_VERS_OLD 0
 30#define TIME_REMOTE_MTOA_VERS 0x9202a8e4
 31#define TIME_REMOTE_MTOA_VERS_COMP 0x00010002
 32#define RPC_TIME_REMOTE_MTOA_NULL   0
 33#define RPC_TIME_TOD_SET_APPS_BASES 2
 34#define RPC_TIME_GET_APPS_USER_TIME 3
 35
 36struct rpc_time_tod_set_apps_bases_args {
 37	uint32_t tick;
 38	uint64_t stamp;
 39};
 40
 41static int read_rtc0_time(struct msm_rpc_server *server,
 42		   struct rpc_request_hdr *req,
 43		   unsigned len)
 44{
 45	int err;
 46	unsigned long tm_sec;
 47	uint32_t size = 0;
 48	void *reply;
 49	uint32_t output_valid;
 50	uint32_t rpc_status = RPC_ACCEPTSTAT_SYSTEM_ERR;
 51	struct rtc_time tm;
 52	struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
 53
 54	if (rtc == NULL) {
 55		pr_err("%s: unable to open rtc device (%s)\n",
 56			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
 57		goto send_reply;
 58	}
 59
 60	err = rtc_read_time(rtc, &tm);
 61	if (err) {
 62		pr_err("%s: Error reading rtc device (%s) : %d\n",
 63			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE, err);
 64		goto close_dev;
 65	}
 66
 67	err = rtc_valid_tm(&tm);
 68	if (err) {
 69		pr_err("%s: Invalid RTC time (%s)\n",
 70			__FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
 71		goto close_dev;
 72	}
 73
 74	rtc_tm_to_time(&tm, &tm_sec);
 75	rpc_status = RPC_ACCEPTSTAT_SUCCESS;
 76
 77close_dev:
 78	rtc_class_close(rtc);
 79
 80send_reply:
 81	reply = msm_rpc_server_start_accepted_reply(server, req->xid,
 82						    rpc_status);
 83	if (rpc_status == RPC_ACCEPTSTAT_SUCCESS) {
 84		output_valid = *((uint32_t *)(req + 1));
 85		*(uint32_t *)reply = output_valid;
 86		size = sizeof(uint32_t);
 87		if (be32_to_cpu(output_valid)) {
 88			reply += sizeof(uint32_t);
 89			*(uint32_t *)reply = cpu_to_be32(tm_sec);
 90			size += sizeof(uint32_t);
 91		}
 92	}
 93	err = msm_rpc_server_send_accepted_reply(server, size);
 94	if (err)
 95		pr_err("%s: send accepted reply failed: %d\n", __func__, err);
 96
 97	return 1;
 98}
 99
100static int handle_rpc_call(struct msm_rpc_server *server,
101			   struct rpc_request_hdr *req, unsigned len)
102{
103	struct timespec ts, tv;
104
105	switch (req->procedure) {
106	case RPC_TIME_REMOTE_MTOA_NULL:
107		return 0;
108
109	case RPC_TIME_TOD_SET_APPS_BASES: {
110		struct rpc_time_tod_set_apps_bases_args *args;
111		args = (struct rpc_time_tod_set_apps_bases_args *)(req + 1);
112		args->tick = be32_to_cpu(args->tick);
113		args->stamp = be64_to_cpu(args->stamp);
114		printk(KERN_INFO "RPC_TIME_TOD_SET_APPS_BASES:\n"
115		       "\ttick = %d\n"
116		       "\tstamp = %lld\n",
117		       args->tick, args->stamp);
118
119		getnstimeofday(&ts);
120		rtc_hctosys();
121		getnstimeofday(&tv);
122		/* Update the alarm information with the new time info. */
123		alarm_update_timedelta(ts, tv);
124		return 0;
125	}
126
127	case RPC_TIME_GET_APPS_USER_TIME:
128		return read_rtc0_time(server, req, len);
129
130	default:
131		return -ENODEV;
132	}
133}
134
135static struct msm_rpc_server rpc_server[] = {
136	{
137		.prog = TIME_REMOTE_MTOA_PROG,
138		.vers = TIME_REMOTE_MTOA_VERS_OLD,
139		.rpc_call = handle_rpc_call,
140	},
141	{
142		.prog = TIME_REMOTE_MTOA_PROG,
143		.vers = TIME_REMOTE_MTOA_VERS,
144		.rpc_call = handle_rpc_call,
145	},
146	{
147		.prog = TIME_REMOTE_MTOA_PROG,
148		.vers = TIME_REMOTE_MTOA_VERS_COMP,
149		.rpc_call = handle_rpc_call,
150	},
151};
152
153static int __init rpc_server_init(void)
154{
155	/* Dual server registration to support backwards compatibility vers */
156	int ret;
157	ret = msm_rpc_create_server(&rpc_server[2]);
158	if (ret < 0)
159		return ret;
160	ret = msm_rpc_create_server(&rpc_server[1]);
161	if (ret < 0)
162		return ret;
163	return msm_rpc_create_server(&rpc_server[0]);
164}
165
166
167module_init(rpc_server_init);