// SPDX-License-Identifier: GPL-2.0-only
/*
 * RISC-V SBI CPU idle driver.
 *
 * Copyright (c) 2021 Western Digital Corporation or its affiliates.
 * Copyright (c) 2022 Ventana Micro Systems Inc.
 */

#define pr_fmt(fmt) "cpuidle-riscv-sbi: " fmt

#include <linux/cpuidle.h>
#include <linux/cpumask.h>
#include <linux/cpu_pm.h>
#include <linux/cpu_cooling.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <asm/cpuidle.h>
#include <asm/sbi.h>
#include <asm/smp.h>
#include <asm/suspend.h>

#include "dt_idle_states.h"
#include "dt_idle_genpd.h"

struct sbi_cpuidle_data {
	u32 *states;
	struct device *dev;
};

struct sbi_domain_state {
	bool available;
	u32 state;
};

static DEFINE_PER_CPU_READ_MOSTLY(struct sbi_cpuidle_data, sbi_cpuidle_data);
static DEFINE_PER_CPU(struct sbi_domain_state, domain_state);
static bool sbi_cpuidle_use_osi;
static bool sbi_cpuidle_use_cpuhp;
static bool sbi_cpuidle_pd_allow_domain_state;

static inline void sbi_set_domain_state(u32 state)
{
	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);

	data->available = true;
	data->state = state;
}

static inline u32 sbi_get_domain_state(void)
{
	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);

	return data->state;
}

static inline void sbi_clear_domain_state(void)
{
	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);

	data->available = false;
}

static inline bool sbi_is_domain_state_available(void)
{
	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);

	return data->available;
}

static int sbi_suspend_finisher(unsigned long suspend_type,
				unsigned long resume_addr,
				unsigned long opaque)
{
	struct sbiret ret;

	ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND,
			suspend_type, resume_addr, opaque, 0, 0, 0);

	return (ret.error) ? sbi_err_map_linux_errno(ret.error) : 0;
}

static int sbi_suspend(u32 state)
{
	if (state & SBI_HSM_SUSP_NON_RET_BIT)
		return cpu_suspend(state, sbi_suspend_finisher);
	else
		return sbi_suspend_finisher(state, 0, 0);
}

static int sbi_cpuidle_enter_state(struct cpuidle_device *dev,
				   struct cpuidle_driver *drv, int idx)
{
	u32 *states = __this_cpu_read(sbi_cpuidle_data.states);

	return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, states[idx]);
}

static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
					  struct cpuidle_driver *drv, int idx,
					  bool s2idle)
{
	struct sbi_cpuidle_data *data = this_cpu_ptr(&sbi_cpuidle_data);
	u32 *states = data->states;
	struct device *pd_dev = data->dev;
	u32 state;
	int ret;

	ret = cpu_pm_enter();
	if (ret)
		return -1;

	/* Do runtime PM to manage a hierarchical CPU toplogy. */
	rcu_irq_enter_irqson();
	if (s2idle)
		dev_pm_genpd_suspend(pd_dev);
	else
		pm_runtime_put_sync_suspend(pd_dev);
	rcu_irq_exit_irqson();

	if (sbi_is_domain_state_available())
		state = sbi_get_domain_state();
	else
		state = states[idx];

	ret = sbi_suspend(state) ? -1 : idx;

	rcu_irq_enter_irqson();
	if (s2idle)
		dev_pm_genpd_resume(pd_dev);
	else
		pm_runtime_get_sync(pd_dev);
	rcu_irq_exit_irqson();

	cpu_pm_exit();

	/* Clear the domain state to start fresh when back from idle. */
	sbi_clear_domain_state();
	return ret;
}

static int sbi_enter_domain_idle_state(struct cpuidle_device *dev,
				       struct cpuidle_driver *drv, int idx)
{
	return __sbi_enter_domain_idle_state(dev, drv, idx, false);
}

static int sbi_enter_s2idle_domain_idle_state(struct cpuidle_device *dev,
					      struct cpuidle_driver *drv,
					      int idx)
{
	return __sbi_enter_domain_idle_state(dev, drv, idx, true);
}

static int sbi_cpuidle_cpuhp_up(unsigned int cpu)
{
	struct device *pd_dev = __this_cpu_read(sbi_cpuidle_data.dev);

	if (pd_dev)
		pm_runtime_get_sync(pd_dev);

	return 0;
}

static int sbi_cpuidle_cpuhp_down(unsigned int cpu)
{
	struct device *pd_dev = __this_cpu_read(sbi_cpuidle_data.dev);

	if (pd_dev) {
		pm_runtime_put_sync(pd_dev);
		/* Clear domain state to start fresh at next online. */
		sbi_clear_domain_state();
	}

	return 0;
}

static void sbi_idle_init_cpuhp(void)
{
	int err;

	if (!sbi_cpuidle_use_cpuhp)
		return;

	err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
					"cpuidle/sbi:online",
					sbi_cpuidle_cpuhp_up,
					sbi_cpuidle_cpuhp_down);
	if (err)
		pr_warn("Failed %d while setup cpuhp state\n", err);
}

static const struct of_device_id sbi_cpuidle_state_match[] = {
	{ .compatible = "riscv,idle-state",
	  .data = sbi_cpuidle_enter_state },
	{ },
};

static bool sbi_suspend_state_is_valid(u32 state)
{
	if (state > SBI_HSM_SUSPEND_RET_DEFAULT &&
	    state < SBI_HSM_SUSPEND_RET_PLATFORM)
		return false;
	if (state > SBI_HSM_SUSPEND_NON_RET_DEFAULT &&
	    state < SBI_HSM_SUSPEND_NON_RET_PLATFORM)
		return false;
	return true;
}

static int sbi_dt_parse_state_node(struct device_node *np, u32 *state)
{
	int err = of_property_read_u32(np, "riscv,sbi-suspend-param", state);

	if (err) {
		pr_warn("%pOF missing riscv,sbi-suspend-param property\n", np);
		return err;
	}

	if (!sbi_suspend_state_is_valid(*state)) {
		pr_warn("Invalid SBI suspend state %#x\n", *state);
		return -EINVAL;
	}

	return 0;
}

static int sbi_dt_cpu_init_topology(struct cpuidle_driver *drv,
				     struct sbi_cpuidle_data *data,
				     unsigned int state_count, int cpu)
{
	/* Currently limit the hierarchical topology to be used in OSI mode. */
	if (!sbi_cpuidle_use_osi)
		return 0;

	data->dev = dt_idle_attach_cpu(cpu, "sbi");
	if (IS_ERR_OR_NULL(data->dev))
		return PTR_ERR_OR_ZERO(data->dev);

	/*
	 * Using the deepest state for the CPU to trigger a potential selection
	 * of a shared state for the domain, assumes the domain states are all
	 * deeper states.
	 */
	drv->states[state_count - 1].enter = sbi_enter_domain_idle_state;
	drv->states[state_count - 1].enter_s2idle =
					sbi_enter_s2idle_domain_idle_state;
	sbi_cpuidle_use_cpuhp = true;

	return 0;
}

static int sbi_cpuidle_dt_init_states(struct device *dev,
					struct cpuidle_driver *drv,
					unsigned int cpu,
					unsigned int state_count)
{
	struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);
	struct device_node *state_node;
	struct device_node *cpu_node;
	u32 *states;
	int i, ret;

	cpu_node = of_cpu_device_node_get(cpu);
	if (!cpu_node)
		return -ENODEV;

	states = devm_kcalloc(dev, state_count, sizeof(*states), GFP_KERNEL);
	if (!states) {
		ret = -ENOMEM;
		goto fail;
	}

	/* Parse SBI specific details from state DT nodes */
	for (i = 1; i < state_count; i++) {
		state_node = of_get_cpu_state_node(cpu_node, i - 1);
		if (!state_node)
			break;

		ret = sbi_dt_parse_state_node(state_node, &states[i]);
		of_node_put(state_node);

		if (ret)
			return ret;

		pr_debug("sbi-state %#x index %d\n", states[i], i);
	}
	if (i != state_count) {
		ret = -ENODEV;
		goto fail;
	}

	/* Initialize optional data, used for the hierarchical topology. */
	ret = sbi_dt_cpu_init_topology(drv, data, state_count, cpu);
	if (ret < 0)
		return ret;

	/* Store states in the per-cpu struct. */
	data->states = states;

fail:
	of_node_put(cpu_node);

	return ret;
}

static void sbi_cpuidle_deinit_cpu(int cpu)
{
	struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);

	dt_idle_detach_cpu(data->dev);
	sbi_cpuidle_use_cpuhp = false;
}

static int sbi_cpuidle_init_cpu(struct device *dev, int cpu)
{
	struct cpuidle_driver *drv;
	unsigned int state_count = 0;
	int ret = 0;

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

	drv->name = "sbi_cpuidle";
	drv->owner = THIS_MODULE;
	drv->cpumask = (struct cpumask *)cpumask_of(cpu);

	/* RISC-V architectural WFI to be represented as state index 0. */
	drv->states[0].enter = sbi_cpuidle_enter_state;
	drv->states[0].exit_latency = 1;
	drv->states[0].target_residency = 1;
	drv->states[0].power_usage = UINT_MAX;
	strcpy(drv->states[0].name, "WFI");
	strcpy(drv->states[0].desc, "RISC-V WFI");

	/*
	 * If no DT idle states are detected (ret == 0) let the driver
	 * initialization fail accordingly since there is no reason to
	 * initialize the idle driver if only wfi is supported, the
	 * default archictectural back-end already executes wfi
	 * on idle entry.
	 */
	ret = dt_init_idle_driver(drv, sbi_cpuidle_state_match, 1);
	if (ret <= 0) {
		pr_debug("HART%ld: failed to parse DT idle states\n",
			 cpuid_to_hartid_map(cpu));
		return ret ? : -ENODEV;
	}
	state_count = ret + 1; /* Include WFI state as well */

	/* Initialize idle states from DT. */
	ret = sbi_cpuidle_dt_init_states(dev, drv, cpu, state_count);
	if (ret) {
		pr_err("HART%ld: failed to init idle states\n",
		       cpuid_to_hartid_map(cpu));
		return ret;
	}

	ret = cpuidle_register(drv, NULL);
	if (ret)
		goto deinit;

	cpuidle_cooling_register(drv);

	return 0;
deinit:
	sbi_cpuidle_deinit_cpu(cpu);
	return ret;
}

static void sbi_cpuidle_domain_sync_state(struct device *dev)
{
	/*
	 * All devices have now been attached/probed to the PM domain
	 * topology, hence it's fine to allow domain states to be picked.
	 */
	sbi_cpuidle_pd_allow_domain_state = true;
}

#ifdef CONFIG_DT_IDLE_GENPD

static int sbi_cpuidle_pd_power_off(struct generic_pm_domain *pd)
{
	struct genpd_power_state *state = &pd->states[pd->state_idx];
	u32 *pd_state;

	if (!state->data)
		return 0;

	if (!sbi_cpuidle_pd_allow_domain_state)
		return -EBUSY;

	/* OSI mode is enabled, set the corresponding domain state. */
	pd_state = state->data;
	sbi_set_domain_state(*pd_state);

	return 0;
}

struct sbi_pd_provider {
	struct list_head link;
	struct device_node *node;
};

static LIST_HEAD(sbi_pd_providers);

static int sbi_pd_init(struct device_node *np)
{
	struct generic_pm_domain *pd;
	struct sbi_pd_provider *pd_provider;
	struct dev_power_governor *pd_gov;
	int ret = -ENOMEM;

	pd = dt_idle_pd_alloc(np, sbi_dt_parse_state_node);
	if (!pd)
		goto out;

	pd_provider = kzalloc(sizeof(*pd_provider), GFP_KERNEL);
	if (!pd_provider)
		goto free_pd;

	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;

	/* Allow power off when OSI is available. */
	if (sbi_cpuidle_use_osi)
		pd->power_off = sbi_cpuidle_pd_power_off;
	else
		pd->flags |= GENPD_FLAG_ALWAYS_ON;

	/* Use governor for CPU PM domains if it has some states to manage. */
	pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;

	ret = pm_genpd_init(pd, pd_gov, false);
	if (ret)
		goto free_pd_prov;

	ret = of_genpd_add_provider_simple(np, pd);
	if (ret)
		goto remove_pd;

	pd_provider->node = of_node_get(np);
	list_add(&pd_provider->link, &sbi_pd_providers);

	pr_debug("init PM domain %s\n", pd->name);
	return 0;

remove_pd:
	pm_genpd_remove(pd);
free_pd_prov:
	kfree(pd_provider);
free_pd:
	dt_idle_pd_free(pd);
out:
	pr_err("failed to init PM domain ret=%d %pOF\n", ret, np);
	return ret;
}

static void sbi_pd_remove(void)
{
	struct sbi_pd_provider *pd_provider, *it;
	struct generic_pm_domain *genpd;

	list_for_each_entry_safe(pd_provider, it, &sbi_pd_providers, link) {
		of_genpd_del_provider(pd_provider->node);

		genpd = of_genpd_remove_last(pd_provider->node);
		if (!IS_ERR(genpd))
			kfree(genpd);

		of_node_put(pd_provider->node);
		list_del(&pd_provider->link);
		kfree(pd_provider);
	}
}

static int sbi_genpd_probe(struct device_node *np)
{
	struct device_node *node;
	int ret = 0, pd_count = 0;

	if (!np)
		return -ENODEV;

	/*
	 * Parse child nodes for the "#power-domain-cells" property and
	 * initialize a genpd/genpd-of-provider pair when it's found.
	 */
	for_each_child_of_node(np, node) {
		if (!of_find_property(node, "#power-domain-cells", NULL))
			continue;

		ret = sbi_pd_init(node);
		if (ret)
			goto put_node;

		pd_count++;
	}

	/* Bail out if not using the hierarchical CPU topology. */
	if (!pd_count)
		goto no_pd;

	/* Link genpd masters/subdomains to model the CPU topology. */
	ret = dt_idle_pd_init_topology(np);
	if (ret)
		goto remove_pd;

	return 0;

put_node:
	of_node_put(node);
remove_pd:
	sbi_pd_remove();
	pr_err("failed to create CPU PM domains ret=%d\n", ret);
no_pd:
	return ret;
}

#else

static inline int sbi_genpd_probe(struct device_node *np)
{
	return 0;
}

#endif

static int sbi_cpuidle_probe(struct platform_device *pdev)
{
	int cpu, ret;
	struct cpuidle_driver *drv;
	struct cpuidle_device *dev;
	struct device_node *np, *pds_node;

	/* Detect OSI support based on CPU DT nodes */
	sbi_cpuidle_use_osi = true;
	for_each_possible_cpu(cpu) {
		np = of_cpu_device_node_get(cpu);
		if (np &&
		    of_find_property(np, "power-domains", NULL) &&
		    of_find_property(np, "power-domain-names", NULL)) {
			continue;
		} else {
			sbi_cpuidle_use_osi = false;
			break;
		}
	}

	/* Populate generic power domains from DT nodes */
	pds_node = of_find_node_by_path("/cpus/power-domains");
	if (pds_node) {
		ret = sbi_genpd_probe(pds_node);
		of_node_put(pds_node);
		if (ret)
			return ret;
	}

	/* Initialize CPU idle driver for each CPU */
	for_each_possible_cpu(cpu) {
		ret = sbi_cpuidle_init_cpu(&pdev->dev, cpu);
		if (ret) {
			pr_debug("HART%ld: idle driver init failed\n",
				 cpuid_to_hartid_map(cpu));
			goto out_fail;
		}
	}

	/* Setup CPU hotplut notifiers */
	sbi_idle_init_cpuhp();

	pr_info("idle driver registered for all CPUs\n");

	return 0;

out_fail:
	while (--cpu >= 0) {
		dev = per_cpu(cpuidle_devices, cpu);
		drv = cpuidle_get_cpu_driver(dev);
		cpuidle_unregister(drv);
		sbi_cpuidle_deinit_cpu(cpu);
	}

	return ret;
}

static struct platform_driver sbi_cpuidle_driver = {
	.probe = sbi_cpuidle_probe,
	.driver = {
		.name = "sbi-cpuidle",
		.sync_state = sbi_cpuidle_domain_sync_state,
	},
};

static int __init sbi_cpuidle_init(void)
{
	int ret;
	struct platform_device *pdev;

	/*
	 * The SBI HSM suspend function is only available when:
	 * 1) SBI version is 0.3 or higher
	 * 2) SBI HSM extension is available
	 */
	if ((sbi_spec_version < sbi_mk_version(0, 3)) ||
	    sbi_probe_extension(SBI_EXT_HSM) <= 0) {
		pr_info("HSM suspend not available\n");
		return 0;
	}

	ret = platform_driver_register(&sbi_cpuidle_driver);
	if (ret)
		return ret;

	pdev = platform_device_register_simple("sbi-cpuidle",
						-1, NULL, 0);
	if (IS_ERR(pdev)) {
		platform_driver_unregister(&sbi_cpuidle_driver);
		return PTR_ERR(pdev);
	}

	return 0;
}
device_initcall(sbi_cpuidle_init);
