Merge branch 'linus' into x86/x2apic

Conflicts:

	drivers/pci/dmar.c

Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Ingo Molnar
2008-07-25 13:08:16 +02:00
1526 changed files with 69617 additions and 53838 deletions

View File

@ -224,6 +224,17 @@ void enable_irq(unsigned int irq)
}
EXPORT_SYMBOL(enable_irq);
int set_irq_wake_real(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_desc + irq;
int ret = -ENXIO;
if (desc->chip->set_wake)
ret = desc->chip->set_wake(irq, on);
return ret;
}
/**
* set_irq_wake - control irq power management wakeup
* @irq: interrupt to control
@ -240,30 +251,34 @@ int set_irq_wake(unsigned int irq, unsigned int on)
{
struct irq_desc *desc = irq_desc + irq;
unsigned long flags;
int ret = -ENXIO;
int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake;
int ret = 0;
/* wakeup-capable irqs can be shared between drivers that
* don't need to have the same sleep mode behaviors.
*/
spin_lock_irqsave(&desc->lock, flags);
if (on) {
if (desc->wake_depth++ == 0)
desc->status |= IRQ_WAKEUP;
else
set_wake = NULL;
if (desc->wake_depth++ == 0) {
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 0;
else
desc->status |= IRQ_WAKEUP;
}
} else {
if (desc->wake_depth == 0) {
printk(KERN_WARNING "Unbalanced IRQ %d "
"wake disable\n", irq);
WARN_ON(1);
} else if (--desc->wake_depth == 0)
desc->status &= ~IRQ_WAKEUP;
else
set_wake = NULL;
} else if (--desc->wake_depth == 0) {
ret = set_irq_wake_real(irq, on);
if (ret)
desc->wake_depth = 1;
else
desc->status &= ~IRQ_WAKEUP;
}
}
if (set_wake)
ret = desc->chip->set_wake(irq, on);
spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
@ -300,6 +315,30 @@ void compat_irq_chip_set_default_handler(struct irq_desc *desc)
desc->handle_irq = NULL;
}
static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
unsigned long flags)
{
int ret;
if (!chip || !chip->set_type) {
/*
* IRQF_TRIGGER_* but the PIC does not support multiple
* flow-types?
*/
pr_warning("No set_type function for IRQ %d (%s)\n", irq,
chip ? (chip->name ? : "unknown") : "unknown");
return 0;
}
ret = chip->set_type(irq, flags & IRQF_TRIGGER_MASK);
if (ret)
pr_err("setting flow type for irq %u failed (%pF)\n",
irq, chip->set_type);
return ret;
}
/*
* Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
@ -311,6 +350,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
const char *old_name = NULL;
unsigned long flags;
int shared = 0;
int ret;
if (irq >= NR_IRQS)
return -EINVAL;
@ -368,36 +408,24 @@ int setup_irq(unsigned int irq, struct irqaction *new)
shared = 1;
}
*p = new;
/* Exclude IRQ from balancing */
if (new->flags & IRQF_NOBALANCING)
desc->status |= IRQ_NO_BALANCING;
if (!shared) {
irq_chip_set_defaults(desc->chip);
/* Setup the type (level, edge polarity) if configured: */
if (new->flags & IRQF_TRIGGER_MASK) {
ret = __irq_set_trigger(desc->chip, irq, new->flags);
if (ret) {
spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
} else
compat_irq_chip_set_default_handler(desc);
#if defined(CONFIG_IRQ_PER_CPU)
if (new->flags & IRQF_PERCPU)
desc->status |= IRQ_PER_CPU;
#endif
/* Setup the type (level, edge polarity) if configured: */
if (new->flags & IRQF_TRIGGER_MASK) {
if (desc->chip->set_type)
desc->chip->set_type(irq,
new->flags & IRQF_TRIGGER_MASK);
else
/*
* IRQF_TRIGGER_* but the PIC does not support
* multiple flow-types?
*/
printk(KERN_WARNING "No IRQF_TRIGGER set_type "
"function for IRQ %d (%s)\n", irq,
desc->chip->name);
} else
compat_irq_chip_set_default_handler(desc);
desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
IRQ_INPROGRESS | IRQ_SPURIOUS_DISABLED);
@ -415,6 +443,13 @@ int setup_irq(unsigned int irq, struct irqaction *new)
/* Set default affinity mask once everything is setup */
irq_select_affinity(irq);
}
*p = new;
/* Exclude IRQ from balancing */
if (new->flags & IRQF_NOBALANCING)
desc->status |= IRQ_NO_BALANCING;
/* Reset broken irq detection when installing new handler */
desc->irq_count = 0;
desc->irqs_unhandled = 0;