aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-iop13xx/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-iop13xx/msi.c')
-rw-r--r--arch/arm/mach-iop13xx/msi.c52
1 files changed, 12 insertions, 40 deletions
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index 560d5b2dec22..e7730cf9c15d 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -23,10 +23,7 @@
23#include <linux/msi.h> 23#include <linux/msi.h>
24#include <asm/mach/irq.h> 24#include <asm/mach/irq.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26 26#include <mach/irqs.h>
27
28#define IOP13XX_NUM_MSI_IRQS 128
29static DECLARE_BITMAP(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS);
30 27
31/* IMIPR0 CP6 R8 Page 1 28/* IMIPR0 CP6 R8 Page 1
32 */ 29 */
@@ -121,41 +118,6 @@ void __init iop13xx_msi_init(void)
121 irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler); 118 irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler);
122} 119}
123 120
124/*
125 * Dynamic irq allocate and deallocation
126 */
127int create_irq(void)
128{
129 int irq, pos;
130
131again:
132 pos = find_first_zero_bit(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS);
133 irq = IRQ_IOP13XX_MSI_0 + pos;
134 if (irq > NR_IRQS)
135 return -ENOSPC;
136 /* test_and_set_bit operates on 32-bits at a time */
137 if (test_and_set_bit(pos, msi_irq_in_use))
138 goto again;
139
140 dynamic_irq_init(irq);
141
142 return irq;
143}
144
145void destroy_irq(unsigned int irq)
146{
147 int pos = irq - IRQ_IOP13XX_MSI_0;
148
149 dynamic_irq_cleanup(irq);
150
151 clear_bit(pos, msi_irq_in_use);
152}
153
154void arch_teardown_msi_irq(unsigned int irq)
155{
156 destroy_irq(irq);
157}
158
159static void iop13xx_msi_nop(struct irq_data *d) 121static void iop13xx_msi_nop(struct irq_data *d)
160{ 122{
161 return; 123 return;
@@ -172,12 +134,17 @@ static struct irq_chip iop13xx_msi_chip = {
172 134
173int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) 135int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
174{ 136{
175 int id, irq = create_irq(); 137 int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
176 struct msi_msg msg; 138 struct msi_msg msg;
177 139
178 if (irq < 0) 140 if (irq < 0)
179 return irq; 141 return irq;
180 142
143 if (irq >= NR_IOP13XX_IRQS) {
144 irq_free_desc(irq);
145 return -ENOSPC;
146 }
147
181 irq_set_msi_desc(irq, desc); 148 irq_set_msi_desc(irq, desc);
182 149
183 msg.address_hi = 0x0; 150 msg.address_hi = 0x0;
@@ -191,3 +158,8 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
191 158
192 return 0; 159 return 0;
193} 160}
161
162void arch_teardown_msi_irq(unsigned int irq)
163{
164 irq_free_desc(irq);
165}