/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_domain.h>
#include <soc/imx/fsl_sip.h>

#define GPC_MAX_IRQS		(4 * 32)

struct imx_gpc_pm_domain {
	const char name[30];
	struct device *dev;
	struct generic_pm_domain pd;
	u32 gpc_domain_id;
	struct clk **clks;
	unsigned int num_clks;
	struct regulator *reg;
};

enum imx_gpc_pm_domain_state {
	GPC_PD_STATE_OFF,
	GPC_PD_STATE_ON,
};

#define to_imx_gpc_pm_domain(_genpd) container_of(_genpd, struct imx_gpc_pm_domain, pd)

static DEFINE_SPINLOCK(gpc_psci_lock);
static DEFINE_MUTEX(gpc_pd_mutex);

static void imx_gpc_psci_irq_unmask(struct irq_data *d)
{
	struct arm_smccc_res res;

	spin_lock(&gpc_psci_lock);
	arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_UNMASK, d->hwirq,
		      0, 0, 0, 0, 0, &res);
	spin_unlock(&gpc_psci_lock);

	irq_chip_unmask_parent(d);
}

static void imx_gpc_psci_irq_mask(struct irq_data *d)
{
	struct arm_smccc_res res;

	spin_lock(&gpc_psci_lock);
	arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_MASK, d->hwirq,
		      0, 0, 0, 0, 0, &res);
	spin_unlock(&gpc_psci_lock);

	irq_chip_mask_parent(d);
}
static int imx_gpc_psci_irq_set_wake(struct irq_data *d, unsigned int on)
{
	struct arm_smccc_res res;

	spin_lock(&gpc_psci_lock);
	arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_SET_WAKE, d->hwirq,
		      on, 0, 0, 0, 0, &res);
	spin_unlock(&gpc_psci_lock);

	return 0;
}

static int imx_gpc_psci_irq_set_affinity(struct irq_data *d,
					 const struct cpumask *dest, bool force)
{
	/* parse the cpu of irq affinity */
	struct arm_smccc_res res;
	int cpu = cpumask_any_and(dest, cpu_online_mask);

	irq_chip_set_affinity_parent(d, dest, force);

	spin_lock(&gpc_psci_lock);
	arm_smccc_smc(FSL_SIP_GPC, 0x4, d->hwirq,
		      cpu, 0, 0, 0, 0, &res);
	spin_unlock(&gpc_psci_lock);

	return 0;
}

static struct irq_chip imx_gpc_psci_chip = {
	.name			= "GPC-PSCI",
	.irq_eoi		= irq_chip_eoi_parent,
	.irq_mask		= imx_gpc_psci_irq_mask,
	.irq_unmask		= imx_gpc_psci_irq_unmask,
	.irq_retrigger		= irq_chip_retrigger_hierarchy,
	.irq_set_wake		= imx_gpc_psci_irq_set_wake,
	.irq_set_affinity	= imx_gpc_psci_irq_set_affinity,
};

static int imx_gpc_psci_domain_translate(struct irq_domain *d,
				    struct irq_fwspec *fwspec,
				    unsigned long *hwirq,
				    unsigned int *type)
{
	if (is_of_node(fwspec->fwnode)) {
		if (fwspec->param_count != 3)
			return -EINVAL;

		/* No PPI should point to this domain */
		if (fwspec->param[0] != 0)
			return -EINVAL;

		*hwirq = fwspec->param[1];
		*type = fwspec->param[2];
		return 0;
	}

	return -EINVAL;
}

static int imx_gpc_psci_domain_alloc(struct irq_domain *domain,
				  unsigned int irq,
				  unsigned int nr_irqs, void *data)
{
	struct irq_fwspec *fwspec = data;
	struct irq_fwspec parent_fwspec;
	irq_hw_number_t hwirq;
	int i;

	if (fwspec->param_count != 3)
		return -EINVAL;	/* Not GIC compliant */
	if (fwspec->param[0] != 0)
		return -EINVAL;	/* No PPI should point to this domain */

	hwirq = fwspec->param[1];
	if (hwirq >= GPC_MAX_IRQS)
		return -EINVAL;	/* Can't deal with this */

	for (i = 0; i < nr_irqs; i++)
		irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
					      &imx_gpc_psci_chip, NULL);

	parent_fwspec = *fwspec;
	parent_fwspec.fwnode = domain->parent->fwnode;

	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
					    &parent_fwspec);
}

static struct irq_domain_ops imx_gpc_psci_domain_ops = {
	.translate = imx_gpc_psci_domain_translate,
	.alloc	= imx_gpc_psci_domain_alloc,
	.free	= irq_domain_free_irqs_common,
};

static int __init imx_gpc_psci_init(struct device_node *node,
			       struct device_node *parent)
{
	struct irq_domain *parent_domain, *domain;

	if (!parent) {
		pr_err("%s: no parent, giving up\n", node->full_name);
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent);
	if (!parent_domain) {
		pr_err("%s: unable to obtain parent domain\n", node->full_name);
		return -ENXIO;
	}

	domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
					  node, &imx_gpc_psci_domain_ops,
					  NULL);
	if (!domain)
		return -ENOMEM;

	return 0;
}
IRQCHIP_DECLARE(imx_gpc_psci, "fsl,imx8mq-gpc", imx_gpc_psci_init);

static int imx_gpc_pd_power_on(struct generic_pm_domain *domain)
{
	struct imx_gpc_pm_domain *pd = to_imx_gpc_pm_domain(domain);
	struct arm_smccc_res res;
	int index, ret = 0;

	/* power on the external supply */
	if (pd->reg) {
		ret = regulator_enable(pd->reg);
		if (ret) {
			dev_warn(pd->dev, "failed to power up the reg%d\n", ret);
			return ret;
		}
	}

	/* enable the necessary clks needed by the power domain */
	if (pd->num_clks) {
		for (index = 0; index < pd->num_clks; index++)
			clk_prepare_enable(pd->clks[index]);
	}

	mutex_lock(&gpc_pd_mutex);
	arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, pd->gpc_domain_id,
		      GPC_PD_STATE_ON, 0, 0, 0, 0, &res);
	mutex_unlock(&gpc_pd_mutex);

	return 0;
}

static int imx_gpc_pd_power_off(struct generic_pm_domain *domain)
{
	struct imx_gpc_pm_domain *pd = to_imx_gpc_pm_domain(domain);
	struct arm_smccc_res res;
	int index, ret = 0;

	mutex_lock(&gpc_pd_mutex);
	arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_PM_DOMAIN, pd->gpc_domain_id,
		      GPC_PD_STATE_OFF, 0, 0, 0, 0, &res);
	mutex_unlock(&gpc_pd_mutex);

	/* power off the external supply */
	if (pd->reg) {
		ret = regulator_disable(pd->reg);
		if (ret) {
			dev_warn(pd->dev, "failed to power off the reg%d\n", ret);
			return ret;
		}
	}

	/* disable the necessary clks when power domain on finished */
	if (pd->num_clks) {
		for (index = 0; index < pd->num_clks; index++)
			clk_disable_unprepare(pd->clks[index]);
	}

	return ret;
};

static int imx8m_pd_clk_init(struct device_node *np,
			     struct imx_gpc_pm_domain *domain)
{
	struct property *pp;
	struct clk **clks;
	int index;

	pp = of_find_property(np, "clocks", NULL);
	if (pp)
		domain->num_clks = pp->length / 8;
	else
		domain->num_clks = 0;

	if (domain->num_clks) {
		clks = kcalloc(domain->num_clks, sizeof(*clks), GFP_KERNEL);
		if (!clks) {
			domain->num_clks = 0;
			domain->clks = NULL;
			return -ENOMEM;
		}

		domain->clks = clks;
	}

	for (index = 0; index < domain->num_clks; index++) {
		clks[index] = of_clk_get(np, index);
		if (IS_ERR(clks[index])) {
			for (index = 0; index < domain->num_clks; index++) {
				if (!IS_ERR(clks[index]))
					clk_put(clks[index]);
			}

			domain->num_clks = 0;
			domain->clks = NULL;
			kfree(clks);
			pr_warn("imx8m domain clock init failed\n");
			return -ENODEV;
		}
	}

	return 0;
}

static int imx8m_add_subdomain(struct device_node *parent,
			       struct generic_pm_domain *parent_pd)
{
	struct device_node *child_node;
	struct imx_gpc_pm_domain *child_domain;
	int ret = 0;

	/* add each of the child domain of parent */
	for_each_child_of_node(parent, child_node) {
		if (!of_device_is_available(child_node))
			continue;

		child_domain = kzalloc(sizeof(*child_domain), GFP_KERNEL);
		if (!child_domain)
			return -ENOMEM;

		ret = of_property_read_string(child_node, "domain-name",
					      &child_domain->pd.name);
		if (ret)
			goto exit;

		ret = of_property_read_u32(child_node, "domain-id",
					   &child_domain->gpc_domain_id);
		if (ret)
			goto exit;

		child_domain->pd.power_off = imx_gpc_pd_power_off;
		child_domain->pd.power_on = imx_gpc_pd_power_on;
		/* no reg for subdomains */
		child_domain->reg = NULL;

		imx8m_pd_clk_init(child_node, child_domain);

		/* power domains as off at boot */
		pm_genpd_init(&child_domain->pd, NULL, true);

		/* add subdomain of parent power domain */
		pm_genpd_add_subdomain(parent_pd, &child_domain->pd);

		ret = of_genpd_add_provider_simple(child_node,
						 &child_domain->pd);
		if (ret)
			pr_err("failed to add subdomain\n");
	}

	return 0;
exit:
	kfree(child_domain);
	return ret;
};

static int imx_gpc_pm_domain_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct imx_gpc_pm_domain *imx_pm_domain;
	int ret = 0;

	if (!np) {
		dev_err(dev, "power domain device tree node not found\n");
		return -ENODEV;
	}

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

	ret = of_property_read_string(np, "domain-name", &imx_pm_domain->pd.name);
	if (ret) {
		dev_err(dev, "get domain name failed\n");
		return -EINVAL;
	}

	ret = of_property_read_u32(np, "domain-id", &imx_pm_domain->gpc_domain_id);
	if (ret) {
		dev_err(dev, "get domain id failed\n");
		return -EINVAL;
	}

	imx_pm_domain->reg = devm_regulator_get_optional(dev, "power");
	if (IS_ERR(imx_pm_domain->reg)) {
		if (PTR_ERR(imx_pm_domain->reg) == -EPROBE_DEFER)
			return -EPROBE_DEFER;

		imx_pm_domain->reg = NULL;
	}

	imx8m_pd_clk_init(np, imx_pm_domain);

	imx_pm_domain->pd.power_off = imx_gpc_pd_power_off;
	imx_pm_domain->pd.power_on = imx_gpc_pd_power_on;
	/* all power domains as off at boot */
	pm_genpd_init(&imx_pm_domain->pd, NULL, true);

	ret = of_genpd_add_provider_simple(np,
				 &imx_pm_domain->pd);

	/* add subdomain */
	ret = imx8m_add_subdomain(np, &imx_pm_domain->pd);
	if (ret)
		dev_warn(dev, "please check the child power domain init\n");

	return 0;
}

static const struct of_device_id imx_gpc_pm_domain_ids[] = {
	{.compatible = "fsl,imx8mq-pm-domain"},
	{.compatible = "fsl,imx8mm-pm-domain"},
	{},
};

static struct platform_driver imx_gpc_pm_domain_driver = {
	.driver = {
		.name	= "imx8m_gpc_pm_domain",
		.owner	= THIS_MODULE,
		.of_match_table = imx_gpc_pm_domain_ids,
	},
	.probe = imx_gpc_pm_domain_probe,
};

module_platform_driver(imx_gpc_pm_domain_driver);

MODULE_AUTHOR("NXP");
MODULE_DESCRIPTION("NXP i.MX8M GPC power domain driver");
MODULE_LICENSE("GPL v2");
