12
12
#include <linux/irqchip/chained_irq.h>
13
13
#include <linux/interrupt.h>
14
14
15
- #define ICPU_CFG_INTR_INTR_STICKY 0x10
16
- #define ICPU_CFG_INTR_INTR_ENA 0x18
17
- #define ICPU_CFG_INTR_INTR_ENA_CLR 0x1c
18
- #define ICPU_CFG_INTR_INTR_ENA_SET 0x20
19
- #define ICPU_CFG_INTR_DST_INTR_IDENT (x ) (0x38 + 0x4 * (x))
20
- #define ICPU_CFG_INTR_INTR_TRIGGER (x ) (0x5c + 0x4 * (x))
21
-
22
- #define OCELOT_NR_IRQ 24
15
+ #define ICPU_CFG_INTR_DST_INTR_IDENT (_p , x ) ((_p)->reg_off_ident + 0x4 * (x))
16
+ #define ICPU_CFG_INTR_INTR_TRIGGER (_p , x ) ((_p)->reg_off_trigger + 0x4 * (x))
17
+
18
+ #define FLAGS_HAS_TRIGGER BIT(0)
19
+
20
+ struct chip_props {
21
+ u8 flags ;
22
+ u8 reg_off_sticky ;
23
+ u8 reg_off_ena ;
24
+ u8 reg_off_ena_clr ;
25
+ u8 reg_off_ena_set ;
26
+ u8 reg_off_ident ;
27
+ u8 reg_off_trigger ;
28
+ u8 reg_off_ena_irq0 ;
29
+ u8 n_irq ;
30
+ };
31
+
32
+ static struct chip_props ocelot_props = {
33
+ .flags = FLAGS_HAS_TRIGGER ,
34
+ .reg_off_sticky = 0x10 ,
35
+ .reg_off_ena = 0x18 ,
36
+ .reg_off_ena_clr = 0x1c ,
37
+ .reg_off_ena_set = 0x20 ,
38
+ .reg_off_ident = 0x38 ,
39
+ .reg_off_trigger = 0x5c ,
40
+ .n_irq = 24 ,
41
+ };
23
42
24
43
static void ocelot_irq_unmask (struct irq_data * data )
25
44
{
26
45
struct irq_chip_generic * gc = irq_data_get_irq_chip_data (data );
46
+ struct irq_domain * d = data -> domain ;
47
+ struct chip_props * p = d -> host_data ;
27
48
struct irq_chip_type * ct = irq_data_get_chip_type (data );
28
49
unsigned int mask = data -> mask ;
29
50
u32 val ;
30
51
31
52
irq_gc_lock (gc );
32
- val = irq_reg_readl (gc , ICPU_CFG_INTR_INTR_TRIGGER (0 )) |
33
- irq_reg_readl (gc , ICPU_CFG_INTR_INTR_TRIGGER (1 ));
53
+ val = irq_reg_readl (gc , ICPU_CFG_INTR_INTR_TRIGGER (p , 0 )) |
54
+ irq_reg_readl (gc , ICPU_CFG_INTR_INTR_TRIGGER (p , 1 ));
34
55
if (!(val & mask ))
35
- irq_reg_writel (gc , mask , ICPU_CFG_INTR_INTR_STICKY );
56
+ irq_reg_writel (gc , mask , p -> reg_off_sticky );
36
57
37
58
* ct -> mask_cache &= ~mask ;
38
- irq_reg_writel (gc , mask , ICPU_CFG_INTR_INTR_ENA_SET );
59
+ irq_reg_writel (gc , mask , p -> reg_off_ena_set );
39
60
irq_gc_unlock (gc );
40
61
}
41
62
42
63
static void ocelot_irq_handler (struct irq_desc * desc )
43
64
{
44
65
struct irq_chip * chip = irq_desc_get_chip (desc );
45
66
struct irq_domain * d = irq_desc_get_handler_data (desc );
67
+ struct chip_props * p = d -> host_data ;
46
68
struct irq_chip_generic * gc = irq_get_domain_generic_chip (d , 0 );
47
- u32 reg = irq_reg_readl (gc , ICPU_CFG_INTR_DST_INTR_IDENT (0 ));
69
+ u32 reg = irq_reg_readl (gc , ICPU_CFG_INTR_DST_INTR_IDENT (p , 0 ));
48
70
49
71
chained_irq_enter (chip , desc );
50
72
@@ -58,8 +80,9 @@ static void ocelot_irq_handler(struct irq_desc *desc)
58
80
chained_irq_exit (chip , desc );
59
81
}
60
82
61
- static int __init ocelot_irq_init (struct device_node * node ,
62
- struct device_node * parent )
83
+ static int __init vcoreiii_irq_init (struct device_node * node ,
84
+ struct device_node * parent ,
85
+ struct chip_props * p )
63
86
{
64
87
struct irq_domain * domain ;
65
88
struct irq_chip_generic * gc ;
@@ -69,14 +92,14 @@ static int __init ocelot_irq_init(struct device_node *node,
69
92
if (!parent_irq )
70
93
return - EINVAL ;
71
94
72
- domain = irq_domain_add_linear (node , OCELOT_NR_IRQ ,
95
+ domain = irq_domain_add_linear (node , p -> n_irq ,
73
96
& irq_generic_chip_ops , NULL );
74
97
if (!domain ) {
75
98
pr_err ("%pOFn: unable to add irq domain\n" , node );
76
99
return - ENOMEM ;
77
100
}
78
101
79
- ret = irq_alloc_domain_generic_chips (domain , OCELOT_NR_IRQ , 1 ,
102
+ ret = irq_alloc_domain_generic_chips (domain , p -> n_irq , 1 ,
80
103
"icpu" , handle_level_irq ,
81
104
0 , 0 , 0 );
82
105
if (ret ) {
@@ -92,16 +115,18 @@ static int __init ocelot_irq_init(struct device_node *node,
92
115
goto err_gc_free ;
93
116
}
94
117
95
- gc -> chip_types [0 ].regs .ack = ICPU_CFG_INTR_INTR_STICKY ;
96
- gc -> chip_types [0 ].regs .mask = ICPU_CFG_INTR_INTR_ENA_CLR ;
118
+ gc -> chip_types [0 ].regs .ack = p -> reg_off_sticky ;
119
+ gc -> chip_types [0 ].regs .mask = p -> reg_off_ena_clr ;
97
120
gc -> chip_types [0 ].chip .irq_ack = irq_gc_ack_set_bit ;
98
121
gc -> chip_types [0 ].chip .irq_mask = irq_gc_mask_set_bit ;
99
- gc -> chip_types [0 ].chip .irq_unmask = ocelot_irq_unmask ;
122
+ if (p -> flags & FLAGS_HAS_TRIGGER )
123
+ gc -> chip_types [0 ].chip .irq_unmask = ocelot_irq_unmask ;
100
124
101
125
/* Mask and ack all interrupts */
102
- irq_reg_writel (gc , 0 , ICPU_CFG_INTR_INTR_ENA );
103
- irq_reg_writel (gc , 0xffffffff , ICPU_CFG_INTR_INTR_STICKY );
126
+ irq_reg_writel (gc , 0 , p -> reg_off_ena );
127
+ irq_reg_writel (gc , 0xffffffff , p -> reg_off_sticky );
104
128
129
+ domain -> host_data = p ;
105
130
irq_set_chained_handler_and_data (parent_irq , ocelot_irq_handler ,
106
131
domain );
107
132
@@ -115,4 +140,11 @@ static int __init ocelot_irq_init(struct device_node *node,
115
140
116
141
return ret ;
117
142
}
143
+
144
+ static int __init ocelot_irq_init (struct device_node * node ,
145
+ struct device_node * parent )
146
+ {
147
+ return vcoreiii_irq_init (node , parent , & ocelot_props );
148
+ }
149
+
118
150
IRQCHIP_DECLARE (ocelot_icpu , "mscc,ocelot-icpu-intr" , ocelot_irq_init );
0 commit comments