Example #1
0
/*
 * Have got an event to handle:
 */
fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
				struct irqaction *action)
{
	int ret, retval = 0, status = 0;

	trace_kernel_irq_entry(irq, !(user_mode(regs)));

	if (!(action->flags & SA_INTERRUPT))
		local_irq_enable();

	do {
		ret = action->handler(irq, action->dev_id, regs);
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	local_irq_disable();

	trace_kernel_irq_exit();

	return retval;
}
Example #2
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @regs:	pointer to a register structure
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
			     struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;

	trace_irq_entry(irq, regs);

	handle_dynamic_tick(action);

	if (!(action->flags & IRQF_DISABLED))
		local_irq_enable_in_hardirq();

	do {
		ret = action->handler(irq, action->dev_id, regs);
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	local_irq_disable();

	trace_irq_exit(irq, retval);

	return retval;
}
Example #3
0
static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
{
	struct irqaction * action;

	if ((unsigned) irq > NR_IRQS) {
		printk("device_interrupt: unexpected interrupt %d\n", irq);
		return;
	}

	kstat.interrupts[irq]++;
	action = irq_action[irq];
	/*
	 * For normal interrupts, we mask it out, and then ACK it.
	 * This way another (more timing-critical) interrupt can
	 * come through while we're doing this one.
	 *
	 * Note! A irq without a handler gets masked and acked, but
	 * never unmasked. The autoirq stuff depends on this (it looks
	 * at the masks before and after doing the probing).
	 */
	mask_irq(ack);
	ack_irq(ack);
	if (!action)
		return;
	if (action->flags & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	do {
		action->handler(irq, action->dev_id, regs);
		action = action->next;
	} while (action);
	unmask_irq(ack);
}
Example #4
0
/*
 * This should really return information about whether
 * we should do bottom half handling etc. Right now we
 * end up _always_ checking the bottom half, which is a
 * waste of time and is not what some drivers would
 * prefer.
 */
int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
{
	int status;
	int cpu = smp_processor_id();

	irq_enter(cpu, irq);

	status = 1;	/* Force the "do bottom halves" bit */

	if (!(action->flags & SA_INTERRUPT))
		__sti();

	do {
		status |= action->flags;
		action->handler(irq, action->dev_id, regs);
		action = action->next;
	} while (action);
	if (status & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	__cli();

	irq_exit(cpu, irq);

	return status;
}
Example #5
0
static void
sn1_handle_irq(int irq, void *dummy, struct pt_regs *regs)
{
	int bit, cnode;
	struct sn1_cnode_action_list *alp;
	struct sn1_intr_action *ap;
	void (*handler)(int, void *, struct pt_regs *);
	unsigned long flags = 0;
	int cpuid = smp_processor_id();


	bit = irq_to_bit_pos(irq);
	LOCAL_HUB_CLR_INTR(bit);
	cnode = cpuid_to_cnodeid(cpuid);
	alp = sn1_node_actions[cnode];
	ap = alp[irq].action_list;
	if (ap == NULL) {
		return;
	}
	while (ap) {
		flags |= ap->flags;
		handler = ap->handler;
		(*handler)(irq,ap->intr_arg,regs);
		ap = ap->next;
	}
	if ((flags & SA_SAMPLE_RANDOM) != 0)
                add_interrupt_randomness(irq);

        return;
}
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;
	struct pt_regs *regs = get_irq_regs();

	trace_mark(kernel_irq_entry, "irq_id %u kernel_mode %u", irq,
		(regs)?(!user_mode(regs)):(1));

	handle_dynamic_tick(action);

	if (!(action->flags & IRQF_DISABLED))
		local_irq_enable_in_hardirq();

	do {
		ret = action->handler(irq, action->dev_id);
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	local_irq_disable();

	trace_mark(kernel_irq_exit, MARK_NOARGS);

	return retval;
}
Example #7
0
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
	struct irqaction *action;
	int do_random, cpu;

        cpu = smp_processor_id();
        irq_enter(cpu);
	kstat.irqs[cpu][irq]++;

	action = irq_action[irq];
        if (action) {
                if (!(action->flags & SA_INTERRUPT))
                        __sti();
                action = irq_action[irq];
                do_random = 0;
                do {
                        do_random |= action->flags;
                        action->handler(irq, action->dev_id, regs);
                        action = action->next;
                } while (action);
                if (do_random & SA_SAMPLE_RANDOM)
                        add_interrupt_randomness(irq);
                __cli();
        }
        irq_exit(cpu);

	if (softirq_pending(cpu))
                do_softirq();

        /* unmasking and bottom half handling is done magically for us. */
}
Example #8
0
static int inline handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
#endif	
{
	int status;
	int cpu = smp_processor_id();

	irq_enter(cpu, irq);

	status = 1;	/* Force the "do bottom halves" bit */
#if 0
	if (!(action->flags & SA_INTERRUPT))
		__sti();
#endif
//sc_yang => open shared IRQ
#if 1
//#ifndef JACKSON_NET_WORK	
	do {
		status |= action->flags;
		action->handler(irq, action->dev_id, regs);
		action = action->next;
	} while (action);
	if (status & SA_SAMPLE_RANDOM)
	   	add_interrupt_randomness(irq);

#else
	action->handler(irq, action->dev_id, regs);
#endif	
	//__cli();

	irq_exit(cpu, irq);

	return status;
}
Example #9
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;

	handle_dynamic_tick(action);

	//如果第一个处理程序函数中没有设置IRQF_DISABLED,
	//则用local_irq_enable_in_hardirq启用(当前CPU的)中断。
	//换句话说,该处理程序可以被其他IRQ中断。但根据电流类型,
	//也可能一直屏蔽刚处理的IRQ
	if (!(action->flags & IRQF_DISABLED))
		local_irq_enable_in_hardirq();
	//在共享IRQ时
	do 
	{
		ret = action->handler(irq, action->dev_id);
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	//如果该IRQ设置了IRQF_SAMPLE_RANDOM,
	//则调用add_interrupt_randomness,将事件的时间作为熵池的一个源
	//(如果中断是随机发生的,那么他们是理想的源)
	if (status & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	//禁用中断。
	//因为中断的启用和禁用是不嵌套的,与中断在处理开始时是否启用是不相关的。
	//handle_IRQ_event在调用时禁用中断,在退出时然然预期禁用中断
	local_irq_disable();

	return retval;
}
Example #10
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;

	do {
		trace_irq_handler_entry(irq, action);
		ret = action->handler(irq, action->dev_id);
		trace_irq_handler_exit(irq, action, ret);

		switch (ret) {
		case IRQ_WAKE_THREAD:
			/*
			 * Set result to handled so the spurious check
			 * does not trigger.
			 */
			ret = IRQ_HANDLED;

			/*
			 * Catch drivers which return WAKE_THREAD but
			 * did not set up a thread function
			 */
			if (unlikely(!action->thread_fn)) {
				warn_no_thread(irq, action);
				break;
			}

			/*
			 * Wake up the handler thread for this
			 * action. In case the thread crashed and was
			 * killed we just pretend that we handled the
			 * interrupt. The hardirq handler above has
			 * disabled the device interrupt, so no irq
			 * storm is lurking.
			 */
			if (likely(!test_bit(IRQTF_DIED,
					     &action->thread_flags))) {
				set_bit(IRQTF_RUNTHREAD, &action->thread_flags);
				wake_up_process(action->thread);
			}

			/* Fall through to add to randomness */
		case IRQ_HANDLED:
			status |= action->flags;
			break;

		default:
			break;
		}

		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	local_irq_disable();

	return retval;
}
Example #11
0
/*
 * do_IRQ handles IRQ's that have been installed without the
 * SA_INTERRUPT flag: it uses the full signal-handling return
 * and runs with other interrupts enabled. All relatively slow
 * IRQ's should use this format: notably the keyboard/timer
 * routines.
 */
static void do_IRQ(int irq, struct pt_regs * regs)
{
	struct irqaction *action;
	int do_random, cpu;

	cpu = smp_processor_id();
	irq_enter(cpu);
	kstat.irqs[cpu][irq]++;

	mask_irq(irq);  
	action = *(irq + irq_action);
	if (action) {
		if (!(action->flags & SA_INTERRUPT))
			__sti();
		action = *(irq + irq_action);
		do_random = 0;
        	do {
			do_random |= action->flags;
			action->handler(irq, action->dev_id, regs);
			action = action->next;
        	} while (action);
		if (do_random & SA_SAMPLE_RANDOM)
			add_interrupt_randomness(irq);
		__cli();
	} else {
		printk("do_IRQ: Unregistered IRQ (0x%X) occured\n", irq);
	}
	unmask_irq(irq);
	irq_exit(cpu);

	/* unmasking and bottom half handling is done magically for us. */
}
irqreturn_t
handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
{
	irqreturn_t retval = IRQ_NONE;
	unsigned int random = 0, irq = desc->irq_data.irq;

	do {
		irqreturn_t res;
#ifdef CONFIG_SEC_DEBUG
		sec_debug_timer_log(4444, (int)irqs_disabled(),
						(void *)action->handler);
#endif

		trace_irq_handler_entry(irq, action);
		res = action->handler(irq, action->dev_id);
		trace_irq_handler_exit(irq, action, res);
#ifdef CONFIG_SEC_DEBUG
		sec_debug_timer_log(5555, (int)irqs_disabled(),
						(void *)action->handler);
		/* sec_debug_irq_sched_log(irq, (void *)action->handler, 2); */
#endif

		if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n",
			      irq, action->handler))
			local_irq_disable();

		switch (res) {
		case IRQ_WAKE_THREAD:
			/*
			 * Catch drivers which return WAKE_THREAD but
			 * did not set up a thread function
			 */
			if (unlikely(!action->thread_fn)) {
				warn_no_thread(irq, action);
				break;
			}

			irq_wake_thread(desc, action);

			/* Fall through to add to randomness */
		case IRQ_HANDLED:
			random |= action->flags;
			break;

		default:
			break;
		}

		retval |= res;
		action = action->next;
	} while (action);

	if (random & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);

	if (!noirqdebug)
		note_interrupt(irq, desc, retval);
	return retval;
}
Example #13
0
irqreturn_t
handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
{
	irqreturn_t retval = IRQ_NONE;
	unsigned int flags = 0, irq = desc->irq_data.irq;

#ifdef CONFIG_FOOTPRINT_IRQ
	update_handle_irqs_this_cpu(irq);
#endif

	do {
		irqreturn_t res;

		trace_irq_handler_entry(irq, action);
		res = action->handler(irq, action->dev_id);
		trace_irq_handler_exit(irq, action, res);

		if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n",
			      irq, action->handler))
			local_irq_disable();

		switch (res) {
		case IRQ_WAKE_THREAD:
			/*
			 * Catch drivers which return WAKE_THREAD but
			 * did not set up a thread function
			 */
			if (unlikely(!action->thread_fn)) {
				warn_no_thread(irq, action);
				break;
			}

			irq_wake_thread(desc, action);

			/* Fall through to add to randomness */
		case IRQ_HANDLED:
			flags |= action->flags;
			break;

		default:
			break;
		}

		retval |= res;
		action = action->next;
	} while (action);

	add_interrupt_randomness(irq, flags);

	if (!noirqdebug)
		note_interrupt(irq, desc, retval);

#ifdef CONFIG_FOOTPRINT_IRQ
	release_handle_irqs_this_cpu(irq);
#endif

	return retval;
}
irqreturn_t
handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
{
	irqreturn_t retval = IRQ_NONE;
	unsigned int flags = 0, irq = desc->irq_data.irq;

	while (action) {
		irqreturn_t res;

		if(!action->handler) {
			printk(KERN_WARNING "IRQ %d device %s get event "
				"but no action handle function available.", irq, action->name);
			action = action->next;
			continue;
		}

		trace_irq_handler_entry(irq, action);
		res = action->handler(irq, action->dev_id);
		trace_irq_handler_exit(irq, action, res);

		if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n",
			      irq, action->handler))
			local_irq_disable();

		switch (res) {
		case IRQ_WAKE_THREAD:
			/*
			 * Catch drivers which return WAKE_THREAD but
			 * did not set up a thread function
			 */
			if (unlikely(!action->thread_fn)) {
				warn_no_thread(irq, action);
				break;
			}

			irq_wake_thread(desc, action);

			/* Fall through to add to randomness */
		case IRQ_HANDLED:
			flags |= action->flags;
			break;

		default:
			break;
		}

		retval |= res;
		action = action->next;
    }

	add_interrupt_randomness(irq, flags);

	if (!noirqdebug)
		note_interrupt(irq, desc, retval);
	return retval;
}
Example #15
0
irqreturn_t
handle_irq_event_percpu(struct irq_desc *desc, struct irqaction *action)
{
	irqreturn_t retval = IRQ_NONE;
	unsigned int random = 0, irq = desc->irq_data.irq;

	do {
		irqreturn_t res;

		trace_irq_handler_entry(irq, action);
		res = action->handler(irq, action->dev_id);
		trace_irq_handler_exit(irq, action, res);

		if (WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n",
			      irq, action->handler))
			local_irq_disable();

		switch (res) {
		case IRQ_WAKE_THREAD:
			/*
			 * Set result to handled so the spurious check
			 * does not trigger.
			 */
			res = IRQ_HANDLED;

			/*
			 * Catch drivers which return WAKE_THREAD but
			 * did not set up a thread function
			 */
			if (unlikely(!action->thread_fn)) {
				warn_no_thread(irq, action);
				break;
			}

			irq_wake_thread(desc, action);

			/* Fall through to add to randomness */
		case IRQ_HANDLED:
			random |= action->flags;
			break;

		default:
			break;
		}

		retval |= res;
		action = action->next;
	} while (action);

	if (random & IRQF_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);

	if (!noirqdebug)
		note_interrupt(irq, desc, retval);
	return retval;
}
Example #16
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;

#ifdef __i386__
	if (debug_direct_keyboard && irq == 1)
		lockdep_off();
#endif

	handle_dynamic_tick(action);

	/*
	 * Unconditionally enable interrupts for threaded
	 * IRQ handlers:
	 */
	if (!hardirq_count() || !(action->flags & IRQF_DISABLED))
		local_irq_enable();

	do {
		unsigned int preempt_count = preempt_count();

		ret = action->handler(irq, action->dev_id);
		if (preempt_count() != preempt_count) {
			stop_trace();
			print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler);
			printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count());
			dump_stack();
			preempt_count() = preempt_count;
		}
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM) {
		local_irq_enable();
		add_interrupt_randomness(irq);
	}
	local_irq_disable();

#ifdef __i386__
	if (debug_direct_keyboard && irq == 1)
		lockdep_on();
#endif
	return retval;
}
Example #17
0
asmlinkage void process_int(int irq, struct pt_regs *fp)
{
	irq_enter();
	h8300_clear_isr(irq);
	if (irq >= NR_TRAPS && irq < NR_IRQS) {
		if (irq_list[irq]) {
			irq_list[irq]->handler(irq, irq_list[irq]->dev_id, fp);
			irq_list[irq]->count++;
			if (irq_list[irq]->flags & IRQF_SAMPLE_RANDOM)
				add_interrupt_randomness(irq);
		}
	} else {
		BUG();
	}
	irq_exit();
}
static void usbic_device_irq(u32 irq, irq_desc_t * desc)
{
	struct irqaction * action;
	const u32 cpu = smp_processor_id();

	desc->status |= IRQ_LEVEL;



	if(!desc->depth)
	{
		kstat_cpu(cpu).irqs[irq]++;

		action = desc->action;
		if(action)
		{
			int ret;
			int status = 0;
			int retval = 0;

			local_irq_enable();

			do{
				ret = action->handler(irq, action->dev_id);
				if(ret == IRQ_HANDLED)
					status |= action->flags;
				retval |= ret;
				action = action->next;
			}while(action);

			if(status & IRQF_SAMPLE_RANDOM)
			{
			//	kmsg("sample randomness\n");
				add_interrupt_randomness(irq);
			}

			local_irq_disable();

			if(retval != IRQ_HANDLED)
			; //	kmsg("Error!!! irq %d cannot handle irq\n", irq);
		}
		else
		 ;//	kmsg("irq %d has no ISR\n", irq);
	}
	else
	  ; //	kmsg("irq %d is disabled\n",irq);
}
Example #19
0
File: irq.c Project: 0xffea/gnumach
/*
 * do_IRQ handles IRQ's that have been installed without the
 * SA_INTERRUPT flag: it uses the full signal-handling return
 * and runs with other interrupts enabled. All relatively slow
 * IRQ's should use this format: notably the keyboard/timer
 * routines.
 */
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
	struct irqaction * action = *(irq + irq_action);
	int do_random = 0;
	int c,intm,mask;
#ifdef IRQ_DEBUG
	static int count;
	if (smp_processor_id() != 0 && count++ < 1000)
	  printk("IRQ %d: done by CPU %d\n",irq,smp_processor_id());
#endif	  
	if (irq  >= 8) {
	  c = cache_A1;
	  intm = inb(0xA1);
	  mask =  1 << (irq - 8);
	} else {
	  c = cache_21;
	  intm = inb(0x21);
	  mask =  1 << irq;
	}
	if (!(c & mask) || !(intm & mask)) {
#ifdef IRQ_DEBUG	
	  printk("IRQ %d (proc %d):cache_x1=0x%x,INT mask=0x%x\n", irq, smp_processor_id(),c,intm);
#endif	  
	  /* better to return because the interrupt may be asserted again,
	     the bad thing is that we may loose some interrupts */
	  return;
	}
#ifdef __SMP__
	if(smp_threads_ready && active_kernel_processor!=smp_processor_id())
		panic("IRQ %d: active processor set wrongly(%d not %d).\n", irq, active_kernel_processor, smp_processor_id());
#endif

	kstat.interrupts[irq]++;
#ifdef __SMP_PROF__
	int_count[smp_processor_id()][irq]++;
#endif
	while (action) {
		do_random |= action->flags;
		action->handler(irq, action->dev_id, regs);
		action = action->next;
	}
	if (do_random & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
}
Example #20
0
asmlinkage void process_int(int vec, struct pt_regs *fp)
{
	irq_enter(0,0);
	/* ISR clear       */
	/* compatible i386 */
	if (vec >= EXT_IRQ0 && vec <= EXT_IRQ5)
		*(volatile unsigned char *)ISR &= ~(1 << (vec - EXT_IRQ0));
	if (vec < NR_IRQS) {
		if (irq_list[vec]) {
			irq_list[vec]->handler(vec, irq_list[vec]->dev_id, fp);
			irq_list[vec]->count++;
			if (irq_list[vec]->flags & SA_SAMPLE_RANDOM)
				add_interrupt_randomness(vec);
		}
	} else {
		BUG();
	}
	irq_exit(0,0);
}
Example #21
0
/**
 * handle_IRQ_event - irq action chain handler
 * @irq:	the interrupt number
 * @regs:	pointer to a register structure
 * @action:	the interrupt action chain for this irq
 *
 * Handles the action chain of an irq event
 */
irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
			     struct irqaction *action)
{
	irqreturn_t ret, retval = IRQ_NONE;
	unsigned int status = 0;
  
 	MARK(kernel_irq_entry, "%u %u", irq, (regs)?(!user_mode(regs)):(1));
	handle_dynamic_tick(action);

	/*
	 * Unconditionally enable interrupts for threaded
	 * IRQ handlers:
	 */
	if (!hardirq_count() || !(action->flags & IRQF_DISABLED))
		local_irq_enable();

	do {
		unsigned int preempt_count = preempt_count();

		ret = action->handler(irq, action->dev_id, regs);
		if (preempt_count() != preempt_count) {
			stop_trace();
			print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler);
			printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count());
			dump_stack();
			preempt_count() = preempt_count;
		}
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & IRQF_SAMPLE_RANDOM) {
		local_irq_enable();
		add_interrupt_randomness(irq);
	}
	local_irq_disable();

 	MARK(kernel_irq_exit, MARK_NOARGS);

	return retval;
}
Example #22
0
/*
 * This is a threaded interrupt handler so we can make some
 * I2C calls etc.
 */
static irqreturn_t ab3100_irq_handler(int irq, void *data)
{
	struct ab3100 *ab3100 = data;
	u8 event_regs[3];
	u32 fatevent;
	int err;

	add_interrupt_randomness(irq);

	err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
				       event_regs, 3);
	if (err)
		goto err_event;

	fatevent = (event_regs[0] << 16) |
		(event_regs[1] << 8) |
		event_regs[2];

	if (!ab3100->startup_events_read) {
		ab3100->startup_events[0] = event_regs[0];
		ab3100->startup_events[1] = event_regs[1];
		ab3100->startup_events[2] = event_regs[2];
		ab3100->startup_events_read = true;
	}
	/*
	 * The notified parties will have to mask out the events
	 * they're interested in and react to them. They will be
	 * notified on all events, then they use the fatevent value
	 * to determine if they're interested.
	 */
	blocking_notifier_call_chain(&ab3100->event_subscribers,
				     fatevent, NULL);

	dev_dbg(ab3100->dev,
		"IRQ Event: 0x%08x\n", fatevent);

	return IRQ_HANDLED;

 err_event:
	dev_dbg(ab3100->dev,
		"error reading event status\n");
	return IRQ_HANDLED;
}
static irqreturn_t ab3100_irq_handler(int irq, void *data)
{
	struct ab3100 *ab3100 = data;
	u8 event_regs[3];
	u32 fatevent;
	int err;

	add_interrupt_randomness(irq);

	err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
				       event_regs, 3);
	if (err)
		goto err_event;

	fatevent = (event_regs[0] << 16) |
		(event_regs[1] << 8) |
		event_regs[2];

	if (!ab3100->startup_events_read) {
		ab3100->startup_events[0] = event_regs[0];
		ab3100->startup_events[1] = event_regs[1];
		ab3100->startup_events[2] = event_regs[2];
		ab3100->startup_events_read = true;
	}
	/*
                                                         
                                                         
                                                            
                                       
  */
	blocking_notifier_call_chain(&ab3100->event_subscribers,
				     fatevent, NULL);

	dev_dbg(ab3100->dev,
		"IRQ Event: 0x%08x\n", fatevent);

	return IRQ_HANDLED;

 err_event:
	dev_dbg(ab3100->dev,
		"error reading event status\n");
	return IRQ_HANDLED;
}
Example #24
0
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
	struct irqaction *action;
	int do_random, cpu;
        int retval = 0;

        cpu = smp_processor_id();
        irq_enter();
	kstat_cpu(cpu).irqs[irq]++;

	action = irq_action[irq];
        if (action) {
                if (!(action->flags & SA_INTERRUPT))
                        local_irq_enable();
                action = irq_action[irq];
                do_random = 0;
                do {
                        do_random |= action->flags;
                        retval |= action->handler(irq, action->dev_id, regs);
                        action = action->next;
                } while (action);

                if (retval != 1) {
			if (retval) {
				printk("irq event %d: bogus retval mask %x\n",
					irq, retval);
			} else {
				printk("irq %d: nobody cared\n", irq);
			}
		}

                if (do_random & SA_SAMPLE_RANDOM)
                        add_interrupt_randomness(irq);
		local_irq_disable();
        }
        irq_exit();

	if (softirq_pending(cpu))
                do_softirq();

        /* unmasking and bottom half handling is done magically for us. */
}
Example #25
0
int Loop()
{
	pid_t pid;
	int  status;

	while(link_count > 0)
	{
		pid = Receive(0, &msg, sizeof(msg));

		if(pid == -1) {
			if(errno != EINTR) {
				Log("Receive() failed: [%d] %s", ERR(errno));
			}
			continue;
		}
		if(pid == IrqProxy()) {
			while(Creceive(pid, 0, 0) == pid)
				; // clear out any proxy overruns

			add_interrupt_randomness(options.irq);

//			Log("Irq: random size %d\n", get_random_size());

			// now that we have more entropy...
			SelectTrigger();
			DoReadQueue();

			continue;
		}

		status = Service(pid, &msg);

		Log("Service() returned status %d (%s), link_count %d",
			status, status == -1 ? "none" : strerror(status), link_count);

		if(status >= EOK) {
			msg.status = status;
			ReplyMsg(pid, &msg, sizeof(msg.status));
		}
	}
	return 0;
}
Example #26
0
static void
__do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
{
	unsigned int status;

	spin_unlock(&irq_controller_lock);
	if (!(action->flags & SA_INTERRUPT))
		local_irq_enable();

	status = 0;
	do {
		status |= action->flags;
		action->handler(irq, action->dev_id, regs);
		action = action->next;
	} while (action);

	if (status & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);

	spin_lock_irq(&irq_controller_lock);
}
Example #27
0
int
handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
		 struct irqaction *action)
{
	int status = 1;	/* Force the "do bottom halves" bit */

	do {
		if (!(action->flags & SA_INTERRUPT))
			local_irq_enable();
		else
			local_irq_disable();

		status |= action->flags;
		action->handler(irq, action->dev_id, regs);
		action = action->next;
	} while (action);
	if (status & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
	local_irq_disable();

	return status;
}
Example #28
0
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
	struct irqaction *action;
	int do_random, cpu;
        int ret, retval = 0;

        cpu = smp_processor_id();
        irq_enter();
	kstat_cpu(cpu).irqs[irq - FIRST_IRQ]++;
	action = irq_action[irq - FIRST_IRQ];

        if (action) {
                if (!(action->flags & SA_INTERRUPT))
                        local_irq_enable();
                do_random = 0;
                do {
			ret = action->handler(irq, action->dev_id, regs);
			if (ret == IRQ_HANDLED)
				do_random |= action->flags;
                        retval |= ret;
                        action = action->next;
                } while (action);

                if (retval != 1) {
			if (retval) {
				printk("irq event %d: bogus retval mask %x\n",
					irq, retval);
			} else {
				printk("irq %d: nobody cared\n", irq);
			}
		}

                if (do_random & SA_SAMPLE_RANDOM)
                        add_interrupt_randomness(irq);
		local_irq_disable();
        }
        irq_exit();
}
Example #29
0
File: irq.c Project: 0xffea/gnumach
/*
 * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
 * stuff - the handler is also running with interrupts disabled unless
 * it explicitly enables them later.
 */
asmlinkage void do_fast_IRQ(int irq)
{
	struct irqaction * action = *(irq + irq_action);
	int do_random = 0;
	
#ifdef __SMP__
	/* IRQ 13 is allowed - that's a flush tlb */
	if(smp_threads_ready && active_kernel_processor!=smp_processor_id() && irq!=13)
		panic("fast_IRQ %d: active processor set wrongly(%d not %d).\n", irq, active_kernel_processor, smp_processor_id());
#endif

	kstat.interrupts[irq]++;
#ifdef __SMP_PROF__
	int_count[smp_processor_id()][irq]++;
#endif
	while (action) {
		do_random |= action->flags;
		action->handler(irq, action->dev_id, NULL);
		action = action->next;
	}
	if (do_random & SA_SAMPLE_RANDOM)
		add_interrupt_randomness(irq);
}
Example #30
0
/*
 * Have got an event to handle:
 */
fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
				struct irqaction *action)
{
	int ret, retval = 0, status = 0;

	/*
	 * Unconditionally enable interrupts for threaded
	 * IRQ handlers:
	 */
	if (!hardirq_count() || !(action->flags & SA_INTERRUPT))
		local_irq_enable();

	do {
		unsigned int preempt_count = preempt_count();

		ret = action->handler(irq, action->dev_id, regs);
		if (preempt_count() != preempt_count) {
			stop_trace();
			print_symbol("BUG: unbalanced irq-handler preempt count in %s!\n", (unsigned long) action->handler);
			printk("entered with %08x, exited with %08x.\n", preempt_count, preempt_count());
			dump_stack();
			preempt_count() = preempt_count;
		}
		if (ret == IRQ_HANDLED)
			status |= action->flags;
		retval |= ret;
		action = action->next;
	} while (action);

	if (status & SA_SAMPLE_RANDOM) {
		local_irq_enable();
		add_interrupt_randomness(irq);
	}
	local_irq_disable();

	return retval;
}