Commit | Line | Data |
---|---|---|
2e686bc3 PM |
1 | #include <linux/string.h> |
2 | #include <linux/kernel.h> | |
3 | #include <linux/init.h> | |
4 | #include <linux/module.h> | |
5 | #include <linux/mod_devicetable.h> | |
734d6524 PM |
6 | #include <linux/slab.h> |
7 | ||
2e686bc3 PM |
8 | #include <asm/errno.h> |
9 | #include <asm/of_device.h> | |
10 | ||
11 | /** | |
7eebde70 | 12 | * of_match_node - Tell if an device_node has a matching of_match structure |
2e686bc3 | 13 | * @ids: array of of device match structures to search in |
7eebde70 | 14 | * @node: the of device structure to match against |
2e686bc3 | 15 | * |
7eebde70 | 16 | * Low level utility function used by device matching. |
2e686bc3 | 17 | */ |
7eebde70 BH |
18 | const struct of_device_id *of_match_node(const struct of_device_id *matches, |
19 | const struct device_node *node) | |
2e686bc3 | 20 | { |
2e686bc3 PM |
21 | while (matches->name[0] || matches->type[0] || matches->compatible[0]) { |
22 | int match = 1; | |
23 | if (matches->name[0]) | |
7eebde70 BH |
24 | match &= node->name |
25 | && !strcmp(matches->name, node->name); | |
2e686bc3 | 26 | if (matches->type[0]) |
7eebde70 BH |
27 | match &= node->type |
28 | && !strcmp(matches->type, node->type); | |
2e686bc3 | 29 | if (matches->compatible[0]) |
7eebde70 BH |
30 | match &= device_is_compatible(node, |
31 | matches->compatible); | |
2e686bc3 PM |
32 | if (match) |
33 | return matches; | |
34 | matches++; | |
35 | } | |
36 | return NULL; | |
37 | } | |
38 | ||
7eebde70 BH |
39 | /** |
40 | * of_match_device - Tell if an of_device structure has a matching | |
41 | * of_match structure | |
42 | * @ids: array of of device match structures to search in | |
43 | * @dev: the of device structure to match against | |
44 | * | |
45 | * Used by a driver to check whether an of_device present in the | |
46 | * system is in its list of supported devices. | |
47 | */ | |
48 | const struct of_device_id *of_match_device(const struct of_device_id *matches, | |
49 | const struct of_device *dev) | |
2e686bc3 | 50 | { |
7eebde70 BH |
51 | if (!dev->node) |
52 | return NULL; | |
53 | return of_match_node(matches, dev->node); | |
2e686bc3 PM |
54 | } |
55 | ||
56 | struct of_device *of_dev_get(struct of_device *dev) | |
57 | { | |
58 | struct device *tmp; | |
59 | ||
60 | if (!dev) | |
61 | return NULL; | |
62 | tmp = get_device(&dev->dev); | |
63 | if (tmp) | |
64 | return to_of_device(tmp); | |
65 | else | |
66 | return NULL; | |
67 | } | |
68 | ||
69 | void of_dev_put(struct of_device *dev) | |
70 | { | |
71 | if (dev) | |
72 | put_device(&dev->dev); | |
73 | } | |
74 | ||
7eebde70 BH |
75 | static ssize_t dev_show_devspec(struct device *dev, |
76 | struct device_attribute *attr, char *buf) | |
2e686bc3 PM |
77 | { |
78 | struct of_device *ofdev; | |
79 | ||
80 | ofdev = to_of_device(dev); | |
81 | return sprintf(buf, "%s", ofdev->node->full_name); | |
82 | } | |
83 | ||
84 | static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL); | |
85 | ||
86 | /** | |
87 | * of_release_dev - free an of device structure when all users of it are finished. | |
88 | * @dev: device that's been disconnected | |
89 | * | |
90 | * Will be called only by the device core when all users of this of device are | |
91 | * done. | |
92 | */ | |
93 | void of_release_dev(struct device *dev) | |
94 | { | |
95 | struct of_device *ofdev; | |
96 | ||
97 | ofdev = to_of_device(dev); | |
98 | of_node_put(ofdev->node); | |
99 | kfree(ofdev); | |
100 | } | |
101 | ||
102 | int of_device_register(struct of_device *ofdev) | |
103 | { | |
104 | int rc; | |
2e686bc3 PM |
105 | |
106 | BUG_ON(ofdev->node == NULL); | |
107 | ||
2e686bc3 PM |
108 | rc = device_register(&ofdev->dev); |
109 | if (rc) | |
110 | return rc; | |
111 | ||
112 | device_create_file(&ofdev->dev, &dev_attr_devspec); | |
113 | ||
114 | return 0; | |
115 | } | |
116 | ||
117 | void of_device_unregister(struct of_device *ofdev) | |
118 | { | |
2e686bc3 PM |
119 | device_remove_file(&ofdev->dev, &dev_attr_devspec); |
120 | ||
2e686bc3 PM |
121 | device_unregister(&ofdev->dev); |
122 | } | |
123 | ||
2e686bc3 PM |
124 | |
125 | EXPORT_SYMBOL(of_match_device); | |
2e686bc3 PM |
126 | EXPORT_SYMBOL(of_device_register); |
127 | EXPORT_SYMBOL(of_device_unregister); | |
128 | EXPORT_SYMBOL(of_dev_get); | |
129 | EXPORT_SYMBOL(of_dev_put); | |
2e686bc3 | 130 | EXPORT_SYMBOL(of_release_dev); |