summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormullerf <mullerf@google.com>2021-05-27 19:19:59 -0700
committerjonerlin <jonerlin@google.com>2021-06-03 16:52:19 +0800
commit51fdb329040f7a62d452d8beaf6fdb469c09cc80 (patch)
treeca0972661f1935b534740d33e6eb7161831ea10a
parenteadc62a0e3b80018ddb898454f6e330db7cfbcd7 (diff)
downloadbroadcom-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.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/nitrous.c b/nitrous.c
index 70021ed..4b87a6a 100644
--- a/nitrous.c
+++ b/nitrous.c
@@ -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: