From: Ahmad Fatoum <[email protected]> simple-pm-bus is currently handled exactly the same as simple-bus in barebox with the assumption that clocks/power-domains are already enabled.
This is not necessarily the case, so let's add a driver for simple-pm-bus that actually does power management and keep the old behavior the same for devices without deep probe. Signed-off-by: Ahmad Fatoum <[email protected]> --- v2 -> v3: - new change --- drivers/bus/Kconfig | 10 ++++++++ drivers/bus/Makefile | 1 + drivers/bus/simple-pm-bus.c | 47 +++++++++++++++++++++++++++++++++++++ drivers/of/base.c | 2 ++ 4 files changed, 60 insertions(+) create mode 100644 drivers/bus/simple-pm-bus.c diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index b480cf8bff0f..9b2e0c0ae8ea 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -34,4 +34,14 @@ config ACPI Driver needed for supporting drivers probed from ACPI tables. The root SDT is found via UEFI. +config OF_SIMPLE_PM_BUS + def_bool PM_GENERIC_DOMAINS + prompt "Simple Power-managed bus" if COMPILE_TEST + depends on OFDEVICE + help + simple-pm-bus is a bus that may have clocks and power domains + that need to be enabled before the bus may be accessed. + If this option is disabled or deep probe is not enabled at + runtime, simple-pm-bus will be treated identically to simple-bus. + endmenu diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 2c54b3ea307d..1e18c14b970c 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_IMX_WEIM) += imx-weim.o obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o obj-$(CONFIG_TI_SYSC) += ti-sysc.o obj-$(CONFIG_ACPI) += acpi.o +obj-$(CONFIG_OF_SIMPLE_PM_BUS) += simple-pm-bus.o diff --git a/drivers/bus/simple-pm-bus.c b/drivers/bus/simple-pm-bus.c new file mode 100644 index 000000000000..8536982b69c4 --- /dev/null +++ b/drivers/bus/simple-pm-bus.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Simple Power-Managed Bus Driver + * + * Copyright (C) 2014-2015 Glider bvba + */ + +#include <linux/clk.h> +#include <driver.h> +#include <of.h> + +static int simple_pm_bus_probe(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct clk_bulk_data *clks; + int num_clks; + + if (deep_probe_is_supported()) { + num_clks = clk_bulk_get_all(dev, &clks); + if (num_clks < 0) + return dev_err_probe(dev, num_clks, "failed to get clocks\n"); + + num_clks = clk_bulk_prepare_enable(num_clks, clks); + if (num_clks) + return dev_err_probe(dev, num_clks, "failed to enable clocks\n"); + } + + of_platform_populate(np, NULL, dev); + + return 0; +} + +static const struct of_device_id simple_pm_bus_of_match[] = { + { .compatible = "simple-pm-bus", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, simple_pm_bus_of_match); + +static struct driver simple_pm_bus_driver = { + .probe = simple_pm_bus_probe, + .name = "simple-pm-bus", + .of_match_table = simple_pm_bus_of_match, +}; +core_platform_driver(simple_pm_bus_driver); + +MODULE_DESCRIPTION("Simple Power-Managed Bus Driver"); +MODULE_AUTHOR("Geert Uytterhoeven <[email protected]>"); diff --git a/drivers/of/base.c b/drivers/of/base.c index 15265dc22623..3cec2878efab 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -2875,8 +2875,10 @@ const struct of_device_id of_default_bus_match_table[] = { { .compatible = "simple-bus", }, { +#ifndef CONFIG_OF_SIMPLE_PM_BUS .compatible = "simple-pm-bus", }, { +#endif .compatible = "simple-mfd", }, { /* sentinel */ -- 2.47.3
