uint8_t UARTDevice::Read8(uint32_t offset) { uint8_t ret; if (LCR & UART_LCR_DLAB) { switch (offset) { case UART_DLL: return DLL; break; case UART_DLH: return DLH; break; } } switch (offset) { case 0: ret = input; input = 0; ClearInterrupt(UART_IIR_RDI); ClearInterrupt(UART_IIR_CTI); { std::lock_guard<std::mutex> lock(fifoMutex); if (fifo.size() >= 1) { input = fifo.front(); fifo.pop(); LSR |= UART_LSR_DATA_READY; } else { LSR &= ~UART_LSR_DATA_READY; } } return ret; case UART_IER: return IER & 0x0F; case UART_MSR: return MSR; case UART_IIR: { ret = (IIR & 0x0f) | 0xC0; // the two top bits are always set if (IIR == UART_IIR_THRI) { ClearInterrupt(UART_IIR_THRI); } return ret; } case UART_LCR: return LCR; case UART_LSR: return LSR; default: cpu->DebugMessage("INFO (UART): 8-bit read of unsupported offset 0x%08x", offset); return 0; } }
static irqreturn_t isicom_interrupt(int irq, void *dev_id) { struct isi_board *card = dev_id; struct isi_port *port; struct tty_struct *tty; unsigned long base; u16 header, word_count, count, channel; short byte_count; unsigned char *rp; if (!card || !(card->status & FIRMWARE_LOADED)) return IRQ_NONE; base = card->base; /* did the card interrupt us? */ if (!(inw(base + 0x0e) & 0x02)) return IRQ_NONE; spin_lock(&card->card_lock); /* * disable any interrupts from the PCI card and lower the * interrupt line */ outw(0x8000, base+0x04); ClearInterrupt(base); inw(base); /* get the dummy word out */ header = inw(base); channel = (header & 0x7800) >> card->shift_count; byte_count = header & 0xff; if (channel + 1 > card->port_count) { printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): " "%d(channel) > port_count.\n", base, channel+1); outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; } port = card->ports + channel; if (!(port->flags & ASYNC_INITIALIZED)) { outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; } tty = port->tty; if (tty == NULL) { word_count = byte_count >> 1; while(byte_count > 1) { inw(base); byte_count -= 2; } if (byte_count & 0x01) inw(base); outw(0x0000, base+0x04); /* enable interrupts */ spin_unlock(&card->card_lock); return IRQ_HANDLED; }
void CPdd6410Uart::PostInit() { DWORD dwCount=0; m_HardwareLock.Lock(); m_pReg6410Uart->Write_UCON(0); // Set to Default; DisableInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM); // Mask all interrupt. while ((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))!=0 && dwCount <MAX_RETRY) { InitReceive(TRUE); InitLine(TRUE); ClearInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM); dwCount++; } ASSERT((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))==0); m_HardwareLock.Unlock(); CSerialPDD::PostInit(); CeSetPriority(m_dwPriority256); #ifdef DEBUG if ( ZONE_INIT ) { m_pReg6410Uart->DumpRegister(); } #endif ThreadStart(); // Start IST. }
void Timer_ConfigureInterrupt(void) { SetInterruptHandler(); ConfigureInterruptSourceModeRegister(); ClearInterrupt(); EnableCompareInterruptForRegisterC(); }
int IntrHandler(void *arg) { unsigned int source; source = ClearInterrupt(); printk(KERN_DEBUG PFX "Received PPS IRQ source=%08x\n", source); return 0; }
static irqreturn_t isicom_interrupt(int irq, void *dev_id) { struct isi_board *card = dev_id; struct isi_port *port; struct tty_struct *tty; unsigned long base; u16 header, word_count, count, channel; short byte_count; unsigned char *rp; if (!card || !(card->status & FIRMWARE_LOADED)) return IRQ_NONE; base = card->base; if (!(inw(base + 0x0e) & 0x02)) return IRQ_NONE; spin_lock(&card->card_lock); outw(0x8000, base+0x04); ClearInterrupt(base); inw(base); header = inw(base); channel = (header & 0x7800) >> card->shift_count; byte_count = header & 0xff; if (channel + 1 > card->port_count) { pr_warning("%s(0x%lx): %d(channel) > port_count.\n", __func__, base, channel+1); outw(0x0000, base+0x04); spin_unlock(&card->card_lock); return IRQ_HANDLED; } port = card->ports + channel; if (!(port->port.flags & ASYNC_INITIALIZED)) { outw(0x0000, base+0x04); spin_unlock(&card->card_lock); return IRQ_HANDLED; } tty = tty_port_tty_get(&port->port); if (tty == NULL) { word_count = byte_count >> 1; while (byte_count > 1) { inw(base); byte_count -= 2; } if (byte_count & 0x01) inw(base); outw(0x0000, base+0x04); spin_unlock(&card->card_lock); return IRQ_HANDLED; }
void UARTDevice::ReceiveChar(uint8_t x) { std::lock_guard<std::mutex> lock(fifoMutex); fifo.push(x); if (fifo.size() >= 1) { input = fifo.front(); fifo.pop(); ClearInterrupt(UART_IIR_CTI); LSR |= UART_LSR_DATA_READY; ThrowCTI(); } };
DWORD CPdd6410Uart::ThreadRun() { DWORD dwData; DWORD interrupts; while ( m_hISTEvent!=NULL && !IsTerminated() ) { if ( WaitForSingleObject( m_hISTEvent, m_dwISTTimeout) == WAIT_OBJECT_0) { m_HardwareLock.Lock(); while ( !IsTerminated() ) { dwData = ( GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM) ); if (dwData) { DEBUGMSG(ZONE_THREAD, (TEXT(" CPdd6410Uart::ThreadRun Active INT=%x\r\n"), dwData)); // Clear the interrupt value to notify to MDD interrupts=NULL; DEBUGCHK(interrupts==NULL); if ((dwData & S6410UART_INT_RXD)!=0) { interrupts |= INTR_RX; } if ((dwData & S6410UART_INT_TXD)!=0) { interrupts |= INTR_TX; } if ((dwData & S6410UART_INT_ERR)!=0) { interrupts |= INTR_LINE | INTR_RX; } if ((dwData & S6410UART_INT_MODEM)!=0) { interrupts |=INTR_MODEM; } NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts ); ClearInterrupt(dwData); } else { break; } } m_HardwareLock.Unlock(); InterruptDone(m_dwSysIntr); } else { DEBUGMSG(ZONE_THREAD,(TEXT(" CPdd6410Uart::ThreadRun timeout INT=%x,MASK=%d\r\n"),m_pReg6410Uart->Read_UINTP()/*m_pReg6410Uart->Read_UINTSP()*/, m_pReg6410Uart->Read_UINTM()) ); ASSERT(FALSE); } } return 1; }