]> Git Repo - linux.git/blob - drivers/of/module.c
ACPI: CPPC: Adjust debug messages in amd_set_max_freq_ratio() to warn
[linux.git] / drivers / of / module.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Linux kernel module helpers.
4  */
5
6 #include <linux/of.h>
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/string.h>
10
11 ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len)
12 {
13         const char *compat;
14         char *c;
15         struct property *p;
16         ssize_t csize;
17         ssize_t tsize;
18
19         /*
20          * Prevent a kernel oops in vsnprintf() -- it only allows passing a
21          * NULL ptr when the length is also 0. Also filter out the negative
22          * lengths...
23          */
24         if ((len > 0 && !str) || len < 0)
25                 return -EINVAL;
26
27         /* Name & Type */
28         /* %p eats all alphanum characters, so %c must be used here */
29         csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
30                          of_node_get_device_type(np));
31         tsize = csize;
32         if (csize >= len)
33                 csize = len > 0 ? len - 1 : 0;
34         len -= csize;
35         str += csize;
36
37         of_property_for_each_string(np, "compatible", p, compat) {
38                 csize = strlen(compat) + 1;
39                 tsize += csize;
40                 if (csize >= len)
41                         continue;
42
43                 csize = snprintf(str, len, "C%s", compat);
44                 for (c = str; c; ) {
45                         c = strchr(c, ' ');
46                         if (c)
47                                 *c++ = '_';
48                 }
49                 len -= csize;
50                 str += csize;
51         }
52
53         return tsize;
54 }
55
56 int of_request_module(const struct device_node *np)
57 {
58         char *str;
59         ssize_t size;
60         int ret;
61
62         if (!np)
63                 return -ENODEV;
64
65         size = of_modalias(np, NULL, 0);
66         if (size < 0)
67                 return size;
68
69         /* Reserve an additional byte for the trailing '\0' */
70         size++;
71
72         str = kmalloc(size, GFP_KERNEL);
73         if (!str)
74                 return -ENOMEM;
75
76         of_modalias(np, str, size);
77         str[size - 1] = '\0';
78         ret = request_module(str);
79         kfree(str);
80
81         return ret;
82 }
83 EXPORT_SYMBOL_GPL(of_request_module);
This page took 0.037195 seconds and 4 git commands to generate.