@@ -38,13 +38,35 @@ struct regmap_irq_chip_data {
3838 unsigned int * wake_buf ;
3939 unsigned int * type_buf ;
4040 unsigned int * type_buf_def ;
41+ unsigned int * * virt_buf ;
4142
4243 unsigned int irq_reg_stride ;
4344 unsigned int type_reg_stride ;
4445
4546 bool clear_status :1 ;
4647};
4748
49+ static int sub_irq_reg (struct regmap_irq_chip_data * data ,
50+ unsigned int base_reg , int i )
51+ {
52+ const struct regmap_irq_chip * chip = data -> chip ;
53+ struct regmap * map = data -> map ;
54+ struct regmap_irq_sub_irq_map * subreg ;
55+ unsigned int offset ;
56+ int reg = 0 ;
57+
58+ if (!chip -> sub_reg_offsets || !chip -> not_fixed_stride ) {
59+ /* Assume linear mapping */
60+ reg = base_reg + (i * map -> reg_stride * data -> irq_reg_stride );
61+ } else {
62+ subreg = & chip -> sub_reg_offsets [i ];
63+ offset = subreg -> offset [0 ];
64+ reg = base_reg + offset ;
65+ }
66+
67+ return reg ;
68+ }
69+
4870static inline const
4971struct regmap_irq * irq_to_regmap_irq (struct regmap_irq_chip_data * data ,
5072 int irq )
@@ -73,7 +95,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
7395{
7496 struct regmap_irq_chip_data * d = irq_data_get_irq_chip_data (data );
7597 struct regmap * map = d -> map ;
76- int i , ret ;
98+ int i , j , ret ;
7799 u32 reg ;
78100 u32 unmask_offset ;
79101 u32 val ;
@@ -87,8 +109,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
87109
88110 if (d -> clear_status ) {
89111 for (i = 0 ; i < d -> chip -> num_regs ; i ++ ) {
90- reg = d -> chip -> status_base +
91- (i * map -> reg_stride * d -> irq_reg_stride );
112+ reg = sub_irq_reg (d , d -> chip -> status_base , i );
92113
93114 ret = regmap_read (map , reg , & val );
94115 if (ret )
@@ -108,8 +129,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
108129 if (!d -> chip -> mask_base )
109130 continue ;
110131
111- reg = d -> chip -> mask_base +
112- (i * map -> reg_stride * d -> irq_reg_stride );
132+ reg = sub_irq_reg (d , d -> chip -> mask_base , i );
113133 if (d -> chip -> mask_invert ) {
114134 ret = regmap_irq_update_bits (d , reg ,
115135 d -> mask_buf_def [i ], ~d -> mask_buf [i ]);
@@ -136,8 +156,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
136156 dev_err (d -> map -> dev , "Failed to sync masks in %x\n" ,
137157 reg );
138158
139- reg = d -> chip -> wake_base +
140- (i * map -> reg_stride * d -> irq_reg_stride );
159+ reg = sub_irq_reg (d , d -> chip -> wake_base , i );
141160 if (d -> wake_buf ) {
142161 if (d -> chip -> wake_invert )
143162 ret = regmap_irq_update_bits (d , reg ,
@@ -161,8 +180,8 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
161180 * it'll be ignored in irq handler, then may introduce irq storm
162181 */
163182 if (d -> mask_buf [i ] && (d -> chip -> ack_base || d -> chip -> use_ack )) {
164- reg = d -> chip -> ack_base +
165- ( i * map -> reg_stride * d -> irq_reg_stride );
183+ reg = sub_irq_reg ( d , d -> chip -> ack_base , i );
184+
166185 /* some chips ack by write 0 */
167186 if (d -> chip -> ack_invert )
168187 ret = regmap_write (map , reg , ~d -> mask_buf [i ]);
@@ -187,8 +206,7 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
187206 for (i = 0 ; i < d -> chip -> num_type_reg ; i ++ ) {
188207 if (!d -> type_buf_def [i ])
189208 continue ;
190- reg = d -> chip -> type_base +
191- (i * map -> reg_stride * d -> type_reg_stride );
209+ reg = sub_irq_reg (d , d -> chip -> type_base , i );
192210 if (d -> chip -> type_invert )
193211 ret = regmap_irq_update_bits (d , reg ,
194212 d -> type_buf_def [i ], ~d -> type_buf [i ]);
@@ -201,6 +219,20 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
201219 }
202220 }
203221
222+ if (d -> chip -> num_virt_regs ) {
223+ for (i = 0 ; i < d -> chip -> num_virt_regs ; i ++ ) {
224+ for (j = 0 ; j < d -> chip -> num_regs ; j ++ ) {
225+ reg = sub_irq_reg (d , d -> chip -> virt_reg_base [i ],
226+ j );
227+ ret = regmap_write (map , reg , d -> virt_buf [i ][j ]);
228+ if (ret != 0 )
229+ dev_err (d -> map -> dev ,
230+ "Failed to write virt 0x%x: %d\n" ,
231+ reg , ret );
232+ }
233+ }
234+ }
235+
204236 if (d -> chip -> runtime_pm )
205237 pm_runtime_put (map -> dev );
206238
@@ -301,6 +333,11 @@ static int regmap_irq_set_type(struct irq_data *data, unsigned int type)
301333 default :
302334 return - EINVAL ;
303335 }
336+
337+ if (d -> chip -> set_type_virt )
338+ return d -> chip -> set_type_virt (d -> virt_buf , type , data -> hwirq ,
339+ reg );
340+
304341 return 0 ;
305342}
306343
@@ -352,8 +389,15 @@ static inline int read_sub_irq_data(struct regmap_irq_chip_data *data,
352389 for (i = 0 ; i < subreg -> num_regs ; i ++ ) {
353390 unsigned int offset = subreg -> offset [i ];
354391
355- ret = regmap_read (map , chip -> status_base + offset ,
356- & data -> status_buf [offset ]);
392+ if (chip -> not_fixed_stride )
393+ ret = regmap_read (map ,
394+ chip -> status_base + offset ,
395+ & data -> status_buf [b ]);
396+ else
397+ ret = regmap_read (map ,
398+ chip -> status_base + offset ,
399+ & data -> status_buf [offset ]);
400+
357401 if (ret )
358402 break ;
359403 }
@@ -474,10 +518,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
474518
475519 } else {
476520 for (i = 0 ; i < data -> chip -> num_regs ; i ++ ) {
477- ret = regmap_read (map , chip -> status_base +
478- (i * map -> reg_stride
479- * data -> irq_reg_stride ),
480- & data -> status_buf [i ]);
521+ unsigned int reg = sub_irq_reg (data ,
522+ data -> chip -> status_base , i );
523+ ret = regmap_read (map , reg , & data -> status_buf [i ]);
481524
482525 if (ret != 0 ) {
483526 dev_err (map -> dev ,
@@ -499,8 +542,8 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
499542 data -> status_buf [i ] &= ~data -> mask_buf [i ];
500543
501544 if (data -> status_buf [i ] && (chip -> ack_base || chip -> use_ack )) {
502- reg = chip -> ack_base +
503- ( i * map -> reg_stride * data -> irq_reg_stride );
545+ reg = sub_irq_reg ( data , data -> chip -> ack_base , i );
546+
504547 if (chip -> ack_invert )
505548 ret = regmap_write (map , reg ,
506549 ~data -> status_buf [i ]);
@@ -605,6 +648,12 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
605648 return - EINVAL ;
606649 }
607650
651+ if (chip -> not_fixed_stride ) {
652+ for (i = 0 ; i < chip -> num_regs ; i ++ )
653+ if (chip -> sub_reg_offsets [i ].num_regs != 1 )
654+ return - EINVAL ;
655+ }
656+
608657 if (irq_base ) {
609658 irq_base = irq_alloc_descs (irq_base , 0 , chip -> num_irqs , 0 );
610659 if (irq_base < 0 ) {
@@ -662,6 +711,24 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
662711 goto err_alloc ;
663712 }
664713
714+ if (chip -> num_virt_regs ) {
715+ /*
716+ * Create virt_buf[chip->num_extra_config_regs][chip->num_regs]
717+ */
718+ d -> virt_buf = kcalloc (chip -> num_virt_regs , sizeof (* d -> virt_buf ),
719+ GFP_KERNEL );
720+ if (!d -> virt_buf )
721+ goto err_alloc ;
722+
723+ for (i = 0 ; i < chip -> num_virt_regs ; i ++ ) {
724+ d -> virt_buf [i ] = kcalloc (chip -> num_regs ,
725+ sizeof (unsigned int ),
726+ GFP_KERNEL );
727+ if (!d -> virt_buf [i ])
728+ goto err_alloc ;
729+ }
730+ }
731+
665732 d -> irq_chip = regmap_irq_chip ;
666733 d -> irq_chip .name = chip -> name ;
667734 d -> irq = irq ;
@@ -700,8 +767,8 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
700767 if (!chip -> mask_base )
701768 continue ;
702769
703- reg = chip -> mask_base +
704- ( i * map -> reg_stride * d -> irq_reg_stride );
770+ reg = sub_irq_reg ( d , d -> chip -> mask_base , i );
771+
705772 if (chip -> mask_invert )
706773 ret = regmap_irq_update_bits (d , reg ,
707774 d -> mask_buf [i ], ~d -> mask_buf [i ]);
@@ -725,8 +792,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
725792 continue ;
726793
727794 /* Ack masked but set interrupts */
728- reg = chip -> status_base +
729- (i * map -> reg_stride * d -> irq_reg_stride );
795+ reg = sub_irq_reg (d , d -> chip -> status_base , i );
730796 ret = regmap_read (map , reg , & d -> status_buf [i ]);
731797 if (ret != 0 ) {
732798 dev_err (map -> dev , "Failed to read IRQ status: %d\n" ,
@@ -735,8 +801,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
735801 }
736802
737803 if (d -> status_buf [i ] && (chip -> ack_base || chip -> use_ack )) {
738- reg = chip -> ack_base +
739- (i * map -> reg_stride * d -> irq_reg_stride );
804+ reg = sub_irq_reg (d , d -> chip -> ack_base , i );
740805 if (chip -> ack_invert )
741806 ret = regmap_write (map , reg ,
742807 ~(d -> status_buf [i ] & d -> mask_buf [i ]));
@@ -765,8 +830,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
765830 if (d -> wake_buf ) {
766831 for (i = 0 ; i < chip -> num_regs ; i ++ ) {
767832 d -> wake_buf [i ] = d -> mask_buf_def [i ];
768- reg = chip -> wake_base +
769- (i * map -> reg_stride * d -> irq_reg_stride );
833+ reg = sub_irq_reg (d , d -> chip -> wake_base , i );
770834
771835 if (chip -> wake_invert )
772836 ret = regmap_irq_update_bits (d , reg ,
@@ -786,8 +850,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
786850
787851 if (chip -> num_type_reg && !chip -> type_in_mask ) {
788852 for (i = 0 ; i < chip -> num_type_reg ; ++ i ) {
789- reg = chip -> type_base +
790- (i * map -> reg_stride * d -> type_reg_stride );
853+ reg = sub_irq_reg (d , d -> chip -> type_base , i );
791854
792855 ret = regmap_read (map , reg , & d -> type_buf_def [i ]);
793856
@@ -838,6 +901,11 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
838901 kfree (d -> mask_buf );
839902 kfree (d -> status_buf );
840903 kfree (d -> status_reg_buf );
904+ if (d -> virt_buf ) {
905+ for (i = 0 ; i < chip -> num_virt_regs ; i ++ )
906+ kfree (d -> virt_buf [i ]);
907+ kfree (d -> virt_buf );
908+ }
841909 kfree (d );
842910 return ret ;
843911}
0 commit comments