提交 a11da7df 编写于 作者: L Linus Torvalds

Merge tag 'pm-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC power management and clock changes from Olof Johansson:
 "This branch contains a largeish set of updates of power management and
  clock setup.  The bulk of it is for OMAP/AM33xx platforms, but also a
  few around hotplug/suspend/resume on Exynos.

  It includes a split-up of some of the OMAP clock data into separate
  files which adds to the diffstat, but gross delta is fairly reasonable."

* tag 'pm-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (60 commits)
  ARM: OMAP: Move plat-omap/dma-omap.h to include/linux/omap-dma.h
  ASoC: OMAP: mcbsp fixes for enabling ARM multiplatform support
  watchdog: OMAP: fixup for ARM multiplatform support
  ARM: EXYNOS: Add flush_cache_all in suspend finisher
  ARM: EXYNOS: Remove scu_enable from cpuidle
  ARM: EXYNOS: Fix soft reboot hang after suspend/resume
  ARM: EXYNOS: Add support for rtc wakeup
  ARM: EXYNOS: fix the hotplug for Cortex-A15
  ARM: OMAP2+: omap_device: Correct resource handling for DT boot
  ARM: OMAP2+: hwmod: Add possibility to count hwmod resources based on type
  ARM: OMAP2+: hwmod: Add support for per hwmod/module context lost count
  ARM: OMAP2+: PRM: initialize some PRM functions early
  ARM: OMAP2+: voltage: fixup oscillator handling when CONFIG_PM=n
  ARM: OMAP4: USB: power down MUSB PHY during boot
  ARM: OMAP2+: clock: Cleanup !CONFIG_COMMON_CLK parts
  ARM: OMAP2xxx: clock: drop obsolete clock data
  ARM: OMAP2: clock: Cleanup !CONFIG_COMMON_CLK parts
  ARM: OMAP3+: DPLL: drop !CONFIG_COMMON_CLK sections
  ARM: AM33xx: clock: drop obsolete clock data
  ARM: OMAP3xxx: clk: drop obsolete clock data
  ...
......@@ -680,6 +680,8 @@ void __init exynos5_init_irq(void)
* uses GIC instead of VIC.
*/
s5p_init_irq(NULL, 0);
gic_arch_extn.irq_set_wake = s3c_irq_wake;
}
struct bus_type exynos_subsys = {
......
......@@ -116,7 +116,8 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,
cpu_suspend(0, idle_finisher);
#ifdef CONFIG_SMP
scu_enable(S5P_VA_SCU);
if (!soc_is_exynos5250())
scu_enable(S5P_VA_SCU);
#endif
cpu_pm_exit();
......
......@@ -20,10 +20,11 @@
#include <asm/smp_plat.h>
#include <mach/regs-pmu.h>
#include <plat/cpu.h>
#include "common.h"
static inline void cpu_enter_lowpower(void)
static inline void cpu_enter_lowpower_a9(void)
{
unsigned int v;
......@@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void)
: "cc");
}
static inline void cpu_enter_lowpower_a15(void)
{
unsigned int v;
asm volatile(
" mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
: "Ir" (CR_C)
: "cc");
flush_cache_louis();
asm volatile(
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1\n"
" bic %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&r" (v)
: "Ir" (0x40)
: "cc");
isb();
dsb();
}
static inline void cpu_leave_lowpower(void)
{
unsigned int v;
......@@ -103,11 +133,20 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
void __ref exynos_cpu_die(unsigned int cpu)
{
int spurious = 0;
int primary_part = 0;
/*
* we're ready for shutdown now, so do it
* we're ready for shutdown now, so do it.
* Exynos4 is A9 based while Exynos5 is A15; check the CPU part
* number by reading the Main ID register and then perform the
* appropriate sequence for entering low power.
*/
cpu_enter_lowpower();
asm("mrc p15, 0, %0, c0, c0, 0" : "=r"(primary_part) : : "cc");
if ((primary_part & 0xfff0) == 0xc0f0)
cpu_enter_lowpower_a15();
else
cpu_enter_lowpower_a9();
platform_do_lowpower(cpu, &spurious);
/*
......
......@@ -81,6 +81,9 @@ static int exynos_cpu_suspend(unsigned long arg)
outer_flush_all();
#endif
if (soc_is_exynos5250())
flush_cache_all();
/* issue the standby signal into the pm unit. */
cpu_do_idle();
......@@ -312,6 +315,10 @@ static void exynos_pm_resume(void)
}
early_wakeup:
/* Clear SLEEP mode set in INFORM1 */
__raw_writel(0x0, S5P_INFORM1);
return;
}
......
......@@ -39,7 +39,7 @@
#include <asm/mach/map.h>
#include <mach/mux.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
#include <mach/irda.h>
#include <linux/platform_data/keypad-omap.h>
......
......@@ -43,7 +43,7 @@
#include <mach/mux.h>
#include <mach/tc.h>
#include <linux/platform_data/keypad-omap.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/flash.h>
#include <mach/hardware.h>
......
......@@ -37,7 +37,7 @@
#include <mach/flash.h>
#include <mach/mux.h>
#include <mach/tc.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/irda.h>
#include <linux/platform_data/keypad-omap.h>
......
......@@ -36,7 +36,7 @@
#include <mach/flash.h>
#include <mach/mux.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
#include <mach/irda.h>
#include <linux/platform_data/keypad-omap.h>
......
......@@ -38,7 +38,7 @@
#include <mach/flash.h>
#include <mach/mux.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
#include <mach/irda.h>
#include <linux/platform_data/keypad-omap.h>
......
......@@ -36,7 +36,7 @@
#include <mach/flash.h>
#include <mach/mux.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/irda.h>
#include <mach/tc.h>
#include <mach/board-sx1.h>
......
......@@ -25,7 +25,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>
#include <mach/irqs.h>
......
......@@ -18,7 +18,7 @@
#include <mach/mux.h>
#include <mach/tc.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include "iomap.h"
#include "common.h"
......
......@@ -27,7 +27,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/hardware.h>
#include <mach/lcdc.h>
......
......@@ -19,7 +19,7 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <mach/mux.h>
#include "soc.h"
#include <linux/platform_data/asoc-ti-mcbsp.h>
......
......@@ -52,7 +52,7 @@
#include <mach/tc.h>
#include <mach/mux.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <plat/dmtimer.h>
#include <mach/irqs.h>
......
......@@ -34,6 +34,7 @@ config ARCH_OMAP2
select CPU_V6
select MULTI_IRQ_HANDLER
select SOC_HAS_OMAP2_SDRC
select COMMON_CLK
config ARCH_OMAP3
bool "TI OMAP3"
......@@ -47,6 +48,7 @@ config ARCH_OMAP3
select PM_OPP if PM
select PM_RUNTIME if CPU_IDLE
select SOC_HAS_OMAP2_SDRC
select COMMON_CLK
select USB_ARCH_HAS_EHCI if USB_SUPPORT
config ARCH_OMAP4
......@@ -68,6 +70,7 @@ config ARCH_OMAP4
select PM_OPP if PM
select PM_RUNTIME if CPU_IDLE
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select COMMON_CLK
config SOC_OMAP5
bool "TI OMAP5"
......@@ -77,6 +80,7 @@ config SOC_OMAP5
select CPU_V7
select HAVE_SMP
select SOC_HAS_REALTIME_COUNTER
select COMMON_CLK
comment "OMAP Core Type"
depends on ARCH_OMAP2
......@@ -111,6 +115,7 @@ config SOC_AM33XX
select ARM_CPU_SUSPEND if PM
select CPU_V7
select MULTI_IRQ_HANDLER
select COMMON_CLK
config OMAP_PACKAGE_ZAF
bool
......
......@@ -160,17 +160,17 @@ obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
obj-$(CONFIG_SOC_OMAP2420) += cclock2420_data.o
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o cclock2430_data.o
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) cclock44xx_data.o
obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o
obj-$(CONFIG_SOC_AM33XX) += clock33xx_data.o
obj-$(CONFIG_SOC_AM33XX) += cclock33xx_data.o
obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
......
......@@ -31,7 +31,7 @@
#include <asm/mach/map.h>
#include "common.h"
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <video/omapdss.h>
#include <video/omap-panel-tfp410.h>
......
......@@ -32,7 +32,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include <plat/debug-devices.h>
#include <video/omapdss.h>
......
......@@ -31,7 +31,7 @@
#include <asm/system_info.h>
#include "common.h"
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include "gpmc-smc91x.h"
#include "board-rx51.h"
......
......@@ -24,7 +24,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat-omap/dma-omap.h>
#include <linux/omap-dma.h>
#include "common.h"
#include "mux.h"
......
此差异已折叠。
......@@ -38,62 +38,88 @@
/* Private functions */
static int _apll96_enable(struct clk *clk)
/**
* omap2xxx_clk_apll_locked - is the APLL locked?
* @hw: struct clk_hw * of the APLL to check
*
* If the APLL IP block referred to by @hw indicates that it's locked,
* return true; otherwise, return false.
*/
static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
u32 r, apll_mask;
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
return ((r & apll_mask) == apll_mask) ? true : false;
}
int omap2_clk_apll96_enable(struct clk_hw *hw)
{
return omap2xxx_cm_apll96_enable();
}
static int _apll54_enable(struct clk *clk)
int omap2_clk_apll54_enable(struct clk_hw *hw)
{
return omap2xxx_cm_apll54_enable();
}
static void _apll96_allow_idle(struct clk *clk)
static void _apll96_allow_idle(struct clk_hw_omap *clk)
{
omap2xxx_cm_set_apll96_auto_low_power_stop();
}
static void _apll96_deny_idle(struct clk *clk)
static void _apll96_deny_idle(struct clk_hw_omap *clk)
{
omap2xxx_cm_set_apll96_disable_autoidle();
}
static void _apll54_allow_idle(struct clk *clk)
static void _apll54_allow_idle(struct clk_hw_omap *clk)
{
omap2xxx_cm_set_apll54_auto_low_power_stop();
}
static void _apll54_deny_idle(struct clk *clk)
static void _apll54_deny_idle(struct clk_hw_omap *clk)
{
omap2xxx_cm_set_apll54_disable_autoidle();
}
static void _apll96_disable(struct clk *clk)
void omap2_clk_apll96_disable(struct clk_hw *hw)
{
omap2xxx_cm_apll96_disable();
}
static void _apll54_disable(struct clk *clk)
void omap2_clk_apll54_disable(struct clk_hw *hw)
{
omap2xxx_cm_apll54_disable();
}
/* Public data */
unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
unsigned long parent_rate)
{
return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0;
}
const struct clkops clkops_apll96 = {
.enable = _apll96_enable,
.disable = _apll96_disable,
.allow_idle = _apll96_allow_idle,
.deny_idle = _apll96_deny_idle,
};
unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
unsigned long parent_rate)
{
return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0;
}
const struct clkops clkops_apll54 = {
.enable = _apll54_enable,
.disable = _apll54_disable,
/* Public data */
const struct clk_hw_omap_ops clkhwops_apll54 = {
.allow_idle = _apll54_allow_idle,
.deny_idle = _apll54_deny_idle,
};
const struct clk_hw_omap_ops clkhwops_apll96 = {
.allow_idle = _apll96_allow_idle,
.deny_idle = _apll96_deny_idle,
};
/* Public functions */
u32 omap2xxx_get_apll_clkin(void)
......
......@@ -29,7 +29,7 @@
* REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
* instead. Add some mechanism to optionally enter this mode.
*/
static void _allow_idle(struct clk *clk)
static void _allow_idle(struct clk_hw_omap *clk)
{
if (!clk || !clk->dpll_data)
return;
......@@ -43,7 +43,7 @@ static void _allow_idle(struct clk *clk)
*
* Disable DPLL automatic idle control. No return value.
*/
static void _deny_idle(struct clk *clk)
static void _deny_idle(struct clk_hw_omap *clk)
{
if (!clk || !clk->dpll_data)
return;
......@@ -53,9 +53,7 @@ static void _deny_idle(struct clk *clk)
/* Public data */
const struct clkops clkops_omap2xxx_dpll_ops = {
const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll = {
.allow_idle = _allow_idle,
.deny_idle = _deny_idle,
};
......@@ -40,7 +40,7 @@
* (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set
* during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
*/
static struct clk *dpll_core_ck;
static struct clk_hw_omap *dpll_core_ck;
/**
* omap2xxx_clk_get_core_rate - return the CORE_CLK rate
......@@ -104,13 +104,16 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
}
unsigned long omap2_dpllcore_recalc(struct clk *clk)
unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
unsigned long parent_rate)
{
return omap2xxx_clk_get_core_rate();
}
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
u32 cur_rate, low, mult, div, valid_rate, done_rate;
u32 bypass = 0;
struct prcm_config tmpset;
......@@ -188,8 +191,8 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
* statically defined, this code may need to change to increment some
* kind of use count on dpll_ck.
*/
void omap2xxx_clkt_dpllcore_init(struct clk *clk)
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw)
{
WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
dpll_core_ck = clk;
dpll_core_ck = to_clk_hw_omap(hw);
}
此差异已折叠。
......@@ -40,9 +40,8 @@ u32 omap2xxx_get_sysclkdiv(void)
return div;
}
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
unsigned long parent_rate)
{
return clk->parent->rate / omap2xxx_get_sysclkdiv();
return parent_rate / omap2xxx_get_sysclkdiv();
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -28,6 +28,7 @@
#include "cm.h"
#include "cm-regbits-24xx.h"
struct clk_hw *dclk_hw;
/*
* Omap24xx specific clock functions
*/
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册