Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[powerpc.git] / drivers / pci / msi.c
index 52c253c..68555c1 100644 (file)
@@ -192,37 +192,6 @@ static struct msi_desc* alloc_msi_entry(void)
        return 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_msi(irq, entry);
-
-       return irq;
-}
-
-static void destroy_msi_irq(unsigned int irq)
-{
-       struct msi_desc *entry;
-
-       entry = get_irq_msi(irq);
-       set_irq_chip(irq, NULL);
-       set_irq_msi(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;
@@ -438,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;
@@ -446,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_msi(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;
@@ -478,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;
        set_irq_msi(irq, entry);
+
        /* Set MSI enabled bits  */
        enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
@@ -507,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;
@@ -530,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_msi(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;
@@ -545,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;
@@ -557,12 +529,6 @@ 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;
-               }
 
                set_irq_msi(irq, entry);
        }
@@ -706,8 +672,6 @@ 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 = get_irq_msi(irq);
        if (!entry || entry->dev != dev) {
                return -EINVAL;
@@ -718,9 +682,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
        base = entry->mask_base;
        get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
        get_irq_msi(entry->link.tail)->link.head = entry->link.head;
-       entry->dev = NULL;
 
-       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 +