From: Linus Torvalds Date: Wed, 3 Oct 2012 01:32:35 +0000 (-0700) Subject: Merge tag 'pm-for-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael... X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=16642a2e7be23bbda013fc32d8f6c68982eab603;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git Merge tag 'pm-for-3.7-rc1' of git://git./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 ... --- 16642a2e7be23bbda013fc32d8f6c68982eab603 diff --cc arch/arm/kernel/smp.c index aa4ffe6e5ecf,8e03567c9583..dea7a925c7e2 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@@ -24,9 -25,9 +24,10 @@@ #include #include #include + #include #include +#include #include #include #include diff --cc arch/arm/mach-shmobile/board-ap4evb.c index bc3b5da59e25,264340a60f65..790dc68c4312 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@@ -1226,11 -1224,20 +1226,20 @@@ static struct i2c_board_info i2c1_devic }; -#define GPIO_PORT9CR 0xE6051009 -#define GPIO_PORT10CR 0xE605100A -#define USCCR1 0xE6058144 +#define GPIO_PORT9CR IOMEM(0xE6051009) +#define GPIO_PORT10CR IOMEM(0xE605100A) +#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; diff --cc arch/arm/mach-shmobile/board-mackerel.c index 62783b5d8813,c76776a3e70d..0c27c810cf99 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@@ -1404,14 -1402,30 +1404,30 @@@ static struct i2c_board_info i2c1_devic }, }; -#define GPIO_PORT9CR 0xE6051009 -#define GPIO_PORT10CR 0xE605100A -#define GPIO_PORT167CR 0xE60520A7 -#define GPIO_PORT168CR 0xE60520A8 -#define SRCR4 0xe61580bc -#define USCCR1 0xE6058144 +#define GPIO_PORT9CR IOMEM(0xE6051009) +#define GPIO_PORT10CR IOMEM(0xE605100A) +#define GPIO_PORT167CR IOMEM(0xE60520A7) +#define GPIO_PORT168CR IOMEM(0xE60520A8) +#define SRCR4 IOMEM(0xe61580bc) +#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; diff --cc arch/arm/mach-shmobile/include/mach/common.h index f80f9c549393,eb89293fff4d..ed77ab8c9143 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@@ -73,10 -81,13 +75,8 @@@ extern void r8a7779_pinmux_init(void) extern void r8a7779_pm_init(void); extern void r8a7740_meram_workaround(void); -extern unsigned int r8a7779_get_core_count(void); -extern int r8a7779_platform_cpu_kill(unsigned int cpu); -extern void r8a7779_secondary_init(unsigned int cpu); -extern int r8a7779_boot_secondary(unsigned int cpu); -extern void r8a7779_smp_prepare_cpus(void); extern void r8a7779_register_twd(void); - extern void shmobile_init_late(void); - #ifdef CONFIG_SUSPEND int shmobile_suspend_init(void); #else @@@ -89,15 -100,10 +89,21 @@@ int shmobile_cpuidle_init(void) static inline int shmobile_cpuidle_init(void) { return 0; } #endif +extern void shmobile_cpu_die(unsigned int cpu); +extern int shmobile_cpu_disable(unsigned int cpu); + +#ifdef CONFIG_HOTPLUG_CPU +extern int shmobile_cpu_is_dead(unsigned int cpu); +#else +static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; } +#endif + +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 --cc arch/arm/mach-shmobile/include/mach/r8a7779.h index f504c5e81b47,7ad47977d2e7..499f52d2a4a1 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@@ -347,19 -347,9 +347,11 @@@ extern int r8a7779_sysc_power_down(stru 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; + #endif /* __ASM_R8A7779_H__ */ diff --cc drivers/base/platform.c index ddeca142293c,d51514b79efe..8727e9c5eea4 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@@ -20,13 -20,10 +20,14 @@@ #include #include #include +#include #include "base.h" + #include "power/power.h" +/* For automatically allocated device IDs */ +static DEFINE_IDA(platform_devid_ida); + #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ driver)) diff --cc drivers/cpufreq/powernow-k8.c index 1a40935c85fd,0b19faf002ee..129e80bfff22 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@@ -1104,52 -978,11 +977,18 @@@ static int transition_frequency_fidvid( return res; } - /* Take a frequency, and issue the hardware pstate transition command */ - static int transition_frequency_pstate(struct powernow_k8_data *data, - unsigned int index) - { - u32 pstate = 0; - int res, i; - struct cpufreq_freqs freqs; - - pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index); - - /* get MSR index for hardware pstate transition */ - pstate = index & HW_PSTATE_MASK; - if (pstate > data->max_hw_pstate) - return -EINVAL; - - freqs.old = find_khz_freq_from_pstate(data->powernow_table, - data->currpstate); - freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } - - res = transition_pstate(data, pstate); - freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); - - for_each_cpu(i, data->available_cores) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } - return res; - } - -/* Driver entry point to switch to the target frequency */ -static int powernowk8_target(struct cpufreq_policy *pol, - unsigned targfreq, unsigned relation) +struct powernowk8_target_arg { + struct cpufreq_policy *pol; + unsigned targfreq; + unsigned relation; +}; + +static long powernowk8_target_fn(void *arg) { - cpumask_var_t oldmask; + struct powernowk8_target_arg *pta = arg; + struct cpufreq_policy *pol = pta->pol; + unsigned targfreq = pta->targfreq; + unsigned relation = pta->relation; struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); u32 checkfid; u32 checkvid; @@@ -1171,20 -1017,17 +1010,17 @@@ pol->cpu, targfreq, pol->min, pol->max, relation); if (query_current_values_with_pending_wait(data)) - goto err_out; + return -EIO; - if (cpu_family != CPU_HW_PSTATE) { - pr_debug("targ: curr fid 0x%x, vid 0x%x\n", - data->currfid, data->currvid); + pr_debug("targ: curr fid 0x%x, vid 0x%x\n", + data->currfid, data->currvid); - if ((checkvid != data->currvid) || - (checkfid != data->currfid)) { - printk(KERN_INFO PFX - "error - out of sync, fix 0x%x 0x%x, " - "vid 0x%x 0x%x\n", - checkfid, data->currfid, - checkvid, data->currvid); - } + if ((checkvid != data->currvid) || + (checkfid != data->currfid)) { + pr_info(PFX + "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", + checkfid, data->currfid, + checkvid, data->currvid); } if (cpufreq_frequency_table_target(pol, data->powernow_table, @@@ -1195,42 -1038,23 +1031,35 @@@ powernow_k8_acpi_pst_values(data, newstate); - if (cpu_family == CPU_HW_PSTATE) - ret = transition_frequency_pstate(data, - data->powernow_table[newstate].index); - else - ret = transition_frequency_fidvid(data, newstate); + ret = transition_frequency_fidvid(data, newstate); + if (ret) { printk(KERN_ERR PFX "transition frequency failed\n"); - ret = 1; mutex_unlock(&fidvid_mutex); - goto err_out; + return 1; } mutex_unlock(&fidvid_mutex); - if (cpu_family == CPU_HW_PSTATE) - pol->cur = find_khz_freq_from_pstate(data->powernow_table, - data->powernow_table[newstate].index); - else - pol->cur = find_khz_freq_from_fid(data->currfid); + pol->cur = find_khz_freq_from_fid(data->currfid); - ret = 0; -err_out: - set_cpus_allowed_ptr(current, oldmask); - free_cpumask_var(oldmask); - return ret; + return 0; +} + +/* Driver entry point to switch to the target frequency */ +static int powernowk8_target(struct cpufreq_policy *pol, + unsigned targfreq, unsigned relation) +{ + struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, + .relation = relation }; + + /* + * Must run on @pol->cpu. cpufreq core is responsible for ensuring + * that we're bound to the current CPU and pol->cpu stays online. + */ + if (smp_processor_id() == pol->cpu) + return powernowk8_target_fn(&pta); + else + return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); } /* Driver entry point to verify the policy and range of frequencies */