From 03daea192aa3e251ab7593f5add27765dc6b6109 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 25 May 2023 22:48:12 +0200 Subject: of: unittest: Switch i2c driver back to use .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit b8a1a4cd5a98 ("i2c: Provide a temporary .probe_new() call-back type"), all drivers being converted to .probe_new() and then 03c835f498b5 ("i2c: Switch .probe() to not take an id parameter") convert back to (the new) .probe() to be able to eventually drop .probe_new() from struct i2c_driver. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20230525204812.733642-1-u.kleine-koenig@pengutronix.de Signed-off-by: Rob Herring --- drivers/of/unittest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 2191c0136531..7d3e3c6ab49b 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2686,7 +2686,7 @@ static struct i2c_driver unittest_i2c_dev_driver = { .driver = { .name = "unittest-i2c-dev", }, - .probe_new = unittest_i2c_dev_probe, + .probe = unittest_i2c_dev_probe, .remove = unittest_i2c_dev_remove, .id_table = unittest_i2c_dev_id, }; @@ -2763,7 +2763,7 @@ static struct i2c_driver unittest_i2c_mux_driver = { .driver = { .name = "unittest-i2c-mux", }, - .probe_new = unittest_i2c_mux_probe, + .probe = unittest_i2c_mux_probe, .remove = unittest_i2c_mux_remove, .id_table = unittest_i2c_mux_id, }; -- cgit v1.3.1 From 0f8e5651095bcf6e60330c8d558fd1227e0d71b3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 15 Jun 2023 17:52:43 +0300 Subject: of/platform: Propagate firmware node by calling device_set_node() Insulate of_device_alloc() and of_amba_device_create() from possible changes to fwnode_handle implementation by using device_set_node() instead of open-coding dev->dev.fwnode assignments. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230615145243.37095-1-andriy.shevchenko@linux.intel.com Signed-off-by: Rob Herring --- drivers/of/platform.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 78ae84187449..051e29b7ad2b 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -140,8 +140,8 @@ struct platform_device *of_device_alloc(struct device_node *np, } } - dev->dev.of_node = of_node_get(np); - dev->dev.fwnode = &np->fwnode; + /* setup generic device info */ + device_set_node(&dev->dev, of_fwnode_handle(np)); dev->dev.parent = parent ? : &platform_bus; if (bus_id) @@ -239,8 +239,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, dev->dev.dma_mask = &dev->dev.coherent_dma_mask; /* setup generic device info */ - dev->dev.of_node = of_node_get(node); - dev->dev.fwnode = &node->fwnode; + device_set_node(&dev->dev, of_fwnode_handle(node)); dev->dev.parent = parent ? : &platform_bus; dev->dev.platform_data = platform_data; if (bus_id) -- cgit v1.3.1 From 83ba7361e168cd7b24aa95d2aefb4e31e3cc6cd0 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 14 Jun 2023 21:20:42 +0200 Subject: of: reserved_mem: Try to keep range allocations contiguous Right now dynamic reserved memory regions are allocated either bottom-up or top-down, depending on the memblock setting of the architecture. This is fine when the address is arbitrary. However, when using "alloc-ranges" the regions are often placed somewhere in the middle of (free) RAM, even if the range starts or ends next to another (static) reservation. Try to detect this situation, and choose explicitly between bottom-up or top-down to allocate the memory close to the other reservations: 1. If the "alloc-range" starts at the end or inside an existing reservation, use bottom-up. 2. If the "alloc-range" ends at the start or inside an existing reservation, use top-down. 3. If both or none is the case, keep the current (architecture-specific) behavior. There are plenty of edge cases where only a more complex algorithm would help, but even this simple approach helps in many cases to keep the reserved memory (and therefore also the free memory) contiguous. Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20230510-dt-resv-bottom-up-v2-1-aeb2afc8ac25@gerhold.net Signed-off-by: Rob Herring --- drivers/of/of_reserved_mem.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 948efa9f99e3..7f892c3dcc63 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -77,6 +77,57 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname, return; } +/* + * __reserved_mem_alloc_in_range() - allocate reserved memory described with + * 'alloc-ranges'. Choose bottom-up/top-down depending on nearby existing + * reserved regions to keep the reserved memory contiguous if possible. + */ +static int __init __reserved_mem_alloc_in_range(phys_addr_t size, + phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap, + phys_addr_t *res_base) +{ + bool prev_bottom_up = memblock_bottom_up(); + bool bottom_up = false, top_down = false; + int ret, i; + + for (i = 0; i < reserved_mem_count; i++) { + struct reserved_mem *rmem = &reserved_mem[i]; + + /* Skip regions that were not reserved yet */ + if (rmem->size == 0) + continue; + + /* + * If range starts next to an existing reservation, use bottom-up: + * |....RRRR................RRRRRRRR..............| + * --RRRR------ + */ + if (start >= rmem->base && start <= (rmem->base + rmem->size)) + bottom_up = true; + + /* + * If range ends next to an existing reservation, use top-down: + * |....RRRR................RRRRRRRR..............| + * -------RRRR----- + */ + if (end >= rmem->base && end <= (rmem->base + rmem->size)) + top_down = true; + } + + /* Change setting only if either bottom-up or top-down was selected */ + if (bottom_up != top_down) + memblock_set_bottom_up(bottom_up); + + ret = early_init_dt_alloc_reserved_memory_arch(size, align, + start, end, nomap, res_base); + + /* Restore old setting if needed */ + if (bottom_up != top_down) + memblock_set_bottom_up(prev_bottom_up); + + return ret; +} + /* * __reserved_mem_alloc_size() - allocate reserved memory described by * 'size', 'alignment' and 'alloc-ranges' properties. @@ -137,8 +188,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, end = start + dt_mem_next_cell(dt_root_size_cells, &prop); - ret = early_init_dt_alloc_reserved_memory_arch(size, - align, start, end, nomap, &base); + ret = __reserved_mem_alloc_in_range(size, align, + start, end, nomap, &base); if (ret == 0) { pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", uname, &base, -- cgit v1.3.1 From 4cea2821882b06cd2c9c896d501f58746c16a90b Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Wed, 14 Jun 2023 21:20:43 +0200 Subject: of: reserved_mem: Use stable allocation order sort() in Linux is based on heapsort which is not a stable sort algorithm - equal elements are being reordered. For reserved memory in the device tree this happens mainly for dynamic allocations: They do not have an address to sort with, so they are reordered somewhat randomly when adding/removing other unrelated reserved memory nodes. Functionally this is not a big problem, but it's confusing during development when all the addresses change after adding unrelated reserved memory nodes. Make the order stable by sorting dynamic allocations according to the node order in the device tree. Static allocations are not affected by this because they are still sorted by their (fixed) address. Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20230510-dt-resv-bottom-up-v2-2-aeb2afc8ac25@gerhold.net Signed-off-by: Rob Herring --- drivers/of/of_reserved_mem.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 7f892c3dcc63..7ec94cfcbddb 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -268,6 +268,11 @@ static int __init __rmem_cmp(const void *a, const void *b) if (ra->size > rb->size) return 1; + if (ra->fdt_node < rb->fdt_node) + return -1; + if (ra->fdt_node > rb->fdt_node) + return 1; + return 0; } -- cgit v1.3.1