aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-04 05:16:59 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:29 -0400
commit3b7d1921f4cdd6d6ddb7899ae7a8d413991c5cf4 (patch)
tree5f809e0c4310f60dfa6f65d54fbaf9f01e2ebff9 /drivers
parent277bc33bc2479707e88b0b2ae6fe56e8e4aabe81 (diff)
[PATCH] msi: refactor and move the msi irq_chip into the arch code
It turns out msi_ops was simply not enough to abstract the architecture specific details of msi. So I have moved the resposibility of constructing the struct irq_chip to the architectures, and have two architecture specific functions arch_setup_msi_irq, and arch_teardown_msi_irq. For simple architectures those functions can do all of the work. For architectures with platform dependencies they can call into the appropriate platform code. With this msi.c is finally free of assuming you have an apic, and this actually takes less code. The helpers for the architecture specific code are declared in the linux/msi.h to keep them separate from the msi functions used by drivers in linux/pci.h Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Tony Luck <tony.luck@intel.com> Cc: Andi Kleen <ak@suse.de> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Greg KH <greg@kroah.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/msi-altix.c81
-rw-r--r--drivers/pci/msi-apic.c86
-rw-r--r--drivers/pci/msi.c150
-rw-r--r--drivers/pci/msi.h27
4 files changed, 145 insertions, 199 deletions
diff --git a/drivers/pci/msi-altix.c b/drivers/pci/msi-altix.c
index 7aedc2ac8c28..6ffd1f850d41 100644
--- a/drivers/pci/msi-altix.c
+++ b/drivers/pci/msi-altix.c
@@ -7,8 +7,10 @@
7 */ 7 */
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <linux/irq.h>
10#include <linux/pci.h> 11#include <linux/pci.h>
11#include <linux/cpumask.h> 12#include <linux/cpumask.h>
13#include <linux/msi.h>
12 14
13#include <asm/sn/addrs.h> 15#include <asm/sn/addrs.h>
14#include <asm/sn/intr.h> 16#include <asm/sn/intr.h>
@@ -16,17 +18,16 @@
16#include <asm/sn/pcidev.h> 18#include <asm/sn/pcidev.h>
17#include <asm/sn/nodepda.h> 19#include <asm/sn/nodepda.h>
18 20
19#include "msi.h"
20
21struct sn_msi_info { 21struct sn_msi_info {
22 u64 pci_addr; 22 u64 pci_addr;
23 struct sn_irq_info *sn_irq_info; 23 struct sn_irq_info *sn_irq_info;
24}; 24};
25 25
26static struct sn_msi_info *sn_msi_info; 26static struct sn_msi_info sn_msi_info[NR_IRQS];
27
28static struct irq_chip sn_msi_chip;
27 29
28static void 30void sn_teardown_msi_irq(unsigned int irq)
29sn_msi_teardown(unsigned int irq)
30{ 31{
31 nasid_t nasid; 32 nasid_t nasid;
32 int widget; 33 int widget;
@@ -61,9 +62,10 @@ sn_msi_teardown(unsigned int irq)
61 return; 62 return;
62} 63}
63 64
64int 65int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
65sn_msi_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
66{ 66{
67 struct msi_msg msg;
68 struct msi_desc *entry;
67 int widget; 69 int widget;
68 int status; 70 int status;
69 nasid_t nasid; 71 nasid_t nasid;
@@ -72,6 +74,10 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
72 struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); 74 struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
73 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 75 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
74 76
77 entry = get_irq_data(irq);
78 if (!entry->msi_attrib.is_64)
79 return -EINVAL;
80
75 if (bussoft == NULL) 81 if (bussoft == NULL)
76 return -EINVAL; 82 return -EINVAL;
77 83
@@ -121,25 +127,29 @@ sn_msi_setup(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
121 sn_msi_info[irq].sn_irq_info = sn_irq_info; 127 sn_msi_info[irq].sn_irq_info = sn_irq_info;
122 sn_msi_info[irq].pci_addr = bus_addr; 128 sn_msi_info[irq].pci_addr = bus_addr;
123 129
124 msg->address_hi = (u32)(bus_addr >> 32); 130 msg.address_hi = (u32)(bus_addr >> 32);
125 msg->address_lo = (u32)(bus_addr & 0x00000000ffffffff); 131 msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
126 132
127 /* 133 /*
128 * In the SN platform, bit 16 is a "send vector" bit which 134 * In the SN platform, bit 16 is a "send vector" bit which
129 * must be present in order to move the vector through the system. 135 * must be present in order to move the vector through the system.
130 */ 136 */
131 msg->data = 0x100 + irq; 137 msg.data = 0x100 + irq;
132 138
133#ifdef CONFIG_SMP 139#ifdef CONFIG_SMP
134 set_irq_affinity_info(irq, sn_irq_info->irq_cpuid, 0); 140 set_irq_affinity_info(irq, sn_irq_info->irq_cpuid, 0);
135#endif 141#endif
136 142
143 write_msi_msg(irq, &msg);
144 set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
145
137 return 0; 146 return 0;
138} 147}
139 148
140static void 149#ifdef CONFIG_SMP
141sn_msi_target(unsigned int irq, cpumask_t cpu_mask, struct msi_msg *msg) 150static void sn_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
142{ 151{
152 struct msi_msg msg;
143 int slice; 153 int slice;
144 nasid_t nasid; 154 nasid_t nasid;
145 u64 bus_addr; 155 u64 bus_addr;
@@ -159,11 +169,12 @@ sn_msi_target(unsigned int irq, cpumask_t cpu_mask, struct msi_msg *msg)
159 * Release XIO resources for the old MSI PCI address 169 * Release XIO resources for the old MSI PCI address
160 */ 170 */
161 171
172 read_msi_msg(irq, &msg);
162 sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; 173 sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
163 pdev = sn_pdev->pdi_linux_pcidev; 174 pdev = sn_pdev->pdi_linux_pcidev;
164 provider = SN_PCIDEV_BUSPROVIDER(pdev); 175 provider = SN_PCIDEV_BUSPROVIDER(pdev);
165 176
166 bus_addr = (u64)(msg->address_hi) << 32 | (u64)(msg->address_lo); 177 bus_addr = (u64)(msg.address_hi) << 32 | (u64)(msg.address_lo);
167 (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE); 178 (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
168 sn_msi_info[irq].pci_addr = 0; 179 sn_msi_info[irq].pci_addr = 0;
169 180
@@ -185,27 +196,35 @@ sn_msi_target(unsigned int irq, cpumask_t cpu_mask, struct msi_msg *msg)
185 SN_DMA_MSI|SN_DMA_ADDR_XIO); 196 SN_DMA_MSI|SN_DMA_ADDR_XIO);
186 197
187 sn_msi_info[irq].pci_addr = bus_addr; 198 sn_msi_info[irq].pci_addr = bus_addr;
188 msg->address_hi = (u32)(bus_addr >> 32); 199 msg.address_hi = (u32)(bus_addr >> 32);
189 msg->address_lo = (u32)(bus_addr & 0x00000000ffffffff); 200 msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
201
202 write_msi_msg(irq, &msg);
203 set_native_irq_info(irq, cpu_mask);
190} 204}
205#endif /* CONFIG_SMP */
191 206
192struct msi_ops sn_msi_ops = { 207static void sn_ack_msi_irq(unsigned int irq)
193 .needs_64bit_address = 1, 208{
194 .setup = sn_msi_setup, 209 move_native_irq(irq);
195 .teardown = sn_msi_teardown, 210 ia64_eoi();
196#ifdef CONFIG_SMP 211}
197 .target = sn_msi_target,
198#endif
199};
200 212
201int 213static int sn_msi_retrigger_irq(unsigned int irq)
202sn_msi_init(void)
203{ 214{
204 sn_msi_info = 215 unsigned int vector = irq;
205 kzalloc(sizeof(struct sn_msi_info) * NR_IRQS, GFP_KERNEL); 216 ia64_resend_irq(vector);
206 if (! sn_msi_info)
207 return -ENOMEM;
208 217
209 msi_register(&sn_msi_ops); 218 return 1;
210 return 0;
211} 219}
220
221static struct irq_chip sn_msi_chip = {
222 .name = "PCI-MSI",
223 .mask = mask_msi_irq,
224 .unmask = unmask_msi_irq,
225 .ack = sn_ack_msi_irq,
226#ifdef CONFIG_SMP
227 .set_affinity = sn_set_msi_irq_affinity,
228#endif
229 .retrigger = sn_msi_retrigger_irq,
230};
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
index afc0ed13aa89..822e59a1b822 100644
--- a/drivers/pci/msi-apic.c
+++ b/drivers/pci/msi-apic.c
@@ -4,10 +4,9 @@
4 4
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/irq.h> 6#include <linux/irq.h>
7#include <linux/msi.h>
7#include <asm/smp.h> 8#include <asm/smp.h>
8 9
9#include "msi.h"
10
11/* 10/*
12 * Shifts for APIC-based data 11 * Shifts for APIC-based data
13 */ 12 */
@@ -31,6 +30,7 @@
31 * Shift/mask fields for APIC-based bus address 30 * Shift/mask fields for APIC-based bus address
32 */ 31 */
33 32
33#define MSI_TARGET_CPU_SHIFT 4
34#define MSI_ADDR_HEADER 0xfee00000 34#define MSI_ADDR_HEADER 0xfee00000
35 35
36#define MSI_ADDR_DESTID_MASK 0xfff0000f 36#define MSI_ADDR_DESTID_MASK 0xfff0000f
@@ -44,58 +44,100 @@
44#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT) 44#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
45#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT) 45#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
46 46
47static struct irq_chip ia64_msi_chip;
47 48
48static void 49#ifdef CONFIG_SMP
49msi_target_apic(unsigned int irq, cpumask_t cpu_mask, struct msi_msg *msg) 50static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
50{ 51{
51 u32 addr = msg->address_lo; 52 struct msi_msg msg;
53 u32 addr;
54
55 read_msi_msg(irq, &msg);
52 56
57 addr = msg.address_lo;
53 addr &= MSI_ADDR_DESTID_MASK; 58 addr &= MSI_ADDR_DESTID_MASK;
54 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask))); 59 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(first_cpu(cpu_mask)));
60 msg.address_lo = addr;
55 61
56 msg->address_lo = addr; 62 write_msi_msg(irq, &msg);
63 set_native_irq_info(irq, cpu_mask);
57} 64}
65#endif /* CONFIG_SMP */
58 66
59static int 67int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
60msi_setup_apic(struct pci_dev *pdev, /* unused in generic */
61 unsigned int irq,
62 struct msi_msg *msg)
63{ 68{
69 struct msi_msg msg;
64 unsigned long dest_phys_id; 70 unsigned long dest_phys_id;
65 unsigned int vector; 71 unsigned int vector;
66 72
67 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); 73 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
68 vector = irq; 74 vector = irq;
69 75
70 msg->address_hi = 0; 76 msg.address_hi = 0;
71 msg->address_lo = 77 msg.address_lo =
72 MSI_ADDR_HEADER | 78 MSI_ADDR_HEADER |
73 MSI_ADDR_DESTMODE_PHYS | 79 MSI_ADDR_DESTMODE_PHYS |
74 MSI_ADDR_REDIRECTION_CPU | 80 MSI_ADDR_REDIRECTION_CPU |
75 MSI_ADDR_DESTID_CPU(dest_phys_id); 81 MSI_ADDR_DESTID_CPU(dest_phys_id);
76 82
77 msg->data = 83 msg.data =
78 MSI_DATA_TRIGGER_EDGE | 84 MSI_DATA_TRIGGER_EDGE |
79 MSI_DATA_LEVEL_ASSERT | 85 MSI_DATA_LEVEL_ASSERT |
80 MSI_DATA_DELIVERY_FIXED | 86 MSI_DATA_DELIVERY_FIXED |
81 MSI_DATA_VECTOR(vector); 87 MSI_DATA_VECTOR(vector);
82 88
89 write_msi_msg(irq, &msg);
90 set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
91
83 return 0; 92 return 0;
84} 93}
85 94
86static void 95void ia64_teardown_msi_irq(unsigned int irq)
87msi_teardown_apic(unsigned int irq)
88{ 96{
89 return; /* no-op */ 97 return; /* no-op */
90} 98}
91 99
100static void ia64_ack_msi_irq(unsigned int irq)
101{
102 move_native_irq(irq);
103 ia64_eoi();
104}
105
106static int ia64_msi_retrigger_irq(unsigned int irq)
107{
108 unsigned int vector = irq;
109 ia64_resend_irq(vector);
110
111 return 1;
112}
113
92/* 114/*
93 * Generic ops used on most IA archs/platforms. Set with msi_register() 115 * Generic ops used on most IA64 platforms.
94 */ 116 */
95 117static struct irq_chip ia64_msi_chip = {
96struct msi_ops msi_apic_ops = { 118 .name = "PCI-MSI",
97 .needs_64bit_address = 0, 119 .mask = mask_msi_irq,
98 .setup = msi_setup_apic, 120 .unmask = unmask_msi_irq,
99 .teardown = msi_teardown_apic, 121 .ack = ia64_ack_msi_irq,
100 .target = msi_target_apic, 122#ifdef CONFIG_SMP
123 .set_affinity = ia64_set_msi_irq_affinity,
124#endif
125 .retrigger = ia64_msi_retrigger_irq,
101}; 126};
127
128
129int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
130{
131 if (platform_setup_msi_irq)
132 return platform_setup_msi_irq(irq, pdev);
133
134 return ia64_setup_msi_irq(irq, pdev);
135}
136
137void arch_teardown_msi_irq(unsigned int irq)
138{
139 if (platform_teardown_msi_irq)
140 return platform_teardown_msi_irq(irq);
141
142 return ia64_teardown_msi_irq(irq);
143}
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];
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 77823bfed5c1..f0cca1772f9c 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -6,8 +6,6 @@
6#ifndef MSI_H 6#ifndef MSI_H
7#define MSI_H 7#define MSI_H
8 8
9#include <asm/msi.h>
10
11/* 9/*
12 * MSI-X Address Register 10 * MSI-X Address Register
13 */ 11 */
@@ -49,29 +47,4 @@
49#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) 47#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
50#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) 48#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
51 49
52struct msi_desc {
53 struct {
54 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */
55 __u8 maskbit : 1; /* mask-pending bit supported ? */
56 __u8 unused : 1;
57 __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
58 __u8 pos; /* Location of the msi capability */
59 __u16 entry_nr; /* specific enabled entry */
60 unsigned default_irq; /* default pre-assigned irq */
61 }msi_attrib;
62
63 struct {
64 __u16 head;
65 __u16 tail;
66 }link;
67
68 void __iomem *mask_base;
69 struct pci_dev *dev;
70
71#ifdef CONFIG_PM
72 /* PM save area for MSIX address/data */
73 struct msi_msg msg_save;
74#endif
75};
76
77#endif /* MSI_H */ 50#endif /* MSI_H */