77 */
88
99#include <linux/bitops.h>
10+ #include <linux/io.h>
1011#include <linux/irq.h>
1112#include <linux/irqchip.h>
1213#include <linux/irqchip/chained_irq.h>
1314#include <linux/irqdomain.h>
14- #include <linux/mfd/syscon .h>
15+ #include <linux/of_address .h>
1516#include <linux/of_irq.h>
16- #include <linux/regmap.h>
1717
18- #define ASPEED_SCU_IC_REG 0x018
19- #define ASPEED_SCU_IC_SHIFT 0
20- #define ASPEED_SCU_IC_ENABLE GENMASK(15, ASPEED_SCU_IC_SHIFT)
21- #define ASPEED_SCU_IC_NUM_IRQS 7
2218#define ASPEED_SCU_IC_STATUS GENMASK(28, 16)
2319#define ASPEED_SCU_IC_STATUS_SHIFT 16
2420
25- #define ASPEED_AST2600_SCU_IC0_REG 0x560
26- #define ASPEED_AST2600_SCU_IC0_SHIFT 0
27- #define ASPEED_AST2600_SCU_IC0_ENABLE \
28- GENMASK(5, ASPEED_AST2600_SCU_IC0_SHIFT)
29- #define ASPEED_AST2600_SCU_IC0_NUM_IRQS 6
21+ struct aspeed_scu_ic_variant {
22+ const char * compatible ;
23+ unsigned long irq_enable ;
24+ unsigned long irq_shift ;
25+ unsigned int num_irqs ;
26+ };
27+
28+ #define SCU_VARIANT (_compat , _shift , _enable , _num ) { \
29+ .compatible = _compat, \
30+ .irq_shift = _shift, \
31+ .irq_enable = _enable, \
32+ .num_irqs = _num, \
33+ }
3034
31- #define ASPEED_AST2600_SCU_IC1_REG 0x570
32- #define ASPEED_AST2600_SCU_IC1_SHIFT 4
33- #define ASPEED_AST2600_SCU_IC1_ENABLE \
34- GENMASK(5, ASPEED_AST2600_SCU_IC1_SHIFT)
35- #define ASPEED_AST2600_SCU_IC1_NUM_IRQS 2
35+ static const struct aspeed_scu_ic_variant scu_ic_variants [] __initconst = {
36+ SCU_VARIANT ("aspeed,ast2400-scu-ic" , 0 , GENMASK (15 , 0 ), 7 ),
37+ SCU_VARIANT ("aspeed,ast2500-scu-ic" , 0 , GENMASK (15 , 0 ), 7 ),
38+ SCU_VARIANT ("aspeed,ast2600-scu-ic0" , 0 , GENMASK (5 , 0 ), 6 ),
39+ SCU_VARIANT ("aspeed,ast2600-scu-ic1" , 4 , GENMASK (5 , 4 ), 2 ),
40+ };
3641
3742struct aspeed_scu_ic {
38- unsigned long irq_enable ;
39- unsigned long irq_shift ;
40- unsigned int num_irqs ;
41- unsigned int reg ;
42- struct regmap * scu ;
43- struct irq_domain * irq_domain ;
43+ unsigned long irq_enable ;
44+ unsigned long irq_shift ;
45+ unsigned int num_irqs ;
46+ void __iomem * base ;
47+ struct irq_domain * irq_domain ;
4448};
4549
4650static void aspeed_scu_ic_irq_handler (struct irq_desc * desc )
4751{
48- unsigned int sts ;
49- unsigned long bit ;
50- unsigned long enabled ;
51- unsigned long max ;
52- unsigned long status ;
5352 struct aspeed_scu_ic * scu_ic = irq_desc_get_handler_data (desc );
5453 struct irq_chip * chip = irq_desc_get_chip (desc );
55- unsigned int mask = scu_ic -> irq_enable << ASPEED_SCU_IC_STATUS_SHIFT ;
54+ unsigned long bit , enabled , max , status ;
55+ unsigned int sts , mask ;
5656
5757 chained_irq_enter (chip , desc );
5858
59+ mask = scu_ic -> irq_enable << ASPEED_SCU_IC_STATUS_SHIFT ;
5960 /*
6061 * The SCU IC has just one register to control its operation and read
6162 * status. The interrupt enable bits occupy the lower 16 bits of the
@@ -66,19 +67,17 @@ static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
6667 * shifting the status down to get the mapping and then back up to
6768 * clear the bit.
6869 */
69- regmap_read (scu_ic -> scu , scu_ic -> reg , & sts );
70+ sts = readl (scu_ic -> base );
7071 enabled = sts & scu_ic -> irq_enable ;
7172 status = (sts >> ASPEED_SCU_IC_STATUS_SHIFT ) & enabled ;
7273
7374 bit = scu_ic -> irq_shift ;
7475 max = scu_ic -> num_irqs + bit ;
7576
7677 for_each_set_bit_from (bit , & status , max ) {
77- generic_handle_domain_irq (scu_ic -> irq_domain ,
78- bit - scu_ic -> irq_shift );
79-
80- regmap_write_bits (scu_ic -> scu , scu_ic -> reg , mask ,
81- BIT (bit + ASPEED_SCU_IC_STATUS_SHIFT ));
78+ generic_handle_domain_irq (scu_ic -> irq_domain , bit - scu_ic -> irq_shift );
79+ writel ((readl (scu_ic -> base ) & ~mask ) | BIT (bit + ASPEED_SCU_IC_STATUS_SHIFT ),
80+ scu_ic -> base );
8281 }
8382
8483 chained_irq_exit (chip , desc );
@@ -87,30 +86,29 @@ static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
8786static void aspeed_scu_ic_irq_mask (struct irq_data * data )
8887{
8988 struct aspeed_scu_ic * scu_ic = irq_data_get_irq_chip_data (data );
90- unsigned int mask = BIT (data -> hwirq + scu_ic -> irq_shift ) |
91- (scu_ic -> irq_enable << ASPEED_SCU_IC_STATUS_SHIFT );
89+ unsigned int bit = BIT (data -> hwirq + scu_ic -> irq_shift );
90+ unsigned int mask = bit | (scu_ic -> irq_enable << ASPEED_SCU_IC_STATUS_SHIFT );
9291
9392 /*
9493 * Status bits are cleared by writing 1. In order to prevent the mask
9594 * operation from clearing the status bits, they should be under the
9695 * mask and written with 0.
9796 */
98- regmap_update_bits ( scu_ic -> scu , scu_ic -> reg , mask , 0 );
97+ writel ( readl ( scu_ic -> base ) & ~ mask , scu_ic -> base );
9998}
10099
101100static void aspeed_scu_ic_irq_unmask (struct irq_data * data )
102101{
103102 struct aspeed_scu_ic * scu_ic = irq_data_get_irq_chip_data (data );
104103 unsigned int bit = BIT (data -> hwirq + scu_ic -> irq_shift );
105- unsigned int mask = bit |
106- (scu_ic -> irq_enable << ASPEED_SCU_IC_STATUS_SHIFT );
104+ unsigned int mask = bit | (scu_ic -> irq_enable << ASPEED_SCU_IC_STATUS_SHIFT );
107105
108106 /*
109107 * Status bits are cleared by writing 1. In order to prevent the unmask
110108 * operation from clearing the status bits, they should be under the
111109 * mask and written with 0.
112110 */
113- regmap_update_bits ( scu_ic -> scu , scu_ic -> reg , mask , bit );
111+ writel (( readl ( scu_ic -> base ) & ~ mask ) | bit , scu_ic -> base );
114112}
115113
116114static int aspeed_scu_ic_irq_set_affinity (struct irq_data * data ,
@@ -143,21 +141,15 @@ static const struct irq_domain_ops aspeed_scu_ic_domain_ops = {
143141static int aspeed_scu_ic_of_init_common (struct aspeed_scu_ic * scu_ic ,
144142 struct device_node * node )
145143{
146- int irq ;
147- int rc = 0 ;
144+ int irq , rc = 0 ;
148145
149- if (!node -> parent ) {
150- rc = - ENODEV ;
146+ scu_ic -> base = of_iomap (node , 0 );
147+ if (IS_ERR (scu_ic -> base )) {
148+ rc = PTR_ERR (scu_ic -> base );
151149 goto err ;
152150 }
153-
154- scu_ic -> scu = syscon_node_to_regmap (node -> parent );
155- if (IS_ERR (scu_ic -> scu )) {
156- rc = PTR_ERR (scu_ic -> scu );
157- goto err ;
158- }
159- regmap_write_bits (scu_ic -> scu , scu_ic -> reg , ASPEED_SCU_IC_STATUS , ASPEED_SCU_IC_STATUS );
160- regmap_write_bits (scu_ic -> scu , scu_ic -> reg , ASPEED_SCU_IC_ENABLE , 0 );
151+ writel (ASPEED_SCU_IC_STATUS , scu_ic -> base );
152+ writel (0 , scu_ic -> base );
161153
162154 irq = irq_of_parse_and_map (node , 0 );
163155 if (!irq ) {
@@ -166,8 +158,7 @@ static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic,
166158 }
167159
168160 scu_ic -> irq_domain = irq_domain_create_linear (of_fwnode_handle (node ), scu_ic -> num_irqs ,
169- & aspeed_scu_ic_domain_ops ,
170- scu_ic );
161+ & aspeed_scu_ic_domain_ops , scu_ic );
171162 if (!scu_ic -> irq_domain ) {
172163 rc = - ENOMEM ;
173164 goto err ;
@@ -180,61 +171,39 @@ static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic,
180171
181172err :
182173 kfree (scu_ic );
183-
184174 return rc ;
185175}
186176
187- static int __init aspeed_scu_ic_of_init (struct device_node * node ,
188- struct device_node * parent )
177+ static const struct aspeed_scu_ic_variant * aspeed_scu_ic_find_variant (struct device_node * np )
189178{
190- struct aspeed_scu_ic * scu_ic = kzalloc (sizeof (* scu_ic ), GFP_KERNEL );
191-
192- if (!scu_ic )
193- return - ENOMEM ;
194-
195- scu_ic -> irq_enable = ASPEED_SCU_IC_ENABLE ;
196- scu_ic -> irq_shift = ASPEED_SCU_IC_SHIFT ;
197- scu_ic -> num_irqs = ASPEED_SCU_IC_NUM_IRQS ;
198- scu_ic -> reg = ASPEED_SCU_IC_REG ;
199-
200- return aspeed_scu_ic_of_init_common (scu_ic , node );
179+ for (int i = 0 ; i < ARRAY_SIZE (scu_ic_variants ); i ++ ) {
180+ if (of_device_is_compatible (np , scu_ic_variants [i ].compatible ))
181+ return & scu_ic_variants [i ];
182+ }
183+ return NULL ;
201184}
202185
203- static int __init aspeed_ast2600_scu_ic0_of_init (struct device_node * node ,
204- struct device_node * parent )
186+ static int __init aspeed_scu_ic_of_init (struct device_node * node , struct device_node * parent )
205187{
206- struct aspeed_scu_ic * scu_ic = kzalloc (sizeof (* scu_ic ), GFP_KERNEL );
207-
208- if (!scu_ic )
209- return - ENOMEM ;
210-
211- scu_ic -> irq_enable = ASPEED_AST2600_SCU_IC0_ENABLE ;
212- scu_ic -> irq_shift = ASPEED_AST2600_SCU_IC0_SHIFT ;
213- scu_ic -> num_irqs = ASPEED_AST2600_SCU_IC0_NUM_IRQS ;
214- scu_ic -> reg = ASPEED_AST2600_SCU_IC0_REG ;
215-
216- return aspeed_scu_ic_of_init_common (scu_ic , node );
217- }
188+ const struct aspeed_scu_ic_variant * variant ;
189+ struct aspeed_scu_ic * scu_ic ;
218190
219- static int __init aspeed_ast2600_scu_ic1_of_init (struct device_node * node ,
220- struct device_node * parent )
221- {
222- struct aspeed_scu_ic * scu_ic = kzalloc (sizeof (* scu_ic ), GFP_KERNEL );
191+ variant = aspeed_scu_ic_find_variant (node );
192+ if (!variant )
193+ return - ENODEV ;
223194
195+ scu_ic = kzalloc (sizeof (* scu_ic ), GFP_KERNEL );
224196 if (!scu_ic )
225197 return - ENOMEM ;
226198
227- scu_ic -> irq_enable = ASPEED_AST2600_SCU_IC1_ENABLE ;
228- scu_ic -> irq_shift = ASPEED_AST2600_SCU_IC1_SHIFT ;
229- scu_ic -> num_irqs = ASPEED_AST2600_SCU_IC1_NUM_IRQS ;
230- scu_ic -> reg = ASPEED_AST2600_SCU_IC1_REG ;
199+ scu_ic -> irq_enable = variant -> irq_enable ;
200+ scu_ic -> irq_shift = variant -> irq_shift ;
201+ scu_ic -> num_irqs = variant -> num_irqs ;
231202
232203 return aspeed_scu_ic_of_init_common (scu_ic , node );
233204}
234205
235206IRQCHIP_DECLARE (ast2400_scu_ic , "aspeed,ast2400-scu-ic" , aspeed_scu_ic_of_init );
236207IRQCHIP_DECLARE (ast2500_scu_ic , "aspeed,ast2500-scu-ic" , aspeed_scu_ic_of_init );
237- IRQCHIP_DECLARE (ast2600_scu_ic0 , "aspeed,ast2600-scu-ic0" ,
238- aspeed_ast2600_scu_ic0_of_init );
239- IRQCHIP_DECLARE (ast2600_scu_ic1 , "aspeed,ast2600-scu-ic1" ,
240- aspeed_ast2600_scu_ic1_of_init );
208+ IRQCHIP_DECLARE (ast2600_scu_ic0 , "aspeed,ast2600-scu-ic0" , aspeed_scu_ic_of_init );
209+ IRQCHIP_DECLARE (ast2600_scu_ic1 , "aspeed,ast2600-scu-ic1" , aspeed_scu_ic_of_init );
0 commit comments