diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 29290f554e79..1183d545da1e 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1070,6 +1070,11 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, | |||
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | if (flags & IOAPIC_MAP_ALLOC) { | 1072 | if (flags & IOAPIC_MAP_ALLOC) { |
1073 | /* special handling for legacy IRQs */ | ||
1074 | if (irq < nr_legacy_irqs() && info->count == 1 && | ||
1075 | mp_irqdomain_map(domain, irq, pin) != 0) | ||
1076 | irq = -1; | ||
1077 | |||
1073 | if (irq > 0) | 1078 | if (irq > 0) |
1074 | info->count++; | 1079 | info->count++; |
1075 | else if (info->count == 0) | 1080 | else if (info->count == 0) |
@@ -2618,6 +2623,7 @@ static struct irq_chip ioapic_chip __read_mostly = { | |||
2618 | .irq_eoi = ack_apic_level, | 2623 | .irq_eoi = ack_apic_level, |
2619 | .irq_set_affinity = native_ioapic_set_affinity, | 2624 | .irq_set_affinity = native_ioapic_set_affinity, |
2620 | .irq_retrigger = ioapic_retrigger_irq, | 2625 | .irq_retrigger = ioapic_retrigger_irq, |
2626 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
2621 | }; | 2627 | }; |
2622 | 2628 | ||
2623 | static inline void init_IO_APIC_traps(void) | 2629 | static inline void init_IO_APIC_traps(void) |
@@ -3168,6 +3174,7 @@ static struct irq_chip msi_chip = { | |||
3168 | .irq_ack = ack_apic_edge, | 3174 | .irq_ack = ack_apic_edge, |
3169 | .irq_set_affinity = msi_set_affinity, | 3175 | .irq_set_affinity = msi_set_affinity, |
3170 | .irq_retrigger = ioapic_retrigger_irq, | 3176 | .irq_retrigger = ioapic_retrigger_irq, |
3177 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
3171 | }; | 3178 | }; |
3172 | 3179 | ||
3173 | int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, | 3180 | int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, |
@@ -3266,6 +3273,7 @@ static struct irq_chip dmar_msi_type = { | |||
3266 | .irq_ack = ack_apic_edge, | 3273 | .irq_ack = ack_apic_edge, |
3267 | .irq_set_affinity = dmar_msi_set_affinity, | 3274 | .irq_set_affinity = dmar_msi_set_affinity, |
3268 | .irq_retrigger = ioapic_retrigger_irq, | 3275 | .irq_retrigger = ioapic_retrigger_irq, |
3276 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
3269 | }; | 3277 | }; |
3270 | 3278 | ||
3271 | int arch_setup_dmar_msi(unsigned int irq) | 3279 | int arch_setup_dmar_msi(unsigned int irq) |
@@ -3316,6 +3324,7 @@ static struct irq_chip hpet_msi_type = { | |||
3316 | .irq_ack = ack_apic_edge, | 3324 | .irq_ack = ack_apic_edge, |
3317 | .irq_set_affinity = hpet_msi_set_affinity, | 3325 | .irq_set_affinity = hpet_msi_set_affinity, |
3318 | .irq_retrigger = ioapic_retrigger_irq, | 3326 | .irq_retrigger = ioapic_retrigger_irq, |
3327 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
3319 | }; | 3328 | }; |
3320 | 3329 | ||
3321 | int default_setup_hpet_msi(unsigned int irq, unsigned int id) | 3330 | int default_setup_hpet_msi(unsigned int irq, unsigned int id) |
@@ -3379,6 +3388,7 @@ static struct irq_chip ht_irq_chip = { | |||
3379 | .irq_ack = ack_apic_edge, | 3388 | .irq_ack = ack_apic_edge, |
3380 | .irq_set_affinity = ht_set_affinity, | 3389 | .irq_set_affinity = ht_set_affinity, |
3381 | .irq_retrigger = ioapic_retrigger_irq, | 3390 | .irq_retrigger = ioapic_retrigger_irq, |
3391 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
3382 | }; | 3392 | }; |
3383 | 3393 | ||
3384 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | 3394 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) |
@@ -3896,7 +3906,15 @@ int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq, | |||
3896 | info->polarity = 1; | 3906 | info->polarity = 1; |
3897 | } | 3907 | } |
3898 | info->node = NUMA_NO_NODE; | 3908 | info->node = NUMA_NO_NODE; |
3899 | info->set = 1; | 3909 | |
3910 | /* | ||
3911 | * setup_IO_APIC_irqs() programs all legacy IRQs with default | ||
3912 | * trigger and polarity attributes. Don't set the flag for that | ||
3913 | * case so the first legacy IRQ user could reprogram the pin | ||
3914 | * with real trigger and polarity attributes. | ||
3915 | */ | ||
3916 | if (virq >= nr_legacy_irqs() || info->count) | ||
3917 | info->set = 1; | ||
3900 | } | 3918 | } |
3901 | set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger, | 3919 | set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger, |
3902 | info->polarity); | 3920 | info->polarity); |
@@ -3946,6 +3964,18 @@ int mp_set_gsi_attr(u32 gsi, int trigger, int polarity, int node) | |||
3946 | return ret; | 3964 | return ret; |
3947 | } | 3965 | } |
3948 | 3966 | ||
3967 | bool mp_should_keep_irq(struct device *dev) | ||
3968 | { | ||
3969 | if (dev->power.is_prepared) | ||
3970 | return true; | ||
3971 | #ifdef CONFIG_PM_RUNTIME | ||
3972 | if (dev->power.runtime_status == RPM_SUSPENDING) | ||
3973 | return true; | ||
3974 | #endif | ||
3975 | |||
3976 | return false; | ||
3977 | } | ||
3978 | |||
3949 | /* Enable IOAPIC early just for system timer */ | 3979 | /* Enable IOAPIC early just for system timer */ |
3950 | void __init pre_init_apic_IRQ0(void) | 3980 | void __init pre_init_apic_IRQ0(void) |
3951 | { | 3981 | { |