• Hans de Goede's avatar
    Bluetooth: hci_bcm: Set pulsed_host_wake flag in sleep parameters · e07c99b0
    Hans de Goede authored
    The IRQ output of the bcm bt-device is really a level IRQ signal, which
    signals a logical high as long as the device's buffer contains data. Since
    the draining in the buffer is done in the tty driver, we cannot (easily)
    wait in a threaded interrupt handler for the draining, after which the
    IRQ should go low again.
    
    So instead we treat the IRQ as an edge interrupt. This opens the window
    for a theoretical race where we wakeup, read some data and then autosuspend
    *before* the IRQ has gone (logical) low, followed by the device just at
    that moment receiving more data, causing the IRQ to stay high and we never
    see an edge.
    
    Since we call pm_runtime_mark_last_busy() on every received byte, there
    should be plenty time for the IRQ to go (logical) low before we ever
    suspend, so this should never happen, but after commit 43fff768
    ("Bluetooth: hci_bcm: Streamline runtime PM code"), which has been reverted
    since, this was actually happening causing the device to get stuck in
    runtime suspend.
    
    The bcm bt-device actually has a workaround for this, if we set the
    pulsed_host_wake flag in the sleep parameters, then the device monitors
    if the host is draining the buffer and if not then after a timeout the
    device will pulse the IRQ line, causing us to see an edge, fixing the
    stuck in suspend condition.
    
    This commit sets the pulsed_host_wake flag to fix the (mostly theoretical)
    race caused by us treating the IRQ as an edge IRQ.
    Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
    Reviewed-by: default avatarLukas Wunner <lukas@wunner.de>
    Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
    e07c99b0
hci_bcm.c 28.5 KB