Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182// SPDX-License-Identifier: GPL-2.0/* * Linux kernel module helpers. */
#include <linux/of.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/string.h>
ssize_t of_modalias(const struct device_node *np, char *str, ssize_t len){ const char *compat; char *c; struct property *p; ssize_t csize; ssize_t tsize;
/* * Prevent a kernel oops in vsnprintf() -- it only allows passing a * NULL ptr when the length is also 0. Also filter out the negative * lengths... */ if ((len > 0 && !str) || len < 0) return -EINVAL;
/* Name & Type */ /* %p eats all alphanum characters, so %c must be used here */ csize = snprintf(str, len, "of:N%pOFn%c%s", np, 'T', of_node_get_device_type(np)); tsize = csize; if (csize >= len) csize = len > 0 ? len - 1 : 0; len -= csize; str += csize;
of_property_for_each_string(np, "compatible", p, compat) { csize = snprintf(str, len, "C%s", compat); tsize += csize; if (csize >= len) continue; for (c = str; c; ) { c = strchr(c, ' '); if (c) *c++ = '_'; } len -= csize; str += csize; }
return tsize;}
int of_request_module(const struct device_node *np){ char *str; ssize_t size; int ret;
if (!np) return -ENODEV;
size = of_modalias(np, NULL, 0); if (size < 0) return size;
/* Reserve an additional byte for the trailing '\0' */ size++;
str = kmalloc(size, GFP_KERNEL); if (!str) return -ENOMEM;
of_modalias(np, str, size); str[size - 1] = '\0'; ret = request_module(str); kfree(str);
return ret;}EXPORT_SYMBOL_GPL(of_request_module);