1f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm/*
2d03299ee6020b0cc64fc4180162fb2e8795394e1Paul Mundt * Runtime PM support code
3f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm *
4f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm *  Copyright (C) 2009-2010 Magnus Damm
5f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm *
6f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm * This file is subject to the terms and conditions of the GNU General Public
7f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm * License.  See the file "COPYING" in the main directory of this archive
8f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm * for more details.
9f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm */
10f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm
11f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/init.h>
12f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/kernel.h>
13f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/io.h>
14f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/pm_runtime.h>
15796204142a98b6e0e71b494e808d1b6ee62cc75fRafael J. Wysocki#include <linux/pm_domain.h>
16b5e8d269d814763d597ccc0108d1fa6639ad35a1Rafael J. Wysocki#include <linux/pm_clock.h>
17f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/platform_device.h>
18f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/clk.h>
19f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/sh_clk.h>
20f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#include <linux/bitmap.h>
211d2b71f61b6a10216274e27b717becf9ae101fc7Rafael J. Wysocki#include <linux/slab.h>
22f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm
23f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#ifdef CONFIG_PM_RUNTIME
248255fe169232364e5a01bd062e8037b8c1a9adecBen Dooksstatic int sh_pm_runtime_suspend(struct device *dev)
258255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks{
268255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	int ret;
278255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
288255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	ret = pm_generic_runtime_suspend(dev);
298255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	if (ret) {
308255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		dev_err(dev, "failed to suspend device\n");
318255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		return ret;
328255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	}
338255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
348255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	ret = pm_clk_suspend(dev);
358255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	if (ret) {
368255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		dev_err(dev, "failed to suspend clock\n");
378255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		pm_generic_runtime_resume(dev);
388255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		return ret;
398255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	}
408255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
418255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	return 0;
428255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks}
438255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
448255fe169232364e5a01bd062e8037b8c1a9adecBen Dooksstatic int sh_pm_runtime_resume(struct device *dev)
458255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks{
468255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	int ret;
478255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
488255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	ret = pm_clk_resume(dev);
498255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	if (ret) {
508255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		dev_err(dev, "failed to resume clock\n");
518255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		return ret;
528255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	}
538255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
548255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks	return pm_generic_runtime_resume(dev);
558255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks}
568255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks
57564b905ab10d17fb42f86aa8b7b9b796276d1336Rafael J. Wysockistatic struct dev_pm_domain default_pm_domain = {
5838ade3a1fa0421c12627c7b48c33e89414fc9b76Rafael J. Wysocki	.ops = {
598255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		.runtime_suspend = sh_pm_runtime_suspend,
608255fe169232364e5a01bd062e8037b8c1a9adecBen Dooks		.runtime_resume = sh_pm_runtime_resume,
6138ade3a1fa0421c12627c7b48c33e89414fc9b76Rafael J. Wysocki		USE_PLATFORM_PM_SLEEP_OPS
6238ade3a1fa0421c12627c7b48c33e89414fc9b76Rafael J. Wysocki	},
6338ade3a1fa0421c12627c7b48c33e89414fc9b76Rafael J. Wysocki};
6438ade3a1fa0421c12627c7b48c33e89414fc9b76Rafael J. Wysocki
65564b905ab10d17fb42f86aa8b7b9b796276d1336Rafael J. Wysocki#define DEFAULT_PM_DOMAIN_PTR	(&default_pm_domain)
661d2b71f61b6a10216274e27b717becf9ae101fc7Rafael J. Wysocki
6785eb8c8d0b0900c073b0e6f89979ac9c439ade1aRafael J. Wysocki#else
68f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm
69564b905ab10d17fb42f86aa8b7b9b796276d1336Rafael J. Wysocki#define DEFAULT_PM_DOMAIN_PTR	NULL
70f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm
71f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm#endif /* CONFIG_PM_RUNTIME */
72f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm
7385eb8c8d0b0900c073b0e6f89979ac9c439ade1aRafael J. Wysockistatic struct pm_clk_notifier_block platform_bus_notifier = {
74564b905ab10d17fb42f86aa8b7b9b796276d1336Rafael J. Wysocki	.pm_domain = DEFAULT_PM_DOMAIN_PTR,
7585eb8c8d0b0900c073b0e6f89979ac9c439ade1aRafael J. Wysocki	.con_ids = { NULL, },
76f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm};
77f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm
78f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Dammstatic int __init sh_pm_runtime_init(void)
79f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm{
803c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven	if (IS_ENABLED(CONFIG_ARCH_SHMOBILE_MULTI)) {
813c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		if (!of_machine_is_compatible("renesas,emev2") &&
823c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r7s72100") &&
833c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a73a4") &&
843c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7740") &&
853c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7778") &&
863c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7779") &&
873c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7790") &&
883c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7791") &&
892f35fb3c8a6018a0a5fe4a7fb0948b853c157256Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7792") &&
902f35fb3c8a6018a0a5fe4a7fb0948b853c157256Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7793") &&
912f35fb3c8a6018a0a5fe4a7fb0948b853c157256Geert Uytterhoeven		    !of_machine_is_compatible("renesas,r8a7794") &&
923c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,sh7372") &&
933c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven		    !of_machine_is_compatible("renesas,sh73a0"))
943c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven			return 0;
953c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven	}
963c90c55dcde745bed81f6447f24ba96bda43d984Geert Uytterhoeven
973d5c30367cbc0c55c93bb158e824e00badc7ddc4Rafael J. Wysocki	pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
98f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm	return 0;
99f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Damm}
100f14c4f141ad88290bb23d597a0a47833e7891fcdMagnus Dammcore_initcall(sh_pm_runtime_init);
101