18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2014 Linaro Ltd.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Author: Ulf Hansson <ulf.hansson@linaro.org>
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Implements PM domains using the generic PM domain for ux500.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci#include <linux/printk.h>
108c2ecf20Sopenharmony_ci#include <linux/slab.h>
118c2ecf20Sopenharmony_ci#include <linux/err.h>
128c2ecf20Sopenharmony_ci#include <linux/of.h>
138c2ecf20Sopenharmony_ci#include <linux/pm_domain.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <dt-bindings/arm/ux500_pm_domains.h>
168c2ecf20Sopenharmony_ci#include "pm_domains.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic int pd_power_off(struct generic_pm_domain *domain)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	/*
218c2ecf20Sopenharmony_ci	 * Handle the gating of the PM domain regulator here.
228c2ecf20Sopenharmony_ci	 *
238c2ecf20Sopenharmony_ci	 * Drivers/subsystems handling devices in the PM domain needs to perform
248c2ecf20Sopenharmony_ci	 * register context save/restore from their respective runtime PM
258c2ecf20Sopenharmony_ci	 * callbacks, to be able to enable PM domain gating/ungating.
268c2ecf20Sopenharmony_ci	 */
278c2ecf20Sopenharmony_ci	return 0;
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistatic int pd_power_on(struct generic_pm_domain *domain)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	/*
338c2ecf20Sopenharmony_ci	 * Handle the ungating of the PM domain regulator here.
348c2ecf20Sopenharmony_ci	 *
358c2ecf20Sopenharmony_ci	 * Drivers/subsystems handling devices in the PM domain needs to perform
368c2ecf20Sopenharmony_ci	 * register context save/restore from their respective runtime PM
378c2ecf20Sopenharmony_ci	 * callbacks, to be able to enable PM domain gating/ungating.
388c2ecf20Sopenharmony_ci	 */
398c2ecf20Sopenharmony_ci	return 0;
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic struct generic_pm_domain ux500_pm_domain_vape = {
438c2ecf20Sopenharmony_ci	.name = "VAPE",
448c2ecf20Sopenharmony_ci	.power_off = pd_power_off,
458c2ecf20Sopenharmony_ci	.power_on = pd_power_on,
468c2ecf20Sopenharmony_ci};
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic struct generic_pm_domain *ux500_pm_domains[NR_DOMAINS] = {
498c2ecf20Sopenharmony_ci	[DOMAIN_VAPE] = &ux500_pm_domain_vape,
508c2ecf20Sopenharmony_ci};
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic const struct of_device_id ux500_pm_domain_matches[] __initconst = {
538c2ecf20Sopenharmony_ci	{ .compatible = "stericsson,ux500-pm-domains", },
548c2ecf20Sopenharmony_ci	{ },
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciint __init ux500_pm_domains_init(void)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	struct device_node *np;
608c2ecf20Sopenharmony_ci	struct genpd_onecell_data *genpd_data;
618c2ecf20Sopenharmony_ci	int i;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	np = of_find_matching_node(NULL, ux500_pm_domain_matches);
648c2ecf20Sopenharmony_ci	if (!np)
658c2ecf20Sopenharmony_ci		return -ENODEV;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	genpd_data = kzalloc(sizeof(*genpd_data), GFP_KERNEL);
688c2ecf20Sopenharmony_ci	if (!genpd_data)
698c2ecf20Sopenharmony_ci		return -ENOMEM;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	genpd_data->domains = ux500_pm_domains;
728c2ecf20Sopenharmony_ci	genpd_data->num_domains = ARRAY_SIZE(ux500_pm_domains);
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(ux500_pm_domains); ++i)
758c2ecf20Sopenharmony_ci		pm_genpd_init(ux500_pm_domains[i], NULL, false);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	of_genpd_add_provider_onecell(np, genpd_data);
788c2ecf20Sopenharmony_ci	return 0;
798c2ecf20Sopenharmony_ci}
80