diff options
author | Linus Torvalds | 2012-10-02 18:32:35 -0700 |
---|---|---|
committer | Linus Torvalds | 2012-10-02 18:32:35 -0700 |
commit | 16642a2e7be23bbda013fc32d8f6c68982eab603 (patch) | |
tree | 346ae485f485f6901e5d8150f0d34d178a7dd448 /arch | |
parent | 51562cba98939da0a1d10fe7c25359b77a069033 (diff) | |
parent | b9142167a2bb979b58b98ffcd928a311b55cbd9f (diff) |
Merge tag 'pm-for-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael J Wysocki:
- Improved system suspend/resume and runtime PM handling for the SH
TMU, CMT and MTU2 clock event devices (also used by ARM/shmobile).
- Generic PM domains framework extensions related to cpuidle support
and domain objects lookup using names.
- ARM/shmobile power management updates including improved support for
the SH7372's A4S power domain containing the CPU core.
- cpufreq changes related to AMD CPUs support from Matthew Garrett,
Andre Przywara and Borislav Petkov.
- cpu0 cpufreq driver from Shawn Guo.
- cpufreq governor fixes related to the relaxing of limit from Michal
Pecio.
- OMAP cpufreq updates from Axel Lin and Richard Zhao.
- cpuidle ladder governor fixes related to the disabling of states from
Carsten Emde and me.
- Runtime PM core updates related to the interactions with the system
suspend core from Alan Stern and Kevin Hilman.
- Wakeup sources modification allowing more helper functions to be
called from interrupt context from John Stultz and additional
diagnostic code from Todd Poynor.
- System suspend error code path fix from Feng Hong.
Fixed up conflicts in cpufreq/powernow-k8 that stemmed from the
workqueue fixes conflicting fairly badly with the removal of support for
hardware P-state chips. The changes were independent but somewhat
intertwined.
* tag 'pm-for-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (76 commits)
Revert "PM QoS: Use spinlock in the per-device PM QoS constraints code"
PM / Runtime: let rpm_resume() succeed if RPM_ACTIVE, even when disabled, v2
cpuidle: rename function name "__cpuidle_register_driver", v2
cpufreq: OMAP: Check IS_ERR() instead of NULL for omap_device_get_by_hwmod_name
cpuidle: remove some empty lines
PM: Prevent runtime suspend during system resume
PM QoS: Use spinlock in the per-device PM QoS constraints code
PM / Sleep: use resume event when call dpm_resume_early
cpuidle / ACPI : move cpuidle_device field out of the acpi_processor_power structure
ACPI / processor: remove pointless variable initialization
ACPI / processor: remove unused function parameter
cpufreq: OMAP: remove loops_per_jiffy recalculate for smp
sections: fix section conflicts in drivers/cpufreq
cpufreq: conservative: update frequency when limits are relaxed
cpufreq / ondemand: update frequency when limits are relaxed
properly __init-annotate pm_sysrq_init()
cpufreq: Add a generic cpufreq-cpu0 driver
PM / OPP: Initialize OPP table from device tree
ARM: add cpufreq transiton notifier to adjust loops_per_jiffy for smp
cpufreq: Remove support for hardware P-state chips from powernow-k8
...
Diffstat (limited to 'arch')
20 files changed, 464 insertions, 336 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index aa4ffe6e5ecf..dea7a925c7e2 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -24,6 +24,7 @@ #include <linux/percpu.h> #include <linux/clockchips.h> #include <linux/completion.h> +#include <linux/cpufreq.h> #include <linux/atomic.h> #include <asm/smp.h> @@ -650,3 +651,56 @@ int setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } + +#ifdef CONFIG_CPU_FREQ + +static DEFINE_PER_CPU(unsigned long, l_p_j_ref); +static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq); +static unsigned long global_l_p_j_ref; +static unsigned long global_l_p_j_ref_freq; + +static int cpufreq_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + int cpu = freq->cpu; + + if (freq->flags & CPUFREQ_CONST_LOOPS) + return NOTIFY_OK; + + if (!per_cpu(l_p_j_ref, cpu)) { + per_cpu(l_p_j_ref, cpu) = + per_cpu(cpu_data, cpu).loops_per_jiffy; + per_cpu(l_p_j_ref_freq, cpu) = freq->old; + if (!global_l_p_j_ref) { + global_l_p_j_ref = loops_per_jiffy; + global_l_p_j_ref_freq = freq->old; + } + } + + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || + (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { + loops_per_jiffy = cpufreq_scale(global_l_p_j_ref, + global_l_p_j_ref_freq, + freq->new); + per_cpu(cpu_data, cpu).loops_per_jiffy = + cpufreq_scale(per_cpu(l_p_j_ref, cpu), + per_cpu(l_p_j_ref_freq, cpu), + freq->new); + } + return NOTIFY_OK; +} + +static struct notifier_block cpufreq_notifier = { + .notifier_call = cpufreq_callback, +}; + +static int __init register_cpufreq_notifier(void) +{ + return cpufreq_register_notifier(&cpufreq_notifier, + CPUFREQ_TRANSITION_NOTIFIER); +} +core_initcall(register_cpufreq_notifier); + +#endif diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 0df5ae6740c6..fe2c97c179d1 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -3,7 +3,7 @@ # # Common objects -obj-y := timer.o console.o clock.o common.o +obj-y := timer.o console.o clock.o # CPU objects obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index bc3b5da59e25..790dc68c4312 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -1231,6 +1231,15 @@ static struct i2c_board_info i2c1_devices[] = { #define USCCR1 IOMEM(0xE6058144) static void __init ap4evb_init(void) { + struct pm_domain_device domain_devices[] = { + { "A4LC", &lcdc1_device, }, + { "A4LC", &lcdc_device, }, + { "A4MP", &fsi_device, }, + { "A3SP", &sh_mmcif_device, }, + { "A3SP", &sdhi0_device, }, + { "A3SP", &sdhi1_device, }, + { "A4R", &ceu_device, }, + }; u32 srcr4; struct clk *clk; @@ -1463,14 +1472,8 @@ static void __init ap4evb_init(void) platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device); - - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device); + rmobile_add_devices_to_domains(domain_devices, + ARRAY_SIZE(domain_devices)); hdmi_init_pm_clock(); fsi_init_pm_clock(); @@ -1485,6 +1488,6 @@ MACHINE_START(AP4EVB, "ap4evb") .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = ap4evb_init, - .init_late = shmobile_init_late, + .init_late = sh7372_pm_init_late, .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index c6593d394273..2912eab3b967 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -1209,10 +1209,10 @@ static void __init eva_init(void) eva_clock_init(); - rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device); - rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device); + rmobile_add_device_to_domain("A4LC", &lcdc0_device); + rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device); if (usb) - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb); + rmobile_add_device_to_domain("A3SP", usb); } static void __init eva_earlytimer_init(void) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 62783b5d8813..0c27c810cf99 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -1412,6 +1412,22 @@ static struct i2c_board_info i2c1_devices[] = { #define USCCR1 IOMEM(0xE6058144) static void __init mackerel_init(void) { + struct pm_domain_device domain_devices[] = { + { "A4LC", &lcdc_device, }, + { "A4LC", &hdmi_lcdc_device, }, + { "A4LC", &meram_device, }, + { "A4MP", &fsi_device, }, + { "A3SP", &usbhs0_device, }, + { "A3SP", &usbhs1_device, }, + { "A3SP", &nand_flash_device, }, + { "A3SP", &sh_mmcif_device, }, + { "A3SP", &sdhi0_device, }, +#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) + { "A3SP", &sdhi1_device, }, +#endif + { "A3SP", &sdhi2_device, }, + { "A4R", &ceu_device, }, + }; u32 srcr4; struct clk *clk; @@ -1626,20 +1642,8 @@ static void __init mackerel_init(void) platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &hdmi_lcdc_device); - rmobile_add_device_to_domain(&sh7372_pd_a4lc, &meram_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &nand_flash_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device); -#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device); -#endif - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi2_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device); + rmobile_add_devices_to_domains(domain_devices, + ARRAY_SIZE(domain_devices)); hdmi_init_pm_clock(); sh7372_pm_init(); @@ -1653,6 +1657,6 @@ MACHINE_START(MACKEREL, "mackerel") .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = mackerel_init, - .init_late = shmobile_init_late, + .init_late = sh7372_pm_init_late, .timer = &shmobile_timer, MACHINE_END diff --git a/arch/arm/mach-shmobile/common.c b/arch/arm/mach-shmobile/common.c deleted file mode 100644 index 608aba9d60d7..000000000000 --- a/arch/arm/mach-shmobile/common.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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; version 2 of the License. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <mach/common.h> - -void __init shmobile_init_late(void) -{ - shmobile_suspend_init(); - shmobile_cpuidle_init(); -} diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c index 7b541e911ab4..9e050268cde4 100644 --- a/arch/arm/mach-shmobile/cpuidle.c +++ b/arch/arm/mach-shmobile/cpuidle.c @@ -16,51 +16,38 @@ #include <asm/cpuidle.h> #include <asm/io.h> -static void shmobile_enter_wfi(void) +int shmobile_enter_wfi(struct cpuidle_device *dev, struct cpuidle_driver *drv, + int index) { cpu_do_idle(); -} - -void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = { - shmobile_enter_wfi, /* regular sleep mode */ -}; - -static int shmobile_cpuidle_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - shmobile_cpuidle_modes[index](); - - return index; + return 0; } static struct cpuidle_device shmobile_cpuidle_dev; -static struct cpuidle_driver shmobile_cpuidle_driver = { +static struct cpuidle_driver shmobile_cpuidle_default_driver = { .name = "shmobile_cpuidle", .owner = THIS_MODULE, .en_core_tk_irqen = 1, .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[0].enter = shmobile_enter_wfi, .safe_state_index = 0, /* C1 */ .state_count = 1, }; -void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); +static struct cpuidle_driver *cpuidle_drv = &shmobile_cpuidle_default_driver; + +void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv) +{ + cpuidle_drv = drv; +} int shmobile_cpuidle_init(void) { struct cpuidle_device *dev = &shmobile_cpuidle_dev; - struct cpuidle_driver *drv = &shmobile_cpuidle_driver; - int i; - - for (i = 0; i < CPUIDLE_STATE_MAX; i++) - drv->states[i].enter = shmobile_cpuidle_enter; - - if (shmobile_cpuidle_setup) - shmobile_cpuidle_setup(drv); - cpuidle_register_driver(drv); + cpuidle_register_driver(cpuidle_drv); - dev->state_count = drv->state_count; + dev->state_count = cpuidle_drv->state_count; cpuidle_register_device(dev); return 0; diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index f80f9c549393..ed77ab8c9143 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -13,8 +13,10 @@ extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); extern struct platform_suspend_ops shmobile_suspend_ops; struct cpuidle_driver; -extern void (*shmobile_cpuidle_modes[])(void); -extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); +struct cpuidle_device; +extern int shmobile_enter_wfi(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index); +extern void shmobile_cpuidle_set_driver(struct cpuidle_driver *drv); extern void sh7367_init_irq(void); extern void sh7367_map_io(void); @@ -75,8 +77,6 @@ extern void r8a7740_meram_workaround(void); extern void r8a7779_register_twd(void); -extern void shmobile_init_late(void); - #ifdef CONFIG_SUSPEND int shmobile_suspend_init(void); #else @@ -100,4 +100,10 @@ static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; } extern void shmobile_smp_init_cpus(unsigned int ncores); +static inline void shmobile_init_late(void) +{ + shmobile_suspend_init(); + shmobile_cpuidle_init(); +} + #endif /* __ARCH_MACH_COMMON_H */ diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h index 5a402840fe28..690553a06887 100644 --- a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h +++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h @@ -12,6 +12,8 @@ #include <linux/pm_domain.h> +#define DEFAULT_DEV_LATENCY_NS 250000 + struct platform_device; struct rmobile_pm_domain { @@ -29,16 +31,33 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d) return container_of(d, struct rmobile_pm_domain, genpd); } +struct pm_domain_device { + const char *domain_name; + struct platform_device *pdev; +}; + #ifdef CONFIG_PM -extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd); -extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, - struct platform_device *pdev); -extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, - struct rmobile_pm_domain *rmobile_sd); +extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num); +extern void rmobile_add_device_to_domain_td(const char *domain_name, + struct platform_device *pdev, + struct gpd_timing_data *td); + +static inline void rmobile_add_device_to_domain(const char *domain_name, + struct platform_device *pdev) +{ + rmobile_add_device_to_domain_td(domain_name, pdev, NULL); +} + +extern void rmobile_add_devices_to_domains(struct pm_domain_device data[], + int size); #else -#define rmobile_init_pm_domain(pd) do { } while (0) -#define rmobile_add_device_to_domain(pd, pdev) do { } while (0) -#define rmobile_pm_add_subdomain(pd, sd) do { } while (0) + +#define rmobile_init_domains(domains, num) do { } while (0) +#define rmobile_add_device_to_domain_td(name, pdev, td) do { } while (0) +#define rmobile_add_device_to_domain(name, pdev) do { } while (0) + +static inline void rmobile_add_devices_to_domains(struct pm_domain_device d[], + int size) {} #endif /* CONFIG_PM */ #endif /* PM_RMOBILE_H */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h index 7143147780df..59d252f4cf97 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7740.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h @@ -607,9 +607,9 @@ enum { }; #ifdef CONFIG_PM -extern struct rmobile_pm_domain r8a7740_pd_a4s; -extern struct rmobile_pm_domain r8a7740_pd_a3sp; -extern struct rmobile_pm_domain r8a7740_pd_a4lc; +extern void __init r8a7740_init_pm_domains(void); +#else +static inline void r8a7740_init_pm_domains(void) {} #endif /* CONFIG_PM */ #endif /* __ASM_R8A7740_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index f504c5e81b47..499f52d2a4a1 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -347,17 +347,9 @@ extern int r8a7779_sysc_power_down(struct r8a7779_pm_ch *r8a7779_ch); extern int r8a7779_sysc_power_up(struct r8a7779_pm_ch *r8a7779_ch); #ifdef CONFIG_PM -extern struct r8a7779_pm_domain r8a7779_sh4a; -extern struct r8a7779_pm_domain r8a7779_sgx; -extern struct r8a7779_pm_domain r8a7779_vdp1; -extern struct r8a7779_pm_domain r8a7779_impx3; - -extern void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd); -extern void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd, - struct platform_device *pdev); +extern void __init r8a7779_init_pm_domains(void); #else -#define r8a7779_init_pm_domain(pd) do { } while (0) -#define r8a7779_add_device_to_domain(pd, pdev) do { } while (0) +static inline void r8a7779_init_pm_domains(void) {} #endif /* CONFIG_PM */ extern struct smp_operations r8a7779_smp_ops; diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index b59048e6d8fd..eb98b45c5089 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -478,21 +478,17 @@ extern struct clk sh7372_fsibck_clk; extern struct clk sh7372_fsidiva_clk; extern struct clk sh7372_fsidivb_clk; -#ifdef CONFIG_PM -extern struct rmobile_pm_domain sh7372_pd_a4lc; -extern struct rmobile_pm_domain sh7372_pd_a4mp; -extern struct rmobile_pm_domain sh7372_pd_d4; -extern struct rmobile_pm_domain sh7372_pd_a4r; -extern struct rmobile_pm_domain sh7372_pd_a3rv; -extern struct rmobile_pm_domain sh7372_pd_a3ri; -extern struct rmobile_pm_domain sh7372_pd_a4s; -extern struct rmobile_pm_domain sh7372_pd_a3sp; -extern struct rmobile_pm_domain sh7372_pd_a3sg; -#endif /* CONFIG_PM */ - extern void sh7372_intcs_suspend(void); extern void sh7372_intcs_resume(void); extern void sh7372_intca_suspend(void); extern void sh7372_intca_resume(void); +#ifdef CONFIG_PM +extern void __init sh7372_init_pm_domains(void); +#else +static inline void sh7372_init_pm_domains(void) {} +#endif + +extern void __init sh7372_pm_init_late(void); + #endif /* __ASM_SH7372_H__ */ diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c index 893504d012a6..21e5316d2d88 100644 --- a/arch/arm/mach-shmobile/pm-r8a7740.c +++ b/arch/arm/mach-shmobile/pm-r8a7740.c @@ -21,14 +21,6 @@ static int r8a7740_pd_a4s_suspend(void) return -EBUSY; } -struct rmobile_pm_domain r8a7740_pd_a4s = { - .genpd.name = "A4S", - .bit_shift = 10, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = r8a7740_pd_a4s_suspend, -}; - static int r8a7740_pd_a3sp_suspend(void) { /* @@ -38,17 +30,31 @@ static int r8a7740_pd_a3sp_suspend(void) return console_suspend_enabled ? 0 : -EBUSY; } -struct rmobile_pm_domain r8a7740_pd_a3sp = { - .genpd.name = "A3SP", - .bit_shift = 11, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = r8a7740_pd_a3sp_suspend, +static struct rmobile_pm_domain r8a7740_pm_domains[] = { + { + .genpd.name = "A4S", + .bit_shift = 10, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = r8a7740_pd_a4s_suspend, + }, + { + .genpd.name = "A3SP", + .bit_shift = 11, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = r8a7740_pd_a3sp_suspend, + }, + { + .genpd.name = "A4LC", + .bit_shift = 1, + }, }; -struct rmobile_pm_domain r8a7740_pd_a4lc = { - .genpd.name = "A4LC", - .bit_shift = 1, -}; +void __init r8a7740_init_pm_domains(void) +{ + rmobile_init_domains(r8a7740_pm_domains, ARRAY_SIZE(r8a7740_pm_domains)); + pm_genpd_add_subdomain_names("A4S", "A3SP"); +} #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c index a18a4ae16d2b..d50a8e9b94a4 100644 --- a/arch/arm/mach-shmobile/pm-r8a7779.c +++ b/arch/arm/mach-shmobile/pm-r8a7779.c @@ -183,7 +183,7 @@ static bool pd_active_wakeup(struct device *dev) return true; } -void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) +static void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) { struct generic_pm_domain *genpd = &r8a7779_pd->genpd; @@ -199,43 +199,44 @@ void r8a7779_init_pm_domain(struct r8a7779_pm_domain *r8a7779_pd) pd_power_up(&r8a7779_pd->genpd); } -void r8a7779_add_device_to_domain(struct r8a7779_pm_domain *r8a7779_pd, - struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - pm_genpd_add_device(&r8a7779_pd->genpd, dev); - if (pm_clk_no_clocks(dev)) - pm_clk_add(dev, NULL); -} - -struct r8a7779_pm_domain r8a7779_sh4a = { - .ch = { - .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */ - .isr_bit = 16, /* SH4A */ - } -}; - -struct r8a7779_pm_domain r8a7779_sgx = { - .ch = { - .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */ - .isr_bit = 20, /* SGX */ - } +static struct r8a7779_pm_domain r8a7779_pm_domains[] = { + { + .genpd.name = "SH4A", + .ch = { + .chan_offs = 0x80, /* PWRSR1 .. PWRER1 */ + .isr_bit = 16, /* SH4A */ + }, + }, + { + .genpd.name = "SGX", + .ch = { + .chan_offs = 0xc0, /* PWRSR2 .. PWRER2 */ + .isr_bit = 20, /* SGX */ + }, + }, + { + .genpd.name = "VDP1", + .ch = { + .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ + .isr_bit = 21, /* VDP */ + }, + }, + { + .genpd.name = "IMPX3", + .ch = { + .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */ + .isr_bit = 24, /* IMP */ + }, + }, }; -struct r8a7779_pm_domain r8a7779_vdp1 = { - .ch = { - .chan_offs = 0x100, /* PWRSR3 .. PWRER3 */ - .isr_bit = 21, /* VDP */ - } -}; +void __init r8a7779_init_pm_domains(void) +{ + int j; -struct r8a7779_pm_domain r8a7779_impx3 = { - .ch = { - .chan_offs = 0x140, /* PWRSR4 .. PWRER4 */ - .isr_bit = 24, /* IMP */ - } -}; + for (j = 0; j < ARRAY_SIZE(r8a7779_pm_domains); j++) + r8a7779_init_pm_domain(&r8a7779_pm_domains[j]); +} #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 32e177275e47..1fc05d9453d0 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -134,7 +134,7 @@ static int rmobile_pd_start_dev(struct device *dev) return ret; } -void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) +static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) { struct generic_pm_domain *genpd = &rmobile_pd->genpd; struct dev_power_governor *gov = rmobile_pd->gov; @@ -149,19 +149,38 @@ void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) __rmobile_pd_power_up(rmobile_pd, false); } -void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd, - struct platform_device *pdev) +void rmobile_init_domains(struct rmobile_pm_domain domains[], int num) +{ + int j; + + for (j = 0; j < num; j++) + rmobile_init_pm_domain(&domains[j]); +} + +void rmobile_add_device_to_domain_td(const char *domain_name, + struct platform_device *pdev, + struct gpd_timing_data *td) { struct device *dev = &pdev->dev; - pm_genpd_add_device(&rmobile_pd->genpd, dev); + __pm_genpd_name_add_device(domain_name, dev, td); if (pm_clk_no_clocks(dev)) pm_clk_add(dev, NULL); } -void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd, - struct rmobile_pm_domain *rmobile_sd) +void rmobile_add_devices_to_domains(struct pm_domain_device data[], + int size) { - pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd); + struct gpd_timing_data latencies = { + .stop_latency_ns = DEFAULT_DEV_LATENCY_NS, + .start_latency_ns = DEFAULT_DEV_LATENCY_NS, + .save_state_latency_ns = DEFAULT_DEV_LATENCY_NS, + .restore_state_latency_ns = DEFAULT_DEV_LATENCY_NS, + }; + int j; + + for (j = 0; j < size; j++) + rmobile_add_device_to_domain_td(data[j].domain_name, + data[j].pdev, &latencies); } #endif /* CONFIG_PM */ diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c index 162121842a2b..a0826a48dd08 100644 --- a/arch/arm/mach-shmobile/pm-sh7372.c +++ b/arch/arm/mach-shmobile/pm-sh7372.c @@ -21,6 +21,7 @@ #include <linux/irq.h> #include <linux/bitrev.h> #include <linux/console.h> +#include <asm/cpuidle.h> #include <asm/io.h> #include <asm/tlbflush.h> #include <asm/suspend.h> @@ -72,20 +73,7 @@ #ifdef CONFIG_PM -struct rmobile_pm_domain sh7372_pd_a4lc = { - .genpd.name = "A4LC", - .bit_shift = 1, -}; - -struct rmobile_pm_domain sh7372_pd_a4mp = { - .genpd.name = "A4MP", - .bit_shift = 2, -}; - -struct rmobile_pm_domain sh7372_pd_d4 = { - .genpd.name = "D4", - .bit_shift = 3, -}; +#define PM_DOMAIN_ON_OFF_LATENCY_NS 250000 static int sh7372_a4r_pd_suspend(void) { @@ -94,39 +82,25 @@ static int sh7372_a4r_pd_suspend(void) return 0; } -struct rmobile_pm_domain sh7372_pd_a4r = { - .genpd.name = "A4R", - .bit_shift = 5, - .suspend = sh7372_a4r_pd_suspend, - .resume = sh7372_intcs_resume, -}; +static bool a4s_suspend_ready; -struct rmobile_pm_domain sh7372_pd_a3rv = { - .genpd.name = "A3RV", - .bit_shift = 6, -}; - -struct rmobile_pm_domain sh7372_pd_a3ri = { - .genpd.name = "A3RI", - .bit_shift = 8, -}; - -static int sh7372_pd_a4s_suspend(void) +static int sh7372_a4s_pd_suspend(void) { /* * The A4S domain contains the CPU core and therefore it should - * only be turned off if the CPU is in use. + * only be turned off if the CPU is not in use. This may happen + * during system suspend, when SYSC is going to be used for generating + * resume signals and a4s_suspend_ready is set to let + * sh7372_enter_suspend() know that it can turn A4S off. */ + a4s_suspend_ready = true; return -EBUSY; } -struct rmobile_pm_domain sh7372_pd_a4s = { - .genpd.name = "A4S", - .bit_shift = 10, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = sh7372_pd_a4s_suspend, -}; +static void sh7372_a4s_pd_resume(void) +{ + a4s_suspend_ready = false; +} static int sh7372_a3sp_pd_suspend(void) { @@ -137,18 +111,80 @@ static int sh7372_a3sp_pd_suspend(void) return console_suspend_enabled ? 0 : -EBUSY; } -struct rmobile_pm_domain sh7372_pd_a3sp = { - .genpd.name = "A3SP", - .bit_shift = 11, - .gov = &pm_domain_always_on_gov, - .no_debug = true, - .suspend = sh7372_a3sp_pd_suspend, +static struct rmobile_pm_domain sh7372_pm_domains[] = { + { + .genpd.name = "A4LC", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 1, + }, + { + .genpd.name = "A4MP", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 2, + }, + { + .genpd.name = "D4", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 3, + }, + { + .genpd.name = "A4R", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 5, + .suspend = sh7372_a4r_pd_suspend, + .resume = sh7372_intcs_resume, + }, + { + .genpd.name = "A3RV", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 6, + }, + { + .genpd.name = "A3RI", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 8, + }, + { + .genpd.name = "A4S", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 10, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = sh7372_a4s_pd_suspend, + .resume = sh7372_a4s_pd_resume, + }, + { + .genpd.name = "A3SP", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 11, + .gov = &pm_domain_always_on_gov, + .no_debug = true, + .suspend = sh7372_a3sp_pd_suspend, + }, + { + .genpd.name = "A3SG", + .genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS, + .bit_shift = 13, + }, }; -struct rmobile_pm_domain sh7372_pd_a3sg = { - .genpd.name = "A3SG", - .bit_shift = 13, -}; +void __init sh7372_init_pm_domains(void) +{ + rmobile_init_domains(sh7372_pm_domains, ARRAY_SIZE(sh7372_pm_domains)); + pm_genpd_add_subdomain_names("A4LC", "A3RV"); + pm_genpd_add_subdomain_names("A4R", "A4LC"); + pm_genpd_add_subdomain_names("A4S", "A3SG"); + pm_genpd_add_subdomain_names("A4S", "A3SP"); +} #endif /* CONFIG_PM */ @@ -304,6 +340,21 @@ static void sh7372_enter_a3sm_common(int pllc0_on) sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); sh7372_enter_sysc(pllc0_on, 1 << 12); } + +static void sh7372_enter_a4s_common(int pllc0_on) +{ + sh7372_intca_suspend(); + sh7372_set_reset_vector(SMFRAM); + sh7372_enter_sysc(pllc0_on, 1 << 10); + sh7372_intca_resume(); +} + +static void sh7372_pm_setup_smfram(void) +{ + memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); +} +#else +static inline void sh7372_pm_setup_smfram(void) {} #endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */ #ifdef CONFIG_CPU_IDLE @@ -313,7 +364,8 @@ static int sh7372_do_idle_core_standby(unsigned long unused) return 0; } -static void sh7372_enter_core_standby(void) +static int sh7372_enter_core_standby(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc)); @@ -324,83 +376,102 @@ static void sh7372_enter_core_standby(void) /* disable reset vector translation */ __raw_writel(0, SBAR); + + return 1; } -static void sh7372_enter_a3sm_pll_on(void) +static int sh7372_enter_a3sm_pll_on(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { sh7372_enter_a3sm_common(1); + return 2; } -static void sh7372_enter_a3sm_pll_off(void) +static int sh7372_enter_a3sm_pll_off(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { sh7372_enter_a3sm_common(0); + return 3; } -static void sh7372_cpuidle_setup(struct cpuidle_driver *drv) +static int sh7372_enter_a4s(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { - struct cpuidle_state *state = &drv->states[drv->state_count]; - - snprintf(state->name, CPUIDLE_NAME_LEN, "C2"); - strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN); - state->exit_latency = 10; - state->target_residency = 20 + 10; - state->flags = CPUIDLE_FLAG_TIME_VALID; - shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby; - drv->state_count++; - - state = &drv->states[drv->state_count]; - snprintf(state->name, CPUIDLE_NAME_LEN, "C3"); - strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN); - state->exit_latency = 20; - state->target_residency = 30 + 20; - state->flags = CPUIDLE_FLAG_TIME_VALID; - shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on; - drv->state_count++; - - state = &drv->states[drv->state_count]; - snprintf(state->name, CPUIDLE_NAME_LEN, "C4"); - strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN); - state->exit_latency = 120; - state->target_residency = 30 + 120; - state->flags = CPUIDLE_FLAG_TIME_VALID; - shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off; - drv->state_count++; + unsigned long msk, msk2; + + if (!sh7372_sysc_valid(&msk, &msk2)) + return sh7372_enter_a3sm_pll_off(dev, drv, index); + + sh7372_setup_sysc(msk, msk2); + sh7372_enter_a4s_common(0); + return 4; } +static struct cpuidle_driver sh7372_cpuidle_driver = { + .name = "sh7372_cpuidle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .state_count = 5, + .safe_state_index = 0, /* C1 */ + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[0].enter = shmobile_enter_wfi, + .states[1] = { + .name = "C2", + .desc = "Core Standby Mode", + .exit_latency = 10, + .target_residency = 20 + 10, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_core_standby, + }, + .states[2] = { + .name = "C3", + .desc = "A3SM PLL ON", + .exit_latency = 20, + .target_residency = 30 + 20, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_a3sm_pll_on, + }, + .states[3] = { + .name = "C4", + .desc = "A3SM PLL OFF", + .exit_latency = 120, + .target_residency = 30 + 120, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_a3sm_pll_off, + }, + .states[4] = { + .name = "C5", + .desc = "A4S PLL OFF", + .exit_latency = 240, + .target_residency = 30 + 240, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = sh7372_enter_a4s, + .disabled = true, + }, +}; + static void sh7372_cpuidle_init(void) { - shmobile_cpuidle_setup = sh7372_cpuidle_setup; + shmobile_cpuidle_set_driver(&sh7372_cpuidle_driver); } #else static void sh7372_cpuidle_init(void) {} #endif #ifdef CONFIG_SUSPEND -static void sh7372_enter_a4s_common(int pllc0_on) -{ - sh7372_intca_suspend(); - memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100); - sh7372_set_reset_vector(SMFRAM); - sh7372_enter_sysc(pllc0_on, 1 << 10); - sh7372_intca_resume(); -} - static int sh7372_enter_suspend(suspend_state_t suspend_state) { unsigned long msk, msk2; /* check active clocks to determine potential wakeup sources */ - if (sh7372_sysc_valid(&msk, &msk2)) { - if (!console_suspend_enabled && - sh7372_pd_a4s.genpd.status == GPD_STATE_POWER_OFF) { - /* convert INTC mask/sense to SYSC mask/sense */ - sh7372_setup_sysc(msk, msk2); - - /* enter A4S sleep with PLLC0 off */ - pr_debug("entering A4S\n"); - sh7372_enter_a4s_common(0); - return 0; - } + if (sh7372_sysc_valid(&msk, &msk2) && a4s_suspend_ready) { + /* convert INTC mask/sense to SYSC mask/sense */ + sh7372_setup_sysc(msk, msk2); + + /* enter A4S sleep with PLLC0 off */ + pr_debug("entering A4S\n"); + sh7372_enter_a4s_common(0); + return 0; } /* default to enter A3SM sleep with PLLC0 off */ @@ -426,7 +497,7 @@ static int sh7372_pm_notifier_fn(struct notifier_block *notifier, * executed during system suspend and resume, respectively, so * that those functions don't crash while accessing the INTCS. */ - pm_genpd_poweron(&sh7372_pd_a4r.genpd); + pm_genpd_name_poweron("A4R"); break; case PM_POST_SUSPEND: pm_genpd_poweroff_unused(); @@ -455,6 +526,14 @@ void __init sh7372_pm_init(void) /* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */ __raw_writel(0, PDNSEL); + sh7372_pm_setup_smfram(); + sh7372_suspend_init(); sh7372_cpuidle_init(); } + +void __init sh7372_pm_init_late(void) +{ + shmobile_init_late(); + pm_genpd_name_attach_cpuidle("A4S", 4); +} diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 78948a9dba0e..11bb1d984197 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -673,12 +673,7 @@ void __init r8a7740_add_standard_devices(void) r8a7740_i2c_workaround(&i2c0_device); r8a7740_i2c_workaround(&i2c1_device); - /* PM domain */ - rmobile_init_pm_domain(&r8a7740_pd_a4s); - rmobile_init_pm_domain(&r8a7740_pd_a3sp); - rmobile_init_pm_domain(&r8a7740_pd_a4lc); - - rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp); + r8a7740_init_pm_domains(); /* add devices */ platform_add_devices(r8a7740_early_devices, @@ -688,16 +683,16 @@ void __init r8a7740_add_standard_devices(void) /* add devices to PM domain */ - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device); - rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device); + rmobile_add_device_to_domain("A3SP", &scif0_device); + rmobile_add_device_to_domain("A3SP", &scif1_device); + rmobile_add_device_to_domain("A3SP", &scif2_device); + rmobile_add_device_to_domain("A3SP", &scif3_device); + rmobile_add_device_to_domain("A3SP", &scif4_device); + rmobile_add_device_to_domain("A3SP", &scif5_device); + rmobile_add_device_to_domain("A3SP", &scif6_device); + rmobile_add_device_to_domain("A3SP", &scif7_device); + rmobile_add_device_to_domain("A3SP", &scifb_device); + rmobile_add_device_to_domain("A3SP", &i2c1_device); } static void __init r8a7740_earlytimer_init(void) diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index e98e46f6cf55..2917668f0091 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -251,10 +251,7 @@ void __init r8a7779_add_standard_devices(void) #endif r8a7779_pm_init(); - r8a7779_init_pm_domain(&r8a7779_sh4a); - r8a7779_init_pm_domain(&r8a7779_sgx); - r8a7779_init_pm_domain(&r8a7779_vdp1); - r8a7779_init_pm_domain(&r8a7779_impx3); + r8a7779_init_pm_domains(); platform_add_devices(r8a7779_early_devices, ARRAY_SIZE(r8a7779_early_devices)); diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 838a87be1d5c..a07954fbcd22 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1001,21 +1001,34 @@ static struct platform_device *sh7372_late_devices[] __initdata = { void __init sh7372_add_standard_devices(void) { - rmobile_init_pm_domain(&sh7372_pd_a4lc); - rmobile_init_pm_domain(&sh7372_pd_a4mp); - rmobile_init_pm_domain(&sh7372_pd_d4); - rmobile_init_pm_domain(&sh7372_pd_a4r); - rmobile_init_pm_domain(&sh7372_pd_a3rv); - rmobile_init_pm_domain(&sh7372_pd_a3ri); - rmobile_init_pm_domain(&sh7372_pd_a4s); - rmobile_init_pm_domain(&sh7372_pd_a3sp); - rmobile_init_pm_domain(&sh7372_pd_a3sg); - - rmobile_pm_add_subdomain(&sh7372_pd_a4lc, &sh7372_pd_a3rv); - rmobile_pm_add_subdomain(&sh7372_pd_a4r, &sh7372_pd_a4lc); - - rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sg); - rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sp); + struct pm_domain_device domain_devices[] = { + { "A3RV", &vpu_device, }, + { "A4MP", &spu0_device, }, + { "A4MP", &spu1_device, }, + { "A3SP", &scif0_device, }, + { "A3SP", &scif1_device, }, + { "A3SP", &scif2_device, }, + { "A3SP", &scif3_device, }, + { "A3SP", &scif4_device, }, + { "A3SP", &scif5_device, }, + { "A3SP", &scif6_device, }, + { "A3SP", &iic1_device, }, + { "A3SP", &dma0_device, }, + { "A3SP", &dma1_device, }, + { "A3SP", &dma2_device, }, + { "A3SP", &usb_dma0_device, }, + { "A3SP", &usb_dma1_device, }, + { "A4R", &iic0_device, }, + { "A4R", &veu0_device, }, + { "A4R", &veu1_device, }, + { "A4R", &veu2_device, }, + { "A4R", &veu3_device, }, + { "A4R", &jpu_device, }, + { "A4R", &tmu00_device, }, + { "A4R", &tmu01_device, }, + }; + + sh7372_init_pm_domains(); platform_add_devices(sh7372_early_devices, ARRAY_SIZE(sh7372_early_devices)); @@ -1023,30 +1036,8 @@ void __init sh7372_add_standard_devices(void) platform_add_devices(sh7372_late_devices, ARRAY_SIZE(sh7372_late_devices)); - rmobile_add_device_to_domain(&sh7372_pd_a3rv, &vpu_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu0_device); - rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif2_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif3_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif4_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif5_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif6_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &iic1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma1_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma2_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma0_device); - rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &iic0_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu0_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu1_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu2_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu3_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &jpu_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu00_device); - rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu01_device); + rmobile_add_devices_to_domains(domain_devices, + ARRAY_SIZE(domain_devices)); } static void __init sh7372_earlytimer_init(void) diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 957ec87385af..fbee9714d9ab 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -248,6 +248,9 @@ #define MSR_IA32_PERF_STATUS 0x00000198 #define MSR_IA32_PERF_CTL 0x00000199 +#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 +#define MSR_AMD_PERF_STATUS 0xc0010063 +#define MSR_AMD_PERF_CTL 0xc0010062 #define MSR_IA32_MPERF 0x000000e7 #define MSR_IA32_APERF 0x000000e8 |