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;
}
Exemple #10
0
/**
 * 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__);
}
Exemple #12
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 (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;
}
Exemple #14
0
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;
}
Exemple #16
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);
	}
}
Exemple #24
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 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__);
}