aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/opp/core.c
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2015-12-08 21:31:47 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-12-10 17:08:51 -0500
commit01fb4d3c39d35b725441e8a9a26b3f3ad67793ed (patch)
treeb19abc542391b4c9d0e0280b1cc6064a43030572 /drivers/base/power/opp/core.c
parent7de36b0aa51a5a59e28fb2da768fa3ab07de0674 (diff)
PM / OPP: Parse 'opp-<prop>-<name>' bindings
OPP bindings (for few properties) allow a platform to choose a value/range among a set of available options. The options are present as opp-<prop>-<name>, where the platform needs to supply the <name> string. The OPP properties which allow such an option are: opp-microvolt and opp-microamp. Add support to the OPP-core to parse these bindings, by introducing dev_pm_opp_{set|put}_prop_name() APIs. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Tested-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power/opp/core.c')
-rw-r--r--drivers/base/power/opp/core.c165
1 files changed, 150 insertions, 15 deletions
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
index 55cf1a99b532..5c01fec1ed14 100644
--- a/drivers/base/power/opp/core.c
+++ b/drivers/base/power/opp/core.c
@@ -562,6 +562,9 @@ static void _remove_device_opp(struct device_opp *dev_opp)
562 if (dev_opp->supported_hw) 562 if (dev_opp->supported_hw)
563 return; 563 return;
564 564
565 if (dev_opp->prop_name)
566 return;
567
565 list_dev = list_first_entry(&dev_opp->dev_list, struct device_list_opp, 568 list_dev = list_first_entry(&dev_opp->dev_list, struct device_list_opp,
566 node); 569 node);
567 570
@@ -794,35 +797,48 @@ unlock:
794} 797}
795 798
796/* TODO: Support multiple regulators */ 799/* TODO: Support multiple regulators */
797static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev) 800static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev,
801 struct device_opp *dev_opp)
798{ 802{
799 u32 microvolt[3] = {0}; 803 u32 microvolt[3] = {0};
800 u32 val; 804 u32 val;
801 int count, ret; 805 int count, ret;
806 struct property *prop = NULL;
807 char name[NAME_MAX];
808
809 /* Search for "opp-microvolt-<name>" */
810 if (dev_opp->prop_name) {
811 sprintf(name, "opp-microvolt-%s", dev_opp->prop_name);
812 prop = of_find_property(opp->np, name, NULL);
813 }
814
815 if (!prop) {
816 /* Search for "opp-microvolt" */
817 name[13] = '\0';
818 prop = of_find_property(opp->np, name, NULL);
802 819
803 /* Missing property isn't a problem, but an invalid entry is */ 820 /* Missing property isn't a problem, but an invalid entry is */
804 if (!of_find_property(opp->np, "opp-microvolt", NULL)) 821 if (!prop)
805 return 0; 822 return 0;
823 }
806 824
807 count = of_property_count_u32_elems(opp->np, "opp-microvolt"); 825 count = of_property_count_u32_elems(opp->np, name);
808 if (count < 0) { 826 if (count < 0) {
809 dev_err(dev, "%s: Invalid opp-microvolt property (%d)\n", 827 dev_err(dev, "%s: Invalid %s property (%d)\n",
810 __func__, count); 828 __func__, name, count);
811 return count; 829 return count;
812 } 830 }
813 831
814 /* There can be one or three elements here */ 832 /* There can be one or three elements here */
815 if (count != 1 && count != 3) { 833 if (count != 1 && count != 3) {
816 dev_err(dev, "%s: Invalid number of elements in opp-microvolt property (%d)\n", 834 dev_err(dev, "%s: Invalid number of elements in %s property (%d)\n",
817 __func__, count); 835 __func__, name, count);
818 return -EINVAL; 836 return -EINVAL;
819 } 837 }
820 838
821 ret = of_property_read_u32_array(opp->np, "opp-microvolt", microvolt, 839 ret = of_property_read_u32_array(opp->np, name, microvolt, count);
822 count);
823 if (ret) { 840 if (ret) {
824 dev_err(dev, "%s: error parsing opp-microvolt: %d\n", __func__, 841 dev_err(dev, "%s: error parsing %s: %d\n", __func__, name, ret);
825 ret);
826 return -EINVAL; 842 return -EINVAL;
827 } 843 }
828 844
@@ -830,7 +846,20 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev)
830 opp->u_volt_min = microvolt[1]; 846 opp->u_volt_min = microvolt[1];
831 opp->u_volt_max = microvolt[2]; 847 opp->u_volt_max = microvolt[2];
832 848
833 if (!of_property_read_u32(opp->np, "opp-microamp", &val)) 849 /* Search for "opp-microamp-<name>" */
850 prop = NULL;
851 if (dev_opp->prop_name) {
852 sprintf(name, "opp-microamp-%s", dev_opp->prop_name);
853 prop = of_find_property(opp->np, name, NULL);
854 }
855
856 if (!prop) {
857 /* Search for "opp-microamp" */
858 name[12] = '\0';
859 prop = of_find_property(opp->np, name, NULL);
860 }
861
862 if (prop && !of_property_read_u32(opp->np, name, &val))
834 opp->u_amp = val; 863 opp->u_amp = val;
835 864
836 return 0; 865 return 0;
@@ -948,6 +977,112 @@ unlock:
948} 977}
949EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw); 978EXPORT_SYMBOL_GPL(dev_pm_opp_put_supported_hw);
950 979
980/**
981 * dev_pm_opp_set_prop_name() - Set prop-extn name
982 * @dev: Device for which the regulator has to be set.
983 * @name: name to postfix to properties.
984 *
985 * This is required only for the V2 bindings, and it enables a platform to
986 * specify the extn to be used for certain property names. The properties to
987 * which the extension will apply are opp-microvolt and opp-microamp. OPP core
988 * should postfix the property name with -<name> while looking for them.
989 *
990 * Locking: The internal device_opp and opp structures are RCU protected.
991 * Hence this function internally uses RCU updater strategy with mutex locks
992 * to keep the integrity of the internal data structures. Callers should ensure
993 * that this function is *NOT* called under RCU protection or in contexts where
994 * mutex cannot be locked.
995 */
996int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
997{
998 struct device_opp *dev_opp;
999 int ret = 0;
1000
1001 /* Hold our list modification lock here */
1002 mutex_lock(&dev_opp_list_lock);
1003
1004 dev_opp = _add_device_opp(dev);
1005 if (!dev_opp) {
1006 ret = -ENOMEM;
1007 goto unlock;
1008 }
1009
1010 /* Make sure there are no concurrent readers while updating dev_opp */
1011 WARN_ON(!list_empty(&dev_opp->opp_list));
1012
1013 /* Do we already have a prop-name associated with dev_opp? */
1014 if (dev_opp->prop_name) {
1015 dev_err(dev, "%s: Already have prop-name %s\n", __func__,
1016 dev_opp->prop_name);
1017 ret = -EBUSY;
1018 goto err;
1019 }
1020
1021 dev_opp->prop_name = kstrdup(name, GFP_KERNEL);
1022 if (!dev_opp->prop_name) {
1023 ret = -ENOMEM;
1024 goto err;
1025 }
1026
1027 mutex_unlock(&dev_opp_list_lock);
1028 return 0;
1029
1030err:
1031 _remove_device_opp(dev_opp);
1032unlock:
1033 mutex_unlock(&dev_opp_list_lock);
1034
1035 return ret;
1036}
1037EXPORT_SYMBOL_GPL(dev_pm_opp_set_prop_name);
1038
1039/**
1040 * dev_pm_opp_put_prop_name() - Releases resources blocked for prop-name
1041 * @dev: Device for which the regulator has to be set.
1042 *
1043 * This is required only for the V2 bindings, and is called for a matching
1044 * dev_pm_opp_set_prop_name(). Until this is called, the device_opp structure
1045 * will not be freed.
1046 *
1047 * Locking: The internal device_opp and opp structures are RCU protected.
1048 * Hence this function internally uses RCU updater strategy with mutex locks
1049 * to keep the integrity of the internal data structures. Callers should ensure
1050 * that this function is *NOT* called under RCU protection or in contexts where
1051 * mutex cannot be locked.
1052 */
1053void dev_pm_opp_put_prop_name(struct device *dev)
1054{
1055 struct device_opp *dev_opp;
1056
1057 /* Hold our list modification lock here */
1058 mutex_lock(&dev_opp_list_lock);
1059
1060 /* Check for existing list for 'dev' first */
1061 dev_opp = _find_device_opp(dev);
1062 if (IS_ERR(dev_opp)) {
1063 dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp));
1064 goto unlock;
1065 }
1066
1067 /* Make sure there are no concurrent readers while updating dev_opp */
1068 WARN_ON(!list_empty(&dev_opp->opp_list));
1069
1070 if (!dev_opp->prop_name) {
1071 dev_err(dev, "%s: Doesn't have a prop-name\n", __func__);
1072 goto unlock;
1073 }
1074
1075 kfree(dev_opp->prop_name);
1076 dev_opp->prop_name = NULL;
1077
1078 /* Try freeing device_opp if this was the last blocking resource */
1079 _remove_device_opp(dev_opp);
1080
1081unlock:
1082 mutex_unlock(&dev_opp_list_lock);
1083}
1084EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
1085
951static bool _opp_is_supported(struct device *dev, struct device_opp *dev_opp, 1086static bool _opp_is_supported(struct device *dev, struct device_opp *dev_opp,
952 struct device_node *np) 1087 struct device_node *np)
953{ 1088{
@@ -1042,7 +1177,7 @@ static int _opp_add_static_v2(struct device *dev, struct device_node *np)
1042 if (!of_property_read_u32(np, "clock-latency-ns", &val)) 1177 if (!of_property_read_u32(np, "clock-latency-ns", &val))
1043 new_opp->clock_latency_ns = val; 1178 new_opp->clock_latency_ns = val;
1044 1179
1045 ret = opp_parse_supplies(new_opp, dev); 1180 ret = opp_parse_supplies(new_opp, dev, dev_opp);
1046 if (ret) 1181 if (ret)
1047 goto free_opp; 1182 goto free_opp;
1048 1183