diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-02 16:41:36 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-02 16:41:36 -0500 |
commit | 923a789b49c7269a0245d5af6afe486188d940df (patch) | |
tree | c3f168427372e64f7467a794f313416da5086ba0 /kernel/irq/manage.c | |
parent | 103ceffb9501531f6931df6aebc11a05189201f0 (diff) | |
parent | b840d79631c882786925303c2b0f4fefc31845ed (diff) |
Merge branch 'linus' into x86/cleanups
Conflicts:
arch/x86/kernel/reboot.c
Diffstat (limited to 'kernel/irq/manage.c')
-rw-r--r-- | kernel/irq/manage.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 801addda3c43..61c4a9b62165 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -79,7 +79,7 @@ int irq_can_set_affinity(unsigned int irq) | |||
79 | * @cpumask: cpumask | 79 | * @cpumask: cpumask |
80 | * | 80 | * |
81 | */ | 81 | */ |
82 | int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | 82 | int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) |
83 | { | 83 | { |
84 | struct irq_desc *desc = irq_to_desc(irq); | 84 | struct irq_desc *desc = irq_to_desc(irq); |
85 | unsigned long flags; | 85 | unsigned long flags; |
@@ -91,14 +91,14 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | |||
91 | 91 | ||
92 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 92 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
93 | if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) { | 93 | if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) { |
94 | desc->affinity = cpumask; | 94 | cpumask_copy(&desc->affinity, cpumask); |
95 | desc->chip->set_affinity(irq, cpumask); | 95 | desc->chip->set_affinity(irq, cpumask); |
96 | } else { | 96 | } else { |
97 | desc->status |= IRQ_MOVE_PENDING; | 97 | desc->status |= IRQ_MOVE_PENDING; |
98 | desc->pending_mask = cpumask; | 98 | cpumask_copy(&desc->pending_mask, cpumask); |
99 | } | 99 | } |
100 | #else | 100 | #else |
101 | desc->affinity = cpumask; | 101 | cpumask_copy(&desc->affinity, cpumask); |
102 | desc->chip->set_affinity(irq, cpumask); | 102 | desc->chip->set_affinity(irq, cpumask); |
103 | #endif | 103 | #endif |
104 | desc->status |= IRQ_AFFINITY_SET; | 104 | desc->status |= IRQ_AFFINITY_SET; |
@@ -112,26 +112,24 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask) | |||
112 | */ | 112 | */ |
113 | int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc) | 113 | int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc) |
114 | { | 114 | { |
115 | cpumask_t mask; | ||
116 | |||
117 | if (!irq_can_set_affinity(irq)) | 115 | if (!irq_can_set_affinity(irq)) |
118 | return 0; | 116 | return 0; |
119 | 117 | ||
120 | cpus_and(mask, cpu_online_map, irq_default_affinity); | ||
121 | |||
122 | /* | 118 | /* |
123 | * Preserve an userspace affinity setup, but make sure that | 119 | * Preserve an userspace affinity setup, but make sure that |
124 | * one of the targets is online. | 120 | * one of the targets is online. |
125 | */ | 121 | */ |
126 | if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) { | 122 | if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) { |
127 | if (cpus_intersects(desc->affinity, cpu_online_map)) | 123 | if (cpumask_any_and(&desc->affinity, cpu_online_mask) |
128 | mask = desc->affinity; | 124 | < nr_cpu_ids) |
125 | goto set_affinity; | ||
129 | else | 126 | else |
130 | desc->status &= ~IRQ_AFFINITY_SET; | 127 | desc->status &= ~IRQ_AFFINITY_SET; |
131 | } | 128 | } |
132 | 129 | ||
133 | desc->affinity = mask; | 130 | cpumask_and(&desc->affinity, cpu_online_mask, &irq_default_affinity); |
134 | desc->chip->set_affinity(irq, mask); | 131 | set_affinity: |
132 | desc->chip->set_affinity(irq, &desc->affinity); | ||
135 | 133 | ||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
@@ -370,16 +368,18 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, | |||
370 | return 0; | 368 | return 0; |
371 | } | 369 | } |
372 | 370 | ||
373 | ret = chip->set_type(irq, flags & IRQF_TRIGGER_MASK); | 371 | /* caller masked out all except trigger mode flags */ |
372 | ret = chip->set_type(irq, flags); | ||
374 | 373 | ||
375 | if (ret) | 374 | if (ret) |
376 | pr_err("setting trigger mode %d for irq %u failed (%pF)\n", | 375 | pr_err("setting trigger mode %d for irq %u failed (%pF)\n", |
377 | (int)(flags & IRQF_TRIGGER_MASK), | 376 | (int)flags, irq, chip->set_type); |
378 | irq, chip->set_type); | ||
379 | else { | 377 | else { |
378 | if (flags & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
379 | flags |= IRQ_LEVEL; | ||
380 | /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ | 380 | /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ |
381 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | 381 | desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK); |
382 | desc->status |= flags & IRQ_TYPE_SENSE_MASK; | 382 | desc->status |= flags; |
383 | } | 383 | } |
384 | 384 | ||
385 | return ret; | 385 | return ret; |
@@ -459,7 +459,8 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new) | |||
459 | 459 | ||
460 | /* Setup the type (level, edge polarity) if configured: */ | 460 | /* Setup the type (level, edge polarity) if configured: */ |
461 | if (new->flags & IRQF_TRIGGER_MASK) { | 461 | if (new->flags & IRQF_TRIGGER_MASK) { |
462 | ret = __irq_set_trigger(desc, irq, new->flags); | 462 | ret = __irq_set_trigger(desc, irq, |
463 | new->flags & IRQF_TRIGGER_MASK); | ||
463 | 464 | ||
464 | if (ret) { | 465 | if (ret) { |
465 | spin_unlock_irqrestore(&desc->lock, flags); | 466 | spin_unlock_irqrestore(&desc->lock, flags); |
@@ -673,6 +674,18 @@ int request_irq(unsigned int irq, irq_handler_t handler, | |||
673 | struct irq_desc *desc; | 674 | struct irq_desc *desc; |
674 | int retval; | 675 | int retval; |
675 | 676 | ||
677 | /* | ||
678 | * handle_IRQ_event() always ignores IRQF_DISABLED except for | ||
679 | * the _first_ irqaction (sigh). That can cause oopsing, but | ||
680 | * the behavior is classified as "will not fix" so we need to | ||
681 | * start nudging drivers away from using that idiom. | ||
682 | */ | ||
683 | if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) | ||
684 | == (IRQF_SHARED|IRQF_DISABLED)) | ||
685 | pr_warning("IRQ %d/%s: IRQF_DISABLED is not " | ||
686 | "guaranteed on shared IRQs\n", | ||
687 | irq, devname); | ||
688 | |||
676 | #ifdef CONFIG_LOCKDEP | 689 | #ifdef CONFIG_LOCKDEP |
677 | /* | 690 | /* |
678 | * Lockdep wants atomic interrupt handlers: | 691 | * Lockdep wants atomic interrupt handlers: |