Ejemplo n.º 1
0
/*
 * This is mostly serial8250_handle_irq(). We have a slightly different DMA
 * hoook for RX/TX and need different logic for them in the ISR. Therefore we
 * use the default routine in the non-DMA case and this one for with DMA.
 */
static int omap_8250_dma_handle_irq(struct uart_port *port)
{
	struct uart_8250_port *up = up_to_u8250p(port);
	unsigned char status;
	unsigned long flags;
	u8 iir;
	int dma_err = 0;

	serial8250_rpm_get(up);

	iir = serial_port_in(port, UART_IIR);
	if (iir & UART_IIR_NO_INT) {
		serial8250_rpm_put(up);
		return 0;
	}

	spin_lock_irqsave(&port->lock, flags);

	status = serial_port_in(port, UART_LSR);

	if (status & (UART_LSR_DR | UART_LSR_BI)) {

		dma_err = omap_8250_rx_dma(up, iir);
		if (dma_err) {
			status = serial8250_rx_chars(up, status);
			omap_8250_rx_dma(up, 0);
		}
	}
	serial8250_modem_status(up);
	if (status & UART_LSR_THRE && up->dma->tx_err) {
		if (uart_tx_stopped(&up->port) ||
		    uart_circ_empty(&up->port.state->xmit)) {
			up->dma->tx_err = 0;
			serial8250_tx_chars(up);
		} else  {
			/*
			 * try again due to an earlier failer which
			 * might have been resolved by now.
			 */
			dma_err = omap_8250_tx_dma(up);
			if (dma_err)
				serial8250_tx_chars(up);
		}
	}

	spin_unlock_irqrestore(&port->lock, flags);
	serial8250_rpm_put(up);
	return 1;
}
Ejemplo n.º 2
0
static int omap8250_runtime_suspend(struct device *dev)
{
	struct omap8250_priv *priv = dev_get_drvdata(dev);
	struct uart_8250_port *up;

	up = serial8250_get_port(priv->line);
	/*
	 * When using 'no_console_suspend', the console UART must not be
	 * suspended. Since driver suspend is managed by runtime suspend,
	 * preventing runtime suspend (by returning error) will keep device
	 * active during suspend.
	 */
	if (priv->is_suspending && !console_suspend_enabled) {
		if (uart_console(&up->port))
			return -EBUSY;
	}

	omap8250_enable_wakeup(priv, true);
	if (up->dma)
		omap_8250_rx_dma(up, UART_IIR_RX_TIMEOUT);

	priv->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
	schedule_work(&priv->qos_work);

	return 0;
}
Ejemplo n.º 3
0
static void __dma_rx_complete(void *param)
{
	struct uart_8250_port *p = param;
	struct omap8250_priv *priv = p->port.private_data;
	struct uart_8250_dma *dma = p->dma;
	struct dma_tx_state     state;
	unsigned long flags;

	spin_lock_irqsave(&p->port.lock, flags);

	/*
	 * If the tx status is not DMA_COMPLETE, then this is a delayed
	 * completion callback. A previous RX timeout flush would have
	 * already pushed the data, so exit.
	 */
	if (dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state) !=
			DMA_COMPLETE) {
		spin_unlock_irqrestore(&p->port.lock, flags);
		return;
	}
	__dma_rx_do_complete(p);
	if (!priv->throttled)
		omap_8250_rx_dma(p);

	spin_unlock_irqrestore(&p->port.lock, flags);
}
Ejemplo n.º 4
0
static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
{
	switch (iir & 0x3f) {
	case UART_IIR_RLSI:
	case UART_IIR_RX_TIMEOUT:
	case UART_IIR_RDI:
		omap_8250_rx_dma_flush(up);
		return true;
	}
	return omap_8250_rx_dma(up);
}
Ejemplo n.º 5
0
static int omap8250_runtime_resume(struct device *dev)
{
	struct omap8250_priv *priv = dev_get_drvdata(dev);
	struct uart_8250_port *up;

	/* In case runtime-pm tries this before we are setup */
	if (!priv)
		return 0;

	up = serial8250_get_port(priv->line);

	if (omap8250_lost_context(up))
		omap8250_restore_regs(up);

	if (up->dma && up->dma->rxchan)
		omap_8250_rx_dma(up);

	priv->latency = priv->calc_latency;
	schedule_work(&priv->qos_work);
	return 0;
}
Ejemplo n.º 6
0
static void __dma_rx_do_complete(struct uart_8250_port *p, bool error)
{
	struct uart_8250_dma    *dma = p->dma;
	struct tty_port         *tty_port = &p->port.state->port;
	struct dma_tx_state     state;
	int                     count;

	dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
				dma->rx_size, DMA_FROM_DEVICE);

	dma->rx_running = 0;
	dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
	dmaengine_terminate_all(dma->rxchan);

	count = dma->rx_size - state.residue;

	tty_insert_flip_string(tty_port, dma->rx_buf, count);
	p->port.icount.rx += count;
	if (!error)
		omap_8250_rx_dma(p, 0);

	tty_flip_buffer_push(tty_port);
}
Ejemplo n.º 7
0
static int omap8250_runtime_resume(struct device *dev)
{
	struct omap8250_priv *priv = dev_get_drvdata(dev);
	struct uart_8250_port *up;
	int loss_cntx;

	/* In case runtime-pm tries this before we are setup */
	if (!priv)
		return 0;

	up = serial8250_get_port(priv->line);
	omap8250_enable_wakeup(priv, false);
	loss_cntx = omap8250_lost_context(up);

	if (loss_cntx)
		omap8250_restore_regs(up);

	if (up->dma)
		omap_8250_rx_dma(up, 0);

	priv->latency = priv->calc_latency;
	schedule_work(&priv->qos_work);
	return 0;
}
Ejemplo n.º 8
0
static void __dma_rx_complete(void *param)
{
	__dma_rx_do_complete(param);
	omap_8250_rx_dma(param);
}