STATIC ssize_t gnss_lowpower_state_store(struct device *dev, struct kobj_attribute *attr, const char *buf, size_t count) { int flag = 0; struct pm_drv_data *pm_data = NULL; PS_PRINT_DBG("gnss_lowpower_state_store!\n"); if (NULL == buf) { PS_PRINT_ERR("buf is NULL\n"); return -FAILURE; } pm_data = pm_get_drvdata(); if (NULL == pm_data) { PS_PRINT_ERR("pm_data is NULL!\n"); return -FAILURE; } flag = simple_strtol(buf, NULL, 10); /*gnss write the flag to request sleep*/ if (1 == flag) { if (BFGX_PM_DISABLE == pm_data->bfgx_lowpower_enable) { PS_PRINT_WARNING("gnss low power disabled!\n"); return -FAILURE; } if (BFGX_SLEEP == pm_data->ps_pm_interface->bfgx_dev_state_get()) { PS_PRINT_WARNING("gnss proc: dev has been sleep, not allow dev slp\n"); return -FAILURE; } /*if bt and fm are both shutdown ,we will pull down gpio directly*/ PS_PRINT_DBG("flag = 1!\n"); if (!timer_pending(&pm_data->bfg_timer)) { PS_PRINT_SUC("gnss low power request sleep!\n"); host_allow_bfg_sleep(pm_data->ps_pm_interface->ps_core_data); } /*set the flag to 1 means gnss request sleep*/ atomic_set(&pm_data->gnss_sleep_flag, GNSS_AGREE_SLEEP); } else { PS_PRINT_ERR("invalid gnss lowpower data!\n"); return -FAILURE; } return count; }
/** * Prototype : open_tty_drv * Description : called from PS Core when BT protocol stack drivers * registration,or FM/GNSS hal stack open FM/GNSS inode * input : ps_plat_d * output : return 0--> open tty uart is ok * return !0-> open tty uart is false * Calls : * Called By : * * History : * 1.Date : 2012/11/05 * Author : wx144390 * Modification : Created function * */ int32 open_tty_drv(void *pm_data) { struct ps_plat_s *ps_plat_d = NULL; struct ps_core_s *ps_core_d; uint8 retry = OPEN_TTY_RETRY_COUNT; uint64 timeleft = 0; PS_PRINT_DBG("%s\n", __func__); if (unlikely(NULL == pm_data)) { PS_PRINT_ERR("pm_data is NULL\n"); return -EINVAL; } ps_plat_d = (struct ps_plat_s *)pm_data; ps_core_d = ps_plat_d->core_data; if (true == ps_core_d->tty_have_open) { PS_PRINT_DBG("hisi bfgx line discipline have installed\n"); return 0; } reset_uart_rx_buf(); do { INIT_COMPLETION(ps_plat_d->ldisc_installed); ps_plat_d->ldisc_install = TTY_LDISC_INSTALL; PS_PRINT_INFO("ldisc_install = %d\n", TTY_LDISC_INSTALL); sysfs_notify(g_sysfs_hi110x_bfgx, NULL, "install"); ps_uart_state_pre(ps_core_d->tty); timeleft = wait_for_completion_timeout(&ps_plat_d->ldisc_installed, msecs_to_jiffies(HISI_LDISC_TIME)); if (!timeleft) { ps_uart_state_dump(ps_core_d->tty); PS_PRINT_ERR("hisi bfgx ldisc installation timeout\n"); PS_BUG_ON(1); continue; } else { PS_PRINT_SUC("hisi bfgx line discipline install succ\n"); ps_core_d->tty_have_open = true; return 0; } } while (retry--); return -EPERM; }
/** * Prototype : ps_change_uart_baud_rate * Description : change arm platform uart baud rate to secend * baud rate for high baud rate when download patch * input : ps_core_d * output : no * Calls : * Called By : * * History : * 1.Date : 2012/11/05 * Author : wx144390 * Modification : Created function * */ int32 ps_change_uart_baud_rate(int64 baud_rate, uint8 enable_flowctl) { struct ps_plat_s *ps_plat_d = NULL; struct ps_core_s *ps_core_d; uint64 timeleft = 0; PS_PRINT_INFO("%s\n", __func__); ps_get_plat_reference(&ps_plat_d); if (unlikely(NULL == ps_plat_d)) { PS_PRINT_ERR("ps_plat_d is NULL\n"); return -EINVAL; } ps_core_d = ps_plat_d->core_data; if (likely(NULL != ps_core_d->tty)) { tty_ldisc_flush(ps_core_d->tty); tty_driver_flush_buffer(ps_core_d->tty); } if (!IS_ERR_OR_NULL(ps_core_d->tty)) { if (tty_chars_in_buffer(ps_core_d->tty)) { PS_PRINT_INFO("uart tx buf is not empty\n"); } } INIT_COMPLETION(ps_plat_d->ldisc_reconfiged); ps_plat_d->flow_cntrl = enable_flowctl; ps_plat_d->baud_rate = baud_rate; ps_plat_d->ldisc_install = TTY_LDISC_RECONFIG; PS_PRINT_INFO("ldisc_install = %d\n", TTY_LDISC_RECONFIG); sysfs_notify(g_sysfs_hi110x_bfgx, NULL, "install"); timeleft = wait_for_completion_timeout(&ps_plat_d->ldisc_reconfiged, msecs_to_jiffies(HISI_LDISC_TIME)); if (!timeleft) { PS_PRINT_ERR("hisi bfgx ldisc reconfig timeout\n"); CHR_EXCEPTION(CHR_GNSS_DRV(CHR_GNSS_DRV_EVENT_PLAT, CHR_PLAT_DRV_ERROR_CFG_UART)); return -EINVAL; } PS_PRINT_SUC("hisi bfgx ldisc reconfig succ\n"); return 0; }
/** * Prototype : release_tty_drv * Description : called from PS Core when BT protocol stack drivers * unregistration,or FM/GNSS hal stack close FM/GNSS inode * input : ps_plat_d * output : return 0--> open tty uart is ok * return !0-> open tty uart is false * Calls : * Called By : * * History : * 1.Date : 2012/11/05 * Author : wx144390 * Modification : Created function * */ int32 release_tty_drv(void *pm_data) { int32 error; struct ps_plat_s *ps_plat_d = NULL; struct tty_struct *tty = NULL; struct ps_core_s *ps_core_d; uint64 timeleft = 0; uint8 delay_times = RELEASE_DELAT_TIMES; PS_PRINT_INFO("%s\n", __func__); if (unlikely(NULL == pm_data)) { PS_PRINT_ERR("pm_data is NULL"); return -EINVAL; } ps_plat_d = (struct ps_plat_s *)pm_data; ps_core_d = ps_plat_d->core_data; tty = ps_core_d->tty; if (false == ps_core_d->tty_have_open) { PS_PRINT_INFO("hisi bfgx line discipline have uninstalled, ignored\n"); return 0; } /* clean all tx sk_buff */ while(((ps_core_d->tx_high_seq.qlen)||(ps_core_d->tx_low_seq.qlen))&&(delay_times)) { msleep(100); delay_times --; } msleep(200); if (tty) { /* can be called before ldisc is installed */ /* Flush any pending characters in the driver and discipline. */ PS_PRINT_INFO(" %s--> into flush_buffer\n", __func__); tty_ldisc_flush(tty); tty_driver_flush_buffer(tty); } INIT_COMPLETION(ps_plat_d->ldisc_uninstalled); ps_plat_d->ldisc_install = TTY_LDISC_UNINSTALL; PS_PRINT_INFO("ldisc_install = %d\n", TTY_LDISC_UNINSTALL); sysfs_notify(g_sysfs_hi110x_bfgx, NULL, "install"); ps_uart_state_pre(ps_core_d->tty); timeleft = wait_for_completion_timeout(&ps_plat_d->ldisc_uninstalled, msecs_to_jiffies(HISI_LDISC_TIME)); if (!timeleft) { ps_uart_state_dump(ps_core_d->tty); PS_PRINT_ERR("hisi bfgx ldisc uninstall timeout\n"); error = -ETIMEDOUT; } else { PS_PRINT_SUC("hisi bfgx line discipline uninstall succ\n"); error = 0; } ps_core_d->tty_have_open = false; ps_plat_d->flow_cntrl = FLOW_CTRL_ENABLE; ps_plat_d->baud_rate = DEFAULT_BAUD_RATE; return error; }