mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
Merge patch series "Linux compat improvements and CCF prep"
Casey Connolly <casey.connolly@linaro.org> says: This series implements various improvements to Linux header compatibility, largely in preparation for a full port of Linux CCF but many of these changes would also be helpful when porting other drivers. Beside the basic header/compat stuff there are a few larger patches: Patch 1 adds the "%pOF" format specifier to vsprintf, this behaves the same as it does in Linux printing the name of the ofnode, but notably it expects an ofnode pointer rather than a device_node. Patch 2 adds an option to skip doing a full DM scan pre-relocation. Some platforms like Qualcomm don't actually need devices to be probed prior to relocation, it is also quite slow to scan the entire FDT before caches are up. This option gets us to main loop 30-50% faster. Unfortunately it isn't possible to totally skip DM since U-Boot will panic if it can't find a serial port, but the serial uclass code will bind the serial port itself by reading /chosen/stdout-path, however any dependencies like clocks won't be found so this should only be enabled if the serial driver gracefully handles missing clocks. Patch 3 adds [k]strdup_const(), this works the same as the Linux version saving a small amount of memory by avoiding duplicating strings stored in .rodata, this is particularly useful for CCF. Patch 4 adds 64-bit versions of some 32-bit ofnode utilities functions, making it possible to parse 64-bit arrays. Patch 6 provides a simple implementation of kref, this will be used by CCF. Patch 9 adds devm_krealloc() support to devres, it relies on storing allocation sizes in the devres struct which will add a small overhead. Link: https://lore.kernel.org/r/20260401-casey-ccf-compat-v2-0-414d5b7f040b@linaro.org
This commit is contained in:
18
lib/fdtdec.c
18
lib/fdtdec.c
@@ -714,6 +714,24 @@ int fdtdec_get_int_array(const void *blob, int node, const char *prop_name,
|
||||
return err;
|
||||
}
|
||||
|
||||
int fdtdec_get_long_array(const void *blob, int node, const char *prop_name,
|
||||
u64 *array, int count)
|
||||
{
|
||||
const u64 *cell;
|
||||
int err = 0;
|
||||
|
||||
debug("%s: %s\n", __func__, prop_name);
|
||||
cell = get_prop_check_min_len(blob, node, prop_name,
|
||||
sizeof(u64) * count, &err);
|
||||
if (!err) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
array[i] = fdt64_to_cpu(cell[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int fdtdec_get_int_array_count(const void *blob, int node,
|
||||
const char *prop_name, u32 *array, int count)
|
||||
{
|
||||
|
||||
31
lib/string.c
31
lib/string.c
@@ -379,6 +379,37 @@ char * strndup(const char *s, size_t n)
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/**
|
||||
* strdup_const - conditionally duplicate an existing const string
|
||||
* @s: the string to duplicate
|
||||
*
|
||||
* Note: Strings allocated by kstrdup_const should be freed by kfree_const and
|
||||
* must not be passed to krealloc().
|
||||
*
|
||||
* Return: source string if it is in .rodata section otherwise
|
||||
* fallback to kstrdup.
|
||||
*/
|
||||
const char *strdup_const(const char *s)
|
||||
{
|
||||
if (is_kernel_rodata((unsigned long)s))
|
||||
return s;
|
||||
|
||||
return strdup(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* kfree_const - conditionally free memory
|
||||
* @x: pointer to the memory
|
||||
*
|
||||
* Function calls kfree only if @x is not in .rodata section.
|
||||
*/
|
||||
void kfree_const(const void *x)
|
||||
{
|
||||
if (!is_kernel_rodata((unsigned long)x))
|
||||
free((void *)x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSPN
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
/* For %pOF */
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
#include <dm/ofnode.h>
|
||||
#endif
|
||||
|
||||
/* we use this so that we can do without the ctype library */
|
||||
#define is_digit(c) ((c) >= '0' && (c) <= '9')
|
||||
|
||||
@@ -438,6 +443,30 @@ static char *uuid_string(char *buf, char *end, u8 *addr, int field_width,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL) && !defined(API_BUILD)
|
||||
static char *ofnode_string(char *buf, char *end, ofnode *dp, int field_width,
|
||||
int precision, int flags)
|
||||
{
|
||||
#define NP_PATH_MAX 64
|
||||
char str[NP_PATH_MAX] = { 0 };
|
||||
const char *err = "...";
|
||||
|
||||
/* If dp == NULL output the string '<NULL>' */
|
||||
if (!dp || !ofnode_valid(*dp))
|
||||
return string(buf, end, NULL, field_width, precision, flags);
|
||||
|
||||
/* Get the path and indicate if it got cut off */
|
||||
if (ofnode_get_path(*dp, str, NP_PATH_MAX)) {
|
||||
str[NP_PATH_MAX - 1] = '\0';
|
||||
char *p = str + min((NP_PATH_MAX - 2) - strlen(err), strlen(str));
|
||||
memcpy(p, err, strlen(err) + 1);
|
||||
}
|
||||
|
||||
return string(buf, end, str, field_width, precision, flags);
|
||||
#undef NP_PATH_MAX
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Show a '%p' thing. A kernel extension is that the '%p' is followed
|
||||
* by an extra set of alphanumeric characters that are extended format
|
||||
@@ -473,6 +502,14 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
||||
case 'D':
|
||||
return device_path_string(buf, end, ptr, field_width,
|
||||
precision, flags);
|
||||
#endif
|
||||
/* Device paths only exist in the EFI context. */
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL) && !defined(API_BUILD)
|
||||
case 'O':
|
||||
if (fmt[1] == 'F')
|
||||
return ofnode_string(buf, end, ptr, field_width,
|
||||
precision, flags);
|
||||
break;
|
||||
#endif
|
||||
case 'a':
|
||||
flags |= SPECIAL | ZEROPAD;
|
||||
|
||||
Reference in New Issue
Block a user