/* * Aieeeeee .. we should never get here :( */ static void pxa250_irda_rxdma_irq(int ch,void *id, struct pt_regs *regs) { struct net_device *dev=id; struct pxa250_irda *si=dev->priv; u_int dcsr; __ECHO_IN; /* * Make sure that irq is our. */ if ( ch != si->rxdma_ch ) /*just*/ return; /* * Check status */ dcsr = DCSR(ch); DBG("DCSR=%x\n",dcsr); if (dcsr & DCSR_STOPSTATE ) { DBG_IRQ("Chanel %d in stop state\n",ch); } if (dcsr & DCSR_BUSERR ) { /* * BUS Error we must restart reception */ DBG("PXA IrDA: bus error interrupt on channel %d\n", ch); DCSR(ch) |= DCSR_BUSERR; } if (dcsr & DCSR_ENDINTR ) { DBG("PXA IrDA: Normal end of dma channel %d - packet to big\n", ch); DCSR(ch) |= DCSR_ENDINTR; } /* no mater what restart rx*/ pxa250_start_rx_dma(dev); return ; }
struct irq_region *alloc_irq_region( int count, struct irq_region_ops *ops, unsigned long flags, const char *name, void *dev) { struct irq_region *region; int index; index = alloc_irqregion(); if((IRQ_REGION(count-1))) return NULL; if (count < IRQ_PER_REGION) { DBG_IRQ("alloc_irq_region() using minimum of %d irq lines for %s (%d)\n", IRQ_PER_REGION, name, count); count = IRQ_PER_REGION; } if(flags & IRQ_REG_MASK) if(!(ops->mask_irq && ops->unmask_irq)) return NULL; if(flags & IRQ_REG_DIS) if(!(ops->disable_irq && ops->enable_irq)) return NULL; if((irq_region[index])) return NULL; region = kmalloc(sizeof *region, GFP_ATOMIC); if(!region) return NULL; region->action = kmalloc(sizeof *region->action * count, GFP_ATOMIC); if(!region->action) { kfree(region); return NULL; } memset(region->action, 0, sizeof *region->action * count); region->ops = *ops; region->data.irqbase = IRQ_FROM_REGION(index); region->data.flags = flags; region->data.name = name; region->data.dev = dev; irq_region[index] = region; return irq_region[index]; }
void enable_irq(int irq) { struct irq_region *region; #ifdef DEBUG_IRQ if (irq != TIMER_IRQ) #endif DBG_IRQ("enable_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)); region = irq_region[IRQ_REGION(irq)]; if(region->data.flags & IRQ_REG_DIS) region->ops.enable_irq(region->data.dev, IRQ_OFFSET(irq)); else BUG(); }
static inline void mask_irq(int irq) { struct irq_region *region; #ifdef DEBUG_IRQ if (irq != TIMER_IRQ) #endif DBG_IRQ("mask_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)); if(IRQ_REGION(irq) != CPU_IRQ_REGION) { region = irq_region[IRQ_REGION(irq)]; if(region->data.flags & IRQ_REG_MASK) region->ops.mask_irq(region->data.dev, IRQ_OFFSET(irq)); } else { CLEAR_EIEM_BIT(irq); } }
/* FIXME: SMP, flags, bottom halves, rest */ void do_irq(struct irqaction *action, int irq, struct pt_regs * regs) { int cpu = smp_processor_id(); irq_enter(cpu, irq); #ifdef DEBUG_IRQ if (irq != TIMER_IRQ) #endif DBG_IRQ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)); if (action->handler == NULL) printk(KERN_ERR "No handler for interrupt %d !\n", irq); for(; action && action->handler; action = action->next) { action->handler(irq, action->dev_id, regs); } irq_exit(cpu, irq); /* don't need to care about unmasking and stuff */ do_softirq(); }
static void pxa250_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct pxa250_irda *si = dev->priv; int status; /* * Stop RX */ __ECHO_IN; pxa250_dma_stop(si->rxdma_ch); /* * Framing error - we throw away the packet completely. * Clearing RXE flushes the error conditions and data * from the fifo. */ status=ICSR0; if (status & (ICSR0_FRE | ICSR0_RAB)) { DBG_IRQ("Framing error or RAB\n"); si->stats.rx_errors++; if (ICSR0 & ICSR0_FRE) si->stats.rx_frame_errors++; /* Clear RX fifo * DMA will be cleared when we restart RX * Should we check RNE after that? */ ICCR0 &= ~ICCR0_RXE; /* * Clear selected status bits now, so we * don't miss them next time around. */ ICSR0 = status & (ICSR0_FRE | ICSR0_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 (ICSR0 & ICSR0_EIF) pxa250_irda_fir_error(dev); /* * No matter what happens, we must restart reception. */ ICCR0 = 0; pxa250_start_rx_dma(dev); pxa250_ficp_rx_start(); __ECHO_OUT; }
static void pxa250_irda_txdma_irq(int ch, void *id , struct pt_regs *regs) { struct net_device *dev=id; struct pxa250_irda *si=dev->priv; struct sk_buff *skb = si->txskb; u_int dcsr; __ECHO_IN; DBG_IRQ("transmit\n"); /* * Make sure that irq is our. */ if ( ch != si->txdma_ch ) /*just*/ return; /* * Check status */ dcsr = DCSR(ch); DBG("DCSR=%x",dcsr); if (dcsr & DCSR_STOPSTATE ) { DBG("Chanel %d in stop state\n",ch); } if (dcsr & DCSR_BUSERR ) { DBG("PXA IrDA: bus error interrupt on channel %d\n", ch); DCSR(ch) |= DCSR_BUSERR; si->txskb = NULL; } if (dcsr & DCSR_ENDINTR ) { DBG("PXA IrDA: Normal end of dma channel %d\n", ch); DCSR(ch) |= DCSR_ENDINTR; si->txskb = NULL; } /* * Account and free the packet. */ if (skb) { si->stats.tx_packets ++; si->stats.tx_bytes += skb->len; dev_kfree_skb_irq(skb); } /*Disable transceiver and enable receiver*/ if (si->newspeed) { pxa250_irda_set_speed(dev, si->newspeed); si->newspeed = 0; } while (ICSR1 & ICSR1_TBY) udelay(1); ICCR0 &= ~ICCR0_TXE; enable_irq(si->fir_irq); ICCR0 |= ICCR0_RXE; /* * Make sure that the TX queue is available for sending * (for retries). TX has priority over RX at all times. */ netif_wake_queue(dev); __ECHO_OUT; }
/*! \brief Wait until listener is ready to receive This function waits until a listener is ready. \param Pdx Pointer to the device extension. \param SendEoi TRUE if we want to signal an EOI. FALSE otherwise. */ VOID cbmiec_wait_for_listener(IN PDEVICE_EXTENSION Pdx, IN BOOLEAN SendEoi) { ULONG NumberOfAcks = SendEoi ? 2 : 1; FUNC_ENTER(); PERF_EVENT_VERBOSE(0x1100, NumberOfAcks); // This function has two incarnations. The first one // is used if we have successfully allocated the interrupt. // In this case, we just wait until the ISR has done the // essential work // When entering this function, DATA_IN should not be active DBG_ASSERT(CBMIEC_GET(PP_DATA_IN)); if (Pdx->ParallelPortAllocatedInterrupt) { LONG ret; // This is implementation 1. It needs a working // ISR. The main work is done there // Tell the ISR how many interrupts to wait for PERF_EVENT_VERBOSE(0x1101, NumberOfAcks); ret = InterlockedExchange(&Pdx->IrqCount, NumberOfAcks); DBG_ASSERT(ret==0); PERF_EVENT_VERBOSE(0x1102, ret); // in the sequel, allow interrupts to occur DBG_IRQ(("Allow Interrupts")); CBMIEC_SET(PP_LP_IRQ); /*! \todo Shouldn't we make sure that there * is no spurious interrupt until now? */ // Give the LISTENer the sign: We want to send something DBG_IRQ(("Release CLK_OUT")); CBMIEC_RELEASE(PP_CLK_OUT); #ifdef USE_DPC // set the cancel routine which will wake us up if we do not get // an IRQ, and a cancellation is requested PERF_EVENT_VERBOSE(0x1103, 0); DBG_VERIFY(IoSetCancelRoutine(Pdx->IrpQueue.CurrentIrp, WaitCancelRoutine) DBGDO(== NULL)); // Now, wait until we have been signalled PERF_EVENT_VERBOSE(0x1104, 0); DBG_DPC((DBG_PREFIX "CALL KeWaitForSingleObject()")); KeWaitForSingleObject(&Pdx->EventWaitForListener, Executive, KernelMode, FALSE, NULL); DBG_DPC((DBG_PREFIX "RETURN from KeWaitForSingleObject()")); PERF_EVENT_VERBOSE(0x1105, 0); // we do not need the cancel routine anymore: if (IoSetCancelRoutine(Pdx->IrpQueue.CurrentIrp, NULL) == NULL) { PERF_EVENT_VERBOSE(0x1106, -1); // the cancel routine was called! // Make sure the IrqCount is resetted to zero. InterlockedExchange(&Pdx->IrqCount, 0); } #else // Wait until the listener has told us that it is able to listen while (!QueueShouldCancelCurrentIrp(&Pdx->IrpQueue) && Pdx->IrqCount) { cbmiec_schedule_timeout(libiec_global_timeouts.T_WaitForListener_Granu_T_H); } #endif DBG_IRQ(("IrqCount = 0")); // from here on, no interrupts will be generated anymore CBMIEC_RELEASE(PP_LP_IRQ); DBG_IRQ(("No more Interrupts")); }