Update Linux kernel release to v7.2.8-2 for base and BORE kernels
Signed-off-by: Krzysztof Wilczyński <kwilczynski@omarchy.org>
This commit is contained in:
524 files changed
+147294
-88760
No files matched your search
@@ -0,0 +1,113 @@
|
||||
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
|
||||
--- a/drivers/bluetooth/btintel_pcie.c
|
||||
+++ b/drivers/bluetooth/btintel_pcie.c
|
||||
@@ -1012,6 +1012,10 @@ static void btintel_pcie_msix_gp0_handler(struct btintel_pcie_data *data)
|
||||
submit_rx = false;
|
||||
signal_waitq = false;
|
||||
|
||||
+ /* Serialize the alive_intr_ctxt claim against set_dxstate()'s
|
||||
+ * register-based fallback, which can run concurrently.
|
||||
+ */
|
||||
+ spin_lock(&data->irq_lock);
|
||||
switch (data->alive_intr_ctxt) {
|
||||
case BTINTEL_PCIE_ROM:
|
||||
data->alive_intr_ctxt = BTINTEL_PCIE_FW_DL;
|
||||
@@ -1067,6 +1071,7 @@ static void btintel_pcie_msix_gp0_handler(struct btintel_pcie_data *data)
|
||||
data->alive_intr_ctxt);
|
||||
break;
|
||||
}
|
||||
+ spin_unlock(&data->irq_lock);
|
||||
|
||||
if (submit_rx) {
|
||||
btintel_pcie_reset_ia(data);
|
||||
@@ -3047,7 +3052,7 @@ static void btintel_pcie_coredump(struct device *dev)
|
||||
|
||||
static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
|
||||
{
|
||||
- int retry = 0;
|
||||
+ int retry = 0, err;
|
||||
long status;
|
||||
u32 dx_intr_timeout_ms = 200;
|
||||
|
||||
@@ -3059,30 +3064,66 @@ static int btintel_pcie_set_dxstate(struct btintel_pcie_data *data, u32 dxstate)
|
||||
status = wait_event_timeout(data->gp0_wait_q, data->gp0_received,
|
||||
msecs_to_jiffies(dx_intr_timeout_ms));
|
||||
|
||||
- if (status)
|
||||
- return 0;
|
||||
+ if (!status) {
|
||||
+ bt_dev_warn(data->hdev,
|
||||
+ "Timeout (%u ms) on alive interrupt for D%d entry, retry count %d",
|
||||
+ dx_intr_timeout_ms, dxstate, retry);
|
||||
|
||||
- bt_dev_warn(data->hdev,
|
||||
- "Timeout (%u ms) on alive interrupt for D%d entry, retry count %d",
|
||||
- dx_intr_timeout_ms, dxstate, retry);
|
||||
+ /* clear gp0 cause */
|
||||
+ btintel_pcie_clr_reg_bits(data,
|
||||
+ BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
|
||||
+ BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
|
||||
+ }
|
||||
|
||||
- /* clear gp0 cause */
|
||||
- btintel_pcie_clr_reg_bits(data,
|
||||
- BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES,
|
||||
- BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0);
|
||||
-
|
||||
- /* A hardware bug may cause the alive interrupt to be missed. Refresh
|
||||
- * boot_stage_cache from hardware, since only the interrupt handler
|
||||
- * updates it. Finally retry only if the state check still fails.
|
||||
+ /* gp0_received is set at the top of the handler, before the switch on
|
||||
+ * alive_intr_ctxt. Error and lockdown are filtered out above it, but a
|
||||
+ * matched case can still complete without doing anything - D3 breaks
|
||||
+ * unchanged while the controller has not reached D0 - and a hardware
|
||||
+ * bug may drop the interrupt outright. Either way the flag says a gp0
|
||||
+ * was handled, not that the transition completed, and only the register
|
||||
+ * knows. Refresh the cache here and retry only if the state check still
|
||||
+ * fails.
|
||||
*/
|
||||
data->boot_stage_cache = btintel_pcie_rd_reg32(data,
|
||||
BTINTEL_PCIE_CSR_BOOT_STAGE_REG);
|
||||
if (dxstate == BTINTEL_PCIE_STATE_D0) {
|
||||
- if (btintel_pcie_in_d0(data))
|
||||
+ if (btintel_pcie_in_d0(data)) {
|
||||
+ bool armed;
|
||||
+
|
||||
+ /* Claim the transition under irq_lock so a
|
||||
+ * concurrent gp0 handler run cannot also arm RX.
|
||||
+ */
|
||||
+ spin_lock(&data->irq_lock);
|
||||
+ armed = data->alive_intr_ctxt == BTINTEL_PCIE_D0;
|
||||
+ if (!armed)
|
||||
+ data->alive_intr_ctxt = BTINTEL_PCIE_D0;
|
||||
+ spin_unlock(&data->irq_lock);
|
||||
+
|
||||
+ if (armed)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Do what the handler's D3 -> D0 branch
|
||||
+ * would have done, unless it already has.
|
||||
+ */
|
||||
+ btintel_pcie_reset_ia(data);
|
||||
+ err = btintel_pcie_start_rx(data);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
return 0;
|
||||
+ }
|
||||
} else {
|
||||
- if (btintel_pcie_in_d3(data))
|
||||
+ if (btintel_pcie_in_d3(data)) {
|
||||
+ /* Do what the handler's D0 -> D3 branch
|
||||
+ * would have done, unless it already has.
|
||||
+ */
|
||||
+ spin_lock(&data->irq_lock);
|
||||
+ if (data->alive_intr_ctxt != BTINTEL_PCIE_D3)
|
||||
+ data->alive_intr_ctxt = BTINTEL_PCIE_D3;
|
||||
+ spin_unlock(&data->irq_lock);
|
||||
+
|
||||
return 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
} while (++retry < BTINTEL_PCIE_DX_TRANSITION_MAX_RETRIES);
|
||||
Reference in new issue
Block a user