Linux Audio

Check our new training course

Loading...
v6.8
 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
11ssize_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	/* Name & Type */
20	/* %p eats all alphanum characters, so %c must be used here */
21	csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T',
22			 of_node_get_device_type(np));
23	tsize = csize;
 
 
24	len -= csize;
25	if (str)
26		str += csize;
27
28	of_property_for_each_string(np, "compatible", p, compat) {
29		csize = strlen(compat) + 1;
30		tsize += csize;
31		if (csize > len)
32			continue;
33
34		csize = snprintf(str, len, "C%s", compat);
35		for (c = str; c; ) {
36			c = strchr(c, ' ');
37			if (c)
38				*c++ = '_';
39		}
40		len -= csize;
41		str += csize;
42	}
43
44	return tsize;
45}
46
47int of_request_module(const struct device_node *np)
48{
49	char *str;
50	ssize_t size;
51	int ret;
52
53	if (!np)
54		return -ENODEV;
55
56	size = of_modalias(np, NULL, 0);
57	if (size < 0)
58		return size;
59
60	/* Reserve an additional byte for the trailing '\0' */
61	size++;
62
63	str = kmalloc(size, GFP_KERNEL);
64	if (!str)
65		return -ENOMEM;
66
67	of_modalias(np, str, size);
68	str[size - 1] = '\0';
69	ret = request_module(str);
70	kfree(str);
71
72	return ret;
73}
74EXPORT_SYMBOL_GPL(of_request_module);
v6.9.4
 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
11ssize_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
56int 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}
83EXPORT_SYMBOL_GPL(of_request_module);