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); }
static void process_cb_request(void *buffer) { struct rtc_cb_recv *rtc_cb = buffer; 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); printk(KERN_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); /* Do an update of xtime */ rtc_hctosys(); } else pr_err("%s: Unknown event EVENT=%x\n", __func__, rtc_cb->event); }
static int handle_rpc_call(struct msm_rpc_server *server, struct rpc_request_hdr *req, unsigned len) { 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); rtc_hctosys(); return 0; } case RPC_TIME_GET_APPS_USER_TIME: return read_rtc0_time(server, req, len); default: return -ENODEV; } }
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; } }
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 int __devinit msmrtc_probe(struct platform_device *pdev) { int rc; struct msm_rtc *rtc_pdata = NULL; struct rpcsvr_platform_device *rdev = container_of(pdev, struct rpcsvr_platform_device, base); uint32_t prog_version; if (pdev->id == (TIMEREMOTE_PROG_VER_1 & RPC_VERSION_MAJOR_MASK)) prog_version = TIMEREMOTE_PROG_VER_1; else if (pdev->id == (TIMEREMOTE_PROG_VER_2 & RPC_VERSION_MAJOR_MASK)) prog_version = TIMEREMOTE_PROG_VER_2; else return -EINVAL; rtc_pdata = kzalloc(sizeof(*rtc_pdata), GFP_KERNEL); if (rtc_pdata == NULL) { dev_err(&pdev->dev, "%s: Unable to allocate memory\n", __func__); return -ENOMEM; } rtc_pdata->rpc_client = msm_rpc_register_client("rtc", rdev->prog, prog_version, 1, msmrtc_cb_func); if (IS_ERR(rtc_pdata->rpc_client)) { dev_err(&pdev->dev, "%s: init RPC failed! VERS = %x\n", __func__, prog_version); rc = PTR_ERR(rtc_pdata->rpc_client); kfree(rtc_pdata); return rc; } /*< DTS2011052803245 wangjiongfeng 20110531 begin */ huawei_alarm_client = rtc_pdata->rpc_client; /* DTS2011052803245 wangjiongfeng 20110531 end >*/ /* * Set up the callback client. * For older targets this initialization will fail */ rc = msmrtc_setup_cb(rtc_pdata); if (rc) dev_dbg(&pdev->dev, "%s: Could not initialize RPC callback\n", __func__); rtc_pdata->rtcalarm_time = 0; platform_set_drvdata(pdev, rtc_pdata); rtc_pdata->rtc = rtc_device_register("msm_rtc", &pdev->dev, &msm_rtc_ops, THIS_MODULE); if (IS_ERR(rtc_pdata->rtc)) { dev_err(&pdev->dev, "%s: Can't register RTC device (%ld)\n", pdev->name, PTR_ERR(rtc_pdata->rtc)); rc = PTR_ERR(rtc_pdata->rtc); goto fail_cb_setup; } #ifdef CONFIG_RTC_SECURE_TIME_SUPPORT rtc_pdata->rtcsecure = rtc_device_register("msm_rtc_secure", &pdev->dev, &msm_rtc_ops_secure, THIS_MODULE); if (IS_ERR(rtc_pdata->rtcsecure)) { dev_err(&pdev->dev, "%s: Can't register RTC Secure device (%ld)\n", pdev->name, PTR_ERR(rtc_pdata->rtcsecure)); rtc_device_unregister(rtc_pdata->rtc); rc = PTR_ERR(rtc_pdata->rtcsecure); goto fail_cb_setup; } #endif #ifdef CONFIG_RTC_ASYNC_MODEM_SUPPORT rtc_hctosys(); #endif return 0; fail_cb_setup: msm_rpc_unregister_client(rtc_pdata->rpc_client); kfree(rtc_pdata); return rc; }
static int msmrtc_probe(struct platform_device *pdev) { int rc; struct rpcsvr_platform_device *rdev = container_of(pdev, struct rpcsvr_platform_device, base); uint32_t prog_version; if (pdev->id == (TIMEREMOTE_PROG_VER_1 & RPC_VERSION_MAJOR_MASK)) prog_version = TIMEREMOTE_PROG_VER_1; else if (pdev->id == (TIMEREMOTE_PROG_VER_2 & RPC_VERSION_MAJOR_MASK)) prog_version = TIMEREMOTE_PROG_VER_2; else return -EINVAL; rpc_client = msm_rpc_register_client("rtc", rdev->prog, prog_version, 1, msmrtc_cb_func); if (IS_ERR(rpc_client)) { pr_err("%s: init RPC failed! VERS = %x\n", __func__, prog_version); return PTR_ERR(rpc_client); } /* * Set up the callback client. * For older targets this initialization will fail */ rc = msmrtc_setup_cb(); if (rc) pr_debug("%s: Could not initialize RPC callback\n", __func__); rtc = rtc_device_register("msm_rtc", &pdev->dev, &msm_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { pr_err("%s: Can't register RTC device (%ld)\n", pdev->name, PTR_ERR(rtc)); rc = PTR_ERR(rtc); goto fail_cb_setup; } #ifdef CONFIG_RTC_SECURE_TIME_SUPPORT rtcsecure = rtc_device_register("msm_rtc_secure", &pdev->dev, &msm_rtc_ops_secure, THIS_MODULE); if (IS_ERR(rtcsecure)) { pr_err("%s: Can't register RTC Secure device (%ld)\n", pdev->name, PTR_ERR(rtcsecure)); rtc_device_unregister(rtc); rc = PTR_ERR(rtcsecure); goto fail_cb_setup; } #endif #ifdef CONFIG_RTC_ASYNC_MODEM_SUPPORT rtc_hctosys(); #endif return 0; fail_cb_setup: msm_rpc_unregister_client(rpc_client); return rc; }
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); }
static int __devinit msmrtc_probe(struct platform_device *pdev) { int rc; struct msm_rtc *rtc_pdata = NULL; struct rpcsvr_platform_device *rdev = container_of(pdev, struct rpcsvr_platform_device, base); uint32_t prog_version; #if defined(CONFIG_MACH_ACER_A4) || defined(CONFIG_MACH_ACER_A5) struct rtc_time tm; #endif if (pdev->id == (TIMEREMOTE_PROG_VER_1 & RPC_VERSION_MAJOR_MASK)) prog_version = TIMEREMOTE_PROG_VER_1; else if (pdev->id == (TIMEREMOTE_PROG_VER_2 & RPC_VERSION_MAJOR_MASK)) prog_version = TIMEREMOTE_PROG_VER_2; else return -EINVAL; rtc_pdata = kzalloc(sizeof(*rtc_pdata), GFP_KERNEL); if (rtc_pdata == NULL) { dev_err(&pdev->dev, "%s: Unable to allocate memory\n", __func__); return -ENOMEM; } rtc_pdata->rpc_client = msm_rpc_register_client("rtc", rdev->prog, prog_version, 1, msmrtc_cb_func); if (IS_ERR(rtc_pdata->rpc_client)) { dev_err(&pdev->dev, "%s: init RPC failed! VERS = %x\n", __func__, prog_version); rc = PTR_ERR(rtc_pdata->rpc_client); kfree(rtc_pdata); return rc; } /* * Set up the callback client. * For older targets this initialization will fail */ rc = msmrtc_setup_cb(rtc_pdata); if (rc) dev_dbg(&pdev->dev, "%s: Could not initialize RPC callback\n", __func__); rtc_pdata->rtcalarm_time = 0; platform_set_drvdata(pdev, rtc_pdata); #if defined(CONFIG_MACH_ACER_A4) || defined(CONFIG_MACH_ACER_A5) /* Set the default system time to 2011-03-01 00:00:00 UTC. */ msmrtc_timeremote_read_time(&pdev->dev, &tm); if (tm.tm_year < 90) { tm.tm_year = 111; /* RTC layer expects years to start at 1900 */ tm.tm_mon = 2; /* RTC layer expects mons to be 0 based */ tm.tm_mday = 1; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_wday = 1; /* 2011-03-01 is Tuesday */ msmrtc_timeremote_set_time(&pdev->dev, &tm); } #endif rtc_pdata->rtc = rtc_device_register("msm_rtc", &pdev->dev, &msm_rtc_ops, THIS_MODULE); if (IS_ERR(rtc_pdata->rtc)) { dev_err(&pdev->dev, "%s: Can't register RTC device (%ld)\n", pdev->name, PTR_ERR(rtc_pdata->rtc)); rc = PTR_ERR(rtc_pdata->rtc); goto fail_cb_setup; } #ifdef CONFIG_RTC_SECURE_TIME_SUPPORT rtc_pdata->rtcsecure = rtc_device_register("msm_rtc_secure", &pdev->dev, &msm_rtc_ops_secure, THIS_MODULE); if (IS_ERR(rtc_pdata->rtcsecure)) { dev_err(&pdev->dev, "%s: Can't register RTC Secure device (%ld)\n", pdev->name, PTR_ERR(rtc_pdata->rtcsecure)); rtc_device_unregister(rtc_pdata->rtc); rc = PTR_ERR(rtc_pdata->rtcsecure); goto fail_cb_setup; } #endif #ifdef CONFIG_RTC_ASYNC_MODEM_SUPPORT rtc_hctosys(); #endif return 0; fail_cb_setup: msm_rpc_unregister_client(rtc_pdata->rpc_client); kfree(rtc_pdata); return rc; }