Пример #1
0
/* This should be used in function that cannot release clocks */
static void hci_h4p_set_clk(struct hci_h4p_info *info, int *clock, int enable)
{
	unsigned long flags;

	spin_lock_irqsave(&info->clocks_lock, flags);
	if (enable && !*clock) {
		NBT_DBG_POWER("Enabling %p\n", clock);
		clk_enable(info->uart_fclk);
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
		if (cpu_is_omap24xx() || cpu_is_omap34xx())
			clk_enable(info->uart_iclk);
#endif
		if (atomic_read(&info->clk_users) == 0)
			hci_h4p_restore_regs(info);
		atomic_inc(&info->clk_users);
	}

	if (!enable && *clock) {
		NBT_DBG_POWER("Disabling %p\n", clock);
		if (atomic_dec_and_test(&info->clk_users))
			hci_h4p_store_regs(info);
		clk_disable(info->uart_fclk);
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
		if (cpu_is_omap24xx() || cpu_is_omap34xx())
			clk_disable(info->uart_iclk);
#endif
	}

	*clock = enable;
	spin_unlock_irqrestore(&info->clocks_lock, flags);
}
Пример #2
0
static irqreturn_t hci_h4p_wakeup_interrupt(int irq, void *dev_inst)
{
	struct hci_h4p_info *info = dev_inst;
	int should_wakeup;
	struct hci_dev *hdev;

	if (!info->hdev)
		return IRQ_HANDLED;

	hdev = info->hdev;

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return IRQ_HANDLED;

	should_wakeup = gpio_get_value(info->host_wakeup_gpio);
	NBT_DBG_POWER("gpio interrupt %d\n", should_wakeup);

	/* Check if wee have missed some interrupts */
	if (info->rx_enabled == should_wakeup)
		return IRQ_HANDLED;

	if (should_wakeup) {
		hci_h4p_enable_rx(info);
	} else {
		hci_h4p_disable_rx(info);
	}

	return IRQ_HANDLED;
}
Пример #3
0
static void hci_h4p_disable_tx(struct hci_h4p_info *info)
{
	NBT_DBG_POWER("\n");

	if (!info->pm_enabled)
		return;

	/* Re-enable smart-idle */
	hci_h4p_smart_idle(info, 1);

	gpio_set_value(info->bt_wakeup_gpio, 0);
	mod_timer(&info->lazy_release, jiffies + msecs_to_jiffies(100));
	info->tx_enabled = 0;
}
Пример #4
0
void hci_h4p_enable_tx(struct hci_h4p_info *info)
{
	unsigned long flags;
	NBT_DBG_POWER("\n");

	if (!info->pm_enabled)
		return;

	spin_lock_irqsave(&info->lock, flags);
	del_timer(&info->lazy_release);
	hci_h4p_set_clk(info, &info->tx_clocks_en, 1);
	info->tx_enabled = 1;
	gpio_set_value(info->bt_wakeup_gpio, 1);
	hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) |
		     UART_IER_THRI);
	/*
	 * Disable smart-idle as UART TX interrupts
	 * are not wake-up capable
	 */
	hci_h4p_smart_idle(info, 0);

	spin_unlock_irqrestore(&info->lock, flags);
}
Пример #5
0
static irqreturn_t brf6150_wakeup_interrupt(int irq, void *dev_inst)
{
	struct brf6150_info *info = dev_inst;
	int should_wakeup;
	unsigned long flags;

	spin_lock_irqsave(&info->lock, flags);
	should_wakeup = omap_get_gpio_datain(info->btinfo->host_wakeup_gpio);
	NBT_DBG_POWER("gpio interrupt %d\n", should_wakeup);
	if (should_wakeup) {
		clk_enable(info->uart_ck);
		brf6150_set_auto_ctsrts(info, 1);
		brf6150_rx(info);
		tasklet_schedule(&info->tx_task);
	} else {
		brf6150_set_auto_ctsrts(info, 0);
		brf6150_set_rts(info, 0);
		clk_disable(info->uart_ck);
	}

	spin_unlock_irqrestore(&info->lock, flags);
	return IRQ_HANDLED;
}