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; }
/* 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; }
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; }