diff options
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r-- | drivers/pci/msi.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f48f7550b4a7..79e56906c7f1 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -75,22 +75,17 @@ void arch_teardown_msi_irqs(struct pci_dev *dev) | |||
75 | } | 75 | } |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | static void __msi_set_enable(struct pci_dev *dev, int pos, int enable) | 78 | static void msi_set_enable(struct pci_dev *dev, int pos, int enable) |
79 | { | 79 | { |
80 | u16 control; | 80 | u16 control; |
81 | 81 | ||
82 | if (pos) { | 82 | BUG_ON(!pos); |
83 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | ||
84 | control &= ~PCI_MSI_FLAGS_ENABLE; | ||
85 | if (enable) | ||
86 | control |= PCI_MSI_FLAGS_ENABLE; | ||
87 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | ||
88 | } | ||
89 | } | ||
90 | 83 | ||
91 | static void msi_set_enable(struct pci_dev *dev, int enable) | 84 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); |
92 | { | 85 | control &= ~PCI_MSI_FLAGS_ENABLE; |
93 | __msi_set_enable(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), enable); | 86 | if (enable) |
87 | control |= PCI_MSI_FLAGS_ENABLE; | ||
88 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | ||
94 | } | 89 | } |
95 | 90 | ||
96 | static void msix_set_enable(struct pci_dev *dev, int enable) | 91 | static void msix_set_enable(struct pci_dev *dev, int enable) |
@@ -300,7 +295,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev) | |||
300 | pos = entry->msi_attrib.pos; | 295 | pos = entry->msi_attrib.pos; |
301 | 296 | ||
302 | pci_intx_for_msi(dev, 0); | 297 | pci_intx_for_msi(dev, 0); |
303 | msi_set_enable(dev, 0); | 298 | msi_set_enable(dev, pos, 0); |
304 | write_msi_msg(dev->irq, &entry->msg); | 299 | write_msi_msg(dev->irq, &entry->msg); |
305 | 300 | ||
306 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | 301 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); |
@@ -362,9 +357,9 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
362 | u16 control; | 357 | u16 control; |
363 | unsigned mask; | 358 | unsigned mask; |
364 | 359 | ||
365 | msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ | ||
366 | |||
367 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 360 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); |
361 | msi_set_enable(dev, pos, 0); /* Disable MSI during set up */ | ||
362 | |||
368 | pci_read_config_word(dev, msi_control_reg(pos), &control); | 363 | pci_read_config_word(dev, msi_control_reg(pos), &control); |
369 | /* MSI Entry Initialization */ | 364 | /* MSI Entry Initialization */ |
370 | entry = alloc_msi_entry(dev); | 365 | entry = alloc_msi_entry(dev); |
@@ -396,7 +391,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) | |||
396 | 391 | ||
397 | /* Set MSI enabled bits */ | 392 | /* Set MSI enabled bits */ |
398 | pci_intx_for_msi(dev, 0); | 393 | pci_intx_for_msi(dev, 0); |
399 | msi_set_enable(dev, 1); | 394 | msi_set_enable(dev, pos, 1); |
400 | dev->msi_enabled = 1; | 395 | dev->msi_enabled = 1; |
401 | 396 | ||
402 | dev->irq = entry->irq; | 397 | dev->irq = entry->irq; |
@@ -593,17 +588,20 @@ void pci_msi_shutdown(struct pci_dev *dev) | |||
593 | struct msi_desc *desc; | 588 | struct msi_desc *desc; |
594 | u32 mask; | 589 | u32 mask; |
595 | u16 ctrl; | 590 | u16 ctrl; |
591 | unsigned pos; | ||
596 | 592 | ||
597 | if (!pci_msi_enable || !dev || !dev->msi_enabled) | 593 | if (!pci_msi_enable || !dev || !dev->msi_enabled) |
598 | return; | 594 | return; |
599 | 595 | ||
600 | msi_set_enable(dev, 0); | 596 | BUG_ON(list_empty(&dev->msi_list)); |
597 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); | ||
598 | pos = desc->msi_attrib.pos; | ||
599 | |||
600 | msi_set_enable(dev, pos, 0); | ||
601 | pci_intx_for_msi(dev, 1); | 601 | pci_intx_for_msi(dev, 1); |
602 | dev->msi_enabled = 0; | 602 | dev->msi_enabled = 0; |
603 | 603 | ||
604 | BUG_ON(list_empty(&dev->msi_list)); | 604 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &ctrl); |
605 | desc = list_first_entry(&dev->msi_list, struct msi_desc, list); | ||
606 | pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl); | ||
607 | mask = msi_capable_mask(ctrl); | 605 | mask = msi_capable_mask(ctrl); |
608 | msi_mask_irq(desc, mask, ~mask); | 606 | msi_mask_irq(desc, mask, ~mask); |
609 | 607 | ||