// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/types.h>

#include "spi-pxa2xx.h"

static bool pxa2xx_spi_idma_filter(struct dma_chan *chan, void *param)
{
	return param == chan->device->dev;
}

static int
pxa2xx_spi_init_ssp(struct platform_device *pdev, struct ssp_device *ssp, enum pxa_ssp_type type)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	int status;
	u64 uid;

	ssp->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(ssp->mmio_base))
		return PTR_ERR(ssp->mmio_base);

	ssp->phys_base = res->start;

	ssp->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(ssp->clk))
		return PTR_ERR(ssp->clk);

	ssp->irq = platform_get_irq(pdev, 0);
	if (ssp->irq < 0)
		return ssp->irq;

	ssp->type = type;
	ssp->dev = dev;

	status = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid);
	if (status)
		ssp->port_id = -1;
	else
		ssp->port_id = uid;

	return 0;
}

static void pxa2xx_spi_ssp_release(void *ssp)
{
	pxa_ssp_free(ssp);
}

static struct ssp_device *pxa2xx_spi_ssp_request(struct platform_device *pdev)
{
	struct ssp_device *ssp;
	int status;

	ssp = pxa_ssp_request(pdev->id, pdev->name);
	if (!ssp)
		return NULL;

	status = devm_add_action_or_reset(&pdev->dev, pxa2xx_spi_ssp_release, ssp);
	if (status)
		return ERR_PTR(status);

	return ssp;
}

static struct pxa2xx_spi_controller *
pxa2xx_spi_init_pdata(struct platform_device *pdev)
{
	struct pxa2xx_spi_controller *pdata;
	struct device *dev = &pdev->dev;
	struct device *parent = dev->parent;
	const void *match = device_get_match_data(dev);
	enum pxa_ssp_type type = SSP_UNDEFINED;
	struct ssp_device *ssp;
	bool is_lpss_priv;
	u32 num_cs = 1;
	int status;

	ssp = pxa2xx_spi_ssp_request(pdev);
	if (IS_ERR(ssp))
		return ERR_CAST(ssp);
	if (ssp) {
		type = ssp->type;
	} else if (match) {
		type = (enum pxa_ssp_type)(uintptr_t)match;
	} else {
		u32 value;

		status = device_property_read_u32(dev, "intel,spi-pxa2xx-type", &value);
		if (status)
			return ERR_PTR(status);

		type = (enum pxa_ssp_type)value;
	}

	/* Validate the SSP type correctness */
	if (!(type > SSP_UNDEFINED && type < SSP_MAX))
		return ERR_PTR(-EINVAL);

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	/* Platforms with iDMA 64-bit */
	is_lpss_priv = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpss_priv");
	if (is_lpss_priv) {
		pdata->tx_param = parent;
		pdata->rx_param = parent;
		pdata->dma_filter = pxa2xx_spi_idma_filter;
	}

	/* Read number of chip select pins, if provided */
	device_property_read_u32(dev, "num-cs", &num_cs);

	pdata->num_chipselect = num_cs;
	pdata->is_target = device_property_read_bool(dev, "spi-slave");
	pdata->enable_dma = true;
	pdata->dma_burst_size = 1;

	/* If SSP has been already enumerated, use it */
	if (ssp)
		return pdata;

	status = pxa2xx_spi_init_ssp(pdev, &pdata->ssp, type);
	if (status)
		return ERR_PTR(status);

	return pdata;
}

static int pxa2xx_spi_platform_probe(struct platform_device *pdev)
{
	struct pxa2xx_spi_controller *platform_info;
	struct device *dev = &pdev->dev;
	struct ssp_device *ssp;
	int ret;

	platform_info = dev_get_platdata(dev);
	if (!platform_info) {
		platform_info = pxa2xx_spi_init_pdata(pdev);
		if (IS_ERR(platform_info))
			return dev_err_probe(dev, PTR_ERR(platform_info), "missing platform data\n");
	}

	ssp = pxa2xx_spi_ssp_request(pdev);
	if (IS_ERR(ssp))
		return PTR_ERR(ssp);
	if (!ssp)
		ssp = &platform_info->ssp;

	pm_runtime_set_autosuspend_delay(dev, 50);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	ret = pxa2xx_spi_probe(dev, ssp, platform_info);
	if (ret)
		pm_runtime_disable(dev);

	return ret;
}

static void pxa2xx_spi_platform_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;

	pm_runtime_get_sync(dev);

	pxa2xx_spi_remove(dev);

	pm_runtime_put_noidle(dev);
	pm_runtime_disable(dev);
}

static const struct acpi_device_id pxa2xx_spi_acpi_match[] = {
	{ "80860F0E" },
	{ "8086228E" },
	{ "INT33C0" },
	{ "INT33C1" },
	{ "INT3430" },
	{ "INT3431" },
	{}
};
MODULE_DEVICE_TABLE(acpi, pxa2xx_spi_acpi_match);

static const struct of_device_id pxa2xx_spi_of_match[] = {
	{ .compatible = "marvell,mmp2-ssp", .data = (void *)MMP2_SSP },
	{}
};
MODULE_DEVICE_TABLE(of, pxa2xx_spi_of_match);

static struct platform_driver driver = {
	.driver = {
		.name	= "pxa2xx-spi",
		.pm	= pm_ptr(&pxa2xx_spi_pm_ops),
		.acpi_match_table = pxa2xx_spi_acpi_match,
		.of_match_table = pxa2xx_spi_of_match,
	},
	.probe = pxa2xx_spi_platform_probe,
	.remove_new = pxa2xx_spi_platform_remove,
};

static int __init pxa2xx_spi_init(void)
{
	return platform_driver_register(&driver);
}
subsys_initcall(pxa2xx_spi_init);

static void __exit pxa2xx_spi_exit(void)
{
	platform_driver_unregister(&driver);
}
module_exit(pxa2xx_spi_exit);

MODULE_AUTHOR("Stephen Street");
MODULE_DESCRIPTION("PXA2xx SSP SPI Controller platform driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS(SPI_PXA2xx);
MODULE_ALIAS("platform:pxa2xx-spi");
MODULE_SOFTDEP("pre: dw_dmac");
