aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Prisk <linux@prisktech.co.nz>2013-04-03 00:57:11 -0400
committerTony Prisk <linux@prisktech.co.nz>2013-04-04 00:59:18 -0400
commitdaeec1f083e02c9ee235e29d2cb28d7b9e81d899 (patch)
tree1b0ad81b8cf846513ba03536d855e6d9183cac64
parent3daf37260e965aa4bb060db99c2ed10b28109e04 (diff)
of: Remove duplicated code for validating property and value
Several functions in of/base.c have the same code duplicated for finding and validating a property and value. struct property *prop = of_find_property(np, propname, NULL); if (!prop) return -EINVAL; if (!prop->value) return -ENODATA; if (<some length> > prop->length) return -EOVERFLOW; This patch adds of_find_property_value_of_size() which performs the equivalent of the above code and removes the instances where it was duplicated in several functions. Reported-by: Rob Herring <robherring2@gmail.com> Signed-off-by: Tony Prisk <linux@prisktech.co.nz> Acked-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Rob Herring <rob.herring@calxeda.com>
-rw-r--r--drivers/of/base.c94
1 files changed, 51 insertions, 43 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f6c89ed38db9..c6443de58fb0 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -746,6 +746,34 @@ struct device_node *of_find_node_by_phandle(phandle handle)
746EXPORT_SYMBOL(of_find_node_by_phandle); 746EXPORT_SYMBOL(of_find_node_by_phandle);
747 747
748/** 748/**
749 * of_find_property_value_of_size
750 *
751 * @np: device node from which the property value is to be read.
752 * @propname: name of the property to be searched.
753 * @len: requested length of property value
754 *
755 * Search for a property in a device node and valid the requested size.
756 * Returns the property value on success, -EINVAL if the property does not
757 * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the
758 * property data isn't large enough.
759 *
760 */
761static void *of_find_property_value_of_size(const struct device_node *np,
762 const char *propname, u32 len)
763{
764 struct property *prop = of_find_property(np, propname, NULL);
765
766 if (!prop)
767 return ERR_PTR(-EINVAL);
768 if (!prop->value)
769 return ERR_PTR(-ENODATA);
770 if (len > prop->length)
771 return ERR_PTR(-EOVERFLOW);
772
773 return prop->value;
774}
775
776/**
749 * of_property_read_u32_index - Find and read a u32 from a multi-value property. 777 * of_property_read_u32_index - Find and read a u32 from a multi-value property.
750 * 778 *
751 * @np: device node from which the property value is to be read. 779 * @np: device node from which the property value is to be read.
@@ -764,16 +792,13 @@ int of_property_read_u32_index(const struct device_node *np,
764 const char *propname, 792 const char *propname,
765 u32 index, u32 *out_value) 793 u32 index, u32 *out_value)
766{ 794{
767 struct property *prop = of_find_property(np, propname, NULL); 795 const u32 *val = of_find_property_value_of_size(np, propname,
796 ((index + 1) * sizeof(*out_value)));
768 797
769 if (!prop) 798 if (IS_ERR(val))
770 return -EINVAL; 799 return PTR_ERR(val);
771 if (!prop->value)
772 return -ENODATA;
773 if (((index + 1) * sizeof(*out_value)) > prop->length)
774 return -EOVERFLOW;
775 800
776 *out_value = be32_to_cpup(((__be32 *)prop->value) + index); 801 *out_value = be32_to_cpup(((__be32 *)val) + index);
777 return 0; 802 return 0;
778} 803}
779EXPORT_SYMBOL_GPL(of_property_read_u32_index); 804EXPORT_SYMBOL_GPL(of_property_read_u32_index);
@@ -799,17 +824,12 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
799int of_property_read_u8_array(const struct device_node *np, 824int of_property_read_u8_array(const struct device_node *np,
800 const char *propname, u8 *out_values, size_t sz) 825 const char *propname, u8 *out_values, size_t sz)
801{ 826{
802 struct property *prop = of_find_property(np, propname, NULL); 827 const u8 *val = of_find_property_value_of_size(np, propname,
803 const u8 *val; 828 (sz * sizeof(*out_values)));
804 829
805 if (!prop) 830 if (IS_ERR(val))
806 return -EINVAL; 831 return PTR_ERR(val);
807 if (!prop->value)
808 return -ENODATA;
809 if ((sz * sizeof(*out_values)) > prop->length)
810 return -EOVERFLOW;
811 832
812 val = prop->value;
813 while (sz--) 833 while (sz--)
814 *out_values++ = *val++; 834 *out_values++ = *val++;
815 return 0; 835 return 0;
@@ -837,17 +857,12 @@ EXPORT_SYMBOL_GPL(of_property_read_u8_array);
837int of_property_read_u16_array(const struct device_node *np, 857int of_property_read_u16_array(const struct device_node *np,
838 const char *propname, u16 *out_values, size_t sz) 858 const char *propname, u16 *out_values, size_t sz)
839{ 859{
840 struct property *prop = of_find_property(np, propname, NULL); 860 const __be16 *val = of_find_property_value_of_size(np, propname,
841 const __be16 *val; 861 (sz * sizeof(*out_values)));
842 862
843 if (!prop) 863 if (IS_ERR(val))
844 return -EINVAL; 864 return PTR_ERR(val);
845 if (!prop->value)
846 return -ENODATA;
847 if ((sz * sizeof(*out_values)) > prop->length)
848 return -EOVERFLOW;
849 865
850 val = prop->value;
851 while (sz--) 866 while (sz--)
852 *out_values++ = be16_to_cpup(val++); 867 *out_values++ = be16_to_cpup(val++);
853 return 0; 868 return 0;
@@ -874,17 +889,12 @@ int of_property_read_u32_array(const struct device_node *np,
874 const char *propname, u32 *out_values, 889 const char *propname, u32 *out_values,
875 size_t sz) 890 size_t sz)
876{ 891{
877 struct property *prop = of_find_property(np, propname, NULL); 892 const __be32 *val = of_find_property_value_of_size(np, propname,
878 const __be32 *val; 893 (sz * sizeof(*out_values)));
879 894
880 if (!prop) 895 if (IS_ERR(val))
881 return -EINVAL; 896 return PTR_ERR(val);
882 if (!prop->value)
883 return -ENODATA;
884 if ((sz * sizeof(*out_values)) > prop->length)
885 return -EOVERFLOW;
886 897
887 val = prop->value;
888 while (sz--) 898 while (sz--)
889 *out_values++ = be32_to_cpup(val++); 899 *out_values++ = be32_to_cpup(val++);
890 return 0; 900 return 0;
@@ -907,15 +917,13 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_array);
907int of_property_read_u64(const struct device_node *np, const char *propname, 917int of_property_read_u64(const struct device_node *np, const char *propname,
908 u64 *out_value) 918 u64 *out_value)
909{ 919{
910 struct property *prop = of_find_property(np, propname, NULL); 920 const __be32 *val = of_find_property_value_of_size(np, propname,
921 sizeof(*out_value));
911 922
912 if (!prop) 923 if (IS_ERR(val))
913 return -EINVAL; 924 return PTR_ERR(val);
914 if (!prop->value) 925
915 return -ENODATA; 926 *out_value = of_read_number(val, 2);
916 if (sizeof(*out_value) > prop->length)
917 return -EOVERFLOW;
918 *out_value = of_read_number(prop->value, 2);
919 return 0; 927 return 0;
920} 928}
921EXPORT_SYMBOL_GPL(of_property_read_u64); 929EXPORT_SYMBOL_GPL(of_property_read_u64);