19
19
#include <linux/bitops.h>
20
20
#include <linux/module.h>
21
21
#include <linux/moduleparam.h>
22
+ #include <linux/interrupt.h>
22
23
#include <linux/irqdomain.h>
23
24
#include <linux/irqchip.h>
24
- #include <linux/irqchip/chained_irq.h>
25
25
#include <linux/of.h>
26
26
#include <linux/of_platform.h>
27
27
#include <linux/mfd/syscon.h>
@@ -39,6 +39,7 @@ struct keystone_irq_device {
39
39
struct irq_domain * irqd ;
40
40
struct regmap * devctrl_regs ;
41
41
u32 devctrl_offset ;
42
+ raw_spinlock_t wa_lock ;
42
43
};
43
44
44
45
static inline u32 keystone_irq_readl (struct keystone_irq_device * kirq )
@@ -83,17 +84,15 @@ static void keystone_irq_ack(struct irq_data *d)
83
84
/* nothing to do here */
84
85
}
85
86
86
- static void keystone_irq_handler (struct irq_desc * desc )
87
+ static irqreturn_t keystone_irq_handler (int irq , void * keystone_irq )
87
88
{
88
- unsigned int irq = irq_desc_get_irq ( desc ) ;
89
- struct keystone_irq_device * kirq = irq_desc_get_handler_data ( desc ) ;
89
+ struct keystone_irq_device * kirq = keystone_irq ;
90
+ unsigned long wa_lock_flags ;
90
91
unsigned long pending ;
91
92
int src , virq ;
92
93
93
94
dev_dbg (kirq -> dev , "start irq %d\n" , irq );
94
95
95
- chained_irq_enter (irq_desc_get_chip (desc ), desc );
96
-
97
96
pending = keystone_irq_readl (kirq );
98
97
keystone_irq_writel (kirq , pending );
99
98
@@ -111,13 +110,15 @@ static void keystone_irq_handler(struct irq_desc *desc)
111
110
if (!virq )
112
111
dev_warn (kirq -> dev , "spurious irq detected hwirq %d, virq %d\n" ,
113
112
src , virq );
113
+ raw_spin_lock_irqsave (& kirq -> wa_lock , wa_lock_flags );
114
114
generic_handle_irq (virq );
115
+ raw_spin_unlock_irqrestore (& kirq -> wa_lock ,
116
+ wa_lock_flags );
115
117
}
116
118
}
117
119
118
- chained_irq_exit (irq_desc_get_chip (desc ), desc );
119
-
120
120
dev_dbg (kirq -> dev , "end irq %d\n" , irq );
121
+ return IRQ_HANDLED ;
121
122
}
122
123
123
124
static int keystone_irq_map (struct irq_domain * h , unsigned int virq ,
@@ -182,9 +183,16 @@ static int keystone_irq_probe(struct platform_device *pdev)
182
183
return - ENODEV ;
183
184
}
184
185
186
+ raw_spin_lock_init (& kirq -> wa_lock );
187
+
185
188
platform_set_drvdata (pdev , kirq );
186
189
187
- irq_set_chained_handler_and_data (kirq -> irq , keystone_irq_handler , kirq );
190
+ ret = request_irq (kirq -> irq , keystone_irq_handler ,
191
+ 0 , dev_name (dev ), kirq );
192
+ if (ret ) {
193
+ irq_domain_remove (kirq -> irqd );
194
+ return ret ;
195
+ }
188
196
189
197
/* clear all source bits */
190
198
keystone_irq_writel (kirq , ~0x0 );
@@ -199,6 +207,8 @@ static int keystone_irq_remove(struct platform_device *pdev)
199
207
struct keystone_irq_device * kirq = platform_get_drvdata (pdev );
200
208
int hwirq ;
201
209
210
+ free_irq (kirq -> irq , kirq );
211
+
202
212
for (hwirq = 0 ; hwirq < KEYSTONE_N_IRQ ; hwirq ++ )
203
213
irq_dispose_mapping (irq_find_mapping (kirq -> irqd , hwirq ));
204
214
0 commit comments