// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
// Copyright(c) 2015-17 Intel Corporation.

/*
 * SDW Intel Init Routines
 *
 * Initializes and creates SDW devices based on ACPI and Hardware values
 */

#include <linux/acpi.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/soundwire/sdw_intel.h>
#include "intel.h"

#define SDW_LINK_TYPE		4 /* from Intel ACPI documentation */
#define SDW_MAX_LINKS		4
#define SDW_SHIM_LCAP		0x0
#define SDW_SHIM_BASE		0x2C000
#define SDW_ALH_BASE		0x2C800
#define SDW_LINK_BASE		0x30000
#define SDW_LINK_SIZE		0x10000

static int link_mask;
module_param_named(sdw_link_mask, link_mask, int, 0444);
MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)");

struct sdw_link_data {
	struct sdw_intel_link_res res;
	struct platform_device *pdev;
};

struct sdw_intel_ctx {
	int count;
	struct sdw_link_data *links;
};

static int sdw_intel_cleanup_pdev(struct sdw_intel_ctx *ctx)
{
	struct sdw_link_data *link = ctx->links;
	int i;

	if (!link)
		return 0;

	for (i = 0; i < ctx->count; i++) {
		if (link->pdev)
			platform_device_unregister(link->pdev);
		link++;
	}

	kfree(ctx->links);
	ctx->links = NULL;

	return 0;
}

static struct sdw_intel_ctx
*sdw_intel_add_controller(struct sdw_intel_res *res)
{
	struct platform_device_info pdevinfo;
	struct platform_device *pdev;
	struct sdw_link_data *link;
	struct sdw_intel_ctx *ctx;
	struct acpi_device *adev;
	int ret, i;
	u8 count;
	u32 caps;

	if (acpi_bus_get_device(res->handle, &adev))
		return NULL;

	/* Found controller, find links supported */
	count = 0;
	ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
					    "mipi-sdw-master-count", &count, 1);

	/* Don't fail on error, continue and use hw value */
	if (ret) {
		dev_err(&adev->dev,
			"Failed to read mipi-sdw-master-count: %d\n", ret);
		count = SDW_MAX_LINKS;
	}

	/* Check SNDWLCAP.LCOUNT */
	caps = ioread32(res->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
	caps &= GENMASK(2, 0);

	/* Check HW supported vs property value and use min of two */
	count = min_t(u8, caps, count);

	/* Check count is within bounds */
	if (count > SDW_MAX_LINKS) {
		dev_err(&adev->dev, "Link count %d exceeds max %d\n",
			count, SDW_MAX_LINKS);
		return NULL;
	} else if (!count) {
		dev_warn(&adev->dev, "No SoundWire links detected\n");
		return NULL;
	}

	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return NULL;

	ctx->count = count;
	ctx->links = kcalloc(ctx->count, sizeof(*ctx->links), GFP_KERNEL);
	if (!ctx->links)
		goto link_err;

	link = ctx->links;

	/* Create SDW Master devices */
	for (i = 0; i < count; i++) {
		if (link_mask && !(link_mask & BIT(i))) {
			dev_dbg(&adev->dev,
				"Link %d masked, will not be enabled\n", i);
			link++;
			continue;
		}

		link->res.irq = res->irq;
		link->res.registers = res->mmio_base + SDW_LINK_BASE
					+ (SDW_LINK_SIZE * i);
		link->res.shim = res->mmio_base + SDW_SHIM_BASE;
		link->res.alh = res->mmio_base + SDW_ALH_BASE;

		link->res.ops = res->ops;
		link->res.arg = res->arg;

		memset(&pdevinfo, 0, sizeof(pdevinfo));

		pdevinfo.parent = res->parent;
		pdevinfo.name = "int-sdw";
		pdevinfo.id = i;
		pdevinfo.fwnode = acpi_fwnode_handle(adev);
		pdevinfo.data = &link->res;
		pdevinfo.size_data = sizeof(link->res);

		pdev = platform_device_register_full(&pdevinfo);
		if (IS_ERR(pdev)) {
			dev_err(&adev->dev,
				"platform device creation failed: %ld\n",
				PTR_ERR(pdev));
			goto pdev_err;
		}

		link->pdev = pdev;
		link++;
	}

	return ctx;

pdev_err:
	sdw_intel_cleanup_pdev(ctx);
link_err:
	kfree(ctx);
	return NULL;
}

static acpi_status sdw_intel_acpi_cb(acpi_handle handle, u32 level,
				     void *cdata, void **return_value)
{
	struct sdw_intel_res *res = cdata;
	struct acpi_device *adev;
	acpi_status status;
	u64 adr;

	status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
	if (ACPI_FAILURE(status))
		return AE_OK; /* keep going */

	if (acpi_bus_get_device(handle, &adev)) {
		pr_err("%s: Couldn't find ACPI handle\n", __func__);
		return AE_NOT_FOUND;
	}

	res->handle = handle;

	/*
	 * On some Intel platforms, multiple children of the HDAS
	 * device can be found, but only one of them is the SoundWire
	 * controller. The SNDW device is always exposed with
	 * Name(_ADR, 0x40000000), with bits 31..28 representing the
	 * SoundWire link so filter accordingly
	 */
	if ((adr & GENMASK(31, 28)) >> 28 != SDW_LINK_TYPE)
		return AE_OK; /* keep going */

	/* device found, stop namespace walk */
	return AE_CTRL_TERMINATE;
}

/**
 * sdw_intel_init() - SoundWire Intel init routine
 * @parent_handle: ACPI parent handle
 * @res: resource data
 *
 * This scans the namespace and creates SoundWire link controller devices
 * based on the info queried.
 */
void *sdw_intel_init(acpi_handle *parent_handle, struct sdw_intel_res *res)
{
	acpi_status status;

	status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
				     parent_handle, 1,
				     sdw_intel_acpi_cb,
				     NULL, res, NULL);
	if (ACPI_FAILURE(status))
		return NULL;

	return sdw_intel_add_controller(res);
}
EXPORT_SYMBOL(sdw_intel_init);

/**
 * sdw_intel_exit() - SoundWire Intel exit
 * @arg: callback context
 *
 * Delete the controller instances created and cleanup
 */
void sdw_intel_exit(void *arg)
{
	struct sdw_intel_ctx *ctx = arg;

	sdw_intel_cleanup_pdev(ctx);
	kfree(ctx);
}
EXPORT_SYMBOL(sdw_intel_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("Intel Soundwire Init Library");
