// SPDX-License-Identifier: GPL-2.0-only
/*
 * ARM Integrator Logical Module bus driver
 * Copyright (C) 2020 Linaro Ltd.
 * Author: Linus Walleij <linus.walleij@linaro.org>
 *
 * See the device tree bindings for this block for more details on the
 * hardware.
 */

#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>

/* All information about the connected logic modules are in here */
#define INTEGRATOR_SC_DEC_OFFSET	0x10

/* Base address for the expansion modules */
#define INTEGRATOR_AP_EXP_BASE		0xc0000000
#define INTEGRATOR_AP_EXP_STRIDE	0x10000000

static int integrator_lm_populate(int num, struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct device_node *child;
	u32 base;
	int ret;

	base = INTEGRATOR_AP_EXP_BASE + (num * INTEGRATOR_AP_EXP_STRIDE);

	/* Walk over the child nodes and see what chipselects we use */
	for_each_available_child_of_node(np, child) {
		struct resource res;

		ret = of_address_to_resource(child, 0, &res);
		if (ret) {
			dev_info(dev, "no valid address on child\n");
			continue;
		}

		/* First populate the syscon then any devices */
		if (res.start == base) {
			dev_info(dev, "populate module @0x%08x from DT\n",
				 base);
			ret = of_platform_default_populate(child, NULL, dev);
			if (ret) {
				dev_err(dev, "failed to populate module\n");
				of_node_put(child);
				return ret;
			}
		}
	}

	return 0;
}

static const struct of_device_id integrator_ap_syscon_match[] = {
	{ .compatible = "arm,integrator-ap-syscon"},
	{ },
};

static int integrator_ap_lm_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *syscon;
	static struct regmap *map;
	u32 val;
	int ret;
	int i;

	/* Look up the system controller */
	syscon = of_find_matching_node(NULL, integrator_ap_syscon_match);
	if (!syscon) {
		dev_err(dev,
			"could not find Integrator/AP system controller\n");
		return -ENODEV;
	}
	map = syscon_node_to_regmap(syscon);
	of_node_put(syscon);
	if (IS_ERR(map)) {
		dev_err(dev,
			"could not find Integrator/AP system controller\n");
		return PTR_ERR(map);
	}

	ret = regmap_read(map, INTEGRATOR_SC_DEC_OFFSET, &val);
	if (ret) {
		dev_err(dev, "could not read from Integrator/AP syscon\n");
		return ret;
	}

	/* Loop over the connected modules */
	for (i = 0; i < 4; i++) {
		if (!(val & BIT(4 + i)))
			continue;

		dev_info(dev, "detected module in slot %d\n", i);
		ret = integrator_lm_populate(i, dev);
		if (ret)
			return ret;
	}

	return 0;
}

static const struct of_device_id integrator_ap_lm_match[] = {
	{ .compatible = "arm,integrator-ap-lm"},
	{ },
};

static struct platform_driver integrator_ap_lm_driver = {
	.probe = integrator_ap_lm_probe,
	.driver = {
		.name = "integratorap-lm",
		.of_match_table = integrator_ap_lm_match,
	},
};
module_platform_driver(integrator_ap_lm_driver);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_DESCRIPTION("Integrator AP Logical Module driver");
