diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-27 20:09:05 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-27 20:09:05 +0300 |
commit | cb6fe2ceb667eb78f252d473b03deb23999ab1cf (patch) | |
tree | b230a03a1a7d763add665e6c5868fbe6798438db | |
parent | d42b1c47570eb2ed818dc3fe94b2678124af109d (diff) | |
parent | 1c5e9170ad93d3bd62a7ed8380e60b62c88b90a8 (diff) | |
download | linux-cb6fe2ceb667eb78f252d473b03deb23999ab1cf.tar.xz |
Merge tag 'devicetree-for-6.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull more devicetree updates from Rob Herring:
- First part of DT header detangling dropping cpu.h from of_device.h
and replacing some includes with forward declarations. A handful of
drivers needed some adjustment to their includes as a result.
- Refactor of_device.h to be used by bus drivers rather than various
device drivers. This moves non-bus related functions out of
of_device.h. The end goal is for of_platform.h and of_device.h to
stop including each other.
- Refactor open coded parsing of "ranges" in some bus drivers to use DT
address parsing functions
- Add some new address parsing functions of_property_read_reg(),
of_range_count(), and of_range_to_resource() in preparation to
convert more open coded parsing of DT addresses to use them.
- Treewide clean-ups to use of_property_read_bool() and
of_property_present() as appropriate. The ones here are the ones that
didn't get picked up elsewhere.
* tag 'devicetree-for-6.4-2' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (34 commits)
bus: tegra-gmi: Replace of_platform.h with explicit includes
hte: Use of_property_present() for testing DT property presence
w1: w1-gpio: Use of_property_read_bool() for boolean properties
virt: fsl: Use of_property_present() for testing DT property presence
soc: fsl: Use of_property_present() for testing DT property presence
sbus: display7seg: Use of_property_read_bool() for boolean properties
sparc: Use of_property_read_bool() for boolean properties
sparc: Use of_property_present() for testing DT property presence
bus: mvebu-mbus: Remove open coded "ranges" parsing
of/address: Add of_property_read_reg() helper
of/address: Add of_range_count() helper
of/address: Add support for 3 address cell bus
of/address: Add of_range_to_resource() helper
of: unittest: Add bus address range parsing tests
of: Drop cpu.h include from of_device.h
OPP: Adjust includes to remove of_device.h
irqchip: loongson-eiointc: Add explicit include for cpuhotplug.h
cpuidle: Adjust includes to remove of_device.h
cpufreq: sun50i: Add explicit include for cpu.h
cpufreq: Adjust includes to remove of_device.h
...
53 files changed, 566 insertions, 373 deletions
diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index 437ff39f7808..fba1f8bb03b5 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -5,7 +5,6 @@ #include <linux/cpuidle.h> #include <linux/of.h> -#include <linux/of_device.h> #include <asm/cpuidle.h> extern struct of_cpuidle_method __cpuidle_method_of_table[]; diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c index 26cbce135338..cb63921232a6 100644 --- a/arch/arm/mach-sunxi/mc_smp.c +++ b/arch/arm/mach-sunxi/mc_smp.c @@ -19,7 +19,6 @@ #include <linux/irqchip/arm-gic.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_device.h> #include <linux/smp.h> #include <asm/cacheflush.h> diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c index 3a13113f1b29..e3829d2de5d9 100644 --- a/arch/riscv/kernel/cacheinfo.c +++ b/arch/riscv/kernel/cacheinfo.c @@ -5,7 +5,6 @@ #include <linux/cpu.h> #include <linux/of.h> -#include <linux/of_device.h> #include <asm/cacheinfo.h> static struct riscv_cacheinfo_ops *rv_cache_ops; diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index a059b73f4ddb..3020f44dcf58 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -8,6 +8,7 @@ * Nick Kossifidis <mick@ics.forth.gr> */ +#include <linux/cpu.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/memblock.h> @@ -15,7 +16,6 @@ #include <linux/console.h> #include <linux/screen_info.h> #include <linux/of_fdt.h> -#include <linux/of_platform.h> #include <linux/sched/task.h> #include <linux/smp.h> #include <linux/efi.h> diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h index 587edb8b5a65..8184575b1336 100644 --- a/arch/sparc/include/asm/prom.h +++ b/arch/sparc/include/asm/prom.h @@ -19,11 +19,14 @@ #include <linux/mutex.h> #include <linux/atomic.h> #include <linux/irqdomain.h> +#include <linux/spinlock.h> #define of_compat_cmp(s1, s2, l) strncmp((s1), (s2), (l)) #define of_prop_cmp(s1, s2) strcasecmp((s1), (s2)) #define of_node_cmp(s1, s2) strcmp((s1), (s2)) +extern raw_spinlock_t devtree_lock; + struct of_irq_controller { unsigned int (*irq_build)(struct device_node *, unsigned int, void *); void *data; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 4ebf51e6e78e..b60f58e04164 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -29,7 +29,7 @@ static int of_bus_pci_match(struct device_node *np) * parent as-is, not with the PCI translate * method which chops off the top address cell. */ - if (!of_find_property(np, "ranges", NULL)) + if (!of_property_present(np, "ranges")) return 0; return 1; @@ -223,7 +223,7 @@ static int __init build_one_resource(struct device_node *parent, static int __init use_1to1_mapping(struct device_node *pp) { /* If we have a ranges property in the parent, use it. */ - if (of_find_property(pp, "ranges", NULL) != NULL) + if (of_property_present(pp, "ranges")) return 0; /* Some SBUS devices use intermediate nodes to express diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 5a9f86b1d4e7..5b5143e17ba3 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -58,7 +58,7 @@ static int of_bus_pci_match(struct device_node *np) * parent as-is, not with the PCI translate * method which chops off the top address cell. */ - if (!of_find_property(np, "ranges", NULL)) + if (!of_property_present(np, "ranges")) return 0; return 1; @@ -78,7 +78,7 @@ static int of_bus_simba_match(struct device_node *np) * simba. */ if (of_node_name_eq(np, "pci")) { - if (!of_find_property(np, "ranges", NULL)) + if (!of_property_present(np, "ranges")) return 1; } @@ -283,7 +283,7 @@ static int __init build_one_resource(struct device_node *parent, static int __init use_1to1_mapping(struct device_node *pp) { /* If we have a ranges property in the parent, use it. */ - if (of_find_property(pp, "ranges", NULL) != NULL) + if (of_property_present(pp, "ranges")) return 0; /* If the parent is the dma node of an ISA bus, pass diff --git a/arch/sparc/kernel/of_device_common.c b/arch/sparc/kernel/of_device_common.c index e717a56efc5d..60f86b837658 100644 --- a/arch/sparc/kernel/of_device_common.c +++ b/arch/sparc/kernel/of_device_common.c @@ -162,7 +162,7 @@ int of_bus_sbus_match(struct device_node *np) * don't have some intervening real bus that provides * ranges based translations. */ - if (of_find_property(dp, "ranges", NULL) != NULL) + if (of_property_present(dp, "ranges")) break; dp = dp->parent; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 421aba00e6b0..23b47f7fdb1d 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1270,7 +1270,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - if (!of_find_property(pbm->op->dev.of_node, "no-bus-parking", NULL)) + if (!of_property_read_bool(pbm->op->dev.of_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; else tmp &= ~SCHIZO_PCICTRL_PARK; diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index d941875dd718..8147985a1dc4 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -28,7 +28,7 @@ static int has_button_interrupt(unsigned int irq, struct device_node *dp) { if (irq == 0xffffffff) return 0; - if (!of_find_property(dp, "button", NULL)) + if (!of_property_read_bool(dp, "button")) return 0; return 1; diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c index f883a50fa333..998aa693d491 100644 --- a/arch/sparc/kernel/prom_64.c +++ b/arch/sparc/kernel/prom_64.c @@ -502,7 +502,7 @@ static void *fill_in_one_cpu(struct device_node *dp, int cpuid, int arg) struct device_node *portid_parent = NULL; int portid = -1; - if (of_find_property(dp, "cpuid", NULL)) { + if (of_property_present(dp, "cpuid")) { int limit = 2; portid_parent = dp; diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 8a08830e4a65..958c2cf4479b 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -277,7 +277,7 @@ static int clock_probe(struct platform_device *op) return -ENODEV; /* Only the primary RTC has an address property */ - if (!of_find_property(dp, "address", NULL)) + if (!of_property_present(dp, "address")) return -ENODEV; m48t59_rtc.resource = &op->resource[0]; diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index f3903d002819..41f0eadf1931 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -14,7 +14,7 @@ #include <linux/cpu.h> #include <linux/device.h> #include <linux/init.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/smp.h> diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index d51573ac525e..00cb792bda18 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -1179,74 +1179,32 @@ static int __init mbus_dt_setup_win(struct mvebu_mbus_state *mbus, return 0; } -static int __init -mbus_parse_ranges(struct device_node *node, - int *addr_cells, int *c_addr_cells, int *c_size_cells, - int *cell_count, const __be32 **ranges_start, - const __be32 **ranges_end) -{ - const __be32 *prop; - int ranges_len, tuple_len; - - /* Allow a node with no 'ranges' property */ - *ranges_start = of_get_property(node, "ranges", &ranges_len); - if (*ranges_start == NULL) { - *addr_cells = *c_addr_cells = *c_size_cells = *cell_count = 0; - *ranges_start = *ranges_end = NULL; - return 0; - } - *ranges_end = *ranges_start + ranges_len / sizeof(__be32); - - *addr_cells = of_n_addr_cells(node); - - prop = of_get_property(node, "#address-cells", NULL); - *c_addr_cells = be32_to_cpup(prop); - - prop = of_get_property(node, "#size-cells", NULL); - *c_size_cells = be32_to_cpup(prop); - - *cell_count = *addr_cells + *c_addr_cells + *c_size_cells; - tuple_len = (*cell_count) * sizeof(__be32); - - if (ranges_len % tuple_len) { - pr_warn("malformed ranges entry '%pOFn'\n", node); - return -EINVAL; - } - return 0; -} - static int __init mbus_dt_setup(struct mvebu_mbus_state *mbus, struct device_node *np) { - int addr_cells, c_addr_cells, c_size_cells; - int i, ret, cell_count; - const __be32 *r, *ranges_start, *ranges_end; + int ret; + struct of_range_parser parser; + struct of_range range; - ret = mbus_parse_ranges(np, &addr_cells, &c_addr_cells, - &c_size_cells, &cell_count, - &ranges_start, &ranges_end); + ret = of_range_parser_init(&parser, np); if (ret < 0) - return ret; + return 0; - for (i = 0, r = ranges_start; r < ranges_end; r += cell_count, i++) { - u32 windowid, base, size; + for_each_of_range(&parser, &range) { + u32 windowid = upper_32_bits(range.bus_addr); u8 target, attr; /* * An entry with a non-zero custom field do not * correspond to a static window, so skip it. */ - windowid = of_read_number(r, 1); if (CUSTOM(windowid)) continue; target = TARGET(windowid); attr = ATTR(windowid); - base = of_read_number(r + c_addr_cells, addr_cells); - size = of_read_number(r + c_addr_cells + addr_cells, - c_size_cells); - ret = mbus_dt_setup_win(mbus, base, size, target, attr); + ret = mbus_dt_setup_win(mbus, range.cpu_addr, range.size, target, attr); if (ret < 0) return ret; } diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c index 662266719682..e3506ef37051 100644 --- a/drivers/bus/tegra-gmi.c +++ b/drivers/bus/tegra-gmi.c @@ -9,7 +9,9 @@ #include <linux/delay.h> #include <linux/io.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> diff --git a/drivers/bus/uniphier-system-bus.c b/drivers/bus/uniphier-system-bus.c index f70dedace20b..cb5c89ce7b86 100644 --- a/drivers/bus/uniphier-system-bus.c +++ b/drivers/bus/uniphier-system-bus.c @@ -176,10 +176,9 @@ static int uniphier_system_bus_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct uniphier_system_bus_priv *priv; - const __be32 *ranges; - u32 cells, addr, size; - u64 paddr; - int pna, bank, rlen, rone, ret; + struct of_range_parser parser; + struct of_range range; + int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -191,48 +190,17 @@ static int uniphier_system_bus_probe(struct platform_device *pdev) priv->dev = dev; - pna = of_n_addr_cells(dev->of_node); - - ret = of_property_read_u32(dev->of_node, "#address-cells", &cells); - if (ret) { - dev_err(dev, "failed to get #address-cells\n"); - return ret; - } - if (cells != 2) { - dev_err(dev, "#address-cells must be 2\n"); - return -EINVAL; - } - - ret = of_property_read_u32(dev->of_node, "#size-cells", &cells); - if (ret) { - dev_err(dev, "failed to get #size-cells\n"); + ret = of_range_parser_init(&parser, dev->of_node); + if (ret) return ret; - } - if (cells != 1) { - dev_err(dev, "#size-cells must be 1\n"); - return -EINVAL; - } - ranges = of_get_property(dev->of_node, "ranges", &rlen); - if (!ranges) { - dev_err(dev, "failed to get ranges property\n"); - return -ENOENT; - } - - rlen /= sizeof(*ranges); - rone = pna + 2; - - for (; rlen >= rone; rlen -= rone) { - bank = be32_to_cpup(ranges++); - addr = be32_to_cpup(ranges++); - paddr = of_translate_address(dev->of_node, ranges); - if (paddr == OF_BAD_ADDR) + for_each_of_range(&parser, &range) { + if (range.cpu_addr == OF_BAD_ADDR) return -EINVAL; - ranges += pna; - size = be32_to_cpup(ranges++); - - ret = uniphier_system_bus_add_bank(priv, bank, addr, - paddr, size); + ret = uniphier_system_bus_add_bank(priv, + upper_32_bits(range.bus_addr), + lower_32_bits(range.bus_addr), + range.cpu_addr, range.size); if (ret) return ret; } diff --git a/drivers/clocksource/ingenic-timer.c b/drivers/clocksource/ingenic-timer.c index 24ed0f1f089b..089ce64b1c3f 100644 --- a/drivers/clocksource/ingenic-timer.c +++ b/drivers/clocksource/ingenic-timer.c @@ -9,13 +9,12 @@ #include <linux/clk.h> #include <linux/clockchips.h> #include <linux/clocksource.h> +#include <linux/cpuhotplug.h> #include <linux/interrupt.h> #include <linux/mfd/ingenic-tcu.h> #include <linux/mfd/syscon.h> #include <linux/of.h> -#include <linux/of_address.h> #include <linux/of_irq.h> -#include <linux/of_platform.h> #include <linux/overflow.h> #include <linux/platform_device.h> #include <linux/regmap.h> diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index e1a5384cf21c..29904395e95f 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -20,6 +20,7 @@ #include <linux/dmi.h> #include <linux/slab.h> #include <linux/string_helpers.h> +#include <linux/platform_device.h> #include <linux/acpi.h> #include <linux/io.h> diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 452181434735..338cf6cc6596 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -6,7 +6,6 @@ #include <linux/err.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include "cpufreq-dt.h" diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index 70ad8fe1d78b..95588101efbd 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -9,7 +9,7 @@ #include <linux/module.h> #include <linux/clk.h> #include <linux/cpufreq.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/io.h> #include <asm/proc-fns.h> diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index 28d346062166..f9306410a07f 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c @@ -23,7 +23,7 @@ #include <linux/completion.h> #include <linux/mutex.h> #include <linux/time.h> -#include <linux/of_device.h> +#include <linux/of.h> #define DBG(fmt...) pr_debug(fmt) diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 0c362932ca60..1d2cfea9858a 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -31,6 +31,7 @@ #include <linux/cpufreq.h> #include <linux/compiler.h> #include <linux/slab.h> +#include <linux/platform_device.h> #include <linux/acpi.h> #include <linux/io.h> diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 7ec6d1bb4592..ec75e79659ac 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -23,7 +23,7 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/hardirq.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <asm/machdep.h> #include <asm/irq.h> diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index ba9c31d98bd6..2cd2b06849a2 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -21,7 +21,7 @@ #include <linux/init.h> #include <linux/completion.h> #include <linux/mutex.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <asm/machdep.h> #include <asm/irq.h> diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index eb54f7f17ab5..a78d7a27b4b5 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -11,8 +11,8 @@ #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_address.h> -#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/slab.h> #include <linux/spinlock.h> diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index c6fdf019dbde..78b875db6b66 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -18,7 +18,7 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/types.h> diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 1583a370da39..4321d7bbe769 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -10,9 +10,10 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/cpu.h> #include <linux/module.h> #include <linux/nvmem-consumer.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/slab.h> diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c index 788672c0c834..aae951d4e77c 100644 --- a/drivers/cpufreq/tegra124-cpufreq.c +++ b/drivers/cpufreq/tegra124-cpufreq.c @@ -11,7 +11,6 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of_device.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_opp.h> diff --git a/drivers/cpufreq/tegra20-cpufreq.c b/drivers/cpufreq/tegra20-cpufreq.c index dfd2de4f8e07..a573186704a5 100644 --- a/drivers/cpufreq/tegra20-cpufreq.c +++ b/drivers/cpufreq/tegra20-cpufreq.c @@ -12,7 +12,7 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/types.h> diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index 6de027f9f6f5..bf68920d038a 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -16,7 +16,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/psci.h> #include <linux/pm_domain.h> diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c index c6e2e91bb4c3..1fc9968eae19 100644 --- a/drivers/cpuidle/cpuidle-qcom-spm.c +++ b/drivers/cpuidle/cpuidle-qcom-spm.c @@ -11,8 +11,7 @@ #include <linux/io.h> #include <linux/slab.h> #include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/of_platform.h> #include <linux/err.h> #include <linux/platform_device.h> #include <linux/cpuidle.h> diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c index 1fab1abc6eb6..f2ccda2c3871 100644 --- a/drivers/cpuidle/cpuidle-riscv-sbi.c +++ b/drivers/cpuidle/cpuidle-riscv-sbi.c @@ -8,6 +8,7 @@ #define pr_fmt(fmt) "cpuidle-riscv-sbi: " fmt +#include <linux/cpuhotplug.h> #include <linux/cpuidle.h> #include <linux/cpumask.h> #include <linux/cpu_pm.h> @@ -15,7 +16,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/slab.h> #include <linux/platform_device.h> #include <linux/pm_domain.h> diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c index 02aa0b39af9d..12fec92a85fd 100644 --- a/drivers/cpuidle/dt_idle_states.c +++ b/drivers/cpuidle/dt_idle_states.c @@ -14,7 +14,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include "dt_idle_states.h" diff --git a/drivers/hte/hte.c b/drivers/hte/hte.c index 7c3b4476f890..9f3221462e75 100644 --- a/drivers/hte/hte.c +++ b/drivers/hte/hte.c @@ -518,7 +518,7 @@ static struct hte_device *hte_of_get_dev(struct device *dev, np = dev->of_node; - if (!of_find_property(np, "timestamp-names", NULL)) { + if (!of_property_present(np, "timestamp-names")) { /* Let hte core construct it during request time */ desc->attr.name = NULL; } else { diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index 90181c42840b..71ef19f77a5a 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -7,16 +7,13 @@ #define pr_fmt(fmt) "eiointc: " fmt +#include <linux/cpuhotplug.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqchip.h> #include <linux/irqdomain.h> #include <linux/irqchip/chained_irq.h> #include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <linux/of_platform.h> #include <linux/syscore_ops.h> #define EIOINTC_REG_NODEMAP 0x14a0 diff --git a/drivers/of/Makefile b/drivers/of/Makefile index e0360a44306e..10f704592561 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y = base.o device.o platform.o property.o +obj-y = base.o cpu.o device.o platform.o property.o obj-$(CONFIG_OF_KOBJ) += kobj.o obj-$(CONFIG_OF_DYNAMIC) += dynamic.o obj-$(CONFIG_OF_FLATTREE) += fdt.o diff --git a/drivers/of/address.c b/drivers/of/address.c index 3aaa63e66fcf..0d49f8c9ed88 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -90,11 +90,17 @@ static int of_bus_default_translate(__be32 *addr, u64 offset, int na) return 0; } +static unsigned int of_bus_default_flags_get_flags(const __be32 *addr) +{ + return of_read_number(addr, 1); +} + static unsigned int of_bus_default_get_flags(const __be32 *addr) { return IORESOURCE_MEM; } + #ifdef CONFIG_PCI static unsigned int of_bus_pci_get_flags(const __be32 *addr) { @@ -213,9 +219,6 @@ int of_pci_range_to_resource(struct of_pci_range *range, res->parent = res->child = res->sibling = NULL; res->name = np->full_name; - if (!IS_ENABLED(CONFIG_PCI)) - return -ENOSYS; - if (res->flags & IORESOURCE_IO) { unsigned long port; err = pci_register_io_range(&np->fwnode, range->cpu_addr, @@ -248,6 +251,34 @@ invalid_range: EXPORT_SYMBOL(of_pci_range_to_resource); /* + * of_range_to_resource - Create a resource from a ranges entry + * @np: device node where the range belongs to + * @index: the 'ranges' index to convert to a resource + * @res: pointer to a valid resource that will be updated to + * reflect the values contained in the range. + * + * Returns ENOENT if the entry is not found or EINVAL if the range cannot be + * converted to resource. + */ +int of_range_to_resource(struct device_node *np, int index, struct resource *res) +{ + int ret, i = 0; + struct of_range_parser parser; + struct of_range range; + + ret = of_range_parser_init(&parser, np); + if (ret) + return ret; + + for_each_of_range(&parser, &range) + if (i++ == index) + return of_pci_range_to_resource(&range, np, res); + + return -ENOENT; +} +EXPORT_SYMBOL(of_range_to_resource); + +/* * ISA bus specific translator */ @@ -303,6 +334,11 @@ static unsigned int of_bus_isa_get_flags(const __be32 *addr) return flags; } +static int of_bus_default_flags_match(struct device_node *np) +{ + return of_bus_n_addr_cells(np) == 3; +} + /* * Array of bus specific translators */ @@ -332,6 +368,17 @@ static struct of_bus of_busses[] = { .has_flags = true, .get_flags = of_bus_isa_get_flags, }, + /* Default with flags cell */ + { + .name = "default-flags", + .addresses = "reg", + .match = of_bus_default_flags_match, + .count_cells = of_bus_default_count_cells, + .map = of_bus_default_map, + .translate = of_bus_default_translate, + .has_flags = true, + .get_flags = of_bus_default_flags_get_flags, + }, /* Default */ { .name = "default", @@ -697,6 +744,29 @@ const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no, } EXPORT_SYMBOL(__of_get_address); +/** + * of_property_read_reg - Retrieve the specified "reg" entry index without translating + * @np: device tree node for which to retrieve "reg" from + * @idx: "reg" entry index to read + * @addr: return value for the untranslated address + * @size: return value for the entry size + * + * Returns -EINVAL if "reg" is not found. Returns 0 on success with addr and + * size values filled in. + */ +int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size) +{ + const __be32 *prop = of_get_address(np, idx, size, NULL); + + if (!prop) + return -EINVAL; + + *addr = of_read_number(prop, of_n_addr_cells(np)); + + return 0; +} +EXPORT_SYMBOL(of_property_read_reg); + static int parser_init(struct of_pci_range_parser *parser, struct device_node *node, const char *name) { diff --git a/drivers/of/base.c b/drivers/of/base.c index ac6fde53342f..7f1720af813c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -287,193 +287,6 @@ const void *of_get_property(const struct device_node *np, const char *name, EXPORT_SYMBOL(of_get_property); /** - * of_get_cpu_hwid - Get the hardware ID from a CPU device node - * - * @cpun: CPU number(logical index) for which device node is required - * @thread: The local thread number to get the hardware ID for. - * - * Return: The hardware ID for the CPU node or ~0ULL if not found. - */ -u64 of_get_cpu_hwid(struct device_node *cpun, unsigned int thread) -{ - const __be32 *cell; - int ac, len; - - ac = of_n_addr_cells(cpun); - cell = of_get_property(cpun, "reg", &len); - if (!cell || !ac || ((sizeof(*cell) * ac * (thread + 1)) > len)) - return ~0ULL; - - cell += ac * thread; - return of_read_number(cell, ac); -} - -/* - * arch_match_cpu_phys_id - Match the given logical CPU and physical id - * - * @cpu: logical cpu index of a core/thread - * @phys_id: physical identifier of a core/thread - * - * CPU logical to physical index mapping is architecture specific. - * However this __weak function provides a default match of physical - * id to logical cpu index. phys_id provided here is usually values read - * from the device tree which must match the hardware internal registers. - * - * Returns true if the physical identifier and the logical cpu index - * correspond to the same core/thread, false otherwise. - */ -bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) -{ - return (u32)phys_id == cpu; -} - -/* - * Checks if the given "prop_name" property holds the physical id of the - * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not - * NULL, local thread number within the core is returned in it. - */ -static bool __of_find_n_match_cpu_property(struct device_node *cpun, - const char *prop_name, int cpu, unsigned int *thread) -{ - const __be32 *cell; - int ac, prop_len, tid; - u64 hwid; - - ac = of_n_addr_cells(cpun); - cell = of_get_property(cpun, prop_name, &prop_len); - if (!cell && !ac && arch_match_cpu_phys_id(cpu, 0)) - return true; - if (!cell || !ac) - return false; - prop_len /= sizeof(*cell) * ac; - for (tid = 0; tid < prop_len; tid++) { - hwid = of_read_number(cell, ac); - if (arch_match_cpu_phys_id(cpu, hwid)) { - if (thread) - *thread = tid; - return true; - } - cell += ac; - } - return false; -} - -/* - * arch_find_n_match_cpu_physical_id - See if the given device node is - * for the cpu corresponding to logical cpu 'cpu'. Return true if so, - * else false. If 'thread' is non-NULL, the local thread number within the - * core is returned in it. - */ -bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, - int cpu, unsigned int *thread) -{ - /* Check for non-standard "ibm,ppc-interrupt-server#s" property - * for thread ids on PowerPC. If it doesn't exist fallback to - * standard "reg" property. - */ - if (IS_ENABLED(CONFIG_PPC) && - __of_find_n_match_cpu_property(cpun, - "ibm,ppc-interrupt-server#s", - cpu, thread)) - return true; - - return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread); -} - -/** - * of_get_cpu_node - Get device node associated with the given logical CPU - * - * @cpu: CPU number(logical index) for which device node is required - * @thread: if not NULL, local thread number within the physical core is - * returned - * - * The main purpose of this function is to retrieve the device node for the - * given logical CPU index. It should be used to initialize the of_node in - * cpu device. Once of_node in cpu device is populated, all the further - * references can use that instead. - * - * CPU logical to physical index mapping is architecture specific and is built - * before booting secondary cores. This function uses arch_match_cpu_phys_id - * which can be overridden by architecture specific implementation. - * - * Return: A node pointer for the logical cpu with refcount incremented, use - * of_node_put() on it when done. Returns NULL if not found. - */ -struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) -{ - struct device_node *cpun; - - for_each_of_cpu_node(cpun) { - if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) - return cpun; - } - return NULL; -} -EXPORT_SYMBOL(of_get_cpu_node); - -/** - * of_cpu_node_to_id: Get the logical CPU number for a given device_node - * - * @cpu_node: Pointer to the device_node for CPU. - * - * Return: The logical CPU number of the given CPU device_node or -ENODEV if the - * CPU is not found. - */ -int of_cpu_node_to_id(struct device_node *cpu_node) -{ - int cpu; - bool found = false; - struct device_node *np; - - for_each_possible_cpu(cpu) { - np = of_cpu_device_node_get(cpu); - found = (cpu_node == np); - of_node_put(np); - if (found) - return cpu; - } - - return -ENODEV; -} -EXPORT_SYMBOL(of_cpu_node_to_id); - -/** - * of_get_cpu_state_node - Get CPU's idle state node at the given index - * - * @cpu_node: The device node for the CPU - * @index: The index in the list of the idle states - * - * Two generic methods can be used to describe a CPU's idle states, either via - * a flattened description through the "cpu-idle-states" binding or via the - * hierarchical layout, using the "power-domains" and the "domain-idle-states" - * bindings. This function check for both and returns the idle state node for - * the requested index. - * - * Return: An idle state node if found at @index. The refcount is incremented - * for it, so call of_node_put() on it when done. Returns NULL if not found. - */ -struct device_node *of_get_cpu_state_node(struct device_node *cpu_node, - int index) -{ - struct of_phandle_args args; - int err; - - err = of_parse_phandle_with_args(cpu_node, "power-domains", - "#power-domain-cells", 0, &args); - if (!err) { - struct device_node *state_node = - of_parse_phandle(args.np, "domain-idle-states", index); - - of_node_put(args.np); - if (state_node) - return state_node; - } - - return of_parse_phandle(cpu_node, "cpu-idle-states", index); -} -EXPORT_SYMBOL(of_get_cpu_state_node); - -/** * __of_device_is_compatible() - Check if the node matches given constraints * @device: pointer to node * @compat: required compatible string, NULL or "" for any match diff --git a/drivers/of/cpu.c b/drivers/of/cpu.c new file mode 100644 index 000000000000..d17b2f851082 --- /dev/null +++ b/drivers/of/cpu.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/cpu.h> +#include <linux/kernel.h> +#include <linux/of.h> + +/** + * of_get_cpu_hwid - Get the hardware ID from a CPU device node + * + * @cpun: CPU number(logical index) for which device node is required + * @thread: The local thread number to get the hardware ID for. + * + * Return: The hardware ID for the CPU node or ~0ULL if not found. + */ +u64 of_get_cpu_hwid(struct device_node *cpun, unsigned int thread) +{ + const __be32 *cell; + int ac, len; + + ac = of_n_addr_cells(cpun); + cell = of_get_property(cpun, "reg", &len); + if (!cell || !ac || ((sizeof(*cell) * ac * (thread + 1)) > len)) + return ~0ULL; + + cell += ac * thread; + return of_read_number(cell, ac); +} + +/* + * arch_match_cpu_phys_id - Match the given logical CPU and physical id + * + * @cpu: logical cpu index of a core/thread + * @phys_id: physical identifier of a core/thread + * + * CPU logical to physical index mapping is architecture specific. + * However this __weak function provides a default match of physical + * id to logical cpu index. phys_id provided here is usually values read + * from the device tree which must match the hardware internal registers. + * + * Returns true if the physical identifier and the logical cpu index + * correspond to the same core/thread, false otherwise. + */ +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return (u32)phys_id == cpu; +} + +/* + * Checks if the given "prop_name" property holds the physical id of the + * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not + * NULL, local thread number within the core is returned in it. + */ +static bool __of_find_n_match_cpu_property(struct device_node *cpun, + const char *prop_name, int cpu, unsigned int *thread) +{ + const __be32 *cell; + int ac, prop_len, tid; + u64 hwid; + + ac = of_n_addr_cells(cpun); + cell = of_get_property(cpun, prop_name, &prop_len); + if (!cell && !ac && arch_match_cpu_phys_id(cpu, 0)) + return true; + if (!cell || !ac) + return false; + prop_len /= sizeof(*cell) * ac; + for (tid = 0; tid < prop_len; tid++) { + hwid = of_read_number(cell, ac); + if (arch_match_cpu_phys_id(cpu, hwid)) { + if (thread) + *thread = tid; + return true; + } + cell += ac; + } + return false; +} + +/* + * arch_find_n_match_cpu_physical_id - See if the given device node is + * for the cpu corresponding to logical cpu 'cpu'. Return true if so, + * else false. If 'thread' is non-NULL, the local thread number within the + * core is returned in it. + */ +bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, + int cpu, unsigned int *thread) +{ + /* Check for non-standard "ibm,ppc-interrupt-server#s" property + * for thread ids on PowerPC. If it doesn't exist fallback to + * standard "reg" property. + */ + if (IS_ENABLED(CONFIG_PPC) && + __of_find_n_match_cpu_property(cpun, + "ibm,ppc-interrupt-server#s", + cpu, thread)) + return true; + + return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread); +} + +/** + * of_get_cpu_node - Get device node associated with the given logical CPU + * + * @cpu: CPU number(logical index) for which device node is required + * @thread: if not NULL, local thread number within the physical core is + * returned + * + * The main purpose of this function is to retrieve the device node for the + * given logical CPU index. It should be used to initialize the of_node in + * cpu device. Once of_node in cpu device is populated, all the further + * references can use that instead. + * + * CPU logical to physical index mapping is architecture specific and is built + * before booting secondary cores. This function uses arch_match_cpu_phys_id + * which can be overridden by architecture specific implementation. + * + * Return: A node pointer for the logical cpu with refcount incremented, use + * of_node_put() on it when done. Returns NULL if not found. + */ +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) +{ + struct device_node *cpun; + + for_each_of_cpu_node(cpun) { + if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) + return cpun; + } + return NULL; +} +EXPORT_SYMBOL(of_get_cpu_node); + +/** + * of_cpu_device_node_get: Get the CPU device_node for a given logical CPU number + * + * @cpu: The logical CPU number + * + * Return: Pointer to the device_node for CPU with its reference count + * incremented of the given logical CPU number or NULL if the CPU device_node + * is not found. + */ +struct device_node *of_cpu_device_node_get(int cpu) +{ + struct device *cpu_dev; + cpu_dev = get_cpu_device(cpu); + if (!cpu_dev) + return of_get_cpu_node(cpu, NULL); + return of_node_get(cpu_dev->of_node); +} +EXPORT_SYMBOL(of_cpu_device_node_get); + +/** + * of_cpu_node_to_id: Get the logical CPU number for a given device_node + * + * @cpu_node: Pointer to the device_node for CPU. + * + * Return: The logical CPU number of the given CPU device_node or -ENODEV if the + * CPU is not found. + */ +int of_cpu_node_to_id(struct device_node *cpu_node) +{ + int cpu; + bool found = false; + struct device_node *np; + + for_each_possible_cpu(cpu) { + np = of_cpu_device_node_get(cpu); + found = (cpu_node == np); + of_node_put(np); + if (found) + return cpu; + } + + return -ENODEV; +} +EXPORT_SYMBOL(of_cpu_node_to_id); + +/** + * of_get_cpu_state_node - Get CPU's idle state node at the given index + * + * @cpu_node: The device node for the CPU + * @index: The index in the list of the idle states + * + * Two generic methods can be used to describe a CPU's idle states, either via + * a flattened description through the "cpu-idle-states" binding or via the + * hierarchical layout, using the "power-domains" and the "domain-idle-states" + * bindings. This function check for both and returns the idle state node for + * the requested index. + * + * Return: An idle state node if found at @index. The refcount is incremented + * for it, so call of_node_put() on it when done. Returns NULL if not found. + */ +struct device_node *of_get_cpu_state_node(struct device_node *cpu_node, + int index) +{ + struct of_phandle_args args; + int err; + + err = of_parse_phandle_with_args(cpu_node, "power-domains", + "#power-domain-cells", 0, &args); + if (!err) { + struct device_node *state_node = + of_parse_phandle(args.np, "domain-idle-states", index); + + of_node_put(args.np); + if (state_node) + return state_node; + } + + return of_parse_phandle(cpu_node, "cpu-idle-states", index); +} +EXPORT_SYMBOL(of_get_cpu_state_node); diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index fb6792d381a6..b57f1014e419 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -38,6 +38,7 @@ struct alias_prop { #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 extern struct mutex of_mutex; +extern raw_spinlock_t devtree_lock; extern struct list_head aliases_lookup; extern struct kset *of_kset; diff --git a/drivers/of/unittest-data/tests-address.dtsi b/drivers/of/unittest-data/tests-address.dtsi index 6604a52bf6cb..bc0029cbf8ea 100644 --- a/drivers/of/unittest-data/tests-address.dtsi +++ b/drivers/of/unittest-data/tests-address.dtsi @@ -14,7 +14,7 @@ #size-cells = <1>; /* ranges here is to make sure we don't use it for * dma-ranges translation */ - ranges = <0x70000000 0x70000000 0x40000000>, + ranges = <0x70000000 0x70000000 0x50000000>, <0x00000000 0xd0000000 0x20000000>; dma-ranges = <0x0 0x20000000 0x40000000>; @@ -43,6 +43,13 @@ <0x42000000 0x0 0xc0000000 0x20000000 0x0 0x10000000>; }; + bus@a0000000 { + #address-cells = <3>; + #size-cells = <2>; + ranges = <0xf00baa 0x0 0x0 0xa0000000 0x0 0x100000>, + <0xf00bee 0x1 0x0 0xb0000000 0x0 0x200000>; + }; + }; }; }; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index ab3e91445256..2191c0136531 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1008,6 +1008,153 @@ static void __init of_unittest_pci_dma_ranges(void) of_node_put(np); } +static void __init of_unittest_bus_ranges(void) +{ + struct device_node *np; + struct of_range range; + struct of_range_parser parser; + struct resource res; + int ret, count, i = 0; + + np = of_find_node_by_path("/testcase-data/address-tests"); + if (!np) { + pr_err("missing testcase data\n"); + return; + } + + if (of_range_parser_init(&parser, np)) { + pr_err("missing ranges property\n"); + return; + } + + ret = of_range_to_resource(np, 1, &res); + unittest(!ret, "of_range_to_resource returned error (%d) node %pOF\n", + ret, np); + unittest(resource_type(&res) == IORESOURCE_MEM, + "of_range_to_resource wrong resource type on node %pOF res=%pR\n", + np, &res); + unittest(res.start == 0xd0000000, + "of_range_to_resource wrong resource start address on node %pOF res=%pR\n", + np, &res); + unittest(resource_size(&res) == 0x20000000, + "of_range_to_resource wrong resource start address on node %pOF res=%pR\n", + np, &res); + + count = of_range_count(&parser); + unittest(count == 2, + "of_range_count wrong size on node %pOF count=%d\n", + np, count); + + /* + * Get the "ranges" from the device tree + */ + for_each_of_range(&parser, &range) { + unittest(range.flags == IORESOURCE_MEM, + "for_each_of_range wrong flags on node %pOF flags=%x (expected %x)\n", + np, range.flags, IORESOURCE_MEM); + if (!i) { + unittest(range.size == 0x50000000, + "for_each_of_range wrong size on node %pOF size=%llx\n", + np, range.size); + unittest(range.cpu_addr == 0x70000000, + "for_each_of_range wrong CPU addr (%llx) on node %pOF", + range.cpu_addr, np); + unittest(range.bus_addr == 0x70000000, + "for_each_of_range wrong bus addr (%llx) on node %pOF", + range.pci_addr, np); + } else { + unittest(range.size == 0x20000000, + "for_each_of_range wrong size on node %pOF size=%llx\n", + np, range.size); + unittest(range.cpu_addr == 0xd0000000, + "for_each_of_range wrong CPU addr (%llx) on node %pOF", + range.cpu_addr, np); + unittest(range.bus_addr == 0x00000000, + "for_each_of_range wrong bus addr (%llx) on node %pOF", + range.pci_addr, np); + } + i++; + } + + of_node_put(np); +} + +static void __init of_unittest_bus_3cell_ranges(void) +{ + struct device_node *np; + struct of_range range; + struct of_range_parser parser; + int i = 0; + + np = of_find_node_by_path("/testcase-data/address-tests/bus@a0000000"); + if (!np) { + pr_err("missing testcase data\n"); + return; + } + + if (of_range_parser_init(&parser, np)) { + pr_err("missing ranges property\n"); + return; + } + + /* + * Get the "ranges" from the device tree + */ + for_each_of_range(&parser, &range) { + if (!i) { + unittest(range.flags == 0xf00baa, + "for_each_of_range wrong flags on node %pOF flags=%x\n", + np, range.flags); + unittest(range.size == 0x100000, + "for_each_of_range wrong size on node %pOF size=%llx\n", + np, range.size); + unittest(range.cpu_addr == 0xa0000000, + "for_each_of_range wrong CPU addr (%llx) on node %pOF", + range.cpu_addr, np); + unittest(range.bus_addr == 0x0, + "for_each_of_range wrong bus addr (%llx) on node %pOF", + range.pci_addr, np); + } else { + unittest(range.flags == 0xf00bee, + "for_each_of_range wrong flags on node %pOF flags=%x\n", + np, range.flags); + unittest(range.size == 0x200000, + "for_each_of_range wrong size on node %pOF size=%llx\n", + np, range.size); + unittest(range.cpu_addr == 0xb0000000, + "for_each_of_range wrong CPU addr (%llx) on node %pOF", + range.cpu_addr, np); + unittest(range.bus_addr == 0x100000000, + "for_each_of_range wrong bus addr (%llx) on node %pOF", + range.pci_addr, np); + } + i++; + } + + of_node_put(np); +} + +static void __init of_unittest_reg(void) +{ + struct device_node *np; + int ret; + u64 addr, size; + + np = of_find_node_by_path("/testcase-data/address-tests/bus@80000000/device@1000"); + if (!np) { + pr_err("missing testcase data\n"); + return; + } + + ret = of_property_read_reg(np, 0, &addr, &size); + unittest(!ret, "of_property_read_reg(%pOF) returned error %d\n", + np, ret); + unittest(addr == 0x1000, "of_property_read_reg(%pOF) untranslated address (%llx) incorrect\n", + np, addr); + + of_node_put(np); +} + static void __init of_unittest_parse_interrupts(void) { struct device_node *np; @@ -3635,6 +3782,9 @@ static int __init of_unittest(void) of_unittest_dma_get_max_cpu_address(); of_unittest_parse_dma_ranges(); of_unittest_pci_dma_ranges(); + of_unittest_bus_ranges(); + of_unittest_bus_3cell_ranges(); + of_unittest_reg(); of_unittest_match_node(); of_unittest_platform_populate(); of_unittest_overlay(); diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 233eab70e15e..8246e9b7afe7 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -13,7 +13,7 @@ #include <linux/cpu.h> #include <linux/errno.h> #include <linux/device.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/pm_domain.h> #include <linux/slab.h> #include <linux/export.h> diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index d93595b39afa..5368b6ba2884 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c @@ -200,9 +200,8 @@ static int d7s_probe(struct platform_device *op) */ regs = readb(p->regs); opts = of_find_node_by_path("/options"); - if (opts && - of_get_property(opts, "d7s-flipped?", NULL)) - p->flipped = true; + if (opts) + p->flipped = of_property_read_bool(opts, "d7s-flipped?"); if (p->flipped) regs |= D7S_FLIP; diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c index b9c96182a46a..81585733c8a9 100644 --- a/drivers/soc/mediatek/mtk-svs.c +++ b/drivers/soc/mediatek/mtk-svs.c @@ -7,6 +7,7 @@ #include <linux/bits.h> #include <linux/clk.h> #include <linux/completion.h> +#include <linux/cpu.h> #include <linux/cpuidle.h> #include <linux/debugfs.h> #include <linux/device.h> diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c index 4f41102e8b16..6f6daead485e 100644 --- a/drivers/thermal/cpuidle_cooling.c +++ b/drivers/thermal/cpuidle_cooling.c @@ -7,12 +7,13 @@ */ #define pr_fmt(fmt) "cpuidle cooling: " fmt +#include <linux/cpu.h> #include <linux/cpu_cooling.h> #include <linux/cpuidle.h> #include <linux/device.h> #include <linux/err.h> #include <linux/idle_inject.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/slab.h> #include <linux/thermal.h> diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index f8b4389d60d9..e92e2ceb12a4 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -796,7 +796,7 @@ static int has_fsl_hypervisor(void) if (!node) return 0; - ret = of_find_property(node, "fsl,hv-version", NULL) != NULL; + ret = of_property_present(node, "fsl,hv-version"); of_node_put(node); diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index d4632aace402..530c77b8d062 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -87,7 +87,7 @@ static int w1_gpio_probe(struct platform_device *pdev) * driver it high/low like we are in full control of the line and * open drain will happen transparently. */ - if (of_get_property(np, "linux,open-drain", NULL)) + if (of_property_present(np, "linux,open-drain")) gflags = GPIOD_OUT_LOW; pdev->dev.platform_data = pdata; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 541013487a0e..26e2eb399484 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -15,7 +15,6 @@ #include <linux/kobject.h> #include <linux/notifier.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/pm_opp.h> #include <linux/pm_qos.h> #include <linux/spinlock.h> diff --git a/include/linux/of.h b/include/linux/of.h index 0af611307db2..bc2eb39dcf75 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -16,14 +16,10 @@ #include <linux/errno.h> #include <linux/kobject.h> #include <linux/mod_devicetable.h> -#include <linux/spinlock.h> -#include <linux/topology.h> -#include <linux/notifier.h> #include <linux/property.h> #include <linux/list.h> #include <asm/byteorder.h> -#include <asm/errno.h> typedef u32 phandle; typedef u32 ihandle; @@ -145,7 +141,6 @@ extern struct device_node *of_root; extern struct device_node *of_chosen; extern struct device_node *of_aliases; extern struct device_node *of_stdout; -extern raw_spinlock_t devtree_lock; /* * struct device_node flag descriptions @@ -361,6 +356,8 @@ extern const void *of_get_property(const struct device_node *node, const char *name, int *lenp); extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); +extern struct device_node *of_cpu_device_node_get(int cpu); +extern int of_cpu_node_to_id(struct device_node *np); extern struct device_node *of_get_next_cpu_node(struct device_node *prev); extern struct device_node *of_get_cpu_state_node(struct device_node *cpu_node, int index); @@ -373,6 +370,7 @@ extern int of_n_addr_cells(struct device_node *np); extern int of_n_size_cells(struct device_node *np); extern const struct of_device_id *of_match_node( const struct of_device_id *matches, const struct device_node *node); +extern const void *of_device_get_match_data(const struct device *dev); extern int of_modalias_node(struct device_node *node, char *modalias, int len); extern void of_print_phandle_args(const char *msg, const struct of_phandle_args *args); extern int __of_parse_phandle_with_args(const struct device_node *np, @@ -439,8 +437,6 @@ const char *of_prop_next_string(struct property *prop, const char *cur); bool of_console_check(struct device_node *dn, char *name, int index); -extern int of_cpu_node_to_id(struct device_node *np); - int of_map_id(struct device_node *np, u32 id, const char *map_name, const char *map_mask_name, struct device_node **target, u32 *id_out); @@ -635,6 +631,16 @@ static inline struct device_node *of_get_cpu_node(int cpu, return NULL; } +static inline struct device_node *of_cpu_device_node_get(int cpu) +{ + return NULL; +} + +static inline int of_cpu_node_to_id(struct device_node *np) +{ + return -ENODEV; +} + static inline struct device_node *of_get_next_cpu_node(struct device_node *prev) { return NULL; @@ -837,11 +843,6 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag { } -static inline int of_cpu_node_to_id(struct device_node *np) -{ - return -ENODEV; -} - static inline int of_map_id(struct device_node *np, u32 id, const char *map_name, const char *map_mask_name, struct device_node **target, u32 *id_out) @@ -854,6 +855,11 @@ static inline phys_addr_t of_dma_get_max_cpu_address(struct device_node *np) return PHYS_ADDR_MAX; } +static inline const void *of_device_get_match_data(const struct device *dev) +{ + return NULL; +} + #define of_match_ptr(_ptr) NULL #define of_match_node(_matches, _node) NULL #endif /* CONFIG_OF */ @@ -1512,6 +1518,8 @@ enum of_reconfig_change { OF_RECONFIG_CHANGE_REMOVE, }; +struct notifier_block; + #ifdef CONFIG_OF_DYNAMIC extern int of_reconfig_notifier_register(struct notifier_block *); extern int of_reconfig_notifier_unregister(struct notifier_block *); diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 376671594746..26a19daf0d09 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -35,6 +35,22 @@ struct of_pci_range { for (; of_pci_range_parser_one(parser, range);) #define for_each_of_range for_each_of_pci_range +/* + * of_range_count - Get the number of "ranges" or "dma-ranges" entries + * @parser: Parser state initialized by of_range_parser_init() + * + * Returns the number of entries or 0 if none. + * + * Note that calling this within or after the for_each_of_range() iterator will + * be inaccurate giving the number of entries remaining. + */ +static inline int of_range_count(const struct of_range_parser *parser) +{ + if (!parser || !parser->node || !parser->range || parser->range == parser->end) + return 0; + return (parser->end - parser->range) / (parser->na + parser->pna + parser->ns); +} + /* Translate a DMA address from device space to CPU space */ extern u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr); @@ -56,6 +72,8 @@ void __iomem *of_io_request_and_map(struct device_node *device, extern const __be32 *__of_get_address(struct device_node *dev, int index, int bar_no, u64 *size, unsigned int *flags); +int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size); + extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, struct device_node *node); extern int of_pci_dma_range_parser_init(struct of_pci_range_parser *parser, @@ -68,6 +86,8 @@ extern int of_pci_address_to_resource(struct device_node *dev, int bar, extern int of_pci_range_to_resource(struct of_pci_range *range, struct device_node *np, struct resource *res); +extern int of_range_to_resource(struct device_node *np, int index, + struct resource *res); extern bool of_dma_is_coherent(struct device_node *np); #else /* CONFIG_OF_ADDRESS */ static inline void __iomem *of_io_request_and_map(struct device_node *device, @@ -88,6 +108,11 @@ static inline const __be32 *__of_get_address(struct device_node *dev, int index, return NULL; } +static inline int of_property_read_reg(struct device_node *np, int idx, u64 *addr, u64 *size) +{ + return -ENOSYS; +} + static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser, struct device_node *node) { @@ -120,6 +145,12 @@ static inline int of_pci_range_to_resource(struct of_pci_range *range, return -ENOSYS; } +static inline int of_range_to_resource(struct device_node *np, int index, + struct resource *res) +{ + return -ENOSYS; +} + static inline bool of_dma_is_coherent(struct device_node *np) { return false; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index f4b57614979d..33f0ca348a62 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -2,14 +2,14 @@ #ifndef _LINUX_OF_DEVICE_H #define _LINUX_OF_DEVICE_H -#include <linux/cpu.h> #include <linux/platform_device.h> #include <linux/of_platform.h> /* temporary until merge */ #include <linux/of.h> -#include <linux/mod_devicetable.h> struct device; +struct of_device_id; +struct kobj_uevent_env; #ifdef CONFIG_OF extern const struct of_device_id *of_match_device( @@ -26,27 +26,12 @@ static inline int of_driver_match_device(struct device *dev, return of_match_device(drv->of_match_table, dev) != NULL; } -extern int of_device_add(struct platform_device *pdev); -extern int of_device_register(struct platform_device *ofdev); -extern void of_device_unregister(struct platform_device *ofdev); - -extern const void *of_device_get_match_data(const struct device *dev); - extern ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len); extern int of_device_request_module(struct device *dev); extern void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env); extern int of_device_uevent_modalias(const struct device *dev, struct kobj_uevent_env *env); -static inline struct device_node *of_cpu_device_node_get(int cpu) -{ - struct device *cpu_dev; - cpu_dev = get_cpu_device(cpu); - if (!cpu_dev) - return of_get_cpu_node(cpu, NULL); - return of_node_get(cpu_dev->of_node); -} - int of_dma_configure_id(struct device *dev, struct device_node *np, bool force_dma, const u32 *id); @@ -67,11 +52,6 @@ static inline int of_driver_match_device(struct device *dev, static inline void of_device_uevent(const struct device *dev, struct kobj_uevent_env *env) { } -static inline const void *of_device_get_match_data(const struct device *dev) -{ - return NULL; -} - static inline int of_device_modalias(struct device *dev, char *str, ssize_t len) { @@ -95,11 +75,6 @@ static inline const struct of_device_id *of_match_device( return NULL; } -static inline struct device_node *of_cpu_device_node_get(int cpu) -{ - return NULL; -} - static inline int of_dma_configure_id(struct device *dev, struct device_node *np, bool force_dma, diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index d15b6cd5e1c3..d8045bcfc35e 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -6,12 +6,13 @@ * <benh@kernel.crashing.org> */ -#include <linux/device.h> #include <linux/mod_devicetable.h> -#include <linux/pm.h> #include <linux/of_device.h> #include <linux/platform_device.h> +struct device; +struct of_device_id; + /** * struct of_dev_auxdata - lookup table entry for device names & platform_data * @compatible: compatible value of node to match against node @@ -52,6 +53,11 @@ extern const struct of_device_id of_default_bus_match_table[]; extern struct platform_device *of_device_alloc(struct device_node *np, const char *bus_id, struct device *parent); + +extern int of_device_add(struct platform_device *pdev); +extern int of_device_register(struct platform_device *ofdev); +extern void of_device_unregister(struct platform_device *ofdev); + #ifdef CONFIG_OF extern struct platform_device *of_find_device_by_node(struct device_node *np); #else |