diff options
Diffstat (limited to 'arch/ia64/sn/kernel/msi_sn.c')
-rw-r--r-- | arch/ia64/sn/kernel/msi_sn.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index b3a435fd70fb..ea3dc38d73fd 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c | |||
@@ -59,13 +59,12 @@ void sn_teardown_msi_irq(unsigned int irq) | |||
59 | sn_intr_free(nasid, widget, sn_irq_info); | 59 | sn_intr_free(nasid, widget, sn_irq_info); |
60 | sn_msi_info[irq].sn_irq_info = NULL; | 60 | sn_msi_info[irq].sn_irq_info = NULL; |
61 | 61 | ||
62 | return; | 62 | destroy_irq(irq); |
63 | } | 63 | } |
64 | 64 | ||
65 | int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) | 65 | int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) |
66 | { | 66 | { |
67 | struct msi_msg msg; | 67 | struct msi_msg msg; |
68 | struct msi_desc *entry; | ||
69 | int widget; | 68 | int widget; |
70 | int status; | 69 | int status; |
71 | nasid_t nasid; | 70 | nasid_t nasid; |
@@ -73,8 +72,8 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) | |||
73 | struct sn_irq_info *sn_irq_info; | 72 | struct sn_irq_info *sn_irq_info; |
74 | struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); | 73 | struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); |
75 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); | 74 | struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); |
75 | int irq; | ||
76 | 76 | ||
77 | entry = get_irq_data(irq); | ||
78 | if (!entry->msi_attrib.is_64) | 77 | if (!entry->msi_attrib.is_64) |
79 | return -EINVAL; | 78 | return -EINVAL; |
80 | 79 | ||
@@ -84,6 +83,11 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) | |||
84 | if (provider == NULL || provider->dma_map_consistent == NULL) | 83 | if (provider == NULL || provider->dma_map_consistent == NULL) |
85 | return -EINVAL; | 84 | return -EINVAL; |
86 | 85 | ||
86 | irq = create_irq(); | ||
87 | if (irq < 0) | ||
88 | return irq; | ||
89 | |||
90 | set_irq_msi(irq, entry); | ||
87 | /* | 91 | /* |
88 | * Set up the vector plumbing. Let the prom (via sn_intr_alloc) | 92 | * Set up the vector plumbing. Let the prom (via sn_intr_alloc) |
89 | * decide which cpu to direct this msi at by default. | 93 | * decide which cpu to direct this msi at by default. |
@@ -95,12 +99,15 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) | |||
95 | SWIN_WIDGETNUM(bussoft->bs_base); | 99 | SWIN_WIDGETNUM(bussoft->bs_base); |
96 | 100 | ||
97 | sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); | 101 | sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); |
98 | if (! sn_irq_info) | 102 | if (! sn_irq_info) { |
103 | destroy_irq(irq); | ||
99 | return -ENOMEM; | 104 | return -ENOMEM; |
105 | } | ||
100 | 106 | ||
101 | status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); | 107 | status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); |
102 | if (status) { | 108 | if (status) { |
103 | kfree(sn_irq_info); | 109 | kfree(sn_irq_info); |
110 | destroy_irq(irq); | ||
104 | return -ENOMEM; | 111 | return -ENOMEM; |
105 | } | 112 | } |
106 | 113 | ||
@@ -121,6 +128,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) | |||
121 | if (! bus_addr) { | 128 | if (! bus_addr) { |
122 | sn_intr_free(nasid, widget, sn_irq_info); | 129 | sn_intr_free(nasid, widget, sn_irq_info); |
123 | kfree(sn_irq_info); | 130 | kfree(sn_irq_info); |
131 | destroy_irq(irq); | ||
124 | return -ENOMEM; | 132 | return -ENOMEM; |
125 | } | 133 | } |
126 | 134 | ||
@@ -139,7 +147,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) | |||
139 | write_msi_msg(irq, &msg); | 147 | write_msi_msg(irq, &msg); |
140 | set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); | 148 | set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); |
141 | 149 | ||
142 | return 0; | 150 | return irq; |
143 | } | 151 | } |
144 | 152 | ||
145 | #ifdef CONFIG_SMP | 153 | #ifdef CONFIG_SMP |