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

Commit 756b932c 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 66529907 7ea9185a
Loading
Loading
Loading
Loading
+44 −43
Original line number Diff line number Diff line
@@ -122,11 +122,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
@@ -260,34 +260,23 @@ static bool 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);
	}
}

@@ -295,7 +284,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);

	/*
@@ -307,27 +295,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;
@@ -1424,12 +1402,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__);

@@ -1439,7 +1418,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;
@@ -1462,8 +1441,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);
		/*
@@ -1520,18 +1497,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,
@@ -1902,6 +1889,7 @@ static bool handle_tx_dma_xfer(u32 m_irq_status, struct uart_port *uport)

static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport)
{
	u32 rx_dma_len;
	bool ret = false;
	bool drop_rx = false;
	struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
@@ -1934,14 +1922,22 @@ static bool handle_rx_dma_xfer(u32 s_irq_status, struct uart_port *uport)
				uport->icount.brk);
		}

		if (dma_rx_status & RX_EOT || dma_rx_status & RX_DMA_DONE) {
			msm_geni_serial_handle_dma_rx(uport, drop_rx);
			if (!(dma_rx_status & RX_GENI_CANCEL_IRQ)) {
		if (dma_rx_status & RX_EOT ||
				dma_rx_status & RX_DMA_DONE) {
			msm_geni_serial_handle_dma_rx(uport,
						drop_rx);
			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);
			}
		}

		if (dma_rx_status & RX_SBE) {
			IPC_LOG_MSG(msm_port->ipc_log_misc,
				"%s.Rx Errors.  0x%x\n",
@@ -3218,7 +3214,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))