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

Commit 958e1dcc authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "serial: msm_geni_serial: Add enable/disable of dma irq bits"

parents 35976501 f733fefa
Loading
Loading
Loading
Loading
+39 −38
Original line number Diff line number Diff line
@@ -124,11 +124,11 @@
#define S_IRQ_BITS		(S_RX_FIFO_WATERMARK_EN | S_RX_FIFO_LAST_EN |\
				S_CMD_CANCEL_EN | S_CMD_ABORT_EN)
#define DMA_TX_IRQ_BITS		(TX_RESET_DONE | TX_DMA_DONE |\
				TX_GENI_CANCEL_IRQ)
				TX_GENI_CANCEL_IRQ | TX_EOT | TX_SBE)
#define DMA_RX_IRQ_BITS		(RX_EOT | RX_GENI_CANCEL_IRQ |\
				RX_RESET_DONE | UART_DMA_RX_ERRS |\
				UART_DMA_RX_PARITY_ERR | UART_DMA_RX_BREAK |\
				RX_DMA_DONE)
				RX_DMA_DONE | RX_SBE)

/* Required for polling for 100 msecs */
#define POLL_WAIT_TIMEOUT_MSEC	100
@@ -269,34 +269,23 @@ static int msm_geni_serial_spinlocked(struct uart_port *uport)
static void msm_geni_serial_enable_interrupts(struct uart_port *uport)
{
	unsigned int geni_m_irq_en, geni_s_irq_en;
	unsigned int dma_m_irq_en, dma_s_irq_en;
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);

	geni_m_irq_en = geni_read_reg_nolog(uport->membase,
						SE_GENI_M_IRQ_EN);
	geni_s_irq_en = geni_read_reg_nolog(uport->membase,
						SE_GENI_S_IRQ_EN);
	if (port->xfer_mode == SE_DMA) {
		dma_m_irq_en = geni_read_reg_nolog(uport->membase,
						SE_DMA_TX_IRQ_EN);
		dma_s_irq_en = geni_read_reg_nolog(uport->membase,
						SE_DMA_RX_IRQ_EN);
	}

	geni_m_irq_en |= M_IRQ_BITS;
	geni_s_irq_en |= S_IRQ_BITS;
	if (port->xfer_mode == SE_DMA) {
		dma_m_irq_en |= DMA_TX_IRQ_BITS;
		dma_s_irq_en |= DMA_RX_IRQ_BITS;
	}

	geni_write_reg_nolog(geni_m_irq_en, uport->membase, SE_GENI_M_IRQ_EN);
	geni_write_reg_nolog(geni_s_irq_en, uport->membase, SE_GENI_S_IRQ_EN);
	if (port->xfer_mode == SE_DMA) {
		geni_write_reg_nolog(dma_m_irq_en, uport->membase,
							SE_DMA_TX_IRQ_EN);
		geni_write_reg_nolog(dma_s_irq_en, uport->membase,
							SE_DMA_RX_IRQ_EN);
		geni_write_reg_nolog(DMA_TX_IRQ_BITS, uport->membase,
							SE_DMA_TX_IRQ_EN_SET);
		geni_write_reg_nolog(DMA_RX_IRQ_BITS, uport->membase,
							SE_DMA_RX_IRQ_EN_SET);
	}
}

@@ -304,7 +293,6 @@ static void msm_geni_serial_enable_interrupts(struct uart_port *uport)
static bool msm_serial_try_disable_interrupts(struct uart_port *uport)
{
	unsigned int geni_m_irq_en, geni_s_irq_en;
	unsigned int dma_m_irq_en, dma_s_irq_en;
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);

	/*
@@ -316,27 +304,17 @@ static bool msm_serial_try_disable_interrupts(struct uart_port *uport)

	geni_m_irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_M_IRQ_EN);
	geni_s_irq_en = geni_read_reg_nolog(uport->membase, SE_GENI_S_IRQ_EN);
	if (port->xfer_mode == SE_DMA) {
		dma_m_irq_en = geni_read_reg_nolog(uport->membase,
						SE_DMA_TX_IRQ_EN);
		dma_s_irq_en = geni_read_reg_nolog(uport->membase,
						SE_DMA_RX_IRQ_EN);
	}

	geni_m_irq_en &= ~M_IRQ_BITS;
	geni_s_irq_en &= ~S_IRQ_BITS;
	if (port->xfer_mode == SE_DMA) {
		dma_m_irq_en &= ~DMA_TX_IRQ_BITS;
		dma_s_irq_en &= ~DMA_RX_IRQ_BITS;
	}

	geni_write_reg_nolog(geni_m_irq_en, uport->membase, SE_GENI_M_IRQ_EN);
	geni_write_reg_nolog(geni_s_irq_en, uport->membase, SE_GENI_S_IRQ_EN);
	if (port->xfer_mode == SE_DMA) {
		geni_write_reg_nolog(dma_m_irq_en, uport->membase,
							SE_DMA_TX_IRQ_EN);
		geni_write_reg_nolog(dma_s_irq_en, uport->membase,
							SE_DMA_RX_IRQ_EN);
		geni_write_reg_nolog(DMA_TX_IRQ_BITS, uport->membase,
							SE_DMA_TX_IRQ_EN_CLR);
		geni_write_reg_nolog(DMA_RX_IRQ_BITS, uport->membase,
							SE_DMA_RX_IRQ_EN_CLR);
	}

	return true;
@@ -1444,12 +1422,13 @@ static void msm_geni_serial_set_manual_flow(bool enable,
	}
}

static void stop_rx_sequencer(struct uart_port *uport)
static int stop_rx_sequencer(struct uart_port *uport)
{
	unsigned int geni_status;
	bool timeout, is_irq_masked;
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
	unsigned long flags = 0;
	bool is_rx_active;

	IPC_LOG_MSG(port->ipc_log_misc, "%s\n", __func__);

@@ -1459,7 +1438,7 @@ static void stop_rx_sequencer(struct uart_port *uport)
		IPC_LOG_MSG(port->ipc_log_misc,
			"%s: RX is Inactive, geni_sts: 0x%x\n",
						__func__, geni_status);
		return;
		return 0;
	}

	port->s_cmd_done = false;
@@ -1482,7 +1461,6 @@ static void stop_rx_sequencer(struct uart_port *uport)
	mb();
	timeout = geni_wait_for_cmd_done(uport, is_irq_masked);
	if (timeout) {
		bool is_rx_active;
		geni_status = geni_read_reg_nolog(uport->membase,
							SE_GENI_STATUS);
		/*
@@ -1539,18 +1517,28 @@ static void stop_rx_sequencer(struct uart_port *uport)
	geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
	IPC_LOG_MSG(port->ipc_log_misc, "%s: End 0x%x\n",
		    __func__, geni_status);

	is_rx_active = geni_status & S_GENI_CMD_ACTIVE;
	if (is_rx_active)
		return -EBUSY;
	else
		return 0;
}

static void msm_geni_serial_stop_rx(struct uart_port *uport)
{
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
	int ret;

	if (!uart_console(uport) && device_pending_suspend(uport)) {
		IPC_LOG_MSG(port->ipc_log_misc,
				"%s.Device is suspended.\n", __func__);
		return;
	}
	stop_rx_sequencer(uport);
	ret = stop_rx_sequencer(uport);
	if (ret)
		IPC_LOG_MSG(port->ipc_log_misc, "%s: stop rx failed %d\n",
							__func__, ret);
}

static int handle_rx_hs(struct uart_port *uport,
@@ -1847,6 +1835,7 @@ static void msm_geni_serial_handle_isr(struct uart_port *uport,
	unsigned int dma_rx_status;
	unsigned int m_irq_en;
	unsigned int geni_status;
	u32 rx_dma_len;
	struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
	struct tty_port *tport = &uport->state->port;
	bool drop_rx = false;
@@ -1998,9 +1987,16 @@ static void msm_geni_serial_handle_isr(struct uart_port *uport,
					dma_rx_status & RX_DMA_DONE) {
				msm_geni_serial_handle_dma_rx(uport,
							drop_rx);
				if (!(dma_rx_status & RX_GENI_CANCEL_IRQ)) {
				rx_dma_len =
				geni_read_reg_nolog(uport->membase,
							SE_DMA_RX_LEN_IN);
				if (rx_dma_len != 0) {
					geni_se_rx_dma_start(uport->membase,
					DMA_RX_BUF_SIZE, &msm_port->rx_dma);
				} else {
					IPC_LOG_MSG(msm_port->ipc_log_misc,
						"%s.stop dma Rx 0x%x\n",
						__func__, dma_rx_status);
				}
			}

@@ -3398,7 +3394,12 @@ static int msm_geni_serial_runtime_suspend(struct device *dev)
	 * Disable Interrupt
	 * Resources off
	 */
	stop_rx_sequencer(&port->uport);
	ret = stop_rx_sequencer(&port->uport);
	if (ret) {
		IPC_LOG_MSG(port->ipc_log_pwr, "%s: stop rx failed %d\n",
							__func__, ret);
		return -EBUSY;
	}
	geni_status = geni_read_reg_nolog(port->uport.membase, SE_GENI_STATUS);

	if ((geni_status & M_GENI_CMD_ACTIVE))