// SPDX-License-Identifier: GPL-2.0
/*
 * 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/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>

struct simple_pm_bus {
	struct clk_bulk_data *clks;
	int num_clks;
};

static int simple_pm_bus_probe(struct platform_device *pdev)
{
	const struct device *dev = &pdev->dev;
	const struct of_dev_auxdata *lookup = dev_get_platdata(dev);
	struct device_node *np = dev->of_node;
	const struct of_device_id *match;
	struct simple_pm_bus *bus;

	/*
	 * Allow user to use driver_override to bind this driver to a
	 * transparent bus device which has a different compatible string
	 * that's not listed in simple_pm_bus_of_match. We don't want to do any
	 * of the simple-pm-bus tasks for these devices, so return early.
	 */
	if (pdev->driver_override)
		return 0;

	match = of_match_device(dev->driver->of_match_table, dev);
	/*
	 * These are transparent bus devices (not simple-pm-bus matches) that
	 * have their child nodes populated automatically.  So, don't need to
	 * do anything more. We only match with the device if this driver is
	 * the most specific match because we don't want to incorrectly bind to
	 * a device that has a more specific driver.
	 */
	if (match && match->data) {
		if (of_property_match_string(np, "compatible", match->compatible) == 0)
			return 0;
		else
			return -ENODEV;
	}

	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
	if (!bus)
		return -ENOMEM;

	bus->num_clks = devm_clk_bulk_get_all(&pdev->dev, &bus->clks);
	if (bus->num_clks < 0)
		return dev_err_probe(&pdev->dev, bus->num_clks, "failed to get clocks\n");

	dev_set_drvdata(&pdev->dev, bus);

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

	pm_runtime_enable(&pdev->dev);

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

	return 0;
}

static void simple_pm_bus_remove(struct platform_device *pdev)
{
	const void *data = of_device_get_match_data(&pdev->dev);

	if (pdev->driver_override || data)
		return;

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

	pm_runtime_disable(&pdev->dev);
}

static int simple_pm_bus_runtime_suspend(struct device *dev)
{
	struct simple_pm_bus *bus = dev_get_drvdata(dev);

	clk_bulk_disable_unprepare(bus->num_clks, bus->clks);

	return 0;
}

static int simple_pm_bus_runtime_resume(struct device *dev)
{
	struct simple_pm_bus *bus = dev_get_drvdata(dev);
	int ret;

	ret = clk_bulk_prepare_enable(bus->num_clks, bus->clks);
	if (ret) {
		dev_err(dev, "failed to enable clocks: %d\n", ret);
		return ret;
	}

	return 0;
}

static int simple_pm_bus_suspend(struct device *dev)
{
	struct simple_pm_bus *bus = dev_get_drvdata(dev);

	if (!bus)
		return 0;

	return pm_runtime_force_suspend(dev);
}

static int simple_pm_bus_resume(struct device *dev)
{
	struct simple_pm_bus *bus = dev_get_drvdata(dev);

	if (!bus)
		return 0;

	return pm_runtime_force_resume(dev);
}

static const struct dev_pm_ops simple_pm_bus_pm_ops = {
	RUNTIME_PM_OPS(simple_pm_bus_runtime_suspend, simple_pm_bus_runtime_resume, NULL)
	NOIRQ_SYSTEM_SLEEP_PM_OPS(simple_pm_bus_suspend, simple_pm_bus_resume)
};

#define ONLY_BUS	((void *) 1) /* Match if the device is only a bus. */

static const struct of_device_id simple_pm_bus_of_match[] = {
	{ .compatible = "simple-pm-bus", },
	{ .compatible = "simple-bus",	.data = ONLY_BUS },
	{ .compatible = "simple-mfd",	.data = ONLY_BUS },
	{ .compatible = "isa",		.data = ONLY_BUS },
	{ .compatible = "arm,amba-bus",	.data = ONLY_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,
		.pm = pm_ptr(&simple_pm_bus_pm_ops),
	},
};

module_platform_driver(simple_pm_bus_driver);

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