diff options
-rw-r--r-- | drivers/pci/msi.c | 43 | ||||
-rw-r--r-- | drivers/pci/msi.h | 2 | ||||
-rw-r--r-- | include/linux/irq.h | 7 | ||||
-rw-r--r-- | kernel/irq/chip.c | 7 |
4 files changed, 23 insertions, 36 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index da2c6c2b6b11..e3ba3963988c 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -188,18 +188,6 @@ static void unmask_MSI_irq(unsigned int irq) | |||
188 | 188 | ||
189 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) | 189 | static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) |
190 | { | 190 | { |
191 | struct msi_desc *entry; | ||
192 | unsigned long flags; | ||
193 | |||
194 | spin_lock_irqsave(&msi_lock, flags); | ||
195 | entry = msi_desc[irq]; | ||
196 | if (!entry || !entry->dev) { | ||
197 | spin_unlock_irqrestore(&msi_lock, flags); | ||
198 | return 0; | ||
199 | } | ||
200 | entry->msi_attrib.state = 1; /* Mark it active */ | ||
201 | spin_unlock_irqrestore(&msi_lock, flags); | ||
202 | |||
203 | return 0; /* never anything pending */ | 191 | return 0; /* never anything pending */ |
204 | } | 192 | } |
205 | 193 | ||
@@ -212,14 +200,6 @@ static unsigned int startup_msi_irq_w_maskbit(unsigned int irq) | |||
212 | 200 | ||
213 | static void shutdown_msi_irq(unsigned int irq) | 201 | static void shutdown_msi_irq(unsigned int irq) |
214 | { | 202 | { |
215 | struct msi_desc *entry; | ||
216 | unsigned long flags; | ||
217 | |||
218 | spin_lock_irqsave(&msi_lock, flags); | ||
219 | entry = msi_desc[irq]; | ||
220 | if (entry && entry->dev) | ||
221 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
222 | spin_unlock_irqrestore(&msi_lock, flags); | ||
223 | } | 203 | } |
224 | 204 | ||
225 | static void end_msi_irq_wo_maskbit(unsigned int irq) | 205 | static void end_msi_irq_wo_maskbit(unsigned int irq) |
@@ -671,7 +651,6 @@ static int msi_capability_init(struct pci_dev *dev) | |||
671 | entry->link.head = irq; | 651 | entry->link.head = irq; |
672 | entry->link.tail = irq; | 652 | entry->link.tail = irq; |
673 | entry->msi_attrib.type = PCI_CAP_ID_MSI; | 653 | entry->msi_attrib.type = PCI_CAP_ID_MSI; |
674 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
675 | entry->msi_attrib.is_64 = is_64bit_address(control); | 654 | entry->msi_attrib.is_64 = is_64bit_address(control); |
676 | entry->msi_attrib.entry_nr = 0; | 655 | entry->msi_attrib.entry_nr = 0; |
677 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 656 | entry->msi_attrib.maskbit = is_mask_bit_support(control); |
@@ -744,7 +723,6 @@ static int msix_capability_init(struct pci_dev *dev, | |||
744 | j = entries[i].entry; | 723 | j = entries[i].entry; |
745 | entries[i].vector = irq; | 724 | entries[i].vector = irq; |
746 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; | 725 | entry->msi_attrib.type = PCI_CAP_ID_MSIX; |
747 | entry->msi_attrib.state = 0; /* Mark it not active */ | ||
748 | entry->msi_attrib.is_64 = 1; | 726 | entry->msi_attrib.is_64 = 1; |
749 | entry->msi_attrib.entry_nr = j; | 727 | entry->msi_attrib.entry_nr = j; |
750 | entry->msi_attrib.maskbit = 1; | 728 | entry->msi_attrib.maskbit = 1; |
@@ -897,12 +875,12 @@ void pci_disable_msi(struct pci_dev* dev) | |||
897 | spin_unlock_irqrestore(&msi_lock, flags); | 875 | spin_unlock_irqrestore(&msi_lock, flags); |
898 | return; | 876 | return; |
899 | } | 877 | } |
900 | if (entry->msi_attrib.state) { | 878 | if (irq_has_action(dev->irq)) { |
901 | spin_unlock_irqrestore(&msi_lock, flags); | 879 | spin_unlock_irqrestore(&msi_lock, flags); |
902 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " | 880 | printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " |
903 | "free_irq() on MSI irq %d\n", | 881 | "free_irq() on MSI irq %d\n", |
904 | pci_name(dev), dev->irq); | 882 | pci_name(dev), dev->irq); |
905 | BUG_ON(entry->msi_attrib.state > 0); | 883 | BUG_ON(irq_has_action(dev->irq)); |
906 | } else { | 884 | } else { |
907 | default_irq = entry->msi_attrib.default_irq; | 885 | default_irq = entry->msi_attrib.default_irq; |
908 | spin_unlock_irqrestore(&msi_lock, flags); | 886 | spin_unlock_irqrestore(&msi_lock, flags); |
@@ -1035,17 +1013,16 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1035 | 1013 | ||
1036 | temp = dev->irq; | 1014 | temp = dev->irq; |
1037 | if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { | 1015 | if (!msi_lookup_irq(dev, PCI_CAP_ID_MSIX)) { |
1038 | int state, irq, head, tail = 0, warning = 0; | 1016 | int irq, head, tail = 0, warning = 0; |
1039 | unsigned long flags; | 1017 | unsigned long flags; |
1040 | 1018 | ||
1041 | irq = head = dev->irq; | 1019 | irq = head = dev->irq; |
1042 | dev->irq = temp; /* Restore pin IRQ */ | 1020 | dev->irq = temp; /* Restore pin IRQ */ |
1043 | while (head != tail) { | 1021 | while (head != tail) { |
1044 | spin_lock_irqsave(&msi_lock, flags); | 1022 | spin_lock_irqsave(&msi_lock, flags); |
1045 | state = msi_desc[irq]->msi_attrib.state; | ||
1046 | tail = msi_desc[irq]->link.tail; | 1023 | tail = msi_desc[irq]->link.tail; |
1047 | spin_unlock_irqrestore(&msi_lock, flags); | 1024 | spin_unlock_irqrestore(&msi_lock, flags); |
1048 | if (state) | 1025 | if (irq_has_action(irq)) |
1049 | warning = 1; | 1026 | warning = 1; |
1050 | else if (irq != head) /* Release MSI-X irq */ | 1027 | else if (irq != head) /* Release MSI-X irq */ |
1051 | msi_free_irq(dev, irq); | 1028 | msi_free_irq(dev, irq); |
@@ -1072,7 +1049,7 @@ void pci_disable_msix(struct pci_dev* dev) | |||
1072 | **/ | 1049 | **/ |
1073 | void msi_remove_pci_irq_vectors(struct pci_dev* dev) | 1050 | void msi_remove_pci_irq_vectors(struct pci_dev* dev) |
1074 | { | 1051 | { |
1075 | int state, pos, temp; | 1052 | int pos, temp; |
1076 | unsigned long flags; | 1053 | unsigned long flags; |
1077 | 1054 | ||
1078 | if (!pci_msi_enable || !dev) | 1055 | if (!pci_msi_enable || !dev) |
@@ -1081,14 +1058,11 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) | |||
1081 | temp = dev->irq; /* Save IOAPIC IRQ */ | 1058 | temp = dev->irq; /* Save IOAPIC IRQ */ |
1082 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 1059 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
1083 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { | 1060 | if (pos > 0 && !msi_lookup_irq(dev, PCI_CAP_ID_MSI)) { |
1084 | spin_lock_irqsave(&msi_lock, flags); | 1061 | if (irq_has_action(dev->irq)) { |
1085 | state = msi_desc[dev->irq]->msi_attrib.state; | ||
1086 | spin_unlock_irqrestore(&msi_lock, flags); | ||
1087 | if (state) { | ||
1088 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " | 1062 | printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " |
1089 | "called without free_irq() on MSI irq %d\n", | 1063 | "called without free_irq() on MSI irq %d\n", |
1090 | pci_name(dev), dev->irq); | 1064 | pci_name(dev), dev->irq); |
1091 | BUG_ON(state > 0); | 1065 | BUG_ON(irq_has_action(dev->irq)); |
1092 | } else /* Release MSI irq assigned to this device */ | 1066 | } else /* Release MSI irq assigned to this device */ |
1093 | msi_free_irq(dev, dev->irq); | 1067 | msi_free_irq(dev, dev->irq); |
1094 | dev->irq = temp; /* Restore IOAPIC IRQ */ | 1068 | dev->irq = temp; /* Restore IOAPIC IRQ */ |
@@ -1101,11 +1075,10 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) | |||
1101 | irq = head = dev->irq; | 1075 | irq = head = dev->irq; |
1102 | while (head != tail) { | 1076 | while (head != tail) { |
1103 | spin_lock_irqsave(&msi_lock, flags); | 1077 | spin_lock_irqsave(&msi_lock, flags); |
1104 | state = msi_desc[irq]->msi_attrib.state; | ||
1105 | tail = msi_desc[irq]->link.tail; | 1078 | tail = msi_desc[irq]->link.tail; |
1106 | base = msi_desc[irq]->mask_base; | 1079 | base = msi_desc[irq]->mask_base; |
1107 | spin_unlock_irqrestore(&msi_lock, flags); | 1080 | spin_unlock_irqrestore(&msi_lock, flags); |
1108 | if (state) | 1081 | if (irq_has_action(irq)) |
1109 | warning = 1; | 1082 | warning = 1; |
1110 | else if (irq != head) /* Release MSI-X irq */ | 1083 | else if (irq != head) /* Release MSI-X irq */ |
1111 | msi_free_irq(dev, irq); | 1084 | msi_free_irq(dev, irq); |
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index 435d05aae4ba..77823bfed5c1 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h | |||
@@ -53,7 +53,7 @@ struct msi_desc { | |||
53 | struct { | 53 | struct { |
54 | __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ | 54 | __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ |
55 | __u8 maskbit : 1; /* mask-pending bit supported ? */ | 55 | __u8 maskbit : 1; /* mask-pending bit supported ? */ |
56 | __u8 state : 1; /* {0: free, 1: busy} */ | 56 | __u8 unused : 1; |
57 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ | 57 | __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ |
58 | __u8 pos; /* Location of the msi capability */ | 58 | __u8 pos; /* Location of the msi capability */ |
59 | __u16 entry_nr; /* specific enabled entry */ | 59 | __u16 entry_nr; /* specific enabled entry */ |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 69855b23dff9..6f463606c318 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -372,6 +372,13 @@ set_irq_chained_handler(unsigned int irq, | |||
372 | extern int create_irq(void); | 372 | extern int create_irq(void); |
373 | extern void destroy_irq(unsigned int irq); | 373 | extern void destroy_irq(unsigned int irq); |
374 | 374 | ||
375 | /* Test to see if a driver has successfully requested an irq */ | ||
376 | static inline int irq_has_action(unsigned int irq) | ||
377 | { | ||
378 | struct irq_desc *desc = irq_desc + irq; | ||
379 | return desc->action != NULL; | ||
380 | } | ||
381 | |||
375 | /* Dynamic irq helper functions */ | 382 | /* Dynamic irq helper functions */ |
376 | extern void dynamic_irq_init(unsigned int irq); | 383 | extern void dynamic_irq_init(unsigned int irq); |
377 | extern void dynamic_irq_cleanup(unsigned int irq); | 384 | extern void dynamic_irq_cleanup(unsigned int irq); |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 0dc24386dd99..4cf65f5c6a74 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -67,6 +67,13 @@ void dynamic_irq_cleanup(unsigned int irq) | |||
67 | 67 | ||
68 | desc = irq_desc + irq; | 68 | desc = irq_desc + irq; |
69 | spin_lock_irqsave(&desc->lock, flags); | 69 | spin_lock_irqsave(&desc->lock, flags); |
70 | if (desc->action) { | ||
71 | spin_unlock_irqrestore(&desc->lock, flags); | ||
72 | printk(KERN_ERR "Destroying IRQ%d without calling free_irq\n", | ||
73 | irq); | ||
74 | WARN_ON(1); | ||
75 | return; | ||
76 | } | ||
70 | desc->handle_irq = handle_bad_irq; | 77 | desc->handle_irq = handle_bad_irq; |
71 | desc->chip = &no_irq_chip; | 78 | desc->chip = &no_irq_chip; |
72 | spin_unlock_irqrestore(&desc->lock, flags); | 79 | spin_unlock_irqrestore(&desc->lock, flags); |