Merge commit 'v2.6.27-rc8' into genirq
This commit is contained in:
@@ -177,8 +177,7 @@ static void __enable_irq(struct irq_desc *desc, unsigned int irq)
|
||||
{
|
||||
switch (desc->depth) {
|
||||
case 0:
|
||||
printk(KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
|
||||
WARN_ON(1);
|
||||
WARN(1, KERN_WARNING "Unbalanced enable for IRQ %d\n", irq);
|
||||
break;
|
||||
case 1: {
|
||||
unsigned int status = desc->status & ~IRQ_DISABLED;
|
||||
@@ -217,6 +216,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
|
||||
@@ -233,30 +243,32 @@ 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;
|
||||
WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
|
||||
} 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;
|
||||
}
|
||||
@@ -293,6 +305,31 @@ 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 trigger mode %d for irq %u failed (%pF)\n",
|
||||
(int)(flags & IRQF_TRIGGER_MASK),
|
||||
irq, chip->set_type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Internal function to register an irqaction - typically used to
|
||||
* allocate special interrupts that are part of the architecture.
|
||||
@@ -304,6 +341,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;
|
||||
@@ -361,36 +399,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);
|
||||
|
||||
@@ -405,6 +431,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;
|
||||
|
Reference in New Issue
Block a user