static void
serial_omap_console_write(struct console *co, const char *s,
		unsigned int count)
{
	struct uart_omap_port *up = serial_omap_console_ports[co->index];
	unsigned long flags;
	unsigned int ier;
	int locked = 1;

	pm_runtime_get_sync(&up->pdev->dev);

	local_irq_save(flags);
	if (up->port.sysrq)
		locked = 0;
	else if (oops_in_progress)
		locked = spin_trylock(&up->port.lock);
	else
		spin_lock(&up->port.lock);

	ier = serial_in(up, UART_IER);
	serial_out(up, UART_IER, 0);

	uart_console_write(&up->port, s, count, serial_omap_console_putchar);

	wait_for_xmitr(up);
	serial_out(up, UART_IER, ier);
	if (up->msr_saved_flags)
		check_modem_status(up);

	pm_runtime_mark_last_busy(&up->pdev->dev);
	pm_runtime_put_autosuspend(&up->pdev->dev);
	if (locked)
		spin_unlock(&up->port.lock);
	local_irq_restore(flags);
}
示例#2
0
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned long flags;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;

	spin_lock_irqsave(&up->port.lock, flags);
	lsr = serial_in(up, UART_LSR);
	if (iir & UART_IIR_RLSI) {
		if (!up->use_dma) {
			if (lsr & UART_LSR_DR)
				receive_chars(up, &lsr);
		} else {
			up->ier &= ~(UART_IER_RDI | UART_IER_RLSI);
			serial_out(up, UART_IER, up->ier);
			if ((serial_omap_start_rxdma(up) != 0) &&
					(lsr & UART_LSR_DR))
				receive_chars(up, &lsr);
		}
	}

	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI))
		transmit_chars(up);

	spin_unlock_irqrestore(&up->port.lock, flags);
	up->port_activity = jiffies;
	return IRQ_HANDLED;
}
/*
 * This handles the interrupt from one port.
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;
	lsr = serial_in(up, UART_LSR);
	if ((iir & 0x4) && up->use_dma) {
		up->ier &= ~UART_IER_RDI;
		serial_out(up, UART_IER, up->ier);
		serial_omap_start_rxdma(up);
	}
	else if (lsr & UART_LSR_DR) {
		receive_chars(up, &lsr);
	}
	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & 0x2)) {
		transmit_chars(up);
	}
	isr8250_activity = jiffies;

	return IRQ_HANDLED;
}
/*
 * Print a string to the serial port trying not to disturb
 * any possible real use of the port...
 *
 *	The console_lock must be held when we get here.
 */
static void
serial_omap_console_write(struct console *co, const char *s,
		unsigned int count)
{
	/* TBD: In 8250 interrupts were disabled in the beginning of this
	 * function and enabled in the end. We might need to do the same*/
	struct uart_omap_port *up = serial_omap_console_ports[co->index];
	unsigned int ier;

	/*
	 *	First save the IER then disable the interrupts
	 */
	ier = serial_in(up, UART_IER);
	serial_out(up, UART_IER, 0);

	uart_console_write(&up->port, s, count, serial_omap_console_putchar);

	/*
	 *	Finally, wait for transmitter to become empty
	 *	and restore the IER
	 */
	wait_for_xmitr(up);
	serial_out(up, UART_IER, ier);
	/*
	 *	The receive handling will happen properly because the
	 *	receive ready bit will still be set; it is not cleared
	 *	on read.  However, modem control will not, we must
	 *	call it if we have saved something in the saved flags
	 *	while processing with interrupts off.
	 */
	if (up->msr_saved_flags)
		check_modem_status(up);
}
示例#5
0
/*
 * This handles the interrupt from one port.
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;
	lsr = serial_in(up, UART_LSR);
	if ((iir & 0x4) && up->use_dma) {
		up->ier &= ~UART_IER_RDI;
		serial_out(up, UART_IER, up->ier);
		serial_omap_start_rxdma(up);
	} else if (lsr & UART_LSR_DR) {
		receive_chars(up, &lsr);
		/* XXX: After driver resume optimization, lower this */
		wake_lock_timeout(&omap_serial_wakelock, (HZ * 1));
	}
	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & 0x2))
		transmit_chars(up);
	isr8250_activity = jiffies;

	return IRQ_HANDLED;
}
示例#6
0
static irqreturn_t
ser_interrupt(int irq, void *dev_id)
{
	struct uart_cris_port *up = (struct uart_cris_port *)dev_id;
	void __iomem *regi_ser;
	int handled = 0;

	spin_lock(&up->port.lock);

	regi_ser = up->regi_ser;

	if (regi_ser) {
		reg_ser_r_masked_intr masked_intr;

		masked_intr = REG_RD(ser, regi_ser, r_masked_intr);
		/*
		 * Check what interrupts are active before taking
		 * actions. If DMA is used the interrupt shouldn't
		 * be enabled.
		 */
		if (masked_intr.dav) {
			receive_chars_no_dma(up);
			handled = 1;
		}
		check_modem_status(up);

		if (masked_intr.tr_rdy) {
			transmit_chars_no_dma(up);
			handled = 1;
		}
	}
	spin_unlock(&up->port.lock);
	return IRQ_RETVAL(handled);
}
示例#7
0
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	struct tty_struct *tty = up->port.state->port.tty;
	unsigned int iir, lsr;
	unsigned int type;
	irqreturn_t ret = IRQ_NONE;
	int max_count = 256;

	spin_lock(&up->port.lock);
	pm_runtime_get_sync(up->dev);

	do {
		iir = serial_in(up, UART_IIR);
		if (iir & UART_IIR_NO_INT)
			break;

		ret = IRQ_HANDLED;
		lsr = serial_in(up, UART_LSR);

		/* extract IRQ type from IIR register */
		type = iir & 0x3e;

		switch (type) {
		case UART_IIR_MSI:
			check_modem_status(up);
			break;
		case UART_IIR_THRI:
			transmit_chars(up, lsr);
			break;
		case UART_IIR_RX_TIMEOUT:
			/* FALLTHROUGH */
		case UART_IIR_RDI:
			serial_omap_rdi(up, lsr);
			break;
		case UART_IIR_RLSI:
			serial_omap_rlsi(up, lsr);
			break;
		case UART_IIR_CTS_RTS_DSR:
			/* simply try again */
			break;
		case UART_IIR_XOFF:
			/* FALLTHROUGH */
		default:
			break;
		}
	} while (!(iir & UART_IIR_NO_INT) && max_count--);

	spin_unlock(&up->port.lock);

	tty_flip_buffer_push(tty);

	pm_runtime_mark_last_busy(up->dev);
	pm_runtime_put_autosuspend(up->dev);
	up->port_activity = jiffies;

	return ret;
}
示例#8
0
文件: amiserial.c 项目: kprog/linux
static irqreturn_t ser_vbl_int( int irq, void *data)
{
        /* vbl is just a periodic interrupt we tie into to update modem status */
	struct serial_state *info = data;
	/*
	 * TBD - is it better to unregister from this interrupt or to
	 * ignore it if MSI is clear ?
	 */
	if(info->IER & UART_IER_MSI)
	  check_modem_status(info);
	return IRQ_HANDLED;
}
示例#9
0
文件: mfd.c 项目: ANFS/ANFS-kernel
/*
 * This handles the interrupt from one port.
 */
static irqreturn_t port_irq(int irq, void *dev_id)
{
	struct uart_hsu_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned long flags;

	if (unlikely(!up->running))
		return IRQ_NONE;

	spin_lock_irqsave(&up->port.lock, flags);
	if (up->use_dma) {
		lsr = serial_in(up, UART_LSR);
		if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE |
				       UART_LSR_FE | UART_LSR_OE)))
			dev_warn(up->dev,
				"Got lsr irq while using DMA, lsr = 0x%2x\n",
				lsr);
		check_modem_status(up);
		spin_unlock_irqrestore(&up->port.lock, flags);
		return IRQ_HANDLED;
	}

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT) {
		spin_unlock_irqrestore(&up->port.lock, flags);
		return IRQ_NONE;
	}

	lsr = serial_in(up, UART_LSR);
	if (lsr & UART_LSR_DR)
		receive_chars(up, &lsr);
	check_modem_status(up);

	/* lsr will be renewed during the receive_chars */
	if (lsr & UART_LSR_THRE)
		transmit_chars(up);

	spin_unlock_irqrestore(&up->port.lock, flags);
	return IRQ_HANDLED;
}
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned long flags;

	spin_lock_irqsave(&up->port.lock, flags);
#ifdef CONFIG_PM
	/*
	 * This will enable the clock for some reason if the
	 * clocks get disabled. This would enable the ICK also
	 * in case if the Idle state is set and the PRCM modul
	 * just shutdown the ICK because of inactivity.
	 */
	omap_uart_enable_clock_from_irq(up->pdev->id);
#endif

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT) {
		spin_unlock_irqrestore(&up->port.lock, flags);
		return IRQ_NONE;
	}

	lsr = serial_in(up, UART_LSR);
	if (iir & UART_IIR_RLSI) {
		if (!up->use_dma) {
			if (lsr & UART_LSR_DR) {
				receive_chars(up, &lsr);
				if (omap_is_console_port(&up->port) &&
						(up->plat_hold_wakelock)) {
					spin_unlock(&up->port.lock);
					up->plat_hold_wakelock(up, WAKELK_IRQ);
					spin_lock(&up->port.lock);
				}
			}
		} else {
			up->ier &= ~UART_IER_RDI;
			serial_out(up, UART_IER, up->ier);
			if (serial_omap_start_rxdma(up) != 0)
				if (lsr & UART_LSR_DR)
					receive_chars(up, &lsr);
		}
	}

	check_modem_status(up);
	if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI))
		transmit_chars(up);

	spin_unlock_irqrestore(&up->port.lock, flags);
	up->port_activity = jiffies;
	return IRQ_HANDLED;
}
示例#11
0
/*
 * This handles the interrupt from one port.
 */
static inline void
serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
{
	unsigned int status = serial_inp(up, UART_LSR);

	DEBUG_INTR("status = %x...", status);

	if (status & UART_LSR_DR)
		receive_chars(up, &status, regs);
	check_modem_status(up);
	if (status & UART_LSR_THRE)
		transmit_chars(up);
}
示例#12
0
static void
serial_omap_console_write(struct console *co, const char *s,
		unsigned int count)
{
	struct uart_omap_port *up = serial_omap_console_ports[co->index];
	unsigned long flags;
	unsigned int ier;
	int locked = 1;

	pm_runtime_get_sync(up->dev);

	local_irq_save(flags);
	if (up->port.sysrq)
		locked = 0;
	else if (oops_in_progress)
		locked = spin_trylock(&up->port.lock);
	else
		spin_lock(&up->port.lock);

	/*
	 * First save the IER then disable the interrupts
	 */
	ier = serial_in(up, UART_IER);
	serial_out(up, UART_IER, 0);

	uart_console_write(&up->port, s, count, serial_omap_console_putchar);

	/*
	 * Finally, wait for transmitter to become empty
	 * and restore the IER
	 */
	wait_for_xmitr(up);
	serial_out(up, UART_IER, ier);
	/*
	 * The receive handling will happen properly because the
	 * receive ready bit will still be set; it is not cleared
	 * on read.  However, modem control will not, we must
	 * call it if we have saved something in the saved flags
	 * while processing with interrupts off.
	 */
	if (up->msr_saved_flags)
		check_modem_status(up);

	pm_runtime_mark_last_busy(up->dev);
	pm_runtime_put_autosuspend(up->dev);
	if (locked)
		spin_unlock(&up->port.lock);
	local_irq_restore(flags);
}
/**
 * serial_omap_irq() - This handles the interrupt from one port
 * @irq: uart port irq number
 * @dev_id: uart port info
 */
static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
{
	struct uart_omap_port *up = dev_id;
	unsigned int iir, lsr;
	unsigned int int_id;
	unsigned long flags;
	int ret = IRQ_HANDLED;
	u8 tx_fifo_lvl;

	serial_omap_port_enable(up);
	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT) {
		serial_omap_port_disable(up);
		return IRQ_NONE;
	}

	int_id = iir & UART_OMAP_IIR_ID;

	spin_lock_irqsave(&up->port.lock, flags);
	lsr = serial_in(up, UART_LSR);
	if (int_id == UART_IIR_RDI || int_id == UART_OMAP_IIR_RX_TIMEOUT ||
	    int_id == UART_IIR_RLSI) {
		if (!up->use_dma) {
			if (lsr & UART_LSR_DR)
				receive_chars(up, &lsr);
		} else {
			up->ier &= ~(UART_IER_RDI | UART_IER_RLSI);
			serial_out(up, UART_IER, up->ier);
			if ((serial_omap_start_rxdma(up) != 0) &&
					(lsr & UART_LSR_DR))
				receive_chars(up, &lsr);
		}
	}

	check_modem_status(up);
	if (int_id == UART_IIR_THRI) {
		tx_fifo_lvl = serial_in(up, UART_OMAP_TXFIFO_LVL);
		if (lsr & UART_LSR_THRE || tx_fifo_lvl < up->port.fifosize)
			transmit_chars(up, tx_fifo_lvl);
		else
			ret = IRQ_NONE;
	}

	spin_unlock_irqrestore(&up->port.lock, flags);
	serial_omap_port_disable(up);

	up->port_activity = jiffies;
	return ret;
}
示例#14
0
/*
 * This handles the interrupt from one port.
 */
static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id)
{
	struct uart_pxa_port *up = dev_id;
	unsigned int iir, lsr;

	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;
	lsr = serial_in(up, UART_LSR);
	if (lsr & UART_LSR_DR)
		receive_chars(up, &lsr);
	check_modem_status(up);
	if (lsr & UART_LSR_THRE)
		transmit_chars(up);
	return IRQ_HANDLED;
}
示例#15
0
static unsigned int serial_omap_get_mctrl(struct uart_port *port)
{
	struct uart_omap_port *up = (struct uart_omap_port *)port;
	unsigned char status;
	unsigned int ret = 0;

	status = check_modem_status(up);
	dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id);

	if (status & UART_MSR_DCD)
		ret |= TIOCM_CAR;
	if (status & UART_MSR_RI)
		ret |= TIOCM_RNG;
	if (status & UART_MSR_DSR)
		ret |= TIOCM_DSR;
	if (status & UART_MSR_CTS)
		ret |= TIOCM_CTS;
	return ret;
}
示例#16
0
/* static void rs_360_interrupt(void *dev_id) */ /* until and if we start servicing irqs here */
static void rs_360_interrupt(int vec, void *dev_id)
{
	u_char	events;
	int	idx;
	ser_info_t *info;
	volatile struct smc_regs *smcp;
	volatile struct scc_regs *sccp;
	
	info = dev_id;

	idx = PORT_NUM(info->state->smc_scc_num);
	if (info->state->smc_scc_num & NUM_IS_SCC) {
		sccp = &pquicc->scc_regs[idx];
		events = sccp->scc_scce;
		if (events & SCCM_RX)
			receive_chars(info);
		if (events & SCCM_TX)
			transmit_chars(info);
		sccp->scc_scce = events;
	} else {
		smcp = &pquicc->smc_regs[idx];
		events = smcp->smc_smce;
		if (events & SMCM_BRKE)
			receive_break(info);
		if (events & SMCM_RX)
			receive_chars(info);
		if (events & SMCM_TX)
			transmit_chars(info);
		smcp->smc_smce = events;
	}
	
#ifdef SERIAL_DEBUG_INTR
	printk("rs_interrupt_single(%d, %x)...",
					info->state->smc_scc_num, events);
#endif
#ifdef modem_control
	check_modem_status(info);
#endif
	info->last_active = jiffies;
#ifdef SERIAL_DEBUG_INTR
	printk("end.\n");
#endif
}
/*
 * This handles the interrupt from one port.
 */
static inline irqreturn_t serial_pxa_irq(int irq, void *dev_id)
{
	struct uart_pxa_port *up = dev_id;
	unsigned int iir, lsr;

	/*
	 * If FCR[4] is set, we may receive EOC interrupt when:
	 * 1) current descritor of DMA finishes successfully;
	 * 2) there are still trailing bytes in UART FIFO.
	 * This interrupt alway comes along with UART_IIR_NO_INT.
	 * So this interrupt is just ignored by us.
	 */
	iir = serial_in(up, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;

	/* timer is not active */
	if (!mod_timer(&up->pxa_timer, jiffies + PXA_TIMER_TIMEOUT))
		pm_qos_update_request(&up->qos_idle[PXA_UART_RX],
				      up->lpm_qos);

	lsr = serial_in(up, UART_LSR);
	if (up->dma_enable) {
		/* we only need to deal with FIFOE here */
		if (lsr & UART_LSR_FIFOE)
			dma_receive_chars(up, &lsr);
	} else {
		if (lsr & UART_LSR_DR)
			receive_chars(up, &lsr);

		check_modem_status(up);
		if (lsr & UART_LSR_THRE) {
			transmit_chars(up);
			/* wait Tx empty */
			while (!serial_pxa_tx_empty(	\
						(struct uart_port *)dev_id))
				;
		}
	}

	return IRQ_HANDLED;
}
示例#18
0
static irqreturn_t siu_interrupt(int irq, void *dev_id)
{
	struct uart_port *port;
	uint8_t iir, lsr;

	port = (struct uart_port *)dev_id;

	iir = siu_read(port, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return IRQ_NONE;

	lsr = siu_read(port, UART_LSR);
	if (lsr & UART_LSR_DR)
		receive_chars(port, &lsr);

	check_modem_status(port);

	if (lsr & UART_LSR_THRE)
		transmit_chars(port);

	return IRQ_HANDLED;
}
示例#19
0
static unsigned int serial_omap_get_mctrl(struct uart_port *port)
{
	struct uart_omap_port *up = to_uart_omap_port(port);
	unsigned int status;
	unsigned int ret = 0;

	pm_runtime_get_sync(up->dev);
	status = check_modem_status(up);
	pm_runtime_mark_last_busy(up->dev);
	pm_runtime_put_autosuspend(up->dev);

	dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line);

	if (status & UART_MSR_DCD)
		ret |= TIOCM_CAR;
	if (status & UART_MSR_RI)
		ret |= TIOCM_RNG;
	if (status & UART_MSR_DSR)
		ret |= TIOCM_DSR;
	if (status & UART_MSR_CTS)
		ret |= TIOCM_CTS;
	return ret;
}
static void
serial_omap_console_write(struct console *co, const char *s,
		unsigned int count)
{
	struct uart_omap_port *up = serial_omap_console_ports[co->index];
	unsigned long flags;
	unsigned int ier;
	int console_lock = 0, locked = 1;

	if (console_trylock())
		console_lock = 1;

	/*
	 * If console_lock is not available and we are in suspending
	 * state then we can avoid the console usage scenario
	 * as this may introduce recursive prints.
	 * Basically this scenario occurs during boot while
	 * printing debug bootlogs.
	 */

	if (!console_lock &&
		up->pdev->dev.power.runtime_status == RPM_SUSPENDING)
		return;

	local_irq_save(flags);
	if (up->port.sysrq)
		locked = 0;
	else if (oops_in_progress)
		locked = spin_trylock(&up->port.lock);
	else
		spin_lock(&up->port.lock);

	serial_omap_port_enable(up);

	/*
	 * First save the IER then disable the interrupts
	 */
	ier = serial_in(up, UART_IER);
	serial_out(up, UART_IER, 0);

	uart_console_write(&up->port, s, count, serial_omap_console_putchar);

	/*
	 * Finally, wait for transmitter to become empty
	 * and restore the IER
	 */
	wait_for_xmitr(up);
	serial_out(up, UART_IER, ier);
	/*
	 * The receive handling will happen properly because the
	 * receive ready bit will still be set; it is not cleared
	 * on read.  However, modem control will not, we must
	 * call it if we have saved something in the saved flags
	 * while processing with interrupts off.
	 */
	if (up->msr_saved_flags)
		check_modem_status(up);

	if (console_lock)
		console_unlock();

	serial_omap_port_disable(up);
	if (locked)
		spin_unlock(&up->port.lock);
	local_irq_restore(flags);
}