aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/msi.c43
-rw-r--r--drivers/pci/msi.h2
-rw-r--r--include/linux/irq.h7
-rw-r--r--kernel/irq/chip.c7
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
189static unsigned int startup_msi_irq_wo_maskbit(unsigned int irq) 189static 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
213static void shutdown_msi_irq(unsigned int irq) 201static 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
225static void end_msi_irq_wo_maskbit(unsigned int irq) 205static 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 **/
1073void msi_remove_pci_irq_vectors(struct pci_dev* dev) 1050void 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,
372extern int create_irq(void); 372extern int create_irq(void);
373extern void destroy_irq(unsigned int irq); 373extern void destroy_irq(unsigned int irq);
374 374
375/* Test to see if a driver has successfully requested an irq */
376static 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 */
376extern void dynamic_irq_init(unsigned int irq); 383extern void dynamic_irq_init(unsigned int irq);
377extern void dynamic_irq_cleanup(unsigned int irq); 384extern 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);