aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/msi_ia64.c19
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c20
2 files changed, 26 insertions, 13 deletions
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 822e59a1b822..0d05450c91c4 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -64,12 +64,17 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
64} 64}
65#endif /* CONFIG_SMP */ 65#endif /* CONFIG_SMP */
66 66
67int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) 67int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
68{ 68{
69 struct msi_msg msg; 69 struct msi_msg msg;
70 unsigned long dest_phys_id; 70 unsigned long dest_phys_id;
71 unsigned int vector; 71 unsigned int irq, vector;
72 72
73 irq = create_irq();
74 if (irq < 0)
75 return irq;
76
77 set_irq_msi(irq, desc);
73 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); 78 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
74 vector = irq; 79 vector = irq;
75 80
@@ -89,12 +94,12 @@ int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
89 write_msi_msg(irq, &msg); 94 write_msi_msg(irq, &msg);
90 set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); 95 set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
91 96
92 return 0; 97 return irq;
93} 98}
94 99
95void ia64_teardown_msi_irq(unsigned int irq) 100void ia64_teardown_msi_irq(unsigned int irq)
96{ 101{
97 return; /* no-op */ 102 destroy_irq(irq);
98} 103}
99 104
100static void ia64_ack_msi_irq(unsigned int irq) 105static void ia64_ack_msi_irq(unsigned int irq)
@@ -126,12 +131,12 @@ static struct irq_chip ia64_msi_chip = {
126}; 131};
127 132
128 133
129int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) 134int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
130{ 135{
131 if (platform_setup_msi_irq) 136 if (platform_setup_msi_irq)
132 return platform_setup_msi_irq(irq, pdev); 137 return platform_setup_msi_irq(pdev, desc);
133 138
134 return ia64_setup_msi_irq(irq, pdev); 139 return ia64_setup_msi_irq(pdev, desc);
135} 140}
136 141
137void arch_teardown_msi_irq(unsigned int irq) 142void arch_teardown_msi_irq(unsigned int irq)
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index 31fbb859b67e..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
65int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) 65int 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_msi(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