diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-07 15:15:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-07 15:15:36 -0500 |
commit | fbce1c234feedb5270468aa4b1770c1cab58a960 (patch) | |
tree | 7391d7bcce50eab43c750c4055b056ab1892d6b2 /drivers/of | |
parent | 7affca3537d74365128e477b40c529d6f2fe86c8 (diff) | |
parent | d0ad5e89256c351ddd40167152c24a88efcb0f6d (diff) |
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6
Changes queued in gpio/next for the start of the 3.3 merge window
* tag 'gpio-for-linus-20120104' of git://git.secretlab.ca/git/linux-2.6:
gpio: Add decode of WM8994 GPIO configuration
gpio: Convert GPIO drivers to module_platform_driver
gpio: Fix typo in comment in Samsung driver
gpio: Explicitly index samsung_gpio_cfgs
gpio: Add Linus Walleij as gpio co-maintainer
of: Add device tree selftests
of: create of_phandle_args to simplify return of phandle parsing data
gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()
gpio/microblaze: Eliminate duplication of of_get_named_gpio_flags()
gpiolib: output basic details and consolidate gpio device drivers
pch_gpio: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor
pch_gpio: Support new device LAPIS Semiconductor ML7831 IOH
spi/pl022: make the chip deselect handling thread safe
spi/pl022: add support for pm_runtime autosuspend
spi/pl022: disable the PL022 block when unused
spi/pl022: move device disable to workqueue thread
spi/pl022: skip default configuration before suspending
spi/pl022: fix build warnings
spi/pl022: only enable RX interrupts when TX is complete
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/Kconfig | 9 | ||||
-rw-r--r-- | drivers/of/Makefile | 1 | ||||
-rw-r--r-- | drivers/of/base.c | 146 | ||||
-rw-r--r-- | drivers/of/gpio.c | 45 | ||||
-rw-r--r-- | drivers/of/selftest.c | 139 |
5 files changed, 243 insertions, 97 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index cac63c9f49ae..268163dd71c7 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -15,6 +15,15 @@ config PROC_DEVICETREE | |||
15 | an image of the device tree that the kernel copies from Open | 15 | an image of the device tree that the kernel copies from Open |
16 | Firmware or other boot firmware. If unsure, say Y here. | 16 | Firmware or other boot firmware. If unsure, say Y here. |
17 | 17 | ||
18 | config OF_SELFTEST | ||
19 | bool "Device Tree Runtime self tests" | ||
20 | help | ||
21 | This option builds in test cases for the device tree infrastructure | ||
22 | that are executed one at boot time, and the results dumped to the | ||
23 | console. | ||
24 | |||
25 | If unsure, say N here, but this option is safe to enable. | ||
26 | |||
18 | config OF_FLATTREE | 27 | config OF_FLATTREE |
19 | bool | 28 | bool |
20 | select DTC | 29 | select DTC |
diff --git a/drivers/of/Makefile b/drivers/of/Makefile index dccb1176be57..a73f5a51ff4c 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_OF_GPIO) += gpio.o | |||
8 | obj-$(CONFIG_OF_I2C) += of_i2c.o | 8 | obj-$(CONFIG_OF_I2C) += of_i2c.o |
9 | obj-$(CONFIG_OF_NET) += of_net.o | 9 | obj-$(CONFIG_OF_NET) += of_net.o |
10 | obj-$(CONFIG_OF_SPI) += of_spi.o | 10 | obj-$(CONFIG_OF_SPI) += of_spi.o |
11 | obj-$(CONFIG_OF_SELFTEST) += selftest.o | ||
11 | obj-$(CONFIG_OF_MDIO) += of_mdio.o | 12 | obj-$(CONFIG_OF_MDIO) += of_mdio.o |
12 | obj-$(CONFIG_OF_PCI) += of_pci.o | 13 | obj-$(CONFIG_OF_PCI) += of_pci.o |
13 | obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o | 14 | obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o |
diff --git a/drivers/of/base.c b/drivers/of/base.c index 9b6588ef0673..c6db9ab9046e 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -824,17 +824,19 @@ of_parse_phandle(struct device_node *np, const char *phandle_name, int index) | |||
824 | EXPORT_SYMBOL(of_parse_phandle); | 824 | EXPORT_SYMBOL(of_parse_phandle); |
825 | 825 | ||
826 | /** | 826 | /** |
827 | * of_parse_phandles_with_args - Find a node pointed by phandle in a list | 827 | * of_parse_phandle_with_args() - Find a node pointed by phandle in a list |
828 | * @np: pointer to a device tree node containing a list | 828 | * @np: pointer to a device tree node containing a list |
829 | * @list_name: property name that contains a list | 829 | * @list_name: property name that contains a list |
830 | * @cells_name: property name that specifies phandles' arguments count | 830 | * @cells_name: property name that specifies phandles' arguments count |
831 | * @index: index of a phandle to parse out | 831 | * @index: index of a phandle to parse out |
832 | * @out_node: optional pointer to device_node struct pointer (will be filled) | 832 | * @out_args: optional pointer to output arguments structure (will be filled) |
833 | * @out_args: optional pointer to arguments pointer (will be filled) | ||
834 | * | 833 | * |
835 | * This function is useful to parse lists of phandles and their arguments. | 834 | * This function is useful to parse lists of phandles and their arguments. |
836 | * Returns 0 on success and fills out_node and out_args, on error returns | 835 | * Returns 0 on success and fills out_args, on error returns appropriate |
837 | * appropriate errno value. | 836 | * errno value. |
837 | * | ||
838 | * Caller is responsible to call of_node_put() on the returned out_args->node | ||
839 | * pointer. | ||
838 | * | 840 | * |
839 | * Example: | 841 | * Example: |
840 | * | 842 | * |
@@ -851,94 +853,96 @@ EXPORT_SYMBOL(of_parse_phandle); | |||
851 | * } | 853 | * } |
852 | * | 854 | * |
853 | * To get a device_node of the `node2' node you may call this: | 855 | * To get a device_node of the `node2' node you may call this: |
854 | * of_parse_phandles_with_args(node3, "list", "#list-cells", 2, &node2, &args); | 856 | * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); |
855 | */ | 857 | */ |
856 | int of_parse_phandles_with_args(struct device_node *np, const char *list_name, | 858 | int of_parse_phandle_with_args(struct device_node *np, const char *list_name, |
857 | const char *cells_name, int index, | 859 | const char *cells_name, int index, |
858 | struct device_node **out_node, | 860 | struct of_phandle_args *out_args) |
859 | const void **out_args) | ||
860 | { | 861 | { |
861 | int ret = -EINVAL; | 862 | const __be32 *list, *list_end; |
862 | const __be32 *list; | 863 | int size, cur_index = 0; |
863 | const __be32 *list_end; | 864 | uint32_t count = 0; |
864 | int size; | ||
865 | int cur_index = 0; | ||
866 | struct device_node *node = NULL; | 865 | struct device_node *node = NULL; |
867 | const void *args = NULL; | 866 | phandle phandle; |
868 | 867 | ||
868 | /* Retrieve the phandle list property */ | ||
869 | list = of_get_property(np, list_name, &size); | 869 | list = of_get_property(np, list_name, &size); |
870 | if (!list) { | 870 | if (!list) |
871 | ret = -ENOENT; | 871 | return -EINVAL; |
872 | goto err0; | ||
873 | } | ||
874 | list_end = list + size / sizeof(*list); | 872 | list_end = list + size / sizeof(*list); |
875 | 873 | ||
874 | /* Loop over the phandles until all the requested entry is found */ | ||
876 | while (list < list_end) { | 875 | while (list < list_end) { |
877 | const __be32 *cells; | 876 | count = 0; |
878 | phandle phandle; | ||
879 | 877 | ||
878 | /* | ||
879 | * If phandle is 0, then it is an empty entry with no | ||
880 | * arguments. Skip forward to the next entry. | ||
881 | */ | ||
880 | phandle = be32_to_cpup(list++); | 882 | phandle = be32_to_cpup(list++); |
881 | args = list; | 883 | if (phandle) { |
882 | 884 | /* | |
883 | /* one cell hole in the list = <>; */ | 885 | * Find the provider node and parse the #*-cells |
884 | if (!phandle) | 886 | * property to determine the argument length |
885 | goto next; | 887 | */ |
886 | 888 | node = of_find_node_by_phandle(phandle); | |
887 | node = of_find_node_by_phandle(phandle); | 889 | if (!node) { |
888 | if (!node) { | 890 | pr_err("%s: could not find phandle\n", |
889 | pr_debug("%s: could not find phandle\n", | 891 | np->full_name); |
890 | np->full_name); | 892 | break; |
891 | goto err0; | 893 | } |
892 | } | 894 | if (of_property_read_u32(node, cells_name, &count)) { |
895 | pr_err("%s: could not get %s for %s\n", | ||
896 | np->full_name, cells_name, | ||
897 | node->full_name); | ||
898 | break; | ||
899 | } | ||
893 | 900 | ||
894 | cells = of_get_property(node, cells_name, &size); | 901 | /* |
895 | if (!cells || size != sizeof(*cells)) { | 902 | * Make sure that the arguments actually fit in the |
896 | pr_debug("%s: could not get %s for %s\n", | 903 | * remaining property data length |
897 | np->full_name, cells_name, node->full_name); | 904 | */ |
898 | goto err1; | 905 | if (list + count > list_end) { |
906 | pr_err("%s: arguments longer than property\n", | ||
907 | np->full_name); | ||
908 | break; | ||
909 | } | ||
899 | } | 910 | } |
900 | 911 | ||
901 | list += be32_to_cpup(cells); | 912 | /* |
902 | if (list > list_end) { | 913 | * All of the error cases above bail out of the loop, so at |
903 | pr_debug("%s: insufficient arguments length\n", | 914 | * this point, the parsing is successful. If the requested |
904 | np->full_name); | 915 | * index matches, then fill the out_args structure and return, |
905 | goto err1; | 916 | * or return -ENOENT for an empty entry. |
917 | */ | ||
918 | if (cur_index == index) { | ||
919 | if (!phandle) | ||
920 | return -ENOENT; | ||
921 | |||
922 | if (out_args) { | ||
923 | int i; | ||
924 | if (WARN_ON(count > MAX_PHANDLE_ARGS)) | ||
925 | count = MAX_PHANDLE_ARGS; | ||
926 | out_args->np = node; | ||
927 | out_args->args_count = count; | ||
928 | for (i = 0; i < count; i++) | ||
929 | out_args->args[i] = be32_to_cpup(list++); | ||
930 | } | ||
931 | return 0; | ||
906 | } | 932 | } |
907 | next: | ||
908 | if (cur_index == index) | ||
909 | break; | ||
910 | 933 | ||
911 | of_node_put(node); | 934 | of_node_put(node); |
912 | node = NULL; | 935 | node = NULL; |
913 | args = NULL; | 936 | list += count; |
914 | cur_index++; | 937 | cur_index++; |
915 | } | 938 | } |
916 | 939 | ||
917 | if (!node) { | 940 | /* Loop exited without finding a valid entry; return an error */ |
918 | /* | 941 | if (node) |
919 | * args w/o node indicates that the loop above has stopped at | 942 | of_node_put(node); |
920 | * the 'hole' cell. Report this differently. | 943 | return -EINVAL; |
921 | */ | ||
922 | if (args) | ||
923 | ret = -EEXIST; | ||
924 | else | ||
925 | ret = -ENOENT; | ||
926 | goto err0; | ||
927 | } | ||
928 | |||
929 | if (out_node) | ||
930 | *out_node = node; | ||
931 | if (out_args) | ||
932 | *out_args = args; | ||
933 | |||
934 | return 0; | ||
935 | err1: | ||
936 | of_node_put(node); | ||
937 | err0: | ||
938 | pr_debug("%s failed with status %d\n", __func__, ret); | ||
939 | return ret; | ||
940 | } | 944 | } |
941 | EXPORT_SYMBOL(of_parse_phandles_with_args); | 945 | EXPORT_SYMBOL(of_parse_phandle_with_args); |
942 | 946 | ||
943 | /** | 947 | /** |
944 | * prom_add_property - Add a property to a node | 948 | * prom_add_property - Add a property to a node |
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c index ef0105fa52b1..7e62d15d60f6 100644 --- a/drivers/of/gpio.c +++ b/drivers/of/gpio.c | |||
@@ -35,32 +35,27 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, | |||
35 | int index, enum of_gpio_flags *flags) | 35 | int index, enum of_gpio_flags *flags) |
36 | { | 36 | { |
37 | int ret; | 37 | int ret; |
38 | struct device_node *gpio_np; | ||
39 | struct gpio_chip *gc; | 38 | struct gpio_chip *gc; |
40 | int size; | 39 | struct of_phandle_args gpiospec; |
41 | const void *gpio_spec; | ||
42 | const __be32 *gpio_cells; | ||
43 | 40 | ||
44 | ret = of_parse_phandles_with_args(np, propname, "#gpio-cells", index, | 41 | ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, |
45 | &gpio_np, &gpio_spec); | 42 | &gpiospec); |
46 | if (ret) { | 43 | if (ret) { |
47 | pr_debug("%s: can't parse gpios property\n", __func__); | 44 | pr_debug("%s: can't parse gpios property\n", __func__); |
48 | goto err0; | 45 | goto err0; |
49 | } | 46 | } |
50 | 47 | ||
51 | gc = of_node_to_gpiochip(gpio_np); | 48 | gc = of_node_to_gpiochip(gpiospec.np); |
52 | if (!gc) { | 49 | if (!gc) { |
53 | pr_debug("%s: gpio controller %s isn't registered\n", | 50 | pr_debug("%s: gpio controller %s isn't registered\n", |
54 | np->full_name, gpio_np->full_name); | 51 | np->full_name, gpiospec.np->full_name); |
55 | ret = -ENODEV; | 52 | ret = -ENODEV; |
56 | goto err1; | 53 | goto err1; |
57 | } | 54 | } |
58 | 55 | ||
59 | gpio_cells = of_get_property(gpio_np, "#gpio-cells", &size); | 56 | if (gpiospec.args_count != gc->of_gpio_n_cells) { |
60 | if (!gpio_cells || size != sizeof(*gpio_cells) || | ||
61 | be32_to_cpup(gpio_cells) != gc->of_gpio_n_cells) { | ||
62 | pr_debug("%s: wrong #gpio-cells for %s\n", | 57 | pr_debug("%s: wrong #gpio-cells for %s\n", |
63 | np->full_name, gpio_np->full_name); | 58 | np->full_name, gpiospec.np->full_name); |
64 | ret = -EINVAL; | 59 | ret = -EINVAL; |
65 | goto err1; | 60 | goto err1; |
66 | } | 61 | } |
@@ -69,13 +64,13 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, | |||
69 | if (flags) | 64 | if (flags) |
70 | *flags = 0; | 65 | *flags = 0; |
71 | 66 | ||
72 | ret = gc->of_xlate(gc, np, gpio_spec, flags); | 67 | ret = gc->of_xlate(gc, &gpiospec, flags); |
73 | if (ret < 0) | 68 | if (ret < 0) |
74 | goto err1; | 69 | goto err1; |
75 | 70 | ||
76 | ret += gc->base; | 71 | ret += gc->base; |
77 | err1: | 72 | err1: |
78 | of_node_put(gpio_np); | 73 | of_node_put(gpiospec.np); |
79 | err0: | 74 | err0: |
80 | pr_debug("%s exited with status %d\n", __func__, ret); | 75 | pr_debug("%s exited with status %d\n", __func__, ret); |
81 | return ret; | 76 | return ret; |
@@ -105,8 +100,8 @@ unsigned int of_gpio_count(struct device_node *np) | |||
105 | do { | 100 | do { |
106 | int ret; | 101 | int ret; |
107 | 102 | ||
108 | ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", | 103 | ret = of_parse_phandle_with_args(np, "gpios", "#gpio-cells", |
109 | cnt, NULL, NULL); | 104 | cnt, NULL); |
110 | /* A hole in the gpios = <> counts anyway. */ | 105 | /* A hole in the gpios = <> counts anyway. */ |
111 | if (ret < 0 && ret != -EEXIST) | 106 | if (ret < 0 && ret != -EEXIST) |
112 | break; | 107 | break; |
@@ -127,12 +122,9 @@ EXPORT_SYMBOL(of_gpio_count); | |||
127 | * gpio chips. This function performs only one sanity check: whether gpio | 122 | * gpio chips. This function performs only one sanity check: whether gpio |
128 | * is less than ngpios (that is specified in the gpio_chip). | 123 | * is less than ngpios (that is specified in the gpio_chip). |
129 | */ | 124 | */ |
130 | int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | 125 | int of_gpio_simple_xlate(struct gpio_chip *gc, |
131 | const void *gpio_spec, u32 *flags) | 126 | const struct of_phandle_args *gpiospec, u32 *flags) |
132 | { | 127 | { |
133 | const __be32 *gpio = gpio_spec; | ||
134 | const u32 n = be32_to_cpup(gpio); | ||
135 | |||
136 | /* | 128 | /* |
137 | * We're discouraging gpio_cells < 2, since that way you'll have to | 129 | * We're discouraging gpio_cells < 2, since that way you'll have to |
138 | * write your own xlate function (that will have to retrive the GPIO | 130 | * write your own xlate function (that will have to retrive the GPIO |
@@ -144,13 +136,16 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, struct device_node *np, | |||
144 | return -EINVAL; | 136 | return -EINVAL; |
145 | } | 137 | } |
146 | 138 | ||
147 | if (n > gc->ngpio) | 139 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) |
140 | return -EINVAL; | ||
141 | |||
142 | if (gpiospec->args[0] > gc->ngpio) | ||
148 | return -EINVAL; | 143 | return -EINVAL; |
149 | 144 | ||
150 | if (flags) | 145 | if (flags) |
151 | *flags = be32_to_cpu(gpio[1]); | 146 | *flags = gpiospec->args[1]; |
152 | 147 | ||
153 | return n; | 148 | return gpiospec->args[0]; |
154 | } | 149 | } |
155 | EXPORT_SYMBOL(of_gpio_simple_xlate); | 150 | EXPORT_SYMBOL(of_gpio_simple_xlate); |
156 | 151 | ||
@@ -198,8 +193,6 @@ int of_mm_gpiochip_add(struct device_node *np, | |||
198 | if (ret) | 193 | if (ret) |
199 | goto err2; | 194 | goto err2; |
200 | 195 | ||
201 | pr_debug("%s: registered as generic GPIO chip, base is %d\n", | ||
202 | np->full_name, gc->base); | ||
203 | return 0; | 196 | return 0; |
204 | err2: | 197 | err2: |
205 | iounmap(mm_gc->regs); | 198 | iounmap(mm_gc->regs); |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c new file mode 100644 index 000000000000..9d2b4803a9d6 --- /dev/null +++ b/drivers/of/selftest.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Self tests for device tree subsystem | ||
3 | */ | ||
4 | |||
5 | #define pr_fmt(fmt) "### %s(): " fmt, __func__ | ||
6 | |||
7 | #include <linux/clk.h> | ||
8 | #include <linux/err.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/of.h> | ||
12 | #include <linux/list.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/device.h> | ||
16 | |||
17 | static bool selftest_passed = true; | ||
18 | #define selftest(result, fmt, ...) { \ | ||
19 | selftest_passed &= (result); \ | ||
20 | if (!(result)) \ | ||
21 | pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \ | ||
22 | } | ||
23 | |||
24 | static void __init of_selftest_parse_phandle_with_args(void) | ||
25 | { | ||
26 | struct device_node *np; | ||
27 | struct of_phandle_args args; | ||
28 | int rc, i; | ||
29 | bool passed_all = true; | ||
30 | |||
31 | pr_info("start\n"); | ||
32 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | ||
33 | if (!np) { | ||
34 | pr_err("missing testcase data\n"); | ||
35 | return; | ||
36 | } | ||
37 | |||
38 | for (i = 0; i < 7; i++) { | ||
39 | bool passed = true; | ||
40 | rc = of_parse_phandle_with_args(np, "phandle-list", | ||
41 | "#phandle-cells", i, &args); | ||
42 | |||
43 | /* Test the values from tests-phandle.dtsi */ | ||
44 | switch (i) { | ||
45 | case 0: | ||
46 | passed &= !rc; | ||
47 | passed &= (args.args_count == 1); | ||
48 | passed &= (args.args[0] == (i + 1)); | ||
49 | break; | ||
50 | case 1: | ||
51 | passed &= !rc; | ||
52 | passed &= (args.args_count == 2); | ||
53 | passed &= (args.args[0] == (i + 1)); | ||
54 | passed &= (args.args[1] == 0); | ||
55 | break; | ||
56 | case 2: | ||
57 | passed &= (rc == -ENOENT); | ||
58 | break; | ||
59 | case 3: | ||
60 | passed &= !rc; | ||
61 | passed &= (args.args_count == 3); | ||
62 | passed &= (args.args[0] == (i + 1)); | ||
63 | passed &= (args.args[1] == 4); | ||
64 | passed &= (args.args[2] == 3); | ||
65 | break; | ||
66 | case 4: | ||
67 | passed &= !rc; | ||
68 | passed &= (args.args_count == 2); | ||
69 | passed &= (args.args[0] == (i + 1)); | ||
70 | passed &= (args.args[1] == 100); | ||
71 | break; | ||
72 | case 5: | ||
73 | passed &= !rc; | ||
74 | passed &= (args.args_count == 0); | ||
75 | break; | ||
76 | case 6: | ||
77 | passed &= !rc; | ||
78 | passed &= (args.args_count == 1); | ||
79 | passed &= (args.args[0] == (i + 1)); | ||
80 | break; | ||
81 | case 7: | ||
82 | passed &= (rc == -EINVAL); | ||
83 | break; | ||
84 | default: | ||
85 | passed = false; | ||
86 | } | ||
87 | |||
88 | if (!passed) { | ||
89 | int j; | ||
90 | pr_err("index %i - data error on node %s rc=%i regs=[", | ||
91 | i, args.np->full_name, rc); | ||
92 | for (j = 0; j < args.args_count; j++) | ||
93 | printk(" %i", args.args[j]); | ||
94 | printk(" ]\n"); | ||
95 | |||
96 | passed_all = false; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* Check for missing list property */ | ||
101 | rc = of_parse_phandle_with_args(np, "phandle-list-missing", | ||
102 | "#phandle-cells", 0, &args); | ||
103 | passed_all &= (rc == -EINVAL); | ||
104 | |||
105 | /* Check for missing cells property */ | ||
106 | rc = of_parse_phandle_with_args(np, "phandle-list", | ||
107 | "#phandle-cells-missing", 0, &args); | ||
108 | passed_all &= (rc == -EINVAL); | ||
109 | |||
110 | /* Check for bad phandle in list */ | ||
111 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-phandle", | ||
112 | "#phandle-cells", 0, &args); | ||
113 | passed_all &= (rc == -EINVAL); | ||
114 | |||
115 | /* Check for incorrectly formed argument list */ | ||
116 | rc = of_parse_phandle_with_args(np, "phandle-list-bad-args", | ||
117 | "#phandle-cells", 1, &args); | ||
118 | passed_all &= (rc == -EINVAL); | ||
119 | |||
120 | pr_info("end - %s\n", passed_all ? "PASS" : "FAIL"); | ||
121 | } | ||
122 | |||
123 | static int __init of_selftest(void) | ||
124 | { | ||
125 | struct device_node *np; | ||
126 | |||
127 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | ||
128 | if (!np) { | ||
129 | pr_info("No testcase data in device tree; not running tests\n"); | ||
130 | return 0; | ||
131 | } | ||
132 | of_node_put(np); | ||
133 | |||
134 | pr_info("start of selftest - you will see error messages\n"); | ||
135 | of_selftest_parse_phandle_with_args(); | ||
136 | pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); | ||
137 | return 0; | ||
138 | } | ||
139 | late_initcall(of_selftest); | ||