irqreturn_t mt_bt_eirq_handler(int i, void *arg)
{
    struct hci_dev *hdev = NULL;

    //printk(KERN_ALERT "mt_bt_eirq_handler\n");
    mt_bt_disable_irq();

if(eint_handle_method == 0) {
//#ifdef CONFIG_BT_HCIUART
    /* BlueZ stack, hci_uart driver */
    hdev = hci_dev_get(0);
    if(hdev == NULL){
        /* Avoid the early interrupt before hci0 registered */
        //BT_HWCTL_ALERT("hdev is NULL\n");
    }else{
        //BT_HWCTL_ALERT("EINT arrives! notify host wakeup\n");
        printk("Send host wakeup command\n");
        hci_send_cmd(hdev, 0xFCC1, 0, NULL);
        /* enable irq after receiving host wakeup command's event */
    }
	mt_bt_enable_irq();
} else {
//#else
    /* Maybe handle the interrupt in user space? */
    eint_gen = 1;
    wake_up_interruptible(&eint_wait);
    /* Send host wakeup command in user space, enable irq then */
//#endif
}

    return IRQ_HANDLED;
}
Example #2
0
/* Close device */
static int hci_uart_close(struct hci_dev *hdev)
{
	BT_DBG("hdev %p", hdev);

	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
		return 0;

#if defined(CONFIG_MT5931_MT6622)
	mt_bt_disable_irq();
#endif
	hci_uart_flush(hdev);
	hdev->flush = NULL;
	return 0;
}
/****************************************************************************
 *                       I R Q   F U N C T I O N S                          *
*****************************************************************************/
static int mt_bt_request_irq(void)
{
    int iRet;
    irq_mask = 0;
    
    iRet = request_irq(irq_num, mt_bt_eirq_handler, 
        IRQF_TRIGGER_HIGH, "BT_INT_B", NULL);
    if (iRet){
        printk(KERN_ALERT MODULE_TAG "request_irq IRQ%d fails, errno %d\n", irq_num, iRet);
    }
    else{
        printk(KERN_INFO MODULE_TAG "request_irq IRQ%d success\n", irq_num);
        mt_bt_disable_irq();
        /* enable irq when driver init complete, at hci_uart_open */
    }
    irq_requested = 1; //wenhui add
    return iRet;
}
Example #4
0
irqreturn_t mt_bt_eirq_handler(int i, void *arg)
{
    struct hci_dev *hdev = NULL;

    //printk(KERN_ALERT "mt_bt_eirq_handler\n");
    mt_bt_disable_irq();

#ifdef CONFIG_BT_HCIUART
    if(mtk_wcn_bt_workqueue)
        queue_work(mtk_wcn_bt_workqueue, &mtk_wcn_bt_event_work);
#else
    /* Maybe handle the interrupt in user space? */
    eint_gen = 1;
    wake_up_interruptible(&eint_wait);
    /* Send host wakeup command in user space, enable irq then */
#endif

    return IRQ_HANDLED;
}
/****************************************************************************
 *                       I R Q   F U N C T I O N S                          *
*****************************************************************************/
static int mt_bt_request_irq(void)
{
    int iRet;
    int trigger = IRQF_TRIGGER_RISING;
    struct mt6622_platform_data *pdata = (struct mt6622_platform_data *)mt_bt_get_platform_data();
		
    irq_mask = 0;
    if(pdata->irq_gpio.enable == GPIO_LOW)
    	trigger = IRQF_TRIGGER_FALLING;
    
    iRet = request_irq(irq_num, mt_bt_eirq_handler, 
        trigger, "BT_INT_B", NULL);
    if (iRet){
        printk(KERN_ALERT MODULE_TAG "request_irq IRQ%d fails, errno %d\n", irq_num, iRet);
    }
    else{
        printk(KERN_INFO MODULE_TAG "request_irq IRQ%d success\n", irq_num);
        mt_bt_disable_irq();
        /* enable irq when driver init complete, at hci_uart_open */
    }
    irq_requested = 1; //wenhui add
    return iRet;
}
/*****************************************************************************
 *  bt_hwctl_ioctl
*****************************************************************************/
static long bt_hwctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    int ret = 0;
     
    BT_HWCTL_DEBUG("bt_hwctl_ioctl\n");
    
    if(!bh) {
        BT_HWCTL_ALERT("bt_hwctl struct not initialized\n");
        return -EFAULT;
    }
    
    switch(cmd)
    {
        case BTHWCTL_IOCTL_SET_POWER:
        {
            unsigned long pwr = 0;
            if (copy_from_user(&pwr, (void*)arg, sizeof(unsigned long)))
                return -EFAULT;
                
            BT_HWCTL_DEBUG("BTHWCTL_IOCTL_SET_POWER: %d\n", (int)pwr);
            
            mutex_lock(&bh->sem);
            if (pwr){
                ret = mt_bt_power_on();
            }
            else{
                mt_bt_power_off();
            }
            mutex_unlock(&bh->sem);
            
            break;
        }
        case BTHWCTL_IOCTL_SET_EINT:
        {
            unsigned long eint = 0;
            if (copy_from_user(&eint, (void*)arg, sizeof(unsigned long)))
                return -EFAULT;
                
            BT_HWCTL_DEBUG("BTHWCTL_IOCTL_SET_EINT: %d\n", (int)eint);
            
            mutex_lock(&bh->sem);
            if (eint){
                /* Enable irq from user space */ 
                BT_HWCTL_DEBUG("Set BT EINT enable\n");
                mt_bt_enable_irq();
            }
            else{
                /* Disable irq from user space, maybe time to close driver */
                BT_HWCTL_DEBUG("Set BT EINT disable\n");
                mt_bt_disable_irq();
                eint_mask = 1;
                wake_up_interruptible(&eint_wait);
            }
            mutex_unlock(&bh->sem);
            
            break;
        }    
        default:
            BT_HWCTL_ALERT("BTHWCTL_IOCTL not support\n");
            return -EPERM;
    }
    
    return ret;
}