5
5
/*
6
6
* This version of the "BD86801 scalable PMIC"'s driver supports only very
7
7
* basic set of the PMIC features. Most notably, there is no support for
8
- * the ERRB interrupt and the configurations which should be done when the
9
- * PMIC is in STBY mode.
10
- *
11
- * Supporting the ERRB interrupt would require dropping the regmap-IRQ
12
- * usage or working around (or accepting a presense of) a naming conflict
13
- * in debugFS IRQs.
8
+ * the configurations which should be done when the PMIC is in STBY mode.
14
9
*
15
10
* Being able to reliably do the configurations like changing the
16
11
* regulator safety limits (like limits for the over/under -voltages, over
22
17
* be the need to configure these safety limits. Hence it's not simple to
23
18
* come up with a generic solution.
24
19
*
25
- * Users who require the ERRB handling and STBY state configurations can
26
- * have a look at the original RFC:
20
+ * Users who require the STBY state configurations can have a look at the
21
+ * original RFC:
27
22
* https://lore.kernel.org/all/[email protected] /
28
- * which implements a workaround to debugFS naming conflict and some of
29
- * the safety limit configurations - but leaves the state change handling
30
- * and synchronization to be implemented.
23
+ * which implements some of the safety limit configurations - but leaves the
24
+ * state change handling and synchronization to be implemented.
31
25
*
32
26
* It would be great to hear (and receive a patch!) if you implement the
33
- * STBY configuration support or a proper fix to the debugFS naming
34
- * conflict in your downstream driver ;)
27
+ * STBY configuration support in your downstream driver ;)
35
28
*/
36
29
37
30
#include <linux/cleanup.h>
@@ -728,6 +721,95 @@ static int initialize_pmic_data(struct device *dev,
728
721
return 0 ;
729
722
}
730
723
724
+ static int bd96801_map_event_all (int irq , struct regulator_irq_data * rid ,
725
+ unsigned long * dev_mask )
726
+ {
727
+ int i ;
728
+
729
+ for (i = 0 ; i < rid -> num_states ; i ++ ) {
730
+ rid -> states [i ].notifs = REGULATOR_EVENT_FAIL ;
731
+ rid -> states [i ].errors = REGULATOR_ERROR_FAIL ;
732
+ * dev_mask |= BIT (i );
733
+ }
734
+
735
+ return 0 ;
736
+ }
737
+
738
+ static int bd96801_rdev_errb_irqs (struct platform_device * pdev ,
739
+ struct regulator_dev * rdev )
740
+ {
741
+ int i ;
742
+ void * retp ;
743
+ static const char * const single_out_errb_irqs [] = {
744
+ "bd96801-%s-pvin-err" , "bd96801-%s-ovp-err" ,
745
+ "bd96801-%s-uvp-err" , "bd96801-%s-shdn-err" ,
746
+ };
747
+
748
+ for (i = 0 ; i < ARRAY_SIZE (single_out_errb_irqs ); i ++ ) {
749
+ struct regulator_irq_desc id = {
750
+ .map_event = bd96801_map_event_all ,
751
+ .irq_off_ms = 1000 ,
752
+ };
753
+ struct regulator_dev * rdev_arr [1 ];
754
+ char tmp [255 ];
755
+ int irq ;
756
+
757
+ snprintf (tmp , 255 , single_out_errb_irqs [i ], rdev -> desc -> name );
758
+ tmp [254 ] = 0 ;
759
+ id .name = tmp ;
760
+
761
+ irq = platform_get_irq_byname (pdev , tmp );
762
+ if (irq < 0 )
763
+ continue ;
764
+
765
+ rdev_arr [0 ] = rdev ;
766
+ retp = devm_regulator_irq_helper (& pdev -> dev , & id , irq , 0 ,
767
+ REGULATOR_ERROR_FAIL , NULL ,
768
+ rdev_arr , 1 );
769
+ if (IS_ERR (retp ))
770
+ return PTR_ERR (retp );
771
+
772
+ }
773
+ return 0 ;
774
+ }
775
+
776
+ static int bd96801_global_errb_irqs (struct platform_device * pdev ,
777
+ struct regulator_dev * * rdev , int num_rdev )
778
+ {
779
+ int i , num_irqs ;
780
+ void * retp ;
781
+ static const char * const global_errb_irqs [] = {
782
+ "bd96801-otp-err" , "bd96801-dbist-err" , "bd96801-eep-err" ,
783
+ "bd96801-abist-err" , "bd96801-prstb-err" , "bd96801-drmoserr1" ,
784
+ "bd96801-drmoserr2" , "bd96801-slave-err" , "bd96801-vref-err" ,
785
+ "bd96801-tsd" , "bd96801-uvlo-err" , "bd96801-ovlo-err" ,
786
+ "bd96801-osc-err" , "bd96801-pon-err" , "bd96801-poff-err" ,
787
+ "bd96801-cmd-shdn-err" , "bd96801-int-shdn-err"
788
+ };
789
+
790
+ num_irqs = ARRAY_SIZE (global_errb_irqs );
791
+ for (i = 0 ; i < num_irqs ; i ++ ) {
792
+ int irq ;
793
+ struct regulator_irq_desc id = {
794
+ .name = global_errb_irqs [i ],
795
+ .map_event = bd96801_map_event_all ,
796
+ .irq_off_ms = 1000 ,
797
+ };
798
+
799
+ irq = platform_get_irq_byname (pdev , global_errb_irqs [i ]);
800
+ if (irq < 0 )
801
+ continue ;
802
+
803
+ retp = devm_regulator_irq_helper (& pdev -> dev , & id , irq , 0 ,
804
+ REGULATOR_ERROR_FAIL , NULL ,
805
+ rdev , num_rdev );
806
+ if (IS_ERR (retp ))
807
+ return PTR_ERR (retp );
808
+ }
809
+
810
+ return 0 ;
811
+ }
812
+
731
813
static int bd96801_rdev_intb_irqs (struct platform_device * pdev ,
732
814
struct bd96801_pmic_data * pdata ,
733
815
struct bd96801_irqinfo * iinfo ,
@@ -783,18 +865,18 @@ static int bd96801_rdev_intb_irqs(struct platform_device *pdev,
783
865
return 0 ;
784
866
}
785
867
786
-
787
-
788
868
static int bd96801_probe (struct platform_device * pdev )
789
869
{
790
870
struct regulator_dev * ldo_errs_rdev_arr [BD96801_NUM_LDOS ];
871
+ struct regulator_dev * all_rdevs [BD96801_NUM_REGULATORS ];
791
872
struct bd96801_regulator_data * rdesc ;
792
873
struct regulator_config config = {};
793
874
int ldo_errs_arr [BD96801_NUM_LDOS ];
794
875
struct bd96801_pmic_data * pdata ;
795
876
int temp_notif_ldos = 0 ;
796
877
struct device * parent ;
797
878
int i , ret ;
879
+ bool use_errb ;
798
880
void * retp ;
799
881
800
882
parent = pdev -> dev .parent ;
@@ -819,6 +901,13 @@ static int bd96801_probe(struct platform_device *pdev)
819
901
config .regmap = pdata -> regmap ;
820
902
config .dev = parent ;
821
903
904
+ ret = of_property_match_string (pdev -> dev .parent -> of_node ,
905
+ "interrupt-names" , "errb" );
906
+ if (ret < 0 )
907
+ use_errb = false;
908
+ else
909
+ use_errb = true;
910
+
822
911
ret = bd96801_walk_regulator_dt (& pdev -> dev , pdata -> regmap , rdesc ,
823
912
BD96801_NUM_REGULATORS );
824
913
if (ret )
@@ -837,6 +926,7 @@ static int bd96801_probe(struct platform_device *pdev)
837
926
rdesc [i ].desc .name );
838
927
return PTR_ERR (rdev );
839
928
}
929
+ all_rdevs [i ] = rdev ;
840
930
/*
841
931
* LDOs don't have own temperature monitoring. If temperature
842
932
* notification was requested for this LDO from DT then we will
@@ -856,6 +946,12 @@ static int bd96801_probe(struct platform_device *pdev)
856
946
if (ret )
857
947
return ret ;
858
948
}
949
+ /* Register per regulator ERRB notifiers */
950
+ if (use_errb ) {
951
+ ret = bd96801_rdev_errb_irqs (pdev , rdev );
952
+ if (ret )
953
+ return ret ;
954
+ }
859
955
}
860
956
if (temp_notif_ldos ) {
861
957
int irq ;
@@ -877,6 +973,10 @@ static int bd96801_probe(struct platform_device *pdev)
877
973
return PTR_ERR (retp );
878
974
}
879
975
976
+ if (use_errb )
977
+ return bd96801_global_errb_irqs (pdev , all_rdevs ,
978
+ ARRAY_SIZE (all_rdevs ));
979
+
880
980
return 0 ;
881
981
}
882
982
0 commit comments