diff options
author | mullerf <mullerf@google.com> | 2021-05-27 19:19:59 -0700 |
---|---|---|
committer | jonerlin <jonerlin@google.com> | 2021-06-03 16:52:19 +0800 |
commit | 51fdb329040f7a62d452d8beaf6fdb469c09cc80 (patch) | |
tree | ca0972661f1935b534740d33e6eb7161831ea10a | |
parent | eadc62a0e3b80018ddb898454f6e330db7cfbcd7 (diff) | |
download | broadcom-51fdb329040f7a62d452d8beaf6fdb469c09cc80.tar.gz |
Keep device from suspending when BT transfer is ongoing
This uses pm_stay_awake/pm_relax/etc. to prevent the device from
suspending when a BT transfer is happening (HOST_WAKE is asserted).
It also allows the device to auto-suspend to pm runtime only when there
are no transfer ongoing as well, meaning when HOST_WAKE is low.
Test: Manual
Bug: 189177739
Bug: 189370529
Signed-off-by: mullerf <mullerf@google.com>
Change-Id: Ia0f99683a08833e33422966e7bcf31c967e43a03
Signed-off-by: jonerlin <jonerlin@google.com>
-rw-r--r-- | nitrous.c | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -112,19 +112,29 @@ static void nitrous_prepare_uart_tx_locked(struct nitrous_bt_lpm *lpm) static irqreturn_t nitrous_host_wake_isr(int irq, void *data) { struct nitrous_bt_lpm *lpm = data; + int host_wake; + + host_wake = gpiod_get_value(lpm->gpio_host_wake); + dev_dbg(lpm->dev, "Host wake IRQ: %u\n", host_wake); - dev_dbg(lpm->dev, "Host wake IRQ: %u\n", gpiod_get_value(lpm->gpio_host_wake)); if (lpm->rfkill_blocked) { dev_err(lpm->dev, "Unexpected Host wake IRQ\n"); logbuffer_log(lpm->log, "Unexpected Host wake IRQ"); return IRQ_HANDLED; } - pm_runtime_get(lpm->dev); - exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_BUSY); - logbuffer_log(lpm->log, "host_wake_isr"); - pm_runtime_mark_last_busy(lpm->dev); - pm_runtime_put_autosuspend(lpm->dev); + /* Check whether host_wake is ACTIVE (== 1) */ + if (host_wake == 1) { + logbuffer_log(lpm->log, "host_wake_isr asserted"); + pm_runtime_get(lpm->dev); + exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_BUSY); + pm_stay_awake(lpm->dev); + } else { + logbuffer_log(lpm->log, "host_wake_isr de-asserted"); + pm_runtime_mark_last_busy(lpm->dev); + pm_runtime_put_autosuspend(lpm->dev); + pm_wakeup_dev_event(lpm->dev, NITROUS_AUTOSUSPEND_DELAY, false); + } return IRQ_HANDLED; } @@ -163,9 +173,9 @@ static int nitrous_lpm_runtime_enable(struct nitrous_bt_lpm *lpm) return 0; } + /* Set irq_host_wake as a trigger edge interrupt. */ rc = devm_request_irq(lpm->dev, lpm->irq_host_wake, nitrous_host_wake_isr, - lpm->wake_polarity ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING, - "bt_host_wake", lpm); + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "bt_host_wake", lpm); if (unlikely(rc)) { dev_err(lpm->dev, "Unable to request IRQ for bt_host_wake GPIO\n"); logbuffer_log(lpm->log, "Unable to request IRQ for bt_host_wake GPIO"); @@ -194,6 +204,7 @@ static void nitrous_lpm_runtime_disable(struct nitrous_bt_lpm *lpm) devm_free_irq(lpm->dev, lpm->irq_host_wake, lpm); device_init_wakeup(lpm->dev, false); + pm_relax(lpm->dev); pm_runtime_disable(lpm->dev); pm_runtime_set_suspended(lpm->dev); @@ -416,6 +427,7 @@ static int nitrous_lpm_init(struct nitrous_bt_lpm *lpm) goto fail; } } + return 0; fail: |