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 /drivers/of | |
| 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>
Diffstat (limited to 'drivers/of')
| -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); |
