Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[powerpc.git] / drivers / pci / msi.c
index 529113d..68555c1 100644 (file)
@@ -24,7 +24,6 @@
 #include "pci.h"
 #include "msi.h"
 
-static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static struct kmem_cache* msi_cachep;
 
 static int pci_msi_enable = 1;
@@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
 {
        struct msi_desc *entry;
 
-       entry = msi_desc[irq];
+       entry = get_irq_msi(irq);
        BUG_ON(!entry || !entry->dev);
        switch (entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
@@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
 
 void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-       struct msi_desc *entry = get_irq_data(irq);
+       struct msi_desc *entry = get_irq_msi(irq);
        switch(entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
        {
@@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 
 void write_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-       struct msi_desc *entry = get_irq_data(irq);
+       struct msi_desc *entry = get_irq_msi(irq);
        switch (entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
        {
@@ -193,42 +192,6 @@ static struct msi_desc* alloc_msi_entry(void)
        return entry;
 }
 
-static void attach_msi_entry(struct msi_desc *entry, int irq)
-{
-       msi_desc[irq] = entry;
-}
-
-static int create_msi_irq(void)
-{
-       struct msi_desc *entry;
-       int irq;
-
-       entry = alloc_msi_entry();
-       if (!entry)
-               return -ENOMEM;
-
-       irq = create_irq();
-       if (irq < 0) {
-               kmem_cache_free(msi_cachep, entry);
-               return -EBUSY;
-       }
-
-       set_irq_data(irq, entry);
-
-       return irq;
-}
-
-static void destroy_msi_irq(unsigned int irq)
-{
-       struct msi_desc *entry;
-
-       entry = get_irq_data(irq);
-       set_irq_chip(irq, NULL);
-       set_irq_data(irq, NULL);
-       destroy_irq(irq);
-       kmem_cache_free(msi_cachep, entry);
-}
-
 static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
 {
        u16 control;
@@ -365,10 +328,10 @@ static int __pci_save_msix_state(struct pci_dev *dev)
        while (head != tail) {
                struct msi_desc *entry;
 
-               entry = msi_desc[irq];
+               entry = get_irq_msi(irq);
                read_msi_msg(irq, &entry->msg_save);
 
-               tail = msi_desc[irq]->link.tail;
+               tail = entry->link.tail;
                irq = tail;
        }
 
@@ -415,10 +378,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
        /* route the table */
        irq = head = dev->first_msi_irq;
        while (head != tail) {
-               entry = msi_desc[irq];
+               entry = get_irq_msi(irq);
                write_msi_msg(irq, &entry->msg_save);
 
-               tail = msi_desc[irq]->link.tail;
+               tail = entry->link.tail;
                irq = tail;
        }
 
@@ -444,7 +407,6 @@ void pci_restore_msi_state(struct pci_dev *dev)
  **/
 static int msi_capability_init(struct pci_dev *dev)
 {
-       int status;
        struct msi_desc *entry;
        int pos, irq;
        u16 control;
@@ -452,13 +414,10 @@ static int msi_capability_init(struct pci_dev *dev)
        pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
        pci_read_config_word(dev, msi_control_reg(pos), &control);
        /* MSI Entry Initialization */
-       irq = create_msi_irq();
-       if (irq < 0)
-               return irq;
+       entry = alloc_msi_entry();
+       if (!entry)
+               return -ENOMEM;
 
-       entry = get_irq_data(irq);
-       entry->link.head = irq;
-       entry->link.tail = irq;
        entry->msi_attrib.type = PCI_CAP_ID_MSI;
        entry->msi_attrib.is_64 = is_64bit_address(control);
        entry->msi_attrib.entry_nr = 0;
@@ -484,14 +443,16 @@ static int msi_capability_init(struct pci_dev *dev)
                        maskbits);
        }
        /* Configure MSI capability structure */
-       status = arch_setup_msi_irq(irq, dev);
-       if (status < 0) {
-               destroy_msi_irq(irq);
-               return status;
+       irq = arch_setup_msi_irq(dev, entry);
+       if (irq < 0) {
+               kmem_cache_free(msi_cachep, entry);
+               return irq;
        }
-
+       entry->link.head = irq;
+       entry->link.tail = irq;
        dev->first_msi_irq = irq;
-       attach_msi_entry(entry, irq);
+       set_irq_msi(irq, entry);
+
        /* Set MSI enabled bits  */
        enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
@@ -513,7 +474,6 @@ static int msix_capability_init(struct pci_dev *dev,
                                struct msix_entry *entries, int nvec)
 {
        struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
-       int status;
        int irq, pos, i, j, nr_entries, temp = 0;
        unsigned long phys_addr;
        u32 table_offset;
@@ -536,13 +496,11 @@ static int msix_capability_init(struct pci_dev *dev,
 
        /* MSI-X Table Initialization */
        for (i = 0; i < nvec; i++) {
-               irq = create_msi_irq();
-               if (irq < 0)
+               entry = alloc_msi_entry();
+               if (!entry)
                        break;
 
-               entry = get_irq_data(irq);
                j = entries[i].entry;
-               entries[i].vector = irq;
                entry->msi_attrib.type = PCI_CAP_ID_MSIX;
                entry->msi_attrib.is_64 = 1;
                entry->msi_attrib.entry_nr = j;
@@ -551,6 +509,14 @@ static int msix_capability_init(struct pci_dev *dev,
                entry->msi_attrib.pos = pos;
                entry->dev = dev;
                entry->mask_base = base;
+
+               /* Configure MSI-X capability structure */
+               irq = arch_setup_msi_irq(dev, entry);
+               if (irq < 0) {
+                       kmem_cache_free(msi_cachep, entry);
+                       break;
+               }
+               entries[i].vector = irq;
                if (!head) {
                        entry->link.head = irq;
                        entry->link.tail = irq;
@@ -563,14 +529,8 @@ static int msix_capability_init(struct pci_dev *dev,
                }
                temp = irq;
                tail = entry;
-               /* Configure MSI-X capability structure */
-               status = arch_setup_msi_irq(irq, dev);
-               if (status < 0) {
-                       destroy_msi_irq(irq);
-                       break;
-               }
 
-               attach_msi_entry(entry, irq);
+               set_irq_msi(irq, entry);
        }
        if (i != nvec) {
                int avail = i - 1;
@@ -687,7 +647,7 @@ void pci_disable_msi(struct pci_dev* dev)
 
        disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
-       entry = msi_desc[dev->first_msi_irq];
+       entry = get_irq_msi(dev->first_msi_irq);
        if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
                return;
        }
@@ -712,9 +672,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
        int head, entry_nr, type;
        void __iomem *base;
 
-       arch_teardown_msi_irq(irq);
-
-       entry = msi_desc[irq];
+       entry = get_irq_msi(irq);
        if (!entry || entry->dev != dev) {
                return -EINVAL;
        }
@@ -722,12 +680,11 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
        entry_nr = entry->msi_attrib.entry_nr;
        head = entry->link.head;
        base = entry->mask_base;
-       msi_desc[entry->link.head]->link.tail = entry->link.tail;
-       msi_desc[entry->link.tail]->link.head = entry->link.head;
-       entry->dev = NULL;
-       msi_desc[irq] = NULL;
+       get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
+       get_irq_msi(entry->link.tail)->link.head = entry->link.head;
 
-       destroy_msi_irq(irq);
+       arch_teardown_msi_irq(irq);
+       kmem_cache_free(msi_cachep, entry);
 
        if (type == PCI_CAP_ID_MSIX) {
                writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -826,7 +783,7 @@ void pci_disable_msix(struct pci_dev* dev)
 
        irq = head = dev->first_msi_irq;
        while (head != tail) {
-               tail = msi_desc[irq]->link.tail;
+               tail = get_irq_msi(irq)->link.tail;
                if (irq_has_action(irq))
                        warning = 1;
                else if (irq != head)   /* Release MSI-X irq */
@@ -872,8 +829,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 
                irq = head = dev->first_msi_irq;
                while (head != tail) {
-                       tail = msi_desc[irq]->link.tail;
-                       base = msi_desc[irq]->mask_base;
+                       tail = get_irq_msi(irq)->link.tail;
+                       base = get_irq_msi(irq)->mask_base;
                        if (irq_has_action(irq))
                                warning = 1;
                        else if (irq != head) /* Release MSI-X irq */