static ssize_t proc_bt_preproto_write(struct file *file, const char __user *buf, size_t length, loff_t *ppos) { char preproto; BT_INFO(""); if (length < 1) return -EINVAL; if (copy_from_user(&preproto, buf, 1)) return -EFAULT; if (preproto == '1') { if(bsi->uport == NULL) { BT_INFO("NULL"); bsi->uport = msm_hs_get_bt_uport(BT_PORT_NUM); } else { BT_INFO("NOT NULL"); } hsuart_power(1); } /* claim that we wrote everything */ return length; }
/** * Cleans up the module. */ static void __exit bluesleep_exit(void) { if (bsi == NULL) return; /* assert bt wake */ if (bsi->has_ext_wake == 1) gpio_set_value(bsi->ext_wake, 0); clear_bit(BT_EXT_WAKE, &flags); if (test_bit(BT_PROTO, &flags)) { if (disable_irq_wake(bsi->host_wake_irq)) BT_ERR("Couldn't disable hostwake IRQ wakeup mode"); free_irq(bsi->host_wake_irq, NULL); del_timer(&tx_timer); if (test_bit(BT_ASLEEP, &flags)) hsuart_power(1); } platform_driver_unregister(&bluesleep_driver); remove_proc_entry("btwrite", sleep_dir); remove_proc_entry("lpm", sleep_dir); remove_proc_entry("sleep", bluetooth_dir); remove_proc_entry("bluetooth", 0); }
/** * @brief@ main sleep work handling function which update the flags * and activate and deactivate UART ,check FIFO. */ static void bluesleep_sleep_work(struct work_struct *work) { if (bluesleep_can_sleep()) { /* already asleep, this is an error case */ if (test_bit(BT_ASLEEP, &flags)) { BT_INFO("already asleep"); return; } if (msm_hs_tx_empty(bsi->uport)) { BT_INFO("going to sleep..."); set_bit(BT_ASLEEP, &flags); /*Deactivating UART */ hsuart_power(0); /* UART clk is not turned off immediately. Release * wakelock after 500 ms. */ #ifdef USE_WAKELOCK wake_lock_timeout(&bsi->wake_lock, HZ / 2); #endif } else { mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); return; } } else { bluesleep_sleep_wakeup(); } }
/** * Stops the Sleep-Mode Protocol on the Host. */ static void gpiosleep_stop(void) { unsigned long irq_flags; spin_lock_irqsave(&rw_lock, irq_flags); if (!test_bit(FLAG_PROTO, &flags)) { spin_unlock_irqrestore(&rw_lock, irq_flags); return; } /* assert MTK_WAKE */ gpio_set_value(gsi->ext_wake, 0); GS_DBG("ext_wake gpio set value 0"); del_timer(&tx_timer); clear_bit(FLAG_PROTO, &flags); if (test_bit(FLAG_ASLEEP, &flags)) { clear_bit(FLAG_ASLEEP, &flags); hsuart_power(1); } atomic_inc(&open_count); spin_unlock_irqrestore(&rw_lock, irq_flags); if (disable_irq_wake(gsi->host_wake_irq)) GS_ERR("Couldn't disable hostwake IRQ wakeup mode\n"); free_irq(gsi->host_wake_irq, NULL); }
void bluesleep_sleep_wakeup(void) { unsigned ext_value=0; #ifdef WAKE_GPIO_ACTIVE_HIGH ext_value=1; #endif //WAKE_GPIO_ACTIVE_HIGH /* Start the timer */ mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (test_bit(BT_ASLEEP, &flags)) { BT_INFO("waking up..."); #ifdef USE_WAKELOCK wake_lock(&bsi->wake_lock); #endif /* Start the timer */ //mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); #ifndef BTLD_CONTROL_WAKE_GPIO gpio_set_value(bsi->ext_wake, ext_value); #endif //BTLD_CONTROL_WAKE_GPIO clear_bit(BT_ASLEEP, &flags); /*Activating UART */ hsuart_power(1); } }
void gpiosleep_sleep_wakeup(void) { if (test_bit(FLAG_ASLEEP, &flags)) { GS_DBG("waking up..."); /* Start the timer */ mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); gpio_set_value(gsi->ext_wake, 0); GS_DBG("ext_wake gpio set value 0"); clear_bit(FLAG_ASLEEP, &flags); /*Activating UART */ hsuart_power(1); } else { /*Tx idle, Rx busy, we must also make host_wake asserted, that is low * 1 means mtk chip can sleep, in gpiosleep.c */ /* Here we depend on the status of MSM gpio, for stability */ if(1 == gpio_get_value(gsi->host_wake)) { GS_DBG("-gpiosleep_sleep_wakeup wakeup mtk chip"); /*0 means wakup MTK chip */ gpio_set_value(gsi->ext_wake, 0); GS_DBG("ext_wake gpio set value 0"); mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); } else { GS_DBG("hit here?"); } } }
/** * Cleans up the module. */ static void __exit bluesleep_exit(void) { if (bsi == NULL) return; /* assert bt wake */ if (bsi->has_ext_wake == 1) { int ret; ret = ice_gpiox_set(bsi->ext_wake, 1); if (ret) BT_ERR("(bluesleep_exit) failed to set ext_wake 1."); } set_bit(BT_EXT_WAKE, &flags); if (test_bit(BT_PROTO, &flags)) { if (disable_irq_wake(bsi->host_wake_irq)) BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n"); free_irq(bsi->host_wake_irq, NULL); del_timer(&tx_timer); if (test_bit(BT_ASLEEP, &flags)) hsuart_power(1); } platform_driver_unregister(&bluesleep_driver); remove_proc_entry("btwrite", sleep_dir); remove_proc_entry("lpm", sleep_dir); remove_proc_entry("asleep", sleep_dir); remove_proc_entry("proto", sleep_dir); remove_proc_entry("hostwake", sleep_dir); remove_proc_entry("btwake", sleep_dir); remove_proc_entry("sleep", bluetooth_dir); remove_proc_entry("bluetooth", 0); mutex_destroy(&bluesleep_mutex); }
void bluesleep_sleep_wakeup(void) { if (test_bit(BT_ASLEEP, &flags)) { BT_DBG("waking up..."); /*Activating UART */ hsuart_power(1); wake_lock(&bsi->wake_lock); /* Start the timer */ mod_timer(&tx_timer, jiffies + msecs_to_jiffies(TX_TIMER_INTERVAL * 1000)); if (bsi->has_ext_wake == 1) { int ret; ret = ice_gpiox_set(bsi->ext_wake, 1); if (ret) { BT_ERR("(bluesleep_sleep_wakeup) failed to set ext_wake 1."); ret = ice_gpiox_set(bsi->ext_wake, 1); BT_ERR("ret = %d", ret); } } set_bit(BT_EXT_WAKE, &flags); clear_bit(BT_ASLEEP, &flags); } else { BT_DBG("bluesleep_sleep_wakeup : already wake up, so start timer..."); mod_timer(&tx_timer, jiffies + msecs_to_jiffies(TX_TIMER_INTERVAL * 1000)); } }
/** * Stops the Sleep-Mode Protocol on the Host. */ static void bluesleep_stop(void) { if (!test_bit(BT_PROTO, &flags)) { BT_ERR("(bluesleep_stop_wq) proto is not set. Failed to stop bluesleep"); bsi->uport = NULL; return; } /* assert BT_WAKE */ if (bsi->has_ext_wake == 1) { int ret; ret = ice_gpiox_set(bsi->ext_wake, 1); if (ret) BT_ERR("(bluesleep_stop) failed to set ext_wake 1."); } set_bit(BT_EXT_WAKE, &flags); del_timer(&tx_timer); clear_bit(BT_PROTO, &flags); if (test_bit(BT_ASLEEP, &flags)) { clear_bit(BT_ASLEEP, &flags); hsuart_power(1); } if (disable_irq_wake(bsi->host_wake_irq)) BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n"); wake_lock_timeout(&bsi->wake_lock, msecs_to_jiffies(125)); bsi->uport = NULL; }
/** * Handles proper timer action when outgoing data is delivered to the * HCI line discipline. Sets BT_TXDATA. */ static void bluesleep_outgoing_data(void) { if (mutex_is_locked(&bluesleep_mutex)) BT_DBG("Wait for mutex unlock in bluesleep_outgoing_data"); mutex_lock(&bluesleep_mutex); /* log data passing by */ set_bit(BT_TXDATA, &flags); BT_DBG("bluesleep_outgoing_data."); if (!test_bit(BT_EXT_WAKE, &flags)) BT_DBG("BT_EXT_WAKE freed"); if (!test_bit(BT_ASLEEP, &flags)) BT_DBG("BT_ASLEEP freed"); /* ** Uart Clk should be enabled promptly ** before bluedroid write TX data. */ hsuart_power(1); bluesleep_tx_data_wakeup(); mutex_unlock(&bluesleep_mutex); }
void bluetooth_pm_sleep(void) { unsigned long irq_flags; //printk("+++ %s\n", __func__); spin_lock_irqsave(&rw_lock, irq_flags); /* already asleep, this is an error case */ if (test_bit(BT_ASLEEP, &flags)) { spin_unlock_irqrestore(&rw_lock, irq_flags); printk("--- %s, already asleep return\n", __func__); return; } //BT_S : [CONBT-1475] LGC_BT_COMMON_IMP_KERNEL_UART_HCI_COMMAND_TIMEOUT uart_off_jiffies = jiffies; if(check_uart_control_available(uart_on_jiffies, uart_off_jiffies) == false) { mod_timer(&uart_control_timer, jiffies + msecs_to_jiffies(UART_CONTROL_BLOCK_TIME)); spin_unlock_irqrestore(&rw_lock, irq_flags); printk("--- %s - UART control unavailable Return\n", __func__); return; } //BT_E : [CONBT-1475] LGC_BT_COMMON_IMP_KERNEL_UART_HCI_COMMAND_TIMEOUT set_bit(BT_ASLEEP, &flags); spin_unlock_irqrestore(&rw_lock, irq_flags); printk("%s, going to sleep...\n", __func__); //printk("%s, WAKE_UNLOCK_START\n", __func__); wake_unlock(&bsi->wake_lock); //printk("%s, WAKE_UNLOCK_END\n", __func__); #ifdef UART_CONTROL_MSM /*Deactivating UART */ hsuart_power(0); #endif /*UART_CONTROL_MSM*/ #ifdef QOS_REQUEST_MSM if(bsi->dma_qos_request == REQUESTED) { pm_qos_update_request(&bsi->dma_qos, 0x7FFFFFF); } #endif /* QOS_REQUEST_MSM */ #ifdef QOS_REQUEST_TEGRA pm_qos_update_request(&bsi->resume_cpu_freq_req, PM_QOS_DEFAULT_VALUE); #endif/*QOS_REQUEST_TEGRA*/ //printk("--- %s\n", __func__); }
/** * @brief@ main sleep work handling function which update the flags * and activate and deactivate UART ,check FIFO. */ static void bluesleep_sleep_work(struct work_struct *work) { if (mutex_is_locked(&bluesleep_mutex)) BT_DBG("Wait for mutex unlock in bluesleep_sleep_work"); mutex_lock(&bluesleep_mutex); if (bluesleep_can_sleep()) { /* already asleep, this is an error case */ if (test_bit(BT_ASLEEP, &flags)) { BT_DBG("already asleep"); mutex_unlock(&bluesleep_mutex); return; } if (msm_hs_tx_empty(bsi->uport)) { if (test_bit(BT_TXDATA, &flags)) { BT_DBG("TXDATA remained. Wait until timer expires."); mod_timer(&tx_timer, jiffies + TX_TIMER_INTERVAL * HZ); mutex_unlock(&bluesleep_mutex); return; } BT_DBG("going to sleep..."); set_bit(BT_ASLEEP, &flags); /*Deactivating UART */ hsuart_power(0); /*Deactivating UART */ /* UART clk is not turned off immediately. Release * wakelock after 500 ms. */ wake_lock_timeout(&bsi->wake_lock, HZ / 2); } else { BT_DBG("host can enter sleep but some tx remained."); mod_timer(&tx_timer, jiffies + TX_TIMER_INTERVAL * HZ); mutex_unlock(&bluesleep_mutex); return; } } else if (!test_bit(BT_EXT_WAKE, &flags) && !test_bit(BT_ASLEEP, &flags)) { BT_DBG("host_wake high and BT_EXT_WAKE & BT_ASLEEP is freed."); mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (bsi->has_ext_wake == 1) { gpio_set_value(bsi->ext_wake, 1); } set_bit(BT_EXT_WAKE, &flags); } else { bluesleep_sleep_wakeup(); } mutex_unlock(&bluesleep_mutex); }
static int bluetooth_power_param_set(const char *val, struct kernel_param *kp) { int ret; printk(KERN_DEBUG "%s: previous power_state=%d\n", __func__, bluetooth_power_state); /* lock change of state and reference */ spin_lock(&bt_power_lock); ret = param_set_bool(val, kp); if (power_control) { if (!ret){ ret = (*power_control)(bluetooth_power_state); printk(KERN_ERR "%s: bluetooth power control, return = (%d)\n", __func__, ret); } else{ printk(KERN_ERR "%s param set bool failed (%d)\n", __func__, ret); } } else { printk(KERN_INFO "%s: deferring power switch until probe\n", __func__); } spin_unlock(&bt_power_lock); printk(KERN_INFO "%s: current power_state=%d\n", __func__, bluetooth_power_state); if(bluetooth_power_state == 0){ hsuart_power(0); gpio_set_value(16,0); msleep(105); gpio_set_value(48,0); } else{ gpio_set_value(16,0); msleep(1); gpio_set_value(48,1); msleep(105); gpio_set_value(16,1); } printk(" ***** ----------- --------- GPIO 48 = %d\n",gpio_get_value(48)); printk(" ***** ----------- --------- GPIO 16 = %d\n",gpio_get_value(16)); return ret; }
void bluesleep_sleep_wakeup(void) { if (test_bit(BT_ASLEEP, &flags)) { BT_DBG("waking up..."); /*Activating UART */ hsuart_power(1); wake_lock(&bsi->wake_lock); /* Start the timer */ mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (bsi->has_ext_wake == 1) { gpio_set_value(bsi->ext_wake, 1); } set_bit(BT_EXT_WAKE, &flags); clear_bit(BT_ASLEEP, &flags); } }
static int bluesleep_resume(struct platform_device *pdev) { if (test_bit(BT_SUSPEND, &flags)) { if (!bt_enabled) { gpio_tlmm_config(GPIO_CFG(bsi->host_wake, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA), GPIO_CFG_ENABLE); } clear_bit(BT_SUSPEND, &flags); if ((bsi->uport != NULL) && (gpio_get_value(bsi->host_wake) == bsi->irq_polarity)) { BT_DBG("bluesleep resume form BT event..."); hsuart_power(1); } } return 0; }
void bluesleep_sleep_wakeup(void) { /* Start the timer */ mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (test_bit(BT_ASLEEP, &flags)) { BT_INFO("bluesleep_sleep_wakeup-waking up..."); wake_lock(&bsi->wake_lock); /* Start the timer */ //mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); #ifndef BTLD_CONTROL_WAKE_GPIO gpio_set_value(bsi->ext_wake, defined(WAKE_GPIO_ACTIVE_HIGH) ? 1 : 0); #endif /* BTLD_CONTROL_WAKE_GPIO */ clear_bit(BT_ASLEEP, &flags); /*Activating UART */ hsuart_power(1); } }
/** * @brief@ main sleep work handling function which update the flags * and activate and deactivate UART ,check FIFO. */ static void bluesleep_sleep_work(struct work_struct *work) { if (bluesleep_can_sleep()) { /* already asleep, this is an error case */ if (test_bit(BT_ASLEEP, &flags)) { if (debug_mask & DEBUG_SUSPEND) pr_info("already asleep\n"); return; } if (msm_hs_tx_empty(bsi->uport)) { if (debug_mask & DEBUG_SUSPEND) pr_info("going to sleep...\n"); set_bit(BT_ASLEEP, &flags); /*Deactivating UART */ hsuart_power(0); /* UART clk is not turned off immediately. Release * wakelock after 125 ms. */ wake_lock_timeout(&bsi->wake_lock, HZ / 8); } else { mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); return; } } else if (test_bit(BT_EXT_WAKE, &flags) && !test_bit(BT_ASLEEP, &flags)) { mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (debug_mask & DEBUG_BTWAKE) pr_info("BT WAKE: set to wake\n"); if (bsi->has_ext_wake == 1) gpio_set_value(bsi->ext_wake, 0); clear_bit(BT_EXT_WAKE, &flags); } else { bluesleep_sleep_wakeup(); } }
void gpiosleep_uart_open(struct uart_port *uport) { unsigned long irq_flags; GS_DBG("gpiosleep_uart_open"); spin_lock_irqsave(&rw_lock, irq_flags); if (!test_bit(FLAG_PROTO, &flags)) { spin_unlock_irqrestore(&rw_lock, irq_flags); return; } spin_unlock_irqrestore(&rw_lock, irq_flags); hsuart_power(1); // must do this, other wise, mtk_cmux set baud rate before uart power on. if(gsi->uport == NULL) { GS_DBG("gpiosleep_uart_open done"); gsi->uport = uport; } }
static int __devexit gpiosleep_remove(struct platform_device *pdev) { /* assert mtk wake */ gpio_set_value(gsi->ext_wake, 0); GS_DBG("ext_wake gpio set value 0"); if (test_bit(FLAG_PROTO, &flags)) { if (disable_irq_wake(gsi->host_wake_irq)) GS_ERR("Couldn't disable hostwake IRQ wakeup mode \n"); free_irq(gsi->host_wake_irq, NULL); del_timer(&tx_timer); if (test_bit(FLAG_ASLEEP, &flags)) hsuart_power(1); } gpio_free(gsi->host_wake); gpio_free(gsi->ext_wake); kfree(gsi); destroy_workqueue(gpiosleep_workqueue); gpiosleep_workqueue = NULL; gpiosleep_remove_proc_entry(); return 0; }
/** * Handles proper timer action when outgoing data is delivered to the * HCI line discipline. Sets BT_TXDATA. */ static void bluesleep_outgoing_data(void) { /* prevent entered upload mode or bt reset. */ /* if bluesleep_tx_timer_expire routine triggered, max 10ms wait for finish. */ int i; for(i=0; i<10 && !test_bit(BT_TXDATA, &flags) && !test_bit(BT_EXT_WAKE, &flags) && !test_bit(BT_ASLEEP, &flags); i++) { BT_DBG("bluesleep_tx_timer_expire routine has not yet finished. 1ms sleep"); usleep(1000); } if (mutex_is_locked(&bluesleep_mutex)) BT_DBG("Wait for mutex unlock in bluesleep_outgoing_data"); mutex_lock(&bluesleep_mutex); /* log data passing by */ set_bit(BT_TXDATA, &flags); BT_DBG("bluesleep_outgoing_data."); if (!test_bit(BT_EXT_WAKE, &flags)) BT_DBG("BT_EXT_WAKE freed"); if (!test_bit(BT_ASLEEP, &flags)) BT_DBG("BT_ASLEEP freed"); /* ** Uart Clk should be enabled promptly ** before bluedroid write TX data. */ hsuart_power(1); bluesleep_tx_data_wakeup(); mutex_unlock(&bluesleep_mutex); }
/** * @brief@ main sleep work handling function which update the flags * and activate and deactivate UART ,check FIFO. */ static void gpiosleep_sleep_work(struct work_struct *work) { if (gpiosleep_can_sleep()) { /* already asleep, this is an error case */ if (test_bit(FLAG_ASLEEP, &flags)) { GS_DBG("already asleep"); return; } if (msm_hs_tx_empty(gsi->uport)) { GS_DBG("going to sleep..."); set_bit(FLAG_ASLEEP, &flags); /*Deactivating UART */ hsuart_power(0); } else { GS_DBG("fifo has data to send, not sleep..."); mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); return; } } else { gpiosleep_sleep_wakeup(); } }
/** * Stops the Sleep-Mode Protocol on the Host. */ static void bluesleep_stop(void) { unsigned long irq_flags; spin_lock_irqsave(&rw_lock, irq_flags); if (!test_bit(BT_PROTO, &flags)) { spin_unlock_irqrestore(&rw_lock, irq_flags); return; } /* assert BT_WAKE */ if (debug_mask & DEBUG_BTWAKE) pr_info("BT WAKE: set to wake\n"); if (bsi->has_ext_wake == 1) gpio_set_value(bsi->ext_wake, 0); clear_bit(BT_EXT_WAKE, &flags); del_timer(&tx_timer); clear_bit(BT_PROTO, &flags); if (test_bit(BT_ASLEEP, &flags)) { clear_bit(BT_ASLEEP, &flags); spin_unlock_irqrestore(&rw_lock, irq_flags); hsuart_power(1); } else { spin_unlock_irqrestore(&rw_lock, irq_flags); } atomic_inc(&open_count); if (disable_irq_wake(bsi->host_wake_irq)) BT_ERR("Couldn't disable hostwake IRQ wakeup mode"); wake_lock_timeout(&bsi->wake_lock, HZ / 8); }
void bluesleep_sleep_wakeup(void) { if (test_bit(BT_ASLEEP, &flags)) { if (debug_mask & DEBUG_SUSPEND) pr_info("waking up...\n"); wake_lock(&bsi->wake_lock); /* Start the timer */ mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (debug_mask & DEBUG_BTWAKE) pr_info("BT WAKE: set to wake\n"); if (bsi->has_ext_wake == 1) gpio_set_value(bsi->ext_wake, 0); clear_bit(BT_EXT_WAKE, &flags); clear_bit(BT_ASLEEP, &flags); /*Activating UART */ hsuart_power(1); } }
/** * @brief@ main sleep work handling function which update the flags * and activate and deactivate UART ,check FIFO. */ static void bluesleep_sleep_work(struct work_struct *work) { #if 0 //For debug : defined(CONFIG_SEC_MIF_UART_SWITCH) int uart_sel = 0; #endif if (mutex_is_locked(&bluesleep_mutex)) BT_DBG("Wait for mutex unlock in bluesleep_sleep_work"); if (bsi->uport == NULL) { BT_DBG("bluesleep_sleep_work - uport is null"); return; } if (bsi->uport->state == NULL) { BT_DBG("bluesleep_sleep_work - bsi->uport->state is null"); return; } if (bsi->uport->state->port.tty == NULL) { BT_DBG("bluesleep_sleep_work - bsi->uport->state->port.tty is null"); return; } mutex_lock(&bluesleep_mutex); if (bluesleep_can_sleep()) { /* already asleep, this is an error case */ if (test_bit(BT_ASLEEP, &flags)) { BT_DBG("already asleep"); mutex_unlock(&bluesleep_mutex); return; } if (msm_hs_tx_empty(bsi->uport)) { if (test_bit(BT_TXDATA, &flags)) { BT_DBG("TXDATA remained. Wait until timer expires."); mod_timer(&tx_timer, jiffies + TX_TIMER_INTERVAL * HZ); mutex_unlock(&bluesleep_mutex); return; } #if 0 //For debug : defined(CONFIG_SEC_MIF_UART_SWITCH) if(system_rev <= 6 /*board rev 06*/) { uart_sel = gpio_get_value(GPIO_UART_SEL); } else{ uart_sel = gpio_get_value(GPIO_UART_SEL_REV07); } if (uart_sel ==1) { BT_DBG("bluesleep_sleep_work GPIO_UART_SEL (%d)", uart_sel); return; } #endif BT_DBG("going to sleep..."); set_bit(BT_ASLEEP, &flags); /*Deactivating UART */ hsuart_power(0); /* Moved from Timer expired */ if (bsi->has_ext_wake == 1) gpio_set_value(bsi->ext_wake, 0); clear_bit(BT_EXT_WAKE, &flags); /*Deactivating UART */ /* UART clk is not turned off immediately. Release * wakelock after 500 ms. */ wake_lock_timeout(&bsi->wake_lock, HZ / 2); } else { BT_DBG("host can enter sleep but some tx remained."); mod_timer(&tx_timer, jiffies + TX_TIMER_INTERVAL * HZ); mutex_unlock(&bluesleep_mutex); return; } } else if (!test_bit(BT_EXT_WAKE, &flags) && !test_bit(BT_ASLEEP, &flags)) { BT_DBG("host_wake high and BT_EXT_WAKE & BT_ASLEEP already freed."); mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); if (bsi->has_ext_wake == 1) { gpio_set_value(bsi->ext_wake, 1); } set_bit(BT_EXT_WAKE, &flags); } else { bluesleep_sleep_wakeup(); } mutex_unlock(&bluesleep_mutex); }
void bluetooth_pm_wakeup(void) { unsigned long irq_flags; //printk("+++ %s\n", __func__); spin_lock_irqsave(&rw_lock, irq_flags); if (test_bit(BT_ASLEEP, &flags)) { printk("%s, waking up...\n", __func__); //BT_S : [CONBT-1475] LGC_BT_COMMON_IMP_KERNEL_UART_HCI_COMMAND_TIMEOUT uart_on_jiffies = jiffies; if(check_uart_control_available(uart_off_jiffies, uart_on_jiffies) == false) { mod_timer(&uart_control_timer, jiffies + msecs_to_jiffies(UART_CONTROL_BLOCK_TIME)); spin_unlock_irqrestore(&rw_lock, irq_flags); printk("--- %s - UART control unavailable Return\n", __func__); return; } //BT_E : [CONBT-1475] LGC_BT_COMMON_IMP_KERNEL_UART_HCI_COMMAND_TIMEOUT clear_bit(BT_ASLEEP, &flags); spin_unlock_irqrestore(&rw_lock, irq_flags); #ifdef QOS_REQUEST_MSM if(bsi->dma_qos_request == REQUESTED) { pm_qos_update_request(&bsi->dma_qos, 19); } #endif/*QOS_REQUEST_MSM*/ #ifdef QOS_REQUEST_TEGRA if (bsi->resume_min_frequency) pm_qos_update_request(&bsi->resume_cpu_freq_req, bsi->resume_min_frequency); #endif/*QOS_REQUEST_TEGRA*/ //printk("%s, WAKE_LOCK_START\n", __func__); wake_lock(&bsi->wake_lock); //printk("%s, WAKE_LOCK_END\n", __func__); #ifdef UART_CONTROL_MSM /*Activating UART */ hsuart_power(1); #endif/*UART_CONTROL_MSM*/ } else { int wake, host_wake; wake = gpio_get_value(bsi->ext_wake); host_wake = gpio_get_value(bsi->host_wake); spin_unlock_irqrestore(&rw_lock, irq_flags); //printk("%s, %d, %d\n", __func__, wake, host_wake); if(wake == DEASSERT && host_wake == ASSERT) { printk("%s - Start Timer : check hostwake status when timer expired\n", __func__); mod_timer(&tx_timer, jiffies + (TX_TIMER_INTERVAL * HZ)); } #ifdef UART_CONTROL_MSM //printk("%s, Workaround for uart runtime suspend : Check UART Satus", __func__); //if(bsi->uport != NULL && msm_hs_get_bt_uport_clock_state(bsi->uport) == CLOCK_REQUEST_AVAILABLE) //{ // printk("%s, Enter abnormal status, HAVE to Call hsuart_power(1)!", __func__); // hsuart_power(1); //} #endif /*UART_CONTROL_MSM*/ } //printk("--- %s\n", __func__); }