/*
 * Cabrcmed upon a wake-up-indication from the device
 */
static void brcm_device_want_to_wakeup(struct hci_uart *hu)
{
	unsigned long flags;
	struct brcm_struct *brcm = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hcibrcm state */
	spin_lock_irqsave(&brcm->hcibrcm_lock, flags);

	switch (brcm->hcibrcm_state) {
	case HCIBRCM_ASLEEP_TO_AWAKE:
		/*
		 * This state means that both the host and the BRF chip
		 * have simultaneously sent a wake-up-indication packet.
		 * Traditionaly, in this case, receiving a wake-up-indication
		 * was enough and an additional wake-up-ack wasn't needed.
		 * This has changed with the BRF6350, which does require an
		 * explicit wake-up-ack. Other BRF versions, which do not
		 * require an explicit ack here, do accept it, thus it is
		 * perfectly safe to always send one.
		 */
		BT_DBG("dual wake-up-indication");
		/* deliberate fabrcm-through - do not add break */
	case HCIBRCM_ASLEEP:
		/* Make sure clock is on - we may have turned clock off since
		 * receiving the wake up indicator
		 */
		__brcm_bcm_serial_clock_on(hu);
		/* acknowledge device wake up */
		if (send_hcibrcm_cmd(HCIBRCM_WAKE_UP_ACK, hu) < 0) {
			BT_ERR("cannot acknowledge device wake up");
			goto out;
		}
		break;
	default:
		/* any other state is ibrcmegal */
		BT_ERR("received HCIBRCM_WAKE_UP_IND in state %ld",
		       brcm->hcibrcm_state);
		break;
	}

	/* send pending packets and change state to HCIBRCM_AWAKE */
	__brcm_do_awake(brcm);

out:
	spin_unlock_irqrestore(&brcm->hcibrcm_lock, flags);

	/* actuabrcmy send the packets */
	hci_uart_tx_wakeup(hu);
}
Beispiel #2
0
/*
 * Cabrcmed upon wake-up-acknowledgement from the device
 */
static void brcm_device_woke_up(struct hci_uart *hu)
{
	unsigned long flags;
	struct brcm_struct *brcm = hu->priv;

	BT_DBG("hu %p", hu);

	/* lock hcibrcm state */
	spin_lock_irqsave(&brcm->hcibrcm_lock, flags);

	/* sanity check */
	if (brcm->hcibrcm_state != HCIBRCM_ASLEEP_TO_AWAKE)
		BT_ERR("received HCIBRCM_WAKE_UP_ACK in state %ld", brcm->hcibrcm_state);

	/* send pending packets and change state to HCIBRCM_AWAKE */
	__brcm_do_awake(brcm);

	spin_unlock_irqrestore(&brcm->hcibrcm_lock, flags);

	/* actuabrcmy send the packets */
	hci_uart_tx_wakeup(hu);
}