static void sa1100_irda_shutdown(struct sa1100_irda *si) { /* * Stop all DMA activity. */ sa1100_stop_dma(si->rxdma); sa1100_stop_dma(si->txdma); /* Disable the port. */ Ser2UTCR3 = 0; Ser2HSCR0 = 0; }
/* * FIR format interrupt service routine. We only have to * handle RX events; transmit events go via the TX DMA handler. * * No matter what, we disable RX, process, and the restart RX. */ static void sa1100_irda_fir_irq(struct net_device *dev) { struct sa1100_irda *si = dev->priv; /* * Stop RX DMA */ sa1100_stop_dma(si->rxdma); /* * Framing error - we throw away the packet completely. * Clearing RXE flushes the error conditions and data * from the fifo. */ if (Ser2HSSR0 & (HSSR0_FRE | HSSR0_RAB)) { si->stats.rx_errors++; if (Ser2HSSR0 & HSSR0_FRE) si->stats.rx_frame_errors++; /* * Clear out the DMA... */ Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; /* * Clear selected status bits now, so we * don't miss them next time around. */ Ser2HSSR0 = HSSR0_FRE | HSSR0_RAB; } /* * Deal with any receive errors. The any of the lowest * 8 bytes in the FIFO may contain an error. We must read * them one by one. The "error" could even be the end of * packet! */ if (Ser2HSSR0 & HSSR0_EIF) sa1100_irda_fir_error(si, dev); /* * No matter what happens, we must restart reception. */ sa1100_irda_rx_dma_start(si); }
/* * Set the IrDA communications speed. */ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) { unsigned long flags; int brd, ret = -EINVAL; switch (speed) { case 9600: case 19200: case 38400: case 57600: case 115200: brd = 3686400 / (16 * speed) - 1; /* * Stop the receive DMA. */ if (IS_FIR(si)) sa1100_stop_dma(si->rxdma); local_irq_save(flags); Ser2UTCR3 = 0; Ser2HSCR0 = HSCR0_UART; Ser2UTCR1 = brd >> 8; Ser2UTCR2 = brd; /* * Clear status register */ Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; if (si->pdata->set_speed) si->pdata->set_speed(si->dev, speed); si->speed = speed; local_irq_restore(flags); ret = 0; break; case 4000000: local_irq_save(flags); si->hscr0 = 0; Ser2HSSR0 = 0xff; Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; Ser2UTCR3 = 0; si->speed = speed; if (si->pdata->set_speed) si->pdata->set_speed(si->dev, speed); sa1100_irda_rx_alloc(si); sa1100_irda_rx_dma_start(si); local_irq_restore(flags); break; default: break; } return ret; }
/* * Set the IrDA communications speed. */ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) { unsigned long flags; int brd, ret = -EINVAL; switch (speed) { case 9600: case 19200: case 38400: case 57600: case 115200: brd = 3686400 / (16 * speed) - 1; /* * Stop the receive DMA. */ if (IS_FIR(si)) sa1100_stop_dma(si->rxdma); local_irq_save(flags); Ser2UTCR3 = 0; Ser2HSCR0 = HSCR0_UART; Ser2UTCR1 = brd >> 8; Ser2UTCR2 = brd; /* * Clear status register */ Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID; Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE; if (machine_is_assabet()) ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL); if (machine_is_h3xxx()) clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL); if (machine_is_yopy()) PPSR &= ~GPIO_IRDA_FIR; si->speed = speed; local_irq_restore(flags); ret = 0; break; case 4000000: local_irq_save(flags); si->hscr0 = 0; Ser2HSSR0 = 0xff; Ser2HSCR0 = si->hscr0 | HSCR0_HSSP; Ser2UTCR3 = 0; si->speed = speed; if (machine_is_assabet()) ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL); if (machine_is_h3xxx()) set_h3600_egpio(IPAQ_EGPIO_IR_FSEL); if (machine_is_yopy()) PPSR |= GPIO_IRDA_FIR; sa1100_irda_rx_alloc(si); sa1100_irda_rx_dma_start(si); local_irq_restore(flags); break; default: break; } return ret; }
void udc_ep2_int_hndlr(struct sausb_dev *usb) { u32 status = Ser0UDCCS2; // check for stupid silicon bug. if (Ser0UDCAR != usb->ctl->address) Ser0UDCAR = usb->ctl->address; udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0); if (!(status & UDCCS2_TPC)) { char *buf = (char *) usb->ep[1].bufdma; int len = usb->ep[1].buflen; printk("usb_send: Not TPC: UDCCS2 = %x\n", status); printk("%s: hmm, what to do here?\n",__FUNCTION__); // udc_ep2_send_reset(usb); printk("%s: Buffer is %x length %d\n",__FUNCTION__,(int)buf,len); if (buf && len) { printk("%s: Retransmitting\n",__FUNCTION__); udc_ep2_send(usb, buf, len); } return; } sa1100_stop_dma(usb->ep[1].dmach); if (status & (UDCCS2_TPE | UDCCS2_TUR)) { printk("usb_send: transmit error %x\n", status); usb->ep[1].fifo_errs ++; udc_ep2_done(usb, -EIO); } else { unsigned int imp; #if 1 // 22Feb01ww/Oleg imp = ep2_curdmalen; #else // this is workaround for case when setting // of Ser0UDCIMP was failed imp = Ser0UDCIMP + 1; #endif usb->ep[1].pktdma += imp; ep2_remain -= imp; usb->ep[1].bytes += imp; usb->ep[1].packets++; sa1100_clear_dma(usb->ep[1].dmach); #if 0 /* induce horrible 5ms delay */ { udelay(1000); udelay(1000); udelay(1000); udelay(1000); udelay(1000); } #endif if (ep2_remain != 0) { ep2_start(usb); } else { udc_ep2_done(usb, 0); } } }
void ep1_int_hndlr() { dma_addr_t dma_addr; unsigned int len; int status = Ser0UDCCS1; PRINTKD( "[%lu]Ep1 int %d\n", (jiffies-start_time)*10, status); if ( naking ) printk( "%sEh? in ISR but naking = %d\n", "usbrx: ", naking ); // Reive packet complete if (status & UDCCS1_RPC) { if (!ep1_curdmalen) { printk("usb_recv: RPC for non-existent buffer\n"); naking = 1; return; } sa1100_stop_dma(dmachn_rx); if (status & UDCCS1_SST) { printk("usb_recv: stall sent OMP=%d\n",Ser0UDCOMP); UDC_flip(Ser0UDCCS1, UDCCS1_SST); ep1_done(-EIO); // UDC aborted current transfer, so we do return; } if (status & UDCCS1_RPE) { printk("usb_recv: RPError %x\n", status); UDC_flip(Ser0UDCCS1, UDCCS1_RPC); ep1_done(-EIO); return; } dma_addr = sa1100_get_dma_pos(dmachn_rx); pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen, PCI_DMA_FROMDEVICE); len = dma_addr - ep1_curdmapos; if (len < ep1_curdmalen) { char *buf = ep1_curdmabuf + len; while (Ser0UDCCS1 & UDCCS1_RNE) { if (len >= ep1_curdmalen) { printk("usb_recv: too much data in fifo\n"); break; } *buf++ = Ser0UDCDR; len++; } } else if (Ser0UDCCS1 & UDCCS1_RNE) { printk("usb_recv: fifo screwed, shouldn't contain data\n"); len = 0; } ep1_curdmalen = 0; /* dma unmap already done */ ep1_remain -= len; naking = 1; ep1_done((len) ? 0 : -EPIPE); } /* else, you can get here if we are holding NAK */ }