Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2d6dd2a authored by Naveen Kaje's avatar Naveen Kaje
Browse files

msm_serial_hs: disable interrupts cleanly in shutdown



Clear and disable the interrupts when the port is closed
such that the interrupt state and the flags are consistent
and eliminate potential race condition.

Change-Id: I25310b30e236a990460127eddb1c3b4e7ade1550
Signed-off-by: default avatarNaveen Kaje <nkaje@codeaurora.org>
parent 41747adc
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -2196,11 +2196,11 @@ void toggle_wakeup_interrupt(struct msm_hs_port *msm_uport)
		return;

	if (!(msm_uport->wakeup.enabled)) {
		spin_lock_irqsave(&uport->lock, flags);
		msm_uport->wakeup.ignore = 1;
		MSM_HS_DBG("%s(): Enable Wakeup IRQ", __func__);
		enable_irq(msm_uport->wakeup.irq);
		disable_irq(uport->irq);
		spin_lock_irqsave(&uport->lock, flags);
		msm_uport->wakeup.ignore = 1;
		msm_uport->wakeup.enabled = true;
		spin_unlock_irqrestore(&uport->lock, flags);
	} else {
@@ -3482,6 +3482,7 @@ static void msm_hs_shutdown(struct uart_port *uport)
	struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
	struct circ_buf *tx_buf = &uport->state->xmit;
	int data;
	unsigned long flags;

	if (is_use_low_power_wakeup(msm_uport))
		irq_set_irq_wake(msm_uport->wakeup.irq, 0);
@@ -3491,7 +3492,18 @@ static void msm_hs_shutdown(struct uart_port *uport)
	else
		disable_irq(uport->irq);

	spin_lock_irqsave(&uport->lock, flags);
	msm_uport->wakeup.enabled = false;
	msm_uport->wakeup.ignore = 1;
	spin_unlock_irqrestore(&uport->lock, flags);

	/* Free the interrupt */
	free_irq(uport->irq, msm_uport);
	if (is_use_low_power_wakeup(msm_uport)) {
		free_irq(msm_uport->wakeup.irq, msm_uport);
		MSM_HS_DBG("%s(): wakeup irq freed", __func__);
	}
	msm_uport->wakeup.freed = true;

	/* make sure tx lh finishes */
	flush_kthread_worker(&msm_uport->tx.kworker);
@@ -3558,14 +3570,6 @@ static void msm_hs_shutdown(struct uart_port *uport)
		MSM_HS_WARN("%s: Client clock vote imbalance\n", __func__);
		atomic_set(&msm_uport->client_req_state, 0);
	}
	/* Free the interrupt */
	free_irq(uport->irq, msm_uport);
	if (is_use_low_power_wakeup(msm_uport)) {
		free_irq(msm_uport->wakeup.irq, msm_uport);
		MSM_HS_DBG("%s(): wakeup irq freed", __func__);
	}
	msm_uport->wakeup.freed = true;

	msm_hs_unconfig_uart_gpios(uport);
	MSM_HS_INFO("%s:UART port closed successfully\n", __func__);
}