Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89d463ea authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Simon Horman
Browse files

drivers: bus: Add Simple Power-Managed Bus Driver



Add a driver for transparent busses that don't need a real driver, but
where the bus controller is part of a PM domain, or under the control of
a functional clock.  Typically, the bus controller's PM domain and/or
clock must be enabled for child devices connected to the bus (either
on-SoC or externally) to function.

Hence the sole purpose of this driver is to enable its clock and PM
domain (if exist(s)), which are specified in the DT and managed from
platform and PM domain code, and to probe for child devices.

Due to the child-parent relationship with devices connected to the bus,
PM domain and clock state transitions are handled in the correct order.

Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Tested-by: default avatarUlrich Hecht <ulrich.hecht+renesas@gmail.com>
Reviewed-by: default avatarKevin Hilman <khilman@linaro.org>
Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
parent b1e5bbd6
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -58,6 +58,19 @@ config OMAP_OCP2SCP
	  OCP2SCP and in OMAP5, both USB PHY and SATA PHY is connected via
	  OCP2SCP.

config SIMPLE_PM_BUS
	bool "Simple Power-Managed Bus Driver"
	depends on OF && PM
	depends on ARCH_SHMOBILE || COMPILE_TEST
	help
	  Driver for transparent busses that don't need a real driver, but
	  where the bus controller is part of a PM domain, or under the control
	  of a functional clock, and thus relies on runtime PM for managing
	  this PM domain and/or clock.
	  An example of such a bus controller is the Renesas Bus State
	  Controller (BSC, sometimes called "LBSC within Bus Bridge", or
	  "External Bus Interface") as found on several Renesas ARM SoCs.

config VEXPRESS_CONFIG
	bool "Versatile Express configuration bus"
	default y if ARCH_VEXPRESS
+1 −0
Original line number Diff line number Diff line
@@ -14,4 +14,5 @@ obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o
obj-$(CONFIG_OMAP_INTERCONNECT)	+= omap_l3_smx.o omap_l3_noc.o

obj-$(CONFIG_OMAP_OCP2SCP)	+= omap-ocp2scp.o
obj-$(CONFIG_SIMPLE_PM_BUS)	+= simple-pm-bus.o
obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o
+58 −0
Original line number Diff line number Diff line
/*
 * Simple Power-Managed Bus Driver
 *
 * Copyright (C) 2014-2015 Glider bvba
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>


static int simple_pm_bus_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;

	dev_dbg(&pdev->dev, "%s\n", __func__);

	pm_runtime_enable(&pdev->dev);

	if (np)
		of_platform_populate(np, NULL, NULL, &pdev->dev);

	return 0;
}

static int simple_pm_bus_remove(struct platform_device *pdev)
{
	dev_dbg(&pdev->dev, "%s\n", __func__);

	pm_runtime_disable(&pdev->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 platform_driver simple_pm_bus_driver = {
	.probe = simple_pm_bus_probe,
	.remove = simple_pm_bus_remove,
	.driver = {
		.name = "simple-pm-bus",
		.of_match_table = simple_pm_bus_of_match,
	},
};

module_platform_driver(simple_pm_bus_driver);

MODULE_DESCRIPTION("Simple Power-Managed Bus Driver");
MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>");
MODULE_LICENSE("GPL v2");