Beispiel #1
0
/*
 * 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 ;
   
}
Beispiel #2
0
Datei: irq.c Projekt: nhanh0/hah
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];
}
Beispiel #3
0
Datei: irq.c Projekt: nhanh0/hah
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();
}
Beispiel #4
0
Datei: irq.c Projekt: nhanh0/hah
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);
	}
}
Beispiel #5
0
Datei: irq.c Projekt: nhanh0/hah
/* 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();
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
/*! \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"));
    }