diff options
Diffstat (limited to 'drivers/pci/msi-altix.c')
-rw-r--r-- | drivers/pci/msi-altix.c | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/drivers/pci/msi-altix.c b/drivers/pci/msi-altix.c index bed4183a5e39..7aedc2ac8c28 100644 --- a/drivers/pci/msi-altix.c +++ b/drivers/pci/msi-altix.c | |||
@@ -26,7 +26,7 @@ struct sn_msi_info { | |||
26 | static struct sn_msi_info *sn_msi_info; | 26 | static struct sn_msi_info *sn_msi_info; |
27 | 27 | ||
28 | static void | 28 | static void |
29 | sn_msi_teardown(unsigned int vector) | 29 | sn_msi_teardown(unsigned int irq) |
30 | { | 30 | { |
31 | nasid_t nasid; | 31 | nasid_t nasid; |
32 | int widget; | 32 | int widget; |
@@ -36,7 +36,7 @@ sn_msi_teardown(unsigned int vector) | |||
36 | struct pcibus_bussoft *bussoft; | 36 | struct pcibus_bussoft *bussoft; |
37 | struct sn_pcibus_provider *provider; | 37 | struct sn_pcibus_provider *provider; |
38 | 38 | ||
39 | sn_irq_info = sn_msi_info[vector].sn_irq_info; | 39 | sn_irq_info = sn_msi_info[irq].sn_irq_info; |
40 | if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) | 40 | if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) |
41 | return; | 41 | return; |
42 | 42 | ||
@@ -45,9 +45,9 @@ sn_msi_teardown(unsigned int vector) | |||
45 | provider = SN_PCIDEV_BUSPROVIDER(pdev); | 45 | provider = SN_PCIDEV_BUSPROVIDER(pdev); |
46 | 46 | ||
47 | (*provider->dma_unmap)(pdev, | 47 | (*provider->dma_unmap)(pdev, |
48 | sn_msi_info[vector].pci_addr, | 48 | sn_msi_info[irq].pci_addr, |
49 | PCI_DMA_FROMDEVICE); | 49 | PCI_DMA_FROMDEVICE); |
50 | sn_msi_info[vector].pci_addr = 0; | 50 | sn_msi_info[irq].pci_addr = 0; |
51 | 51 | ||
52 | bussoft = SN_PCIDEV_BUSSOFT(pdev); | 52 | bussoft = SN_PCIDEV_BUSSOFT(pdev); |
53 | nasid = NASID_GET(bussoft->bs_base); | 53 | nasid = NASID_GET(bussoft->bs_base); |
@@ -56,14 +56,13 @@ sn_msi_teardown(unsigned int vector) | |||
56 | SWIN_WIDGETNUM(bussoft->bs_base); | 56 | SWIN_WIDGETNUM(bussoft->bs_base); |
57 | 57 | ||
58 | sn_intr_free(nasid, widget, sn_irq_info); | 58 | sn_intr_free(nasid, widget, sn_irq_info); |
59 | sn_msi_info[vector].sn_irq_info = NULL; | 59 | sn_msi_info[irq].sn_irq_info = NULL; |
60 | 60 | ||
61 | return; | 61 | return; |
62 | } | 62 | } |
63 | 63 | ||
64 | int | 64 | int |
65 | sn_msi_setup(struct pci_dev *pdev, unsigned int vector, | 65 | sn_msi_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) |
66 | u32 *addr_hi, u32 *addr_lo, u32 *data) | ||
67 | { | 66 | { |
68 | int widget; | 67 | int widget; |
69 | int status; | 68 | int status; |
@@ -93,7 +92,7 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int vector, | |||
93 | if (! sn_irq_info) | 92 | if (! sn_irq_info) |
94 | return -ENOMEM; | 93 | return -ENOMEM; |
95 | 94 | ||
96 | status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1); | 95 | status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); |
97 | if (status) { | 96 | if (status) { |
98 | kfree(sn_irq_info); | 97 | kfree(sn_irq_info); |
99 | return -ENOMEM; | 98 | return -ENOMEM; |
@@ -119,28 +118,27 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int vector, | |||
119 | return -ENOMEM; | 118 | return -ENOMEM; |
120 | } | 119 | } |
121 | 120 | ||
122 | sn_msi_info[vector].sn_irq_info = sn_irq_info; | 121 | sn_msi_info[irq].sn_irq_info = sn_irq_info; |
123 | sn_msi_info[vector].pci_addr = bus_addr; | 122 | sn_msi_info[irq].pci_addr = bus_addr; |
124 | 123 | ||
125 | *addr_hi = (u32)(bus_addr >> 32); | 124 | msg->address_hi = (u32)(bus_addr >> 32); |
126 | *addr_lo = (u32)(bus_addr & 0x00000000ffffffff); | 125 | msg->address_lo = (u32)(bus_addr & 0x00000000ffffffff); |
127 | 126 | ||
128 | /* | 127 | /* |
129 | * In the SN platform, bit 16 is a "send vector" bit which | 128 | * In the SN platform, bit 16 is a "send vector" bit which |
130 | * must be present in order to move the vector through the system. | 129 | * must be present in order to move the vector through the system. |
131 | */ | 130 | */ |
132 | *data = 0x100 + (unsigned int)vector; | 131 | msg->data = 0x100 + irq; |
133 | 132 | ||
134 | #ifdef CONFIG_SMP | 133 | #ifdef CONFIG_SMP |
135 | set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0); | 134 | set_irq_affinity_info(irq, sn_irq_info->irq_cpuid, 0); |
136 | #endif | 135 | #endif |
137 | 136 | ||
138 | return 0; | 137 | return 0; |
139 | } | 138 | } |
140 | 139 | ||
141 | static void | 140 | static void |
142 | sn_msi_target(unsigned int vector, unsigned int cpu, | 141 | sn_msi_target(unsigned int irq, cpumask_t cpu_mask, struct msi_msg *msg) |
143 | u32 *addr_hi, u32 *addr_lo) | ||
144 | { | 142 | { |
145 | int slice; | 143 | int slice; |
146 | nasid_t nasid; | 144 | nasid_t nasid; |
@@ -150,8 +148,10 @@ sn_msi_target(unsigned int vector, unsigned int cpu, | |||
150 | struct sn_irq_info *sn_irq_info; | 148 | struct sn_irq_info *sn_irq_info; |
151 | struct sn_irq_info *new_irq_info; | 149 | struct sn_irq_info *new_irq_info; |
152 | struct sn_pcibus_provider *provider; | 150 | struct sn_pcibus_provider *provider; |
151 | unsigned int cpu; | ||
153 | 152 | ||
154 | sn_irq_info = sn_msi_info[vector].sn_irq_info; | 153 | cpu = first_cpu(cpu_mask); |
154 | sn_irq_info = sn_msi_info[irq].sn_irq_info; | ||
155 | if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) | 155 | if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0) |
156 | return; | 156 | return; |
157 | 157 | ||
@@ -163,15 +163,15 @@ sn_msi_target(unsigned int vector, unsigned int cpu, | |||
163 | pdev = sn_pdev->pdi_linux_pcidev; | 163 | pdev = sn_pdev->pdi_linux_pcidev; |
164 | provider = SN_PCIDEV_BUSPROVIDER(pdev); | 164 | provider = SN_PCIDEV_BUSPROVIDER(pdev); |
165 | 165 | ||
166 | bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo); | 166 | bus_addr = (u64)(msg->address_hi) << 32 | (u64)(msg->address_lo); |
167 | (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE); | 167 | (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE); |
168 | sn_msi_info[vector].pci_addr = 0; | 168 | sn_msi_info[irq].pci_addr = 0; |
169 | 169 | ||
170 | nasid = cpuid_to_nasid(cpu); | 170 | nasid = cpuid_to_nasid(cpu); |
171 | slice = cpuid_to_slice(cpu); | 171 | slice = cpuid_to_slice(cpu); |
172 | 172 | ||
173 | new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice); | 173 | new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice); |
174 | sn_msi_info[vector].sn_irq_info = new_irq_info; | 174 | sn_msi_info[irq].sn_irq_info = new_irq_info; |
175 | if (new_irq_info == NULL) | 175 | if (new_irq_info == NULL) |
176 | return; | 176 | return; |
177 | 177 | ||
@@ -184,12 +184,13 @@ sn_msi_target(unsigned int vector, unsigned int cpu, | |||
184 | sizeof(new_irq_info->irq_xtalkaddr), | 184 | sizeof(new_irq_info->irq_xtalkaddr), |
185 | SN_DMA_MSI|SN_DMA_ADDR_XIO); | 185 | SN_DMA_MSI|SN_DMA_ADDR_XIO); |
186 | 186 | ||
187 | sn_msi_info[vector].pci_addr = bus_addr; | 187 | sn_msi_info[irq].pci_addr = bus_addr; |
188 | *addr_hi = (u32)(bus_addr >> 32); | 188 | msg->address_hi = (u32)(bus_addr >> 32); |
189 | *addr_lo = (u32)(bus_addr & 0x00000000ffffffff); | 189 | msg->address_lo = (u32)(bus_addr & 0x00000000ffffffff); |
190 | } | 190 | } |
191 | 191 | ||
192 | struct msi_ops sn_msi_ops = { | 192 | struct msi_ops sn_msi_ops = { |
193 | .needs_64bit_address = 1, | ||
193 | .setup = sn_msi_setup, | 194 | .setup = sn_msi_setup, |
194 | .teardown = sn_msi_teardown, | 195 | .teardown = sn_msi_teardown, |
195 | #ifdef CONFIG_SMP | 196 | #ifdef CONFIG_SMP |
@@ -201,7 +202,7 @@ int | |||
201 | sn_msi_init(void) | 202 | sn_msi_init(void) |
202 | { | 203 | { |
203 | sn_msi_info = | 204 | sn_msi_info = |
204 | kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL); | 205 | kzalloc(sizeof(struct sn_msi_info) * NR_IRQS, GFP_KERNEL); |
205 | if (! sn_msi_info) | 206 | if (! sn_msi_info) |
206 | return -ENOMEM; | 207 | return -ENOMEM; |
207 | 208 | ||