예제 #1
0
static int handle_rpc_call(struct msm_rpc_server *server,
			   struct rpc_request_hdr *req, unsigned len)
{
	struct timespec ts, tv;

	switch (req->procedure) {
	case RPC_TIME_REMOTE_MTOA_NULL:
		return 0;

	case RPC_TIME_TOD_SET_APPS_BASES: {
		struct rpc_time_tod_set_apps_bases_args *args;
		args = (struct rpc_time_tod_set_apps_bases_args *)(req + 1);
		args->tick = be32_to_cpu(args->tick);
		args->stamp = be64_to_cpu(args->stamp);
		printk(KERN_INFO "RPC_TIME_TOD_SET_APPS_BASES:\n"
		       "\ttick = %d\n"
		       "\tstamp = %lld\n",
		       args->tick, args->stamp);
		getnstimeofday(&ts);
//		msmrtc_updateatsuspend(&ts);
		rtc_hctosys();
		getnstimeofday(&tv);
		/* Update the alarm information with the new time info. */
		alarm_update_timedelta(ts, tv);
		return 0;
	}

	case RPC_TIME_GET_APPS_USER_TIME:
		return read_rtc0_time(server, req, len);

	default:
		return -ENODEV;
	}
}
static void process_cb_request(void *buffer)
{
	struct rtc_cb_recv *rtc_cb = buffer;
	struct timespec ts, tv;

	rtc_cb->client_cb_id = be32_to_cpu(rtc_cb->client_cb_id);
	rtc_cb->event = be32_to_cpu(rtc_cb->event);
	rtc_cb->cb_info_ptr = be32_to_cpu(rtc_cb->cb_info_ptr);

	if (rtc_cb->event == EVENT_TOD_CHANGE) {
		/* A TOD update has been received from the Modem */
		rtc_cb->cb_info_data.tod_update.tick =
			be32_to_cpu(rtc_cb->cb_info_data.tod_update.tick);
		rtc_cb->cb_info_data.tod_update.stamp =
			be64_to_cpu(rtc_cb->cb_info_data.tod_update.stamp);
		rtc_cb->cb_info_data.tod_update.freq =
			be32_to_cpu(rtc_cb->cb_info_data.tod_update.freq);
		pr_info("RPC CALL -- TOD TIME UPDATE: ttick = %d\n"
			"stamp=%lld, freq = %d\n",
			rtc_cb->cb_info_data.tod_update.tick,
			rtc_cb->cb_info_data.tod_update.stamp,
			rtc_cb->cb_info_data.tod_update.freq);

		getnstimeofday(&ts);
		msmrtc_updateatsuspend(&ts);
		rtc_hctosys();
		getnstimeofday(&tv);
		/* Update the alarm information with the new time info. */
		alarm_update_timedelta(ts, tv);

	} else
		pr_err("%s: Unknown event EVENT=%x\n",
					__func__, rtc_cb->event);
}
예제 #3
0
static int handle_rpc_call(struct msm_rpc_server *server,
			   struct rpc_request_hdr *req, unsigned len)
{
	struct timespec ts, tv;
	
	//20110813 [email protected] add period
	int64_t period = 0;

	switch (req->procedure) {
	case RPC_TIME_REMOTE_MTOA_NULL:
		return 0;

	case RPC_TIME_TOD_SET_APPS_BASES: {
		struct rpc_time_tod_set_apps_bases_args *args;
		args = (struct rpc_time_tod_set_apps_bases_args *)(req + 1);
		args->tick = be32_to_cpu(args->tick);
		args->stamp = be64_to_cpu(args->stamp);
		printk(KERN_INFO "RPC_TIME_TOD_SET_APPS_BASES:\n"
		       "\ttick = %d\n"
		       "\tstamp = %lld\n",
		       args->tick, args->stamp);

		getnstimeofday(&ts);
		if (msmrtc_is_suspended()) {
			//20110813 [email protected] add period [START]
			int64_t now, sleep, tick_at_suspend;

			// LGE_UPDATE_S
			//now = msm_timer_get_sclk_time(NULL);
			now = msm_timer_get_sclk_time(&period);
			// LGE_UPDATE_E
			tick_at_suspend = msmrtc_get_tickatsuspend();
			if (now && tick_at_suspend) {
				sleep = now - tick_at_suspend;
				// LGE_UPDATE_S
				if(sleep<0)
					sleep+=period;
				// LGE_UPDATE_E
				timespec_add_ns(&ts, sleep);
			} else
				pr_err("%s: Invalid ticks from SCLK"
					"now=%lld tick_at_suspend=%lld",
					__func__, now, tick_at_suspend);
			//20110813 [email protected] add period [END]

		}
		rtc_hctosys();
		getnstimeofday(&tv);
		/* Update the alarm information with the new time info. */
		alarm_update_timedelta(ts, tv);
		return 0;
	}

	case RPC_TIME_GET_APPS_USER_TIME:
		return read_rtc0_time(server, req, len);

	default:
		return -ENODEV;
	}
}
예제 #4
0
static void process_cb_request(void *buffer)
{
	struct rtc_cb_recv *rtc_cb = buffer;
	struct timespec ts, tv;

	rtc_cb->client_cb_id = be32_to_cpu(rtc_cb->client_cb_id);
	rtc_cb->event = be32_to_cpu(rtc_cb->event);
	rtc_cb->cb_info_ptr = be32_to_cpu(rtc_cb->cb_info_ptr);

	if (rtc_cb->event == EVENT_TOD_CHANGE) {
		/* A TOD update has been received from the Modem */
		rtc_cb->cb_info_data.tod_update.tick =
			be32_to_cpu(rtc_cb->cb_info_data.tod_update.tick);
		rtc_cb->cb_info_data.tod_update.stamp =
			be64_to_cpu(rtc_cb->cb_info_data.tod_update.stamp);
		rtc_cb->cb_info_data.tod_update.freq =
			be32_to_cpu(rtc_cb->cb_info_data.tod_update.freq);
		pr_info("RPC CALL -- TOD TIME UPDATE: ttick = %d\n"
			"stamp=%lld, freq = %d\n",
			rtc_cb->cb_info_data.tod_update.tick,
			rtc_cb->cb_info_data.tod_update.stamp,
			rtc_cb->cb_info_data.tod_update.freq);

		getnstimeofday(&ts);
		if (atomic_read(&suspend_state.state)) {
			int64_t now, sleep, sclk_max;
			now = msm_timer_get_sclk_time(&sclk_max);

			if (now && suspend_state.tick_at_suspend) {
				if (now < suspend_state.tick_at_suspend) {
					sleep = sclk_max -
						suspend_state.tick_at_suspend
						+ now;
				} else {
					sleep = now -
						suspend_state.tick_at_suspend;
				}

				timespec_add_ns(&ts, sleep);
				suspend_state.tick_at_suspend = now;
			} else
				pr_err("%s: Invalid ticks from SCLK"
					"now=%lld tick_at_suspend=%lld",
					__func__, now,
					suspend_state.tick_at_suspend);
		}
		rtc_hctosys();
		getnstimeofday(&tv);
		/* Update the alarm information with the new time info. */
		alarm_update_timedelta(ts, tv);

	} else
		pr_err("%s: Unknown event EVENT=%x\n",
					__func__, rtc_cb->event);
}
static void process_cb_request(void *buffer)
{
	struct rtc_cb_recv *rtc_cb = buffer;
	struct timespec ts, tv;

	rtc_cb->client_cb_id = be32_to_cpu(rtc_cb->client_cb_id);
	rtc_cb->event = be32_to_cpu(rtc_cb->event);
	rtc_cb->cb_info_ptr = be32_to_cpu(rtc_cb->cb_info_ptr);

	if (rtc_cb->event == EVENT_TOD_CHANGE) {
		/* A TOD update has been received from the Modem */
		rtc_cb->cb_info_data.tod_update.tick =
			be32_to_cpu(rtc_cb->cb_info_data.tod_update.tick);
		rtc_cb->cb_info_data.tod_update.stamp =
			be64_to_cpu(rtc_cb->cb_info_data.tod_update.stamp);
		rtc_cb->cb_info_data.tod_update.freq =
			be32_to_cpu(rtc_cb->cb_info_data.tod_update.freq);
		pr_info("RPC CALL -- TOD TIME UPDATE: ttick = %d\n"
			"stamp=%lld, freq = %d\n",
			rtc_cb->cb_info_data.tod_update.tick,
			rtc_cb->cb_info_data.tod_update.stamp,
			rtc_cb->cb_info_data.tod_update.freq);

		getnstimeofday(&ts);

/* CR 291540 - Function/Feature Failure (Partial)
 * system uptime gets corrupted with overflow in slow clock.
 * 
 * Problem description
 * During power collapse, APPS sleep time is calculated using slow clock
 * ticks. The calculation of sleep time does not considers slow clock
 * overflow and thus If slow clock overflows during suspend state then we
 * get wrong sleep time and thus system uptime values gets corrupted.
 * earlier sleep time was calculates as follows:
 * sleep = current_sclk_tick - suspend_state_sclk_tick
 * 
 * Failure frequency: Occasionally
 * Scenario frequency: Uncommon
 * Change description
 * Modified the sleep time calculation to include slow clock overflow as follows:
 * Now sleep time is calculated as:
 * sleep = Maximum_sclk_tick_val - suspend_state_sclk_tick + current_sclk_tick.
 * Files affected
 * kernel/drivers/rtc/rtc-msm.c
 * kernel/arch/arm/mach-msm/rpc_server_time_remote.c
*/	
		if (atomic_read(&suspend_state.state)) {
#if 1 //QCT SBA 404016
			int64_t now, sleep, sclk_max;
			now = msm_timer_get_sclk_time(&sclk_max);
#else
			int64_t now, sleep;
			now = msm_timer_get_sclk_time(NULL);
#endif
			if (now && suspend_state.tick_at_suspend) {
#if 1 //QCT SBA 404016
				if (now < suspend_state.tick_at_suspend) {
					sleep = sclk_max -
							suspend_state.tick_at_suspend
							+ now;
				} else {
					sleep = now -
							suspend_state.tick_at_suspend;
				}
#else
				sleep = now -
					suspend_state.tick_at_suspend;
#endif
				timespec_add_ns(&ts, sleep);
/* CR 293735 - Function/Feature Failure (Partial)
 * When system was in suspend, could make invalid "elapsed system time" at AP side.
 * 
 * Problem description
 * When system is in suspend mode and if more than one network time update
 * comes while system is in suspend mode then the uptime gets corrupted.
 * 
 * Failure frequency: Occasionally
 * Scenario frequency: Uncommon
 * Change description
 * Added change to modify tick_at_suspend (variable that stores time tick
 * while entering suspend) after each update to the current time tick.
 * Setting the suspend mode variable in case alarm time expires the current
 * RTC time as in thic case also system enters suspend mode.
 * to sdcc irq handlers returning IRQ_NONE without handling the interrupt.
 * When interrupt is disabled the communication between the SDIO client and
 * SDCC host controller is stopped while a pending command is in progress
 * and hence WLAN operation is stuck forever and LOGP recovery cannot be
 * processed.
 * Files affected
 * arch/arm/mach-msm/rpc_server_time_remote.c
 * drivers/rtc/rtc-msm.c
 * include/linux/rtc-msm.h
 */
#if 1 //QCT SBA 404017
				suspend_state.tick_at_suspend = now;
#endif
			} else
				pr_err("%s: Invalid ticks from SCLK"
					"now=%lld tick_at_suspend=%lld",
					__func__, now,
					suspend_state.tick_at_suspend);
		}
		rtc_hctosys();
		getnstimeofday(&tv);
		/* Update the alarm information with the new time info. */
		alarm_update_timedelta(ts, tv);

	} else
		pr_err("%s: Unknown event EVENT=%x\n",
					__func__, rtc_cb->event);
}