aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r--drivers/pci/msi.c150
1 files changed, 31 insertions, 119 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index fc7dd2a239dd..f9fdc54473c4 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -15,6 +15,7 @@
15#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
16#include <linux/pci.h> 16#include <linux/pci.h>
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18#include <linux/msi.h>
18 19
19#include <asm/errno.h> 20#include <asm/errno.h>
20#include <asm/io.h> 21#include <asm/io.h>
@@ -29,15 +30,6 @@ static kmem_cache_t* msi_cachep;
29 30
30static int pci_msi_enable = 1; 31static int pci_msi_enable = 1;
31 32
32static struct msi_ops *msi_ops;
33
34int
35msi_register(struct msi_ops *ops)
36{
37 msi_ops = ops;
38 return 0;
39}
40
41static int msi_cache_init(void) 33static int msi_cache_init(void)
42{ 34{
43 msi_cachep = kmem_cache_create("msi_cache", sizeof(struct msi_desc), 35 msi_cachep = kmem_cache_create("msi_cache", sizeof(struct msi_desc),
@@ -80,8 +72,9 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
80 } 72 }
81} 73}
82 74
83static void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) 75void read_msi_msg(unsigned int irq, struct msi_msg *msg)
84{ 76{
77 struct msi_desc *entry = get_irq_data(irq);
85 switch(entry->msi_attrib.type) { 78 switch(entry->msi_attrib.type) {
86 case PCI_CAP_ID_MSI: 79 case PCI_CAP_ID_MSI:
87 { 80 {
@@ -118,8 +111,9 @@ static void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
118 } 111 }
119} 112}
120 113
121static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) 114void write_msi_msg(unsigned int irq, struct msi_msg *msg)
122{ 115{
116 struct msi_desc *entry = get_irq_data(irq);
123 switch (entry->msi_attrib.type) { 117 switch (entry->msi_attrib.type) {
124 case PCI_CAP_ID_MSI: 118 case PCI_CAP_ID_MSI:
125 { 119 {
@@ -157,53 +151,16 @@ static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
157 } 151 }
158} 152}
159 153
160#ifdef CONFIG_SMP 154void mask_msi_irq(unsigned int irq)
161static void set_msi_affinity(unsigned int irq, cpumask_t cpu_mask)
162{
163 struct msi_desc *entry;
164 struct msi_msg msg;
165
166 entry = msi_desc[irq];
167 if (!entry || !entry->dev)
168 return;
169
170 read_msi_msg(entry, &msg);
171 msi_ops->target(irq, cpu_mask, &msg);
172 write_msi_msg(entry, &msg);
173 set_native_irq_info(irq, cpu_mask);
174}
175#else
176#define set_msi_affinity NULL
177#endif /* CONFIG_SMP */
178
179static void mask_MSI_irq(unsigned int irq)
180{ 155{
181 msi_set_mask_bit(irq, 1); 156 msi_set_mask_bit(irq, 1);
182} 157}
183 158
184static void unmask_MSI_irq(unsigned int irq) 159void unmask_msi_irq(unsigned int irq)
185{ 160{
186 msi_set_mask_bit(irq, 0); 161 msi_set_mask_bit(irq, 0);
187} 162}
188 163
189static void ack_msi_irq(unsigned int irq)
190{
191 move_native_irq(irq);
192 ack_APIC_irq();
193}
194
195/*
196 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
197 * which implement the MSI or MSI-X Capability Structure.
198 */
199static struct irq_chip msi_chip = {
200 .name = "PCI-MSI",
201 .unmask = unmask_MSI_irq,
202 .mask = mask_MSI_irq,
203 .ack = ack_msi_irq,
204 .set_affinity = set_msi_affinity
205};
206
207static int msi_free_irq(struct pci_dev* dev, int irq); 164static int msi_free_irq(struct pci_dev* dev, int irq);
208static int msi_init(void) 165static int msi_init(void)
209{ 166{
@@ -219,22 +176,6 @@ static int msi_init(void)
219 return status; 176 return status;
220 } 177 }
221 178
222 status = msi_arch_init();
223 if (status < 0) {
224 pci_msi_enable = 0;
225 printk(KERN_WARNING
226 "PCI: MSI arch init failed. MSI disabled.\n");
227 return status;
228 }
229
230 if (! msi_ops) {
231 pci_msi_enable = 0;
232 printk(KERN_WARNING
233 "PCI: MSI ops not registered. MSI disabled.\n");
234 status = -EINVAL;
235 return status;
236 }
237
238 status = msi_cache_init(); 179 status = msi_cache_init();
239 if (status < 0) { 180 if (status < 0) {
240 pci_msi_enable = 0; 181 pci_msi_enable = 0;
@@ -268,7 +209,7 @@ static void attach_msi_entry(struct msi_desc *entry, int irq)
268 spin_unlock_irqrestore(&msi_lock, flags); 209 spin_unlock_irqrestore(&msi_lock, flags);
269} 210}
270 211
271static int create_msi_irq(struct irq_chip *chip) 212static int create_msi_irq(void)
272{ 213{
273 struct msi_desc *entry; 214 struct msi_desc *entry;
274 int irq; 215 int irq;
@@ -283,7 +224,6 @@ static int create_msi_irq(struct irq_chip *chip)
283 return -EBUSY; 224 return -EBUSY;
284 } 225 }
285 226
286 set_irq_chip_and_handler(irq, chip, handle_edge_irq);
287 set_irq_data(irq, entry); 227 set_irq_data(irq, entry);
288 228
289 return irq; 229 return irq;
@@ -473,7 +413,7 @@ int pci_save_msix_state(struct pci_dev *dev)
473 struct msi_desc *entry; 413 struct msi_desc *entry;
474 414
475 entry = msi_desc[irq]; 415 entry = msi_desc[irq];
476 read_msi_msg(entry, &entry->msg_save); 416 read_msi_msg(irq, &entry->msg_save);
477 417
478 tail = msi_desc[irq]->link.tail; 418 tail = msi_desc[irq]->link.tail;
479 irq = tail; 419 irq = tail;
@@ -512,7 +452,7 @@ void pci_restore_msix_state(struct pci_dev *dev)
512 irq = head = dev->irq; 452 irq = head = dev->irq;
513 while (head != tail) { 453 while (head != tail) {
514 entry = msi_desc[irq]; 454 entry = msi_desc[irq];
515 write_msi_msg(entry, &entry->msg_save); 455 write_msi_msg(irq, &entry->msg_save);
516 456
517 tail = msi_desc[irq]->link.tail; 457 tail = msi_desc[irq]->link.tail;
518 irq = tail; 458 irq = tail;
@@ -524,39 +464,6 @@ void pci_restore_msix_state(struct pci_dev *dev)
524} 464}
525#endif 465#endif
526 466
527static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
528{
529 int status;
530 struct msi_msg msg;
531 int pos;
532 u16 control;
533
534 pos = entry->msi_attrib.pos;
535 pci_read_config_word(dev, msi_control_reg(pos), &control);
536
537 /* Configure MSI capability structure */
538 status = msi_ops->setup(dev, dev->irq, &msg);
539 if (status < 0)
540 return status;
541
542 write_msi_msg(entry, &msg);
543 if (entry->msi_attrib.maskbit) {
544 unsigned int maskbits, temp;
545 /* All MSIs are unmasked by default, Mask them all */
546 pci_read_config_dword(dev,
547 msi_mask_bits_reg(pos, is_64bit_address(control)),
548 &maskbits);
549 temp = (1 << multi_msi_capable(control));
550 temp = ((temp - 1) & ~temp);
551 maskbits |= temp;
552 pci_write_config_dword(dev,
553 msi_mask_bits_reg(pos, is_64bit_address(control)),
554 maskbits);
555 }
556
557 return 0;
558}
559
560/** 467/**
561 * msi_capability_init - configure device's MSI capability structure 468 * msi_capability_init - configure device's MSI capability structure
562 * @dev: pointer to the pci_dev data structure of MSI device function 469 * @dev: pointer to the pci_dev data structure of MSI device function
@@ -576,7 +483,7 @@ static int msi_capability_init(struct pci_dev *dev)
576 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 483 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
577 pci_read_config_word(dev, msi_control_reg(pos), &control); 484 pci_read_config_word(dev, msi_control_reg(pos), &control);
578 /* MSI Entry Initialization */ 485 /* MSI Entry Initialization */
579 irq = create_msi_irq(&msi_chip); 486 irq = create_msi_irq();
580 if (irq < 0) 487 if (irq < 0)
581 return irq; 488 return irq;
582 489
@@ -589,16 +496,27 @@ static int msi_capability_init(struct pci_dev *dev)
589 entry->msi_attrib.maskbit = is_mask_bit_support(control); 496 entry->msi_attrib.maskbit = is_mask_bit_support(control);
590 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ 497 entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
591 entry->msi_attrib.pos = pos; 498 entry->msi_attrib.pos = pos;
592 dev->irq = irq;
593 entry->dev = dev;
594 if (is_mask_bit_support(control)) { 499 if (is_mask_bit_support(control)) {
595 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, 500 entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
596 is_64bit_address(control)); 501 is_64bit_address(control));
597 } 502 }
503 entry->dev = dev;
504 if (entry->msi_attrib.maskbit) {
505 unsigned int maskbits, temp;
506 /* All MSIs are unmasked by default, Mask them all */
507 pci_read_config_dword(dev,
508 msi_mask_bits_reg(pos, is_64bit_address(control)),
509 &maskbits);
510 temp = (1 << multi_msi_capable(control));
511 temp = ((temp - 1) & ~temp);
512 maskbits |= temp;
513 pci_write_config_dword(dev,
514 msi_mask_bits_reg(pos, is_64bit_address(control)),
515 maskbits);
516 }
598 /* Configure MSI capability structure */ 517 /* Configure MSI capability structure */
599 status = msi_register_init(dev, entry); 518 status = arch_setup_msi_irq(irq, dev);
600 if (status != 0) { 519 if (status < 0) {
601 dev->irq = entry->msi_attrib.default_irq;
602 destroy_msi_irq(irq); 520 destroy_msi_irq(irq);
603 return status; 521 return status;
604 } 522 }
@@ -607,6 +525,7 @@ static int msi_capability_init(struct pci_dev *dev)
607 /* Set MSI enabled bits */ 525 /* Set MSI enabled bits */
608 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 526 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
609 527
528 dev->irq = irq;
610 return 0; 529 return 0;
611} 530}
612 531
@@ -624,7 +543,6 @@ static int msix_capability_init(struct pci_dev *dev,
624 struct msix_entry *entries, int nvec) 543 struct msix_entry *entries, int nvec)
625{ 544{
626 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; 545 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
627 struct msi_msg msg;
628 int status; 546 int status;
629 int irq, pos, i, j, nr_entries, temp = 0; 547 int irq, pos, i, j, nr_entries, temp = 0;
630 unsigned long phys_addr; 548 unsigned long phys_addr;
@@ -648,7 +566,7 @@ static int msix_capability_init(struct pci_dev *dev,
648 566
649 /* MSI-X Table Initialization */ 567 /* MSI-X Table Initialization */
650 for (i = 0; i < nvec; i++) { 568 for (i = 0; i < nvec; i++) {
651 irq = create_msi_irq(&msi_chip); 569 irq = create_msi_irq();
652 if (irq < 0) 570 if (irq < 0)
653 break; 571 break;
654 572
@@ -676,13 +594,12 @@ static int msix_capability_init(struct pci_dev *dev,
676 temp = irq; 594 temp = irq;
677 tail = entry; 595 tail = entry;
678 /* Configure MSI-X capability structure */ 596 /* Configure MSI-X capability structure */
679 status = msi_ops->setup(dev, irq, &msg); 597 status = arch_setup_msi_irq(irq, dev);
680 if (status < 0) { 598 if (status < 0) {
681 destroy_msi_irq(irq); 599 destroy_msi_irq(irq);
682 break; 600 break;
683 } 601 }
684 602
685 write_msi_msg(entry, &msg);
686 attach_msi_entry(entry, irq); 603 attach_msi_entry(entry, irq);
687 } 604 }
688 if (i != nvec) { 605 if (i != nvec) {
@@ -746,7 +663,6 @@ int pci_msi_supported(struct pci_dev * dev)
746int pci_enable_msi(struct pci_dev* dev) 663int pci_enable_msi(struct pci_dev* dev)
747{ 664{
748 int pos, temp, status; 665 int pos, temp, status;
749 u16 control;
750 666
751 if (pci_msi_supported(dev) < 0) 667 if (pci_msi_supported(dev) < 0)
752 return -EINVAL; 668 return -EINVAL;
@@ -761,10 +677,6 @@ int pci_enable_msi(struct pci_dev* dev)
761 if (!pos) 677 if (!pos)
762 return -EINVAL; 678 return -EINVAL;
763 679
764 pci_read_config_word(dev, msi_control_reg(pos), &control);
765 if (!is_64bit_address(control) && msi_ops->needs_64bit_address)
766 return -EINVAL;
767
768 WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI)); 680 WARN_ON(!msi_lookup_irq(dev, PCI_CAP_ID_MSI));
769 681
770 /* Check whether driver already requested for MSI-X irqs */ 682 /* Check whether driver already requested for MSI-X irqs */
@@ -831,7 +743,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
831 void __iomem *base; 743 void __iomem *base;
832 unsigned long flags; 744 unsigned long flags;
833 745
834 msi_ops->teardown(irq); 746 arch_teardown_msi_irq(irq);
835 747
836 spin_lock_irqsave(&msi_lock, flags); 748 spin_lock_irqsave(&msi_lock, flags);
837 entry = msi_desc[irq]; 749 entry = msi_desc[irq];