diff options
author | Tony Prisk <linux@prisktech.co.nz> | 2013-04-03 00:57:11 -0400 |
---|---|---|
committer | Tony Prisk <linux@prisktech.co.nz> | 2013-04-04 00:59:18 -0400 |
commit | daeec1f083e02c9ee235e29d2cb28d7b9e81d899 (patch) | |
tree | 1b0ad81b8cf846513ba03536d855e6d9183cac64 | |
parent | 3daf37260e965aa4bb060db99c2ed10b28109e04 (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.c | 94 |
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) | |||
746 | EXPORT_SYMBOL(of_find_node_by_phandle); | 746 | EXPORT_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 | */ | ||
761 | static 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 | } |
779 | EXPORT_SYMBOL_GPL(of_property_read_u32_index); | 804 | EXPORT_SYMBOL_GPL(of_property_read_u32_index); |
@@ -799,17 +824,12 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index); | |||
799 | int of_property_read_u8_array(const struct device_node *np, | 824 | int 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); | |||
837 | int of_property_read_u16_array(const struct device_node *np, | 857 | int 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); | |||
907 | int of_property_read_u64(const struct device_node *np, const char *propname, | 917 | int 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 | } |
921 | EXPORT_SYMBOL_GPL(of_property_read_u64); | 929 | EXPORT_SYMBOL_GPL(of_property_read_u64); |