/* * This is the serial driver's generic interrupt routine */ irqreturn_t rs_interrupt(int irq, void *dev_id) { struct m68k_serial *info = dev_id; struct tty_struct *tty = tty_port_tty_get(&info->tport); m68328_uart *uart; unsigned short rx; unsigned short tx; uart = &uart_addr[info->line]; rx = uart->urx.w; #ifdef USE_INTS tx = uart->utx.w; if (rx & URX_DATA_READY) receive_chars(info, rx); if (tx & UTX_TX_AVAIL) transmit_chars(info, tty); #else receive_chars(info, rx); #endif tty_kref_put(tty); return IRQ_HANDLED; }
static void max3110_console_receive(struct uart_max3110 *max) { int loop = 1, num, total = 0; u8 recv_buf[512], *pbuf; pbuf = recv_buf; do { num = max3110_read_multi(max, 8, pbuf); if (num) { loop = 10; pbuf += num; total += num; if (total >= 500) { receive_chars(max, recv_buf, total); pbuf = recv_buf; total = 0; } } } while (--loop); if (total) receive_chars(max, recv_buf, total); }
/* * Drain the Rx FIFO, called by interrupt handler. */ static void handle_receive(struct tile_uart_port *tile_uart) { struct tty_port *port = &tile_uart->uart.state->port; struct tty_struct *tty = tty_port_tty_get(port); gxio_uart_context_t *context = &tile_uart->context; if (!tty) return; /* First read UART rx fifo. */ receive_chars(tile_uart, tty); /* Reset RFIFO_WE interrupt. */ gxio_uart_write(context, UART_INTERRUPT_STATUS, UART_INTERRUPT_MASK__RFIFO_WE_MASK); /* Final read, if any chars comes between the first read and * the interrupt reset. */ receive_chars(tile_uart, tty); spin_unlock(&tile_uart->uart.lock); tty_flip_buffer_push(port); spin_lock(&tile_uart->uart.lock); tty_kref_put(tty); }
/* * This is the serial driver's generic interrupt routine */ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct m68k_serial * info; m68328_uart *uart; unsigned short rx; #ifdef USE_INTS unsigned short tx; #endif info = IRQ_ports[irq]; if(!info) return; uart = &uart_addr[info->line]; rx = uart->urx.w; #ifdef USE_INTS tx = uart->utx.w; if (rx & URX_DATA_READY) receive_chars(info, regs, rx); if (tx & UTX_TX_AVAIL) transmit_chars(info); #else receive_chars(info, regs, rx); #endif return; }
/** * 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; }
/** * 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; }
/** * 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; }
/* * 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; }
/* Write a 16b word to the device */ static int max3110_out(struct uart_max3110 *max, const u16 out) { void *buf; u16 *obuf, *ibuf; u8 ch; int ret; buf = kzalloc(8, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; obuf = buf; ibuf = buf + 4; *obuf = out; ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); if (ret) { pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", __func__, ret, out); goto exit; } /* If some valid data is read back */ if (*ibuf & MAX3110_READ_DATA_AVAILABLE) { ch = *ibuf & 0xff; receive_chars(max, &ch, 1); } exit: kfree(buf); return ret; }
/* * This handles the interrupt from one port. */ static irqreturn_t dpram_irq_rx(int irq, void *dev_id) { dprintk("dpram_irq_rx\n"); receive_chars(dev_id); 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; }
/* Write a 16b word to the device */ static int max3110_out(struct uart_max3110 *max, const u16 out) { void *buf; u16 *obuf, *ibuf; int ret; buf = kzalloc(8, GFP_KERNEL | GFP_DMA); if (!buf) return -ENOMEM; obuf = buf; ibuf = buf + 4; *obuf = out; ret = max3110_write_then_read(max, obuf, ibuf, 2, 1); if (ret) { pr_warning(PR_FMT "%s(): get err msg %d when sending 0x%x\n", __func__, ret, out); goto exit; } receive_chars(max, ibuf, 1); exit: kfree(buf); return ret; }
/* * This is usually used to read data from SPIC RX FIFO, which doesn't * need any delay like flushing character out. It returns how many * valide bytes are read back */ static int max3110_read_multi(struct uart_max3110 *max, int len, u8 *buf) { u16 out[MAX_READ_LEN], in[MAX_READ_LEN]; u8 *pbuf, valid_str[MAX_READ_LEN]; int i, j, bytelen; if (len > MAX_READ_LEN) { pr_err(PR_FMT "read len %d is too large\n", len); return 0; } bytelen = len * 2; memset(out, 0, bytelen); memset(in, 0, bytelen); if (max3110_write_then_read(max, (u8 *)out, (u8 *)in, bytelen, 1)) return 0; /* If caller don't provide a buffer, then handle received char */ pbuf = buf ? buf : valid_str; for (i = 0, j = 0; i < len; i++) { if (in[i] & MAX3110_READ_DATA_AVAILABLE) pbuf[j++] = (u8)(in[i] & 0xff); } if (j && (pbuf == valid_str)) receive_chars(max, valid_str, j); return j; }
/* * This is the serial driver's generic interrupt routine */ static irqreturn_t am_uart_interrupt(int irq, void *dev, struct pt_regs *regs) { struct am_uart_port *info=(struct am_uart_port *)dev; am_uart_t *uart = NULL; struct tty_struct *tty = NULL; if (!info) goto out; tty = info->port.state->port.tty; if (!tty) { goto out; } uart = uart_addr[info->line]; if (!uart) goto out; if (!(readl(&uart->status) & UART_RXEMPTY)){ receive_chars(info, 0, readl(&uart->rdata)); } if ((readl(&uart->mode) & UART_TXENB)&&!(readl(&uart->status) & UART_TXFULL)) { transmit_chars(info); } out: am_uart_sched_event(info, 0); return IRQ_HANDLED; }
static void rs_interrupt_elsa(struct IsdnCardState *cs) { int status, iir, msr; int pass_counter = 0; #ifdef SERIAL_DEBUG_INTR ; #endif do { status = serial_inp(cs, UART_LSR); debugl1(cs,"rs LSR %02x", status); #ifdef SERIAL_DEBUG_INTR ; #endif if (status & UART_LSR_DR) receive_chars(cs, &status); if (status & UART_LSR_THRE) transmit_chars(cs, NULL); if (pass_counter++ > RS_ISR_PASS_LIMIT) { ; break; } iir = serial_inp(cs, UART_IIR); debugl1(cs,"rs IIR %02x", iir); if ((iir & 0xf) == 0) { msr = serial_inp(cs, UART_MSR); debugl1(cs,"rs MSR %02x", msr); } } while (!(iir & UART_IIR_NO_INT)); #ifdef SERIAL_DEBUG_INTR ; #endif }
static void sci_rx_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int ch; for(ch=0;ch<NR_PORTS;ch++) if(rs_table[ch].irq+1==irq) receive_chars(&rs_table[ch]); }
/* * This is usually used to read data from SPIC RX FIFO, which doesn't * need any delay like flushing character out. * * Return how many valide bytes are read back */ static int max3110_read_multi(struct uart_max3110 *max) { void *buf; u16 *obuf, *ibuf; int ret, blen; blen = M3110_RX_FIFO_DEPTH * sizeof(u16); buf = kzalloc(blen * 2, GFP_KERNEL | GFP_DMA); if (!buf) { pr_warning(PR_FMT "%s(): fail to alloc dma buffer\n", __func__); return 0; } /* tx/rx always have the same length */ obuf = buf; ibuf = buf + blen; if (max3110_write_then_read(max, obuf, ibuf, blen, 1)) { kfree(buf); return 0; } ret = receive_chars(max, ibuf, M3110_RX_FIFO_DEPTH); kfree(buf); return ret; }
void rs_interrupt(int irq, void * dev_id, struct pt_regs * regs) { char status; struct cnxt_serial * info = &uart_info; struct uart_regs *uart = uart_info.uart; status = (uart->iir & 0x0f); /* only concerned w/ lower nibble */ if (status == ISR_Tx_Rdy_Source) { transmit_chars(info); } if ((status == ISR_Rx_Rdy_Source) || (status == ISR_Rx_Rdy_TO_Src )){ receive_chars(info,status); } #if 0 if(!info->use_ints){ serialpoll.data = (void *)&sp_uart_info; queue_task_irq_off(&serialpoll, &tq_timer); } #endif return; }
/* * This is the serial driver's interrupt routine for a single port */ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) { struct serial_state *info = dev_id; receive_chars(&info->port); return IRQ_HANDLED; }
/* * This is the serial driver's generic interrupt routine */ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct LEON_serial * info = &LEON_soft; unsigned int stat = leon->uartstatus1; if (stat & USTAT_DR) receive_chars(info, regs, stat); if (stat & USTAT_TH) transmit_chars(info); return; }
/* 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 void m32r_sio_handle_port(struct uart_sio_port *up, unsigned int status) { pr_debug("status = %x...\n", status); if (status & 0x04) receive_chars(up, &status); if (status & 0x01) transmit_chars(up); }
/* * This is the serial driver's generic interrupt routine */ void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct NIOS_serial * info = (struct NIOS_serial *) dev_id; np_uart * uart= (np_uart *)(info->port); unsigned short stat = uart->np_uartstatus; uart->np_uartstatus = 0; /* clear any error status */ if (stat & np_uartstatus_rrdy_mask) receive_chars(info, regs, stat); if (stat & np_uartstatus_trdy_mask) transmit_chars(info); return; }
/* * This is the serial driver's generic interrupt routine */ void gbatxt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct gbatxt_serial *info; unsigned char isr; info = &gbatxt_table[(irq - IRQBASE)]; isr = (((volatile unsigned char *)info->addr)[MCFUART_UISR]) & info->imr; if (isr & MCFUART_UIR_RXREADY) receive_chars(info, regs, isr); if (isr & MCFUART_UIR_TXREADY) transmit_chars(info); #if 0 if (isr & MCFUART_UIR_DELTABREAK) { printk("%s(%d): delta break!\n", __FILE__, __LINE__); receive_chars(info, regs, isr); } #endif return; }
/* * 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); }
static void send_circ_buf(struct uart_max3110 *max, struct circ_buf *xmit) { void *buf; u16 *obuf, *ibuf; u8 valid_str[WORDS_PER_XFER]; int i, j, len, blen, dma_size, left, ret = 0; dma_size = WORDS_PER_XFER * sizeof(u16) * 2; buf = kzalloc(dma_size, GFP_KERNEL | GFP_DMA); if (!buf) return; obuf = buf; ibuf = buf + dma_size/2; while (!uart_circ_empty(xmit)) { left = uart_circ_chars_pending(xmit); while (left) { len = min(left, WORDS_PER_XFER); blen = len * sizeof(u16); memset(ibuf, 0, blen); for (i = 0; i < len; i++) { obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); } /* Fail to send msg to console is not very critical */ ret = max3110_write_then_read(max, obuf, ibuf, blen, 0); if (ret) pr_warning(PR_FMT "%s(): get err msg %d\n", __func__, ret); for (i = 0, j = 0; i < len; i++) { if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE) valid_str[j++] = ibuf[i] & 0xff; } if (j) receive_chars(max, valid_str, j); max->port.icount.tx += len; left -= len; } } kfree(buf); }
/* * This is the serial driver's generic interrupt routine */ irqreturn_t mcfrs_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct mcf_serial *info; unsigned char isr; info = &mcfrs_table[(irq - IRQBASE)]; isr = info->addr[MCFUART_UISR] & info->imr; if (isr & MCFUART_UIR_RXREADY) receive_chars(info); if (isr & MCFUART_UIR_TXREADY) transmit_chars(info); return IRQ_HANDLED; }
static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) { struct uart_sc26xx_port *up = dev_id; unsigned long flags; bool push; u8 isr; spin_lock_irqsave(&up->port[0].lock, flags); push = false; isr = READ_SC(&up->port[0], ISR); if (isr & ISR_TXRDYA) transmit_chars(&up->port[0]); if (isr & ISR_RXRDYA) push = receive_chars(&up->port[0]); spin_unlock(&up->port[0].lock); if (push) tty_flip_buffer_push(&up->port[0].state->port); spin_lock(&up->port[1].lock); push = false; if (isr & ISR_TXRDYB) transmit_chars(&up->port[1]); if (isr & ISR_RXRDYB) push = receive_chars(&up->port[1]); spin_unlock_irqrestore(&up->port[1].lock, flags); if (push) tty_flip_buffer_push(&up->port[1].state->port); return IRQ_HANDLED; }
/* * ------------------------------------------------------------ * dz_interrupt () * * this is the main interrupt routine for the DZ chip. * It deals with the multiple ports. * ------------------------------------------------------------ */ static void dz_interrupt(int irq, void *dev, struct pt_regs *regs) { struct dz_serial *info; unsigned short status; /* get the reason why we just got an irq */ status = dz_in((struct dz_serial *) dev, DZ_CSR); info = lines[LINE(status)]; /* re-arrange info the proper port */ if (status & DZ_RDONE) receive_chars(info); /* the receive function */ if (status & DZ_TRDY) transmit_chars(info); }
static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) { struct uart_sc26xx_port *up = dev_id; struct tty_struct *tty; unsigned long flags; u8 isr; spin_lock_irqsave(&up->port[0].lock, flags); tty = NULL; isr = READ_SC(&up->port[0], ISR); if (isr & ISR_TXRDYA) transmit_chars(&up->port[0]); if (isr & ISR_RXRDYA) tty = receive_chars(&up->port[0]); spin_unlock(&up->port[0].lock); if (tty) tty_flip_buffer_push(tty); spin_lock(&up->port[1].lock); tty = NULL; if (isr & ISR_TXRDYB) transmit_chars(&up->port[1]); if (isr & ISR_RXRDYB) tty = receive_chars(&up->port[1]); spin_unlock_irqrestore(&up->port[1].lock, flags); if (tty) tty_flip_buffer_push(tty); return IRQ_HANDLED; }