2121
2222struct regmap_irq_chip_data {
2323 struct mutex lock ;
24+ struct lock_class_key lock_key ;
2425 struct irq_chip irq_chip ;
2526
2627 struct regmap * map ;
@@ -801,7 +802,13 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
801802 goto err_alloc ;
802803 }
803804
804- mutex_init (& d -> lock );
805+ /*
806+ * If one regmap-irq is the parent of another then we'll try
807+ * to lock the child with the parent locked, use an explicit
808+ * lock_key so lockdep can figure out what's going on.
809+ */
810+ lockdep_register_key (& d -> lock_key );
811+ mutex_init_with_key (& d -> lock , & d -> lock_key );
805812
806813 for (i = 0 ; i < chip -> num_irqs ; i ++ )
807814 d -> mask_buf_def [chip -> irqs [i ].reg_offset / map -> reg_stride ]
@@ -816,7 +823,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
816823 d -> mask_buf [i ],
817824 chip -> irq_drv_data );
818825 if (ret )
819- goto err_alloc ;
826+ goto err_mutex ;
820827 }
821828
822829 if (chip -> mask_base && !chip -> handle_mask_sync ) {
@@ -827,7 +834,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
827834 if (ret ) {
828835 dev_err (map -> dev , "Failed to set masks in 0x%x: %d\n" ,
829836 reg , ret );
830- goto err_alloc ;
837+ goto err_mutex ;
831838 }
832839 }
833840
@@ -838,7 +845,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
838845 if (ret ) {
839846 dev_err (map -> dev , "Failed to set masks in 0x%x: %d\n" ,
840847 reg , ret );
841- goto err_alloc ;
848+ goto err_mutex ;
842849 }
843850 }
844851
@@ -855,7 +862,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
855862 if (ret != 0 ) {
856863 dev_err (map -> dev , "Failed to read IRQ status: %d\n" ,
857864 ret );
858- goto err_alloc ;
865+ goto err_mutex ;
859866 }
860867 }
861868
@@ -879,7 +886,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
879886 if (ret != 0 ) {
880887 dev_err (map -> dev , "Failed to ack 0x%x: %d\n" ,
881888 reg , ret );
882- goto err_alloc ;
889+ goto err_mutex ;
883890 }
884891 }
885892 }
@@ -901,7 +908,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
901908 if (ret != 0 ) {
902909 dev_err (map -> dev , "Failed to set masks in 0x%x: %d\n" ,
903910 reg , ret );
904- goto err_alloc ;
911+ goto err_mutex ;
905912 }
906913 }
907914 }
@@ -910,15 +917,15 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
910917 if (chip -> status_is_level ) {
911918 ret = read_irq_data (d );
912919 if (ret < 0 )
913- goto err_alloc ;
920+ goto err_mutex ;
914921
915922 memcpy (d -> prev_status_buf , d -> status_buf ,
916923 array_size (d -> chip -> num_regs , sizeof (d -> prev_status_buf [0 ])));
917924 }
918925
919926 ret = regmap_irq_create_domain (fwnode , irq_base , chip , d );
920927 if (ret )
921- goto err_alloc ;
928+ goto err_mutex ;
922929
923930 ret = request_threaded_irq (irq , NULL , regmap_irq_thread ,
924931 irq_flags | IRQF_ONESHOT ,
@@ -935,6 +942,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
935942
936943err_domain :
937944 /* Should really dispose of the domain but... */
945+ err_mutex :
946+ mutex_destroy (& d -> lock );
947+ lockdep_unregister_key (& d -> lock_key );
938948err_alloc :
939949 kfree (d -> type_buf );
940950 kfree (d -> type_buf_def );
@@ -1027,6 +1037,8 @@ void regmap_del_irq_chip(int irq, struct regmap_irq_chip_data *d)
10271037 kfree (d -> config_buf [i ]);
10281038 kfree (d -> config_buf );
10291039 }
1040+ mutex_destroy (& d -> lock );
1041+ lockdep_unregister_key (& d -> lock_key );
10301042 kfree (d );
10311043}
10321044EXPORT_SYMBOL_GPL (regmap_del_irq_chip );
0 commit comments