diff options
author | mullerf <mullerf@google.com> | 2021-07-20 22:10:43 -0700 |
---|---|---|
committer | jonerlin <jonerlin@google.com> | 2021-07-22 17:20:04 +0800 |
commit | f554a2304b0a483b04a17822a3cb1f958ce80edd (patch) | |
tree | c94baa7cf25ee39eeee7d0087badb171bd7d3971 | |
parent | cbbfc2396418f529b94c771e12bbc0c3c8cd8741 (diff) | |
download | broadcom-f554a2304b0a483b04a17822a3cb1f958ce80edd.tar.gz |
Handle BT Rx outside of pm_runtime with its own SICD indexandroid-s-v2-beta-3_r0.6android-s-qpr3-beta-3_r0.5android-s-qpr3-beta-2_r0.5android-s-qpr3-beta-1_r0.6android-s-qpr3-beta-1_r0.5android-12.1.0_r0.6android-12.1.0_r0.40android-12.1.0_r0.35android-12.1.0_r0.28android-12.1.0_r0.22android-12.1.0_r0.16android-12.0.0_r0.9android-12.0.0_r0.8android-12.0.0_r0.42android-12.0.0_r0.36android-12.0.0_r0.26android-12.0.0_r0.17android-12.0.0_r0.16android-gs-raviole-5.10-s-v2-beta-3android-gs-raviole-5.10-s-qpr3-beta-3android-gs-raviole-5.10-s-qpr3-beta-2android-gs-raviole-5.10-android12Landroid-gs-raviole-5.10-android12-qpr3android-gs-raviole-5.10-android12-qpr1-dandroid-gs-raviole-5.10-android12-d1android-gs-bluejay-5.10-android12L-d2
There might be a corner case where host_isr wakes the system from
suspend and UART RTS goes low before nitrous_devcie_resume() gets
executed (since pm_runtime_get puts a work in queue to request the
device resume), but then goes low while a trnasfer is happening
because SICD_STATUS_BUSY was not set yet.
For that, handle SICD BUSY/IDLE through its own Rx index and move away
from pm_runtime routines, as this isn't needed anymore.
Test: Manual
Bug: 193466272
Signed-off-by: mullerf <mullerf@google.com>
Change-Id: I20ca5e865c4c100852166959abe055ddffc23075
Signed-off-by: jonerlin <jonerlin@google.com>
-rw-r--r-- | nitrous.c | 41 |
1 files changed, 17 insertions, 24 deletions
@@ -44,7 +44,7 @@ struct nitrous_bt_lpm { int wake_polarity; /* 0: active low; 1: active high */ bool is_suspended; /* driver is in suspend state */ - bool host_irq_dev_pm_resumed; + bool uart_tx_dev_pm_resumed; int irq_timesync; /* IRQ associated with TIMESYNC GPIO*/ int timesync_state; @@ -56,7 +56,8 @@ struct nitrous_bt_lpm { bool lpm_enabled; struct nitrous_lpm_proc *proc; struct logbuffer *log; - int idle_btip_index; + int idle_bt_tx_ip_index; + int idle_bt_rx_ip_index; }; #define PROC_BTWAKE 0 @@ -139,21 +140,10 @@ static irqreturn_t nitrous_host_wake_isr(int irq, void *data) if (host_wake == 1) { logbuffer_log(lpm->log, "host_wake_isr asserted"); pm_stay_awake(lpm->dev); - /* Only resume device when needed to keep usage count synced. - This is because some falling edges can be missed by irq. */ - if (!lpm->host_irq_dev_pm_resumed) { - pm_runtime_get(lpm->dev); - lpm->host_irq_dev_pm_resumed = true; - } + exynos_update_ip_idle_status(lpm->idle_bt_rx_ip_index, STATUS_BUSY); } else { logbuffer_log(lpm->log, "host_wake_isr de-asserted"); - pm_runtime_mark_last_busy(lpm->dev); - /* Only autosuspend device when needed to keep usage count synced. - This is because some rising edges can be missed by irq. */ - if (lpm->host_irq_dev_pm_resumed) { - pm_runtime_put_autosuspend(lpm->dev); - lpm->host_irq_dev_pm_resumed = false; - } + exynos_update_ip_idle_status(lpm->idle_bt_rx_ip_index, STATUS_IDLE); pm_wakeup_dev_event(lpm->dev, NITROUS_AUTOSUSPEND_DELAY, false); } @@ -248,9 +238,7 @@ static void nitrous_lpm_runtime_disable(struct nitrous_bt_lpm *lpm) pm_runtime_disable(lpm->dev); pm_runtime_set_suspended(lpm->dev); - /* Host IRQ has been freed, so safe to set this here */ - lpm->host_irq_dev_pm_resumed = false; - + lpm->uart_tx_dev_pm_resumed = false; lpm->lpm_enabled = false; } @@ -547,7 +535,8 @@ static int nitrous_rfkill_set_power(void *data, bool blocked) dev_dbg(lpm->dev, "REG_ON: Low"); gpiod_set_value_cansleep(lpm->gpio_power, false); msleep(30); - exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_BUSY); + exynos_update_ip_idle_status(lpm->idle_bt_tx_ip_index, STATUS_BUSY); + exynos_update_ip_idle_status(lpm->idle_bt_rx_ip_index, STATUS_BUSY); dev_dbg(lpm->dev, "REG_ON: High"); gpiod_set_value_cansleep(lpm->gpio_power, true); @@ -563,7 +552,8 @@ static int nitrous_rfkill_set_power(void *data, bool blocked) logbuffer_log(lpm->log, "Power down BT chip"); dev_dbg(lpm->dev, "REG_ON: Low"); gpiod_set_value_cansleep(lpm->gpio_power, false); - exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_IDLE); + exynos_update_ip_idle_status(lpm->idle_bt_tx_ip_index, STATUS_IDLE); + exynos_update_ip_idle_status(lpm->idle_bt_rx_ip_index, STATUS_IDLE); } lpm->rfkill_blocked = blocked; @@ -689,8 +679,11 @@ static int nitrous_probe(struct platform_device *pdev) platform_set_drvdata(pdev, lpm); - lpm->idle_btip_index = exynos_get_idle_ip_index("bluetooth"); - exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_IDLE); + lpm->idle_bt_tx_ip_index = exynos_get_idle_ip_index("bluetooth-tx"); + exynos_update_ip_idle_status(lpm->idle_bt_tx_ip_index, STATUS_IDLE); + + lpm->idle_bt_rx_ip_index = exynos_get_idle_ip_index("bluetooth-rx"); + exynos_update_ip_idle_status(lpm->idle_bt_rx_ip_index, STATUS_IDLE); logbuffer_log(lpm->log, "probe: successful"); @@ -735,7 +728,7 @@ static int nitrous_suspend_device(struct device *dev) (lpm->is_suspended ? "asleep" : "awake")); nitrous_wake_controller(lpm, false); - exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_IDLE); + exynos_update_ip_idle_status(lpm->idle_bt_tx_ip_index, STATUS_IDLE); lpm->is_suspended = true; return 0; @@ -750,7 +743,7 @@ static int nitrous_resume_device(struct device *dev) logbuffer_log(lpm->log, "resume_device from %s", (lpm->is_suspended ? "asleep" : "awake")); - exynos_update_ip_idle_status(lpm->idle_btip_index, STATUS_BUSY); + exynos_update_ip_idle_status(lpm->idle_bt_tx_ip_index, STATUS_BUSY); nitrous_wake_controller(lpm, true); lpm->is_suspended = false; |