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