@@ -578,179 +578,126 @@ static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table,
578578 return false;
579579}
580580
581- static int opp_parse_supplies (struct dev_pm_opp * opp , struct device * dev ,
582- struct opp_table * opp_table )
581+ static u32 * _parse_named_prop (struct dev_pm_opp * opp , struct device * dev ,
582+ struct opp_table * opp_table ,
583+ const char * prop_type , bool * triplet )
583584{
584- u32 * microvolt , * microamp = NULL , * microwatt = NULL ;
585- int supplies = opp_table -> regulator_count ;
586- int vcount , icount , pcount , ret , i , j ;
587585 struct property * prop = NULL ;
588586 char name [NAME_MAX ];
587+ int count , ret ;
588+ u32 * out ;
589589
590- /* Search for "opp-microvolt -<name>" */
590+ /* Search for "opp-<prop_type> -<name>" */
591591 if (opp_table -> prop_name ) {
592- snprintf (name , sizeof (name ), "opp-microvolt -%s" ,
592+ snprintf (name , sizeof (name ), "opp-%s -%s" , prop_type ,
593593 opp_table -> prop_name );
594594 prop = of_find_property (opp -> np , name , NULL );
595595 }
596596
597597 if (!prop ) {
598- /* Search for "opp-microvolt " */
599- sprintf (name , "opp-microvolt" );
598+ /* Search for "opp-<prop_type> " */
599+ snprintf (name , sizeof ( name ), "opp-%s" , prop_type );
600600 prop = of_find_property (opp -> np , name , NULL );
601-
602- /* Missing property isn't a problem, but an invalid entry is */
603- if (!prop ) {
604- if (unlikely (supplies == -1 )) {
605- /* Initialize regulator_count */
606- opp_table -> regulator_count = 0 ;
607- return 0 ;
608- }
609-
610- if (!supplies )
611- return 0 ;
612-
613- dev_err (dev , "%s: opp-microvolt missing although OPP managing regulators\n" ,
614- __func__ );
615- return - EINVAL ;
616- }
617- }
618-
619- if (unlikely (supplies == -1 )) {
620- /* Initialize regulator_count */
621- supplies = opp_table -> regulator_count = 1 ;
622- } else if (unlikely (!supplies )) {
623- dev_err (dev , "%s: opp-microvolt wasn't expected\n" , __func__ );
624- return - EINVAL ;
601+ if (!prop )
602+ return NULL ;
625603 }
626604
627- vcount = of_property_count_u32_elems (opp -> np , name );
628- if (vcount < 0 ) {
629- dev_err (dev , "%s: Invalid %s property (%d)\n" ,
630- __func__ , name , vcount );
631- return vcount ;
605+ count = of_property_count_u32_elems (opp -> np , name );
606+ if (count < 0 ) {
607+ dev_err (dev , "%s: Invalid %s property (%d)\n" , __func__ , name ,
608+ count );
609+ return ERR_PTR ( count ) ;
632610 }
633611
634- /* There can be one or three elements per supply */
635- if (vcount != supplies && vcount != supplies * 3 ) {
636- dev_err (dev , "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n" ,
637- __func__ , name , vcount , supplies );
638- return - EINVAL ;
612+ /*
613+ * Initialize regulator_count, if regulator information isn't provided
614+ * by the platform. Now that one of the properties is available, fix the
615+ * regulator_count to 1.
616+ */
617+ if (unlikely (opp_table -> regulator_count == -1 ))
618+ opp_table -> regulator_count = 1 ;
619+
620+ if (count != opp_table -> regulator_count &&
621+ (!triplet || count != opp_table -> regulator_count * 3 )) {
622+ dev_err (dev , "%s: Invalid number of elements in %s property (%u) with supplies (%d)\n" ,
623+ __func__ , prop_type , count , opp_table -> regulator_count );
624+ return ERR_PTR (- EINVAL );
639625 }
640626
641- microvolt = kmalloc_array (vcount , sizeof (* microvolt ), GFP_KERNEL );
642- if (!microvolt )
643- return - ENOMEM ;
627+ out = kmalloc_array (count , sizeof (* out ), GFP_KERNEL );
628+ if (!out )
629+ return ERR_PTR ( - EINVAL ) ;
644630
645- ret = of_property_read_u32_array (opp -> np , name , microvolt , vcount );
631+ ret = of_property_read_u32_array (opp -> np , name , out , count );
646632 if (ret ) {
647633 dev_err (dev , "%s: error parsing %s: %d\n" , __func__ , name , ret );
648- ret = - EINVAL ;
649- goto free_microvolt ;
634+ kfree ( out ) ;
635+ return ERR_PTR ( - EINVAL ) ;
650636 }
651637
652- /* Search for "opp-microamp-<name>" */
653- prop = NULL ;
654- if (opp_table -> prop_name ) {
655- snprintf (name , sizeof (name ), "opp-microamp-%s" ,
656- opp_table -> prop_name );
657- prop = of_find_property (opp -> np , name , NULL );
658- }
638+ if (triplet )
639+ * triplet = count != opp_table -> regulator_count ;
659640
660- if (!prop ) {
661- /* Search for "opp-microamp" */
662- sprintf (name , "opp-microamp" );
663- prop = of_find_property (opp -> np , name , NULL );
664- }
665-
666- if (prop ) {
667- icount = of_property_count_u32_elems (opp -> np , name );
668- if (icount < 0 ) {
669- dev_err (dev , "%s: Invalid %s property (%d)\n" , __func__ ,
670- name , icount );
671- ret = icount ;
672- goto free_microvolt ;
673- }
641+ return out ;
642+ }
674643
675- if (icount != supplies ) {
676- dev_err (dev , "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n" ,
677- __func__ , name , icount , supplies );
678- ret = - EINVAL ;
679- goto free_microvolt ;
680- }
644+ static u32 * opp_parse_microvolt (struct dev_pm_opp * opp , struct device * dev ,
645+ struct opp_table * opp_table , bool * triplet )
646+ {
647+ u32 * microvolt ;
681648
682- microamp = kmalloc_array (icount , sizeof (* microamp ), GFP_KERNEL );
683- if (!microamp ) {
684- ret = - EINVAL ;
685- goto free_microvolt ;
686- }
649+ microvolt = _parse_named_prop (opp , dev , opp_table , "microvolt" , triplet );
650+ if (IS_ERR (microvolt ))
651+ return microvolt ;
687652
688- ret = of_property_read_u32_array (opp -> np , name , microamp ,
689- icount );
690- if (ret ) {
691- dev_err (dev , "%s: error parsing %s: %d\n" , __func__ ,
692- name , ret );
693- ret = - EINVAL ;
694- goto free_microamp ;
653+ if (!microvolt ) {
654+ /*
655+ * Missing property isn't a problem, but an invalid
656+ * entry is. This property isn't optional if regulator
657+ * information is provided.
658+ */
659+ if (opp_table -> regulator_count > 0 ) {
660+ dev_err (dev , "%s: opp-microvolt missing although OPP managing regulators\n" ,
661+ __func__ );
662+ return ERR_PTR (- EINVAL );
695663 }
696664 }
697665
698- /* Search for "opp-microwatt-<name>" */
699- prop = NULL ;
700- if (opp_table -> prop_name ) {
701- snprintf (name , sizeof (name ), "opp-microwatt-%s" ,
702- opp_table -> prop_name );
703- prop = of_find_property (opp -> np , name , NULL );
704- }
705-
706- if (!prop ) {
707- /* Search for "opp-microwatt" */
708- sprintf (name , "opp-microwatt" );
709- prop = of_find_property (opp -> np , name , NULL );
710- }
666+ return microvolt ;
667+ }
711668
712- if (prop ) {
713- pcount = of_property_count_u32_elems (opp -> np , name );
714- if (pcount < 0 ) {
715- dev_err (dev , "%s: Invalid %s property (%d)\n" , __func__ ,
716- name , pcount );
717- ret = pcount ;
718- goto free_microamp ;
719- }
669+ static int opp_parse_supplies (struct dev_pm_opp * opp , struct device * dev ,
670+ struct opp_table * opp_table )
671+ {
672+ u32 * microvolt , * microamp , * microwatt ;
673+ int ret = 0 , i , j ;
674+ bool triplet ;
720675
721- if (pcount != supplies ) {
722- dev_err (dev , "%s: Invalid number of elements in %s property (%d) with supplies (%d)\n" ,
723- __func__ , name , pcount , supplies );
724- ret = - EINVAL ;
725- goto free_microamp ;
726- }
676+ microvolt = opp_parse_microvolt (opp , dev , opp_table , & triplet );
677+ if (IS_ERR_OR_NULL (microvolt ))
678+ return PTR_ERR (microvolt );
727679
728- microwatt = kmalloc_array (pcount , sizeof (* microwatt ),
729- GFP_KERNEL );
730- if (!microwatt ) {
731- ret = - EINVAL ;
732- goto free_microamp ;
733- }
680+ microamp = _parse_named_prop (opp , dev , opp_table , "microamp" , NULL );
681+ if (IS_ERR (microamp )) {
682+ ret = PTR_ERR (microamp );
683+ goto free_microvolt ;
684+ }
734685
735- ret = of_property_read_u32_array (opp -> np , name , microwatt ,
736- pcount );
737- if (ret ) {
738- dev_err (dev , "%s: error parsing %s: %d\n" , __func__ ,
739- name , ret );
740- ret = - EINVAL ;
741- goto free_microwatt ;
742- }
686+ microwatt = _parse_named_prop (opp , dev , opp_table , "microwatt" , NULL );
687+ if (IS_ERR (microwatt )) {
688+ ret = PTR_ERR (microwatt );
689+ goto free_microamp ;
743690 }
744691
745- for (i = 0 , j = 0 ; i < supplies ; i ++ ) {
692+ for (i = 0 , j = 0 ; i < opp_table -> regulator_count ; i ++ ) {
746693 opp -> supplies [i ].u_volt = microvolt [j ++ ];
747694
748- if (vcount == supplies ) {
749- opp -> supplies [i ].u_volt_min = opp -> supplies [i ].u_volt ;
750- opp -> supplies [i ].u_volt_max = opp -> supplies [i ].u_volt ;
751- } else {
695+ if (triplet ) {
752696 opp -> supplies [i ].u_volt_min = microvolt [j ++ ];
753697 opp -> supplies [i ].u_volt_max = microvolt [j ++ ];
698+ } else {
699+ opp -> supplies [i ].u_volt_min = opp -> supplies [i ].u_volt ;
700+ opp -> supplies [i ].u_volt_max = opp -> supplies [i ].u_volt ;
754701 }
755702
756703 if (microamp )
@@ -760,7 +707,6 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
760707 opp -> supplies [i ].u_watt = microwatt [i ];
761708 }
762709
763- free_microwatt :
764710 kfree (microwatt );
765711free_microamp :
766712 kfree (microamp );
0 commit comments