static void nwpserial_console_write(struct console *co, const char *s, unsigned int count) { struct nwpserial_port *up = &nwpserial_ports[co->index]; unsigned long flags; int locked = 1; if (oops_in_progress) locked = spin_trylock_irqsave(&up->port.lock, flags); else spin_lock_irqsave(&up->port.lock, flags); /* save and disable interrupt */ up->ier = dcr_read(up->dcr_host, UART_IER); dcr_write(up->dcr_host, UART_IER, up->ier & ~UART_IER_RDI); uart_console_write(&up->port, s, count, nwpserial_console_putchar); /* wait for transmitter to become emtpy */ while ((dcr_read(up->dcr_host, UART_LSR) & UART_LSR_THRE) == 0) cpu_relax(); /* restore interrupt state */ dcr_write(up->dcr_host, UART_IER, up->ier); if (locked) spin_unlock_irqrestore(&up->port.lock, flags); }
static irqreturn_t nwpserial_interrupt(int irq, void *dev_id) { struct nwpserial_port *up = dev_id; struct tty_struct *tty = up->port.state->port.tty; irqreturn_t ret; unsigned int iir; unsigned char ch; spin_lock(&up->port.lock); /* check if the uart was the interrupt source. */ iir = dcr_read(up->dcr_host, UART_IIR); if (!iir) { ret = IRQ_NONE; goto out; } do { up->port.icount.rx++; ch = dcr_read(up->dcr_host, UART_RX); if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID) tty_insert_flip_char(tty, ch, TTY_NORMAL); } while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR); tty_flip_buffer_push(tty); ret = IRQ_HANDLED; /* clear interrupt */ dcr_write(up->dcr_host, UART_IIR, 1); out: spin_unlock(&up->port.lock); return ret; }
static int nwpserial_startup(struct uart_port *port) { struct nwpserial_port *up; int err; up = container_of(port, struct nwpserial_port, port); /* disable flow control by default */ up->mcr = dcr_read(up->dcr_host, UART_MCR) & ~UART_MCR_AFE; dcr_write(up->dcr_host, UART_MCR, up->mcr); /* register interrupt handler */ err = request_irq(up->port.irq, nwpserial_interrupt, IRQF_SHARED, "nwpserial", up); if (err) return err; /* enable interrupts */ up->ier = UART_IER_RDI; dcr_write(up->dcr_host, UART_IER, up->ier); /* enable receiving */ up->port.ignore_status_mask &= ~NWPSERIAL_STATUS_RXVALID; return 0; }
static void axon_msi_cascade(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); struct axon_msic *msic = irq_desc_get_handler_data(desc); u32 write_offset, msi; int idx; int retry = 0; write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG); pr_devel("axon_msi: original write_offset 0x%x\n", write_offset); /* write_offset doesn't wrap properly, so we have to mask it */ write_offset &= MSIC_FIFO_SIZE_MASK; while (msic->read_offset != write_offset && retry < 100) { idx = msic->read_offset / sizeof(__le32); msi = le32_to_cpu(msic->fifo_virt[idx]); msi &= 0xFFFF; pr_devel("axon_msi: woff %x roff %x msi %x\n", write_offset, msic->read_offset, msi); if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { generic_handle_irq(msi); msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); } else { /* * Reading the MSIC_WRITE_OFFSET_REG does not * reliably flush the outstanding DMA to the * FIFO buffer. Here we were reading stale * data, so we need to retry. */ udelay(1); retry++; pr_devel("axon_msi: invalid irq 0x%x!\n", msi); continue; } if (retry) { pr_devel("axon_msi: late irq 0x%x, retry %d\n", msi, retry); retry = 0; } msic->read_offset += MSIC_FIFO_ENTRY_SIZE; msic->read_offset &= MSIC_FIFO_SIZE_MASK; } if (retry) { printk(KERN_WARNING "axon_msi: irq timed out\n"); msic->read_offset += MSIC_FIFO_ENTRY_SIZE; msic->read_offset &= MSIC_FIFO_SIZE_MASK; } chip->irq_eoi(&desc->irq_data); }
static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose = pci_bus_to_host(bus); struct ppc4xx_pciex_port *port = &ppc4xx_pciex_ports[hose->indirect_type]; void __iomem *addr; u32 gpl_cfg; BUG_ON(hose != port->hose); if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; addr = ppc4xx_pciex_get_config_base(port, bus, devfn); /* * Reading from configuration space of non-existing device can * generate transaction errors. For the read duration we suppress * assertion of machine check exceptions to avoid those. */ gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); /* Make sure no CRS is recorded */ out_be32(port->utl_base + PEUTL_RCSTA, 0x00040000); switch (len) { case 1: *val = in_8((u8 *)(addr + offset)); break; case 2: *val = in_le16((u16 *)(addr + offset)); break; default: *val = in_le32((u32 *)(addr + offset)); break; } pr_debug("pcie-config-read: bus=%3d [%3d..%3d] devfn=0x%04x" " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", bus->number, hose->first_busno, hose->last_busno, devfn, offset, len, addr + offset, *val); /* Check for CRS (440SPe rev B does that for us but heh ..) */ if (in_be32(port->utl_base + PEUTL_RCSTA) & 0x00040000) { pr_debug("Got CRS !\n"); if (len != 4 || offset != 0) return PCIBIOS_DEVICE_NOT_FOUND; *val = 0xffff0001; } dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); return PCIBIOS_SUCCESSFUL; }
/// /// Read data from OSIF. /// /// This function performs DCR reads on the OSIF registers. Every registers has /// 32 bits. /// Although all OSIF registers should be read at once (in the correct order), /// we allow for shorter reads (down to single bytes), in case the user application /// wants to read the register contents one by one. /// Reads that exceed the last OSIF registers are truncated. The application can /// detect this condition by examining the number of read bytes. This, though, /// should not really happen. /// A warning is printed if the file position jumps unexpectedly (e.g. when not /// reading the registers consecutively). /// /// /// \param filp Pointer to kernel file structure /// \param buf Pointer to _user-space_ buffer /// \param count Number of bytes to read /// \param f_pos Offset into the DCR registers in bytes /// /// \return The number of written bytes /// ssize_t osif_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct osif_dev *dev = filp->private_data; //size_t to_copy = 0, remaining = 0; ssize_t retval; int reg_start; int reg_count; int i; PDEBUG("trying to read %d bytes from pos %ld\n", count, (unsigned long int)*f_pos); reg_count = count/4; reg_start = *f_pos/4; // block if there is no new data // (i.e. there have been no interrupts) if(reg_start < 3){ while (dev->irq_count == 0 && reg_start < 3) { // return if nonblocking operation is requested // FIXME: an alternative would be to break, this would read the // DCR data even if it is old if (filp->f_flags & O_NONBLOCK) return -EAGAIN; PDEBUG("osif: read with no new data, blocking\n"); // block; if interrupted, let fs layer handle it if (wait_event_interruptible(dev->read_queue, (dev->irq_count > 0))){ return -ERESTARTSYS; } } dev->irq_count--; } // okay, there seems to be data... reg_count = MIN(reg_count,OSIF_DCR_READSIZE - reg_start); for(i = reg_start; i < reg_start + reg_count; i++){ dev->read_buffer[i] = dcr_read(dev->dcr_host,i); PDEBUG("read 0x%08X from register %d (DCR address 0x%08X)\n", dev->read_buffer[i], i, DCR_ADDR(dev->dcr_host) + i); } // bytewise copy data from read buffer to user space if (copy_to_user(buf, &((char *)(dev->read_buffer))[*f_pos], count)){ retval = -EFAULT; } else { retval = count; } *f_pos = 0; return retval; }
int mvpstb_video_end(void) { int wlr; if (dcr_read(VIDEO_CLIP_WLR, &wlr) < 0) return -1; if (wlr == 0) return 1; else return 0; }
int mvpstb_audio_end(void) { int wlr; if (dcr_read(AUDIO_DSP_STATUS, &wlr) < 0) return -1; if (wlr == 0) return 1; else return 0; }
static void wait_for_bits(struct nwpserial_port *up, int bits) { unsigned int status, tmout = 10000; /* Wait up to 10ms for the character(s) to be sent. */ do { status = dcr_read(up->dcr_host, UART_LSR); if (--tmout == 0) break; udelay(1); } while ((status & bits) != bits); }
static unsigned int nwpserial_tx_empty(struct uart_port *port) { struct nwpserial_port *up; unsigned long flags; int ret; up = container_of(port, struct nwpserial_port, port); spin_lock_irqsave(&up->port.lock, flags); ret = dcr_read(up->dcr_host, UART_LSR); spin_unlock_irqrestore(&up->port.lock, flags); return ret & UART_LSR_TEMT ? TIOCSER_TEMT : 0; }
static u32 xilinx_fb_in32(struct xilinxfb_drvdata *drvdata, u32 offset) { if (drvdata->flags & BUS_ACCESS_FLAG) { if (drvdata->flags & LITTLE_ENDIAN_ACCESS) return ioread32(drvdata->regs + (offset << 2)); else return ioread32be(drvdata->regs + (offset << 2)); } #ifdef CONFIG_PPC_DCR else return dcr_read(drvdata->dcr_host, offset); #endif return 0; }
static inline u32 _mpic_read(enum mpic_reg_type type, struct mpic_reg_bank *rb, unsigned int reg) { switch(type) { #ifdef CONFIG_PPC_DCR case mpic_access_dcr: return dcr_read(rb->dhost, reg); #endif case mpic_access_mmio_be: return in_be32(rb->base + (reg >> 2)); case mpic_access_mmio_le: default: return in_le32(rb->base + (reg >> 2)); } }
static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 val) { struct pci_controller *hose = pci_bus_to_host(bus); struct ppc4xx_pciex_port *port = &ppc4xx_pciex_ports[hose->indirect_type]; void __iomem *addr; u32 gpl_cfg; if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; addr = ppc4xx_pciex_get_config_base(port, bus, devfn); /* * Reading from configuration space of non-existing device can * generate transaction errors. For the read duration we suppress * assertion of machine check exceptions to avoid those. */ gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); pr_debug("pcie-config-write: bus=%3d [%3d..%3d] devfn=0x%04x" " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", bus->number, hose->first_busno, hose->last_busno, devfn, offset, len, addr + offset, val); switch (len) { case 1: out_8((u8 *)(addr + offset), val); break; case 2: out_le16((u16 *)(addr + offset), val); break; default: out_le32((u32 *)(addr + offset), val); break; } dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); return PCIBIOS_SUCCESSFUL; }
static ssize_t dcrraw_read(struct file *filp, char __user *buf, size_t len, loff_t *off) { unsigned long res; unsigned long dcrn; if(len != 4) return -EINVAL; if(*off % 4 != 0) return -EINVAL; if(*off >= 4*1024) return -EINVAL; dcrn = (unsigned long)(*off / 4); //printk(KERN_WARNING "dcrraw: read from dcrn 0x%08lX\n", dcrn); res = dcr_read(dcrn); res = copy_to_user(buf, &res, 4); if(res){ //printk(KERN_WARNING "dcrraw: copy_to_user failed\n"); return -EFAULT; } return 4; }
uint32 tlb_hits(const reconos_tlb_t * tlb) { if(!tlb) return -1; return dcr_read(tlb->status1_dcrn); }
uint32 tlb_misses(const reconos_tlb_t * tlb) { if(!tlb) return -1; return dcr_read(tlb->status2_dcrn); }
/** * temac_dma_dcr_in32 - DCR based DMA read */ static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) { return dcr_read(lp->sdma_dcrs, reg); }
int mvpstb_get_lbox_offset(unsigned int *offset) { return(dcr_read(VIDEO_LETTERBOX_OFFSET,offset)); }