예제 #1
0
/**
 *	probe_irq_on	- begin an interrupt autodetect
 *
 *	Commence probing for an interrupt. The interrupts are scanned
 *	and a mask of potential interrupt lines is returned.
 *
 */
unsigned long probe_irq_on(void)
{
	struct irq_desc *desc;
	unsigned long mask = 0;
	unsigned int status;
	int i;

	/*
	 * quiesce the kernel, or at least the asynchronous portion
	 */
	async_synchronize_full();
	mutex_lock(&probing_active);
	/*
	 * something may have generated an irq long ago and we want to
	 * flush such a longstanding irq before considering it as spurious.
	 */
	for_each_irq_desc_reverse(i, desc) {
		atomic_spin_lock_irq(&desc->lock);
		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
			/*
			 * An old-style architecture might still have
			 * the handle_bad_irq handler there:
			 */
			compat_irq_chip_set_default_handler(desc);

			/*
			 * Some chips need to know about probing in
			 * progress:
			 */
			if (desc->chip->set_type)
				desc->chip->set_type(i, IRQ_TYPE_PROBE);
			desc->chip->startup(i);
		}
		atomic_spin_unlock_irq(&desc->lock);
	}
예제 #2
0
unsigned long probe_irq_on(void)
{
	struct irq_desc *desc;
	unsigned long mask = 0;
	unsigned int status;
	int i;

	
	async_synchronize_full();
	mutex_lock(&probing_active);
	
	for_each_irq_desc_reverse(i, desc) {
		spin_lock_irq(&desc->lock);
		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
			
			compat_irq_chip_set_default_handler(desc);

			
			if (desc->chip->set_type)
				desc->chip->set_type(i, IRQ_TYPE_PROBE);
			desc->chip->startup(i);
		}
		spin_unlock_irq(&desc->lock);
	}
예제 #3
0
/**
 *	probe_irq_on	- begin an interrupt autodetect
 *
 *	Commence probing for an interrupt. The interrupts are scanned
 *	and a mask of potential interrupt lines is returned.
 *
 */
unsigned long probe_irq_on(void)
{
	struct irq_desc *desc;
	unsigned long mask;
	unsigned int i;

	mutex_lock(&probing_active);
	/*
	 * something may have generated an irq long ago and we want to
	 * flush such a longstanding irq before considering it as spurious.
	 */
	for (i = NR_IRQS-1; i > 0; i--) {
		desc = irq_desc + i;

		spin_lock_irq(&desc->lock);
		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
			/*
			 * An old-style architecture might still have
			 * the handle_bad_irq handler there:
			 */
			compat_irq_chip_set_default_handler(desc);

			/*
			 * Some chips need to know about probing in
			 * progress:
			 */
			if (desc->chip->set_type)
				desc->chip->set_type(i, IRQ_TYPE_PROBE);
			desc->chip->startup(i);
		}
		spin_unlock_irq(&desc->lock);
	}

	/* Wait for longstanding interrupts to trigger. */
	msleep(20);

	/*
	 * enable any unassigned irqs
	 * (we must startup again here because if a longstanding irq
	 * happened in the previous stage, it may have masked itself)
	 */
	for (i = NR_IRQS-1; i > 0; i--) {
		desc = irq_desc + i;

		spin_lock_irq(&desc->lock);
		if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
			if (desc->chip->startup(i))
				desc->status |= IRQ_PENDING;
		}
		spin_unlock_irq(&desc->lock);
	}

	/*
	 * Wait for spurious interrupts to trigger
	 */
	msleep(100);

	/*
	 * Now filter out any obviously spurious interrupts
	 */
	mask = 0;
	for (i = 0; i < NR_IRQS; i++) {
		unsigned int status;

		desc = irq_desc + i;
		spin_lock_irq(&desc->lock);
		status = desc->status;

		if (status & IRQ_AUTODETECT) {
			/* It triggered already - consider it spurious. */
			if (!(status & IRQ_WAITING)) {
				desc->status = status & ~IRQ_AUTODETECT;
				desc->chip->shutdown(i);
			} else
				if (i < 32)
					mask |= 1 << i;
		}
		spin_unlock_irq(&desc->lock);
	}

	return mask;
}