]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/arm/mach-shmobile/pm-rmobile.c
2 * rmobile power management support
4 * Copyright (C) 2012 Renesas Solutions Corp.
5 * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
8 * Copyright (C) 2011 Magnus Damm
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
14 #include <linux/console.h>
15 #include <linux/delay.h>
16 #include <linux/platform_device.h>
18 #include <linux/pm_clock.h>
20 #include <mach/pm-rmobile.h>
23 #define SPDCR IOMEM(0xe6180008)
24 #define SWUCR IOMEM(0xe6180014)
25 #define PSTR IOMEM(0xe6180080)
27 #define PSTR_RETRIES 100
28 #define PSTR_DELAY_US 10
31 static int rmobile_pd_power_down(struct generic_pm_domain
*genpd
)
33 struct rmobile_pm_domain
*rmobile_pd
= to_rmobile_pd(genpd
);
34 unsigned int mask
= 1 << rmobile_pd
->bit_shift
;
36 if (rmobile_pd
->suspend
) {
37 int ret
= rmobile_pd
->suspend();
43 if (__raw_readl(PSTR
) & mask
) {
44 unsigned int retry_count
;
45 __raw_writel(mask
, SPDCR
);
47 for (retry_count
= PSTR_RETRIES
; retry_count
; retry_count
--) {
48 if (!(__raw_readl(SPDCR
) & mask
))
54 if (!rmobile_pd
->no_debug
)
55 pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
56 genpd
->name
, mask
, __raw_readl(PSTR
));
61 static int __rmobile_pd_power_up(struct rmobile_pm_domain
*rmobile_pd
,
64 unsigned int mask
= 1 << rmobile_pd
->bit_shift
;
65 unsigned int retry_count
;
68 if (__raw_readl(PSTR
) & mask
)
71 __raw_writel(mask
, SWUCR
);
73 for (retry_count
= 2 * PSTR_RETRIES
; retry_count
; retry_count
--) {
74 if (!(__raw_readl(SWUCR
) & mask
))
76 if (retry_count
> PSTR_RETRIES
)
77 udelay(PSTR_DELAY_US
);
84 if (!rmobile_pd
->no_debug
)
85 pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
86 rmobile_pd
->genpd
.name
, mask
, __raw_readl(PSTR
));
89 if (ret
== 0 && rmobile_pd
->resume
&& do_resume
)
95 static int rmobile_pd_power_up(struct generic_pm_domain
*genpd
)
97 return __rmobile_pd_power_up(to_rmobile_pd(genpd
), true);
100 static bool rmobile_pd_active_wakeup(struct device
*dev
)
102 bool (*active_wakeup
)(struct device
*dev
);
104 active_wakeup
= dev_gpd_data(dev
)->ops
.active_wakeup
;
105 return active_wakeup
? active_wakeup(dev
) : true;
108 static int rmobile_pd_stop_dev(struct device
*dev
)
110 int (*stop
)(struct device
*dev
);
112 stop
= dev_gpd_data(dev
)->ops
.stop
;
118 return pm_clk_suspend(dev
);
121 static int rmobile_pd_start_dev(struct device
*dev
)
123 int (*start
)(struct device
*dev
);
126 ret
= pm_clk_resume(dev
);
130 start
= dev_gpd_data(dev
)->ops
.start
;
137 void rmobile_init_pm_domain(struct rmobile_pm_domain
*rmobile_pd
)
139 struct generic_pm_domain
*genpd
= &rmobile_pd
->genpd
;
140 struct dev_power_governor
*gov
= rmobile_pd
->gov
;
142 pm_genpd_init(genpd
, gov
? : &simple_qos_governor
, false);
143 genpd
->dev_ops
.stop
= rmobile_pd_stop_dev
;
144 genpd
->dev_ops
.start
= rmobile_pd_start_dev
;
145 genpd
->dev_ops
.active_wakeup
= rmobile_pd_active_wakeup
;
146 genpd
->dev_irq_safe
= true;
147 genpd
->power_off
= rmobile_pd_power_down
;
148 genpd
->power_on
= rmobile_pd_power_up
;
149 __rmobile_pd_power_up(rmobile_pd
, false);
152 void rmobile_add_device_to_domain(struct rmobile_pm_domain
*rmobile_pd
,
153 struct platform_device
*pdev
)
155 struct device
*dev
= &pdev
->dev
;
157 pm_genpd_add_device(&rmobile_pd
->genpd
, dev
);
158 if (pm_clk_no_clocks(dev
))
159 pm_clk_add(dev
, NULL
);
162 void rmobile_pm_add_subdomain(struct rmobile_pm_domain
*rmobile_pd
,
163 struct rmobile_pm_domain
*rmobile_sd
)
165 pm_genpd_add_subdomain(&rmobile_pd
->genpd
, &rmobile_sd
->genpd
);
167 #endif /* CONFIG_PM */