@@ -559,6 +559,9 @@ static void _remove_device_opp(struct device_opp *dev_opp)
559559 if (!list_empty (& dev_opp -> opp_list ))
560560 return ;
561561
562+ if (dev_opp -> supported_hw )
563+ return ;
564+
562565 list_dev = list_first_entry (& dev_opp -> dev_list , struct device_list_opp ,
563566 node );
564567
@@ -833,6 +836,145 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev)
833836 return 0 ;
834837}
835838
839+ /**
840+ * dev_pm_opp_set_supported_hw() - Set supported platforms
841+ * @dev: Device for which supported-hw has to be set.
842+ * @versions: Array of hierarchy of versions to match.
843+ * @count: Number of elements in the array.
844+ *
845+ * This is required only for the V2 bindings, and it enables a platform to
846+ * specify the hierarchy of versions it supports. OPP layer will then enable
847+ * OPPs, which are available for those versions, based on its 'opp-supported-hw'
848+ * property.
849+ *
850+ * Locking: The internal device_opp and opp structures are RCU protected.
851+ * Hence this function internally uses RCU updater strategy with mutex locks
852+ * to keep the integrity of the internal data structures. Callers should ensure
853+ * that this function is *NOT* called under RCU protection or in contexts where
854+ * mutex cannot be locked.
855+ */
856+ int dev_pm_opp_set_supported_hw (struct device * dev , const u32 * versions ,
857+ unsigned int count )
858+ {
859+ struct device_opp * dev_opp ;
860+ int ret = 0 ;
861+
862+ /* Hold our list modification lock here */
863+ mutex_lock (& dev_opp_list_lock );
864+
865+ dev_opp = _add_device_opp (dev );
866+ if (!dev_opp ) {
867+ ret = - ENOMEM ;
868+ goto unlock ;
869+ }
870+
871+ /* Make sure there are no concurrent readers while updating dev_opp */
872+ WARN_ON (!list_empty (& dev_opp -> opp_list ));
873+
874+ /* Do we already have a version hierarchy associated with dev_opp? */
875+ if (dev_opp -> supported_hw ) {
876+ dev_err (dev , "%s: Already have supported hardware list\n" ,
877+ __func__ );
878+ ret = - EBUSY ;
879+ goto err ;
880+ }
881+
882+ dev_opp -> supported_hw = kmemdup (versions , count * sizeof (* versions ),
883+ GFP_KERNEL );
884+ if (!dev_opp -> supported_hw ) {
885+ ret = - ENOMEM ;
886+ goto err ;
887+ }
888+
889+ dev_opp -> supported_hw_count = count ;
890+ mutex_unlock (& dev_opp_list_lock );
891+ return 0 ;
892+
893+ err :
894+ _remove_device_opp (dev_opp );
895+ unlock :
896+ mutex_unlock (& dev_opp_list_lock );
897+
898+ return ret ;
899+ }
900+ EXPORT_SYMBOL_GPL (dev_pm_opp_set_supported_hw );
901+
902+ /**
903+ * dev_pm_opp_put_supported_hw() - Releases resources blocked for supported hw
904+ * @dev: Device for which supported-hw has to be set.
905+ *
906+ * This is required only for the V2 bindings, and is called for a matching
907+ * dev_pm_opp_set_supported_hw(). Until this is called, the device_opp structure
908+ * will not be freed.
909+ *
910+ * Locking: The internal device_opp and opp structures are RCU protected.
911+ * Hence this function internally uses RCU updater strategy with mutex locks
912+ * to keep the integrity of the internal data structures. Callers should ensure
913+ * that this function is *NOT* called under RCU protection or in contexts where
914+ * mutex cannot be locked.
915+ */
916+ void dev_pm_opp_put_supported_hw (struct device * dev )
917+ {
918+ struct device_opp * dev_opp ;
919+
920+ /* Hold our list modification lock here */
921+ mutex_lock (& dev_opp_list_lock );
922+
923+ /* Check for existing list for 'dev' first */
924+ dev_opp = _find_device_opp (dev );
925+ if (IS_ERR (dev_opp )) {
926+ dev_err (dev , "Failed to find dev_opp: %ld\n" , PTR_ERR (dev_opp ));
927+ goto unlock ;
928+ }
929+
930+ /* Make sure there are no concurrent readers while updating dev_opp */
931+ WARN_ON (!list_empty (& dev_opp -> opp_list ));
932+
933+ if (!dev_opp -> supported_hw ) {
934+ dev_err (dev , "%s: Doesn't have supported hardware list\n" ,
935+ __func__ );
936+ goto unlock ;
937+ }
938+
939+ kfree (dev_opp -> supported_hw );
940+ dev_opp -> supported_hw = NULL ;
941+ dev_opp -> supported_hw_count = 0 ;
942+
943+ /* Try freeing device_opp if this was the last blocking resource */
944+ _remove_device_opp (dev_opp );
945+
946+ unlock :
947+ mutex_unlock (& dev_opp_list_lock );
948+ }
949+ EXPORT_SYMBOL_GPL (dev_pm_opp_put_supported_hw );
950+
951+ static bool _opp_is_supported (struct device * dev , struct device_opp * dev_opp ,
952+ struct device_node * np )
953+ {
954+ unsigned int count = dev_opp -> supported_hw_count ;
955+ u32 version ;
956+ int ret ;
957+
958+ if (!dev_opp -> supported_hw )
959+ return true;
960+
961+ while (count -- ) {
962+ ret = of_property_read_u32_index (np , "opp-supported-hw" , count ,
963+ & version );
964+ if (ret ) {
965+ dev_warn (dev , "%s: failed to read opp-supported-hw property at index %d: %d\n" ,
966+ __func__ , count , ret );
967+ return false;
968+ }
969+
970+ /* Both of these are bitwise masks of the versions */
971+ if (!(version & dev_opp -> supported_hw [count ]))
972+ return false;
973+ }
974+
975+ return true;
976+ }
977+
836978/**
837979 * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
838980 * @dev: device for which we do this operation
@@ -879,6 +1021,12 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
8791021 goto free_opp ;
8801022 }
8811023
1024+ /* Check if the OPP supports hardware's hierarchy of versions or not */
1025+ if (!_opp_is_supported (dev , dev_opp , np )) {
1026+ dev_dbg (dev , "OPP not supported by hardware: %llu\n" , rate );
1027+ goto free_opp ;
1028+ }
1029+
8821030 /*
8831031 * Rate is defined as an unsigned long in clk API, and so casting
8841032 * explicitly to its type. Must be fixed once rate is 64 bit
0 commit comments