summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorKevin Hilman <khilman@linaro.org>2015-06-11 23:44:21 +0200
committerKevin Hilman <khilman@linaro.org>2015-06-11 23:44:21 +0200
commiteec6492861055a356f3dbc6786d9eac49778e7fe (patch)
treed0b0a1eaaa608a5dfb50fc2ae08842ab3ad08866 /arch/arm
parentARM: ep93xx: simone: support for SPI-based MMC/SD cards (diff)
parentARM: EXYNOS: register power domain driver from core_initcall (diff)
downloadlinux-eec6492861055a356f3dbc6786d9eac49778e7fe.tar.xz
linux-eec6492861055a356f3dbc6786d9eac49778e7fe.zip
Merge tag 'samsung-mach-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/soc
Samsung updates for v4.2 - add failure(exception) handling : of_iomap(), of_find_device_by_node() and kstrdup() - add common poweroff to use PS_HOLD based for all of exynos SoCs - add exnos_get/set_boot_addr() helper - constify platform_device_id and irq_domain_ops - get current parent clock for power domain on/off - use core_initcall to register power domain driver - make exynos_core_restart() less verbose - add support coupled CPUidle for exynos3250 - fix exynos_boot_secondary() return value on timeout - fix clk_enable() in s3c24xx adc - fix missing of_node_put() for power domains * tag 'samsung-mach-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: (301 commits) ARM: EXYNOS: register power domain driver from core_initcall ARM: EXYNOS: use PS_HOLD based poweroff for all supported SoCs ARM: SAMSUNG: Constify platform_device_id ARM: EXYNOS: Constify irq_domain_ops ARM: EXYNOS: add coupled cpuidle support for Exynos3250 ARM: EXYNOS: add exynos_get_boot_addr() helper ARM: EXYNOS: add exynos_set_boot_addr() helper ARM: EXYNOS: make exynos_core_restart() less verbose ARM: EXYNOS: fix exynos_boot_secondary() return value on timeout ARM: EXYNOS: Get current parent clock for power domain on/off ARM: SAMSUNG: fix clk_enable() WARNing in S3C24XX ADC ARM: EXYNOS: Add missing of_node_put() when parsing power domains ARM: EXYNOS: Handle of_find_device_by_node() and kstrdup() failures ARM: EXYNOS: Handle of of_iomap() failure Linux 4.1-rc4 ....
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boot/dts/armada-375.dtsi2
-rw-r--r--arch/arm/boot/dts/armada-38x.dtsi2
-rw-r--r--arch/arm/boot/dts/armada-39x.dtsi2
-rw-r--r--arch/arm/boot/dts/dove-cubox.dts1
-rw-r--r--arch/arm/boot/dts/exynos5420-peach-pit.dts1
-rw-r--r--arch/arm/boot/dts/exynos5800-peach-pi.dts1
-rw-r--r--arch/arm/boot/dts/tegra124.dtsi8
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts1
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca9.dts11
-rw-r--r--arch/arm/include/asm/firmware.h4
-rw-r--r--arch/arm/mach-exynos/common.h6
-rw-r--r--arch/arm/mach-exynos/exynos.c30
-rw-r--r--arch/arm/mach-exynos/firmware.c18
-rw-r--r--arch/arm/mach-exynos/platsmp.c123
-rw-r--r--arch/arm/mach-exynos/pm.c51
-rw-r--r--arch/arm/mach-exynos/pm_domains.c57
-rw-r--r--arch/arm/mach-exynos/pmu.c6
-rw-r--r--arch/arm/mach-exynos/suspend.c9
-rw-r--r--arch/arm/mach-gemini/common.h4
-rw-r--r--arch/arm/mach-gemini/reset.c4
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c68
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c70
-rw-r--r--arch/arm/mach-omap2/prcm43xx.h3
-rw-r--r--arch/arm/mach-omap2/prminst44xx.c20
-rw-r--r--arch/arm/mach-omap2/timer.c13
-rw-r--r--arch/arm/mach-rockchip/pm.c26
-rw-r--r--arch/arm/mach-rockchip/pm.h4
-rw-r--r--arch/arm/net/bpf_jit_32.c42
-rw-r--r--arch/arm/plat-samsung/adc.c6
29 files changed, 368 insertions, 225 deletions
diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
index c675257f2377..f076ff856d8b 100644
--- a/arch/arm/boot/dts/armada-375.dtsi
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -69,7 +69,7 @@
mainpll: mainpll {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <2000000000>;
+ clock-frequency = <1000000000>;
};
/* 25 MHz reference crystal */
refclk: oscillator {
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index ed2dd8ba4080..218a2acd36e5 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -585,7 +585,7 @@
mainpll: mainpll {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <2000000000>;
+ clock-frequency = <1000000000>;
};
/* 25 MHz reference crystal */
diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
index 0e85fc15ceda..ecd1318109ba 100644
--- a/arch/arm/boot/dts/armada-39x.dtsi
+++ b/arch/arm/boot/dts/armada-39x.dtsi
@@ -502,7 +502,7 @@
mainpll: mainpll {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <2000000000>;
+ clock-frequency = <1000000000>;
};
};
};
diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts
index aae7efc09b0b..e6fa251e17b9 100644
--- a/arch/arm/boot/dts/dove-cubox.dts
+++ b/arch/arm/boot/dts/dove-cubox.dts
@@ -87,6 +87,7 @@
/* connect xtal input to 25MHz reference */
clocks = <&ref25>;
+ clock-names = "xtal";
/* connect xtal input as source of pll0 and pll1 */
silabs,pll-source = <0 0>, <1 0>;
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 0788d08fb43e..146e71118a72 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -711,6 +711,7 @@
num-slots = <1>;
broken-cd;
cap-sdio-irq;
+ keep-power-in-suspend;
card-detect-delay = <200>;
clock-frequency = <400000000>;
samsung,dw-mshc-ciu-div = <1>;
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 412f41d62686..02eb8b15374f 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -674,6 +674,7 @@
num-slots = <1>;
broken-cd;
cap-sdio-irq;
+ keep-power-in-suspend;
card-detect-delay = <200>;
clock-frequency = <400000000>;
samsung,dw-mshc-ciu-div = <1>;
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index cf01c818b8ea..13cc7ca5e031 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -826,7 +826,7 @@
<&tegra_car TEGRA124_CLK_PLL_U>,
<&tegra_car TEGRA124_CLK_USBD>;
clock-names = "reg", "pll_u", "utmi-pads";
- resets = <&tegra_car 59>, <&tegra_car 22>;
+ resets = <&tegra_car 22>, <&tegra_car 22>;
reset-names = "usb", "utmi-pads";
nvidia,hssync-start-delay = <0>;
nvidia,idle-wait-delay = <17>;
@@ -838,6 +838,7 @@
nvidia,hssquelch-level = <2>;
nvidia,hsdiscon-level = <5>;
nvidia,xcvr-hsslew = <12>;
+ nvidia,has-utmi-pad-registers;
status = "disabled";
};
@@ -862,7 +863,7 @@
<&tegra_car TEGRA124_CLK_PLL_U>,
<&tegra_car TEGRA124_CLK_USBD>;
clock-names = "reg", "pll_u", "utmi-pads";
- resets = <&tegra_car 22>, <&tegra_car 22>;
+ resets = <&tegra_car 58>, <&tegra_car 22>;
reset-names = "usb", "utmi-pads";
nvidia,hssync-start-delay = <0>;
nvidia,idle-wait-delay = <17>;
@@ -874,7 +875,6 @@
nvidia,hssquelch-level = <2>;
nvidia,hsdiscon-level = <5>;
nvidia,xcvr-hsslew = <12>;
- nvidia,has-utmi-pad-registers;
status = "disabled";
};
@@ -899,7 +899,7 @@
<&tegra_car TEGRA124_CLK_PLL_U>,
<&tegra_car TEGRA124_CLK_USBD>;
clock-names = "reg", "pll_u", "utmi-pads";
- resets = <&tegra_car 58>, <&tegra_car 22>;
+ resets = <&tegra_car 59>, <&tegra_car 22>;
reset-names = "usb", "utmi-pads";
nvidia,hssync-start-delay = <0>;
nvidia,idle-wait-delay = <17>;
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 7a2aeacd62c0..107395c32d82 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -191,6 +191,7 @@
compatible = "arm,cortex-a15-pmu";
interrupts = <0 68 4>,
<0 69 4>;
+ interrupt-affinity = <&cpu0>, <&cpu1>;
};
oscclk6a: oscclk6a {
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 23662b5a5e9d..d949facba376 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -33,28 +33,28 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu@0 {
+ A9_0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
next-level-cache = <&L2>;
};
- cpu@1 {
+ A9_1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
next-level-cache = <&L2>;
};
- cpu@2 {
+ A9_2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <2>;
next-level-cache = <&L2>;
};
- cpu@3 {
+ A9_3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <3>;
@@ -170,6 +170,7 @@
compatible = "arm,pl310-cache";
reg = <0x1e00a000 0x1000>;
interrupts = <0 43 4>;
+ cache-unified;
cache-level = <2>;
arm,data-latency = <1 1 1>;
arm,tag-latency = <1 1 1>;
@@ -181,6 +182,8 @@
<0 61 4>,
<0 62 4>,
<0 63 4>;
+ interrupt-affinity = <&A9_0>, <&A9_1>, <&A9_2>, <&A9_3>;
+
};
dcc {
diff --git a/arch/arm/include/asm/firmware.h b/arch/arm/include/asm/firmware.h
index 89aefe10d66b..34c1d96ef46d 100644
--- a/arch/arm/include/asm/firmware.h
+++ b/arch/arm/include/asm/firmware.h
@@ -34,6 +34,10 @@ struct firmware_ops {
*/
int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
/*
+ * Gets boot address of specified physical CPU
+ */
+ int (*get_cpu_boot_addr)(int cpu, unsigned long *boot_addr);
+ /*
* Boots specified physical CPU
*/
int (*cpu_boot)(int cpu);
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index acd5b560b728..e3a9256ed55f 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -159,9 +159,13 @@ extern void exynos_enter_aftr(void);
extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
+extern void exynos_set_delayed_reset_assertion(bool enable);
+
extern void s5p_init_cpu(void __iomem *cpuid_addr);
extern unsigned int samsung_rev(void);
-extern void __iomem *cpu_boot_reg_base(void);
+extern void exynos_core_restart(u32 core_id);
+extern int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr);
+extern int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr);
static inline void pmu_raw_writel(u32 val, u32 offset)
{
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index bcde0dd668df..4bd8b7653817 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -167,6 +167,33 @@ static void __init exynos_init_io(void)
}
/*
+ * Set or clear the USE_DELAYED_RESET_ASSERTION option. Used by smp code
+ * and suspend.
+ *
+ * This is necessary only on Exynos4 SoCs. When system is running
+ * USE_DELAYED_RESET_ASSERTION should be set so the ARM CLK clock down
+ * feature could properly detect global idle state when secondary CPU is
+ * powered down.
+ *
+ * However this should not be set when such system is going into suspend.
+ */
+void exynos_set_delayed_reset_assertion(bool enable)
+{
+ if (of_machine_is_compatible("samsung,exynos4")) {
+ unsigned int tmp, core_id;
+
+ for (core_id = 0; core_id < num_possible_cpus(); core_id++) {
+ tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
+ if (enable)
+ tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
+ else
+ tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
+ pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
+ }
+ }
+}
+
+/*
* Apparently, these SoCs are not able to wake-up from suspend using
* the PMU. Too bad. Should they suddenly become capable of such a
* feat, the matches below should be moved to suspend.c.
@@ -207,7 +234,8 @@ static void __init exynos_dt_machine_init(void)
exynos_sysram_init();
#if defined(CONFIG_SMP) && defined(CONFIG_ARM_EXYNOS_CPUIDLE)
- if (of_machine_is_compatible("samsung,exynos4210"))
+ if (of_machine_is_compatible("samsung,exynos4210") ||
+ of_machine_is_compatible("samsung,exynos3250"))
exynos_cpuidle.dev.platform_data = &cpuidle_coupled_exynos_data;
#endif
if (of_machine_is_compatible("samsung,exynos4210") ||
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 1bd35763f12e..245f6dec1ded 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -49,6 +49,7 @@ static int exynos_do_idle(unsigned long mode)
sysram_ns_base_addr + 0x24);
__raw_writel(EXYNOS_AFTR_MAGIC, sysram_ns_base_addr + 0x20);
if (soc_is_exynos3250()) {
+ flush_cache_all();
exynos_smc(SMC_CMD_SAVE, OP_TYPE_CORE,
SMC_POWERSTATE_IDLE, 0);
exynos_smc(SMC_CMD_SHUTDOWN, OP_TYPE_CLUSTER,
@@ -104,6 +105,22 @@ static int exynos_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
return 0;
}
+static int exynos_get_cpu_boot_addr(int cpu, unsigned long *boot_addr)
+{
+ void __iomem *boot_reg;
+
+ if (!sysram_ns_base_addr)
+ return -ENODEV;
+
+ boot_reg = sysram_ns_base_addr + 0x1c;
+
+ if (soc_is_exynos4412())
+ boot_reg += 4 * cpu;
+
+ *boot_addr = __raw_readl(boot_reg);
+ return 0;
+}
+
static int exynos_cpu_suspend(unsigned long arg)
{
flush_cache_all();
@@ -138,6 +155,7 @@ static int exynos_resume(void)
static const struct firmware_ops exynos_firmware_ops = {
.do_idle = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_do_idle : NULL,
.set_cpu_boot_addr = exynos_set_cpu_boot_addr,
+ .get_cpu_boot_addr = exynos_get_cpu_boot_addr,
.cpu_boot = exynos_cpu_boot,
.suspend = IS_ENABLED(CONFIG_PM_SLEEP) ? exynos_suspend : NULL,
.resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index ebd135bb0995..58e05a2eae57 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -34,30 +34,6 @@
extern void exynos4_secondary_startup(void);
-/*
- * Set or clear the USE_DELAYED_RESET_ASSERTION option, set on Exynos4 SoCs
- * during hot-(un)plugging CPUx.
- *
- * The feature can be cleared safely during first boot of secondary CPU.
- *
- * Exynos4 SoCs require setting USE_DELAYED_RESET_ASSERTION during powering
- * down a CPU so the CPU idle clock down feature could properly detect global
- * idle state when CPUx is off.
- */
-static void exynos_set_delayed_reset_assertion(u32 core_id, bool enable)
-{
- if (soc_is_exynos4()) {
- unsigned int tmp;
-
- tmp = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(core_id));
- if (enable)
- tmp |= S5P_USE_DELAYED_RESET_ASSERTION;
- else
- tmp &= ~(S5P_USE_DELAYED_RESET_ASSERTION);
- pmu_raw_writel(tmp, EXYNOS_ARM_CORE_OPTION(core_id));
- }
-}
-
#ifdef CONFIG_HOTPLUG_CPU
static inline void cpu_leave_lowpower(u32 core_id)
{
@@ -73,8 +49,6 @@ static inline void cpu_leave_lowpower(u32 core_id)
: "=&r" (v)
: "Ir" (CR_C), "Ir" (0x40)
: "cc");
-
- exynos_set_delayed_reset_assertion(core_id, false);
}
static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
@@ -87,14 +61,6 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)
/* Turn the CPU off on next WFI instruction. */
exynos_cpu_power_down(core_id);
- /*
- * Exynos4 SoCs require setting
- * USE_DELAYED_RESET_ASSERTION so the CPU idle
- * clock down feature could properly detect
- * global idle state when CPUx is off.
- */
- exynos_set_delayed_reset_assertion(core_id, true);
-
wfi();
if (pen_release == core_id) {
@@ -203,7 +169,7 @@ int exynos_cluster_power_state(int cluster)
S5P_CORE_LOCAL_PWR_EN);
}
-void __iomem *cpu_boot_reg_base(void)
+static void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
return pmu_base_addr + S5P_INFORM5;
@@ -229,7 +195,7 @@ static inline void __iomem *cpu_boot_reg(int cpu)
*
* Currently this is needed only when booting secondary CPU on Exynos3250.
*/
-static void exynos_core_restart(u32 core_id)
+void exynos_core_restart(u32 core_id)
{
u32 val;
@@ -244,7 +210,6 @@ static void exynos_core_restart(u32 core_id)
val |= S5P_CORE_WAKEUP_FROM_LOCAL_CFG;
pmu_raw_writel(val, EXYNOS_ARM_CORE_STATUS(core_id));
- pr_info("CPU%u: Software reset\n", core_id);
pmu_raw_writel(EXYNOS_CORE_PO_RESET(core_id), EXYNOS_SWRESET);
}
@@ -282,6 +247,56 @@ static void exynos_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
+int exynos_set_boot_addr(u32 core_id, unsigned long boot_addr)
+{
+ int ret;
+
+ /*
+ * Try to set boot address using firmware first
+ * and fall back to boot register if it fails.
+ */
+ ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
+ if (ret && ret != -ENOSYS)
+ goto fail;
+ if (ret == -ENOSYS) {
+ void __iomem *boot_reg = cpu_boot_reg(core_id);
+
+ if (IS_ERR(boot_reg)) {
+ ret = PTR_ERR(boot_reg);
+ goto fail;
+ }
+ __raw_writel(boot_addr, boot_reg);
+ ret = 0;
+ }
+fail:
+ return ret;
+}
+
+int exynos_get_boot_addr(u32 core_id, unsigned long *boot_addr)
+{
+ int ret;
+
+ /*
+ * Try to get boot address using firmware first
+ * and fall back to boot register if it fails.
+ */
+ ret = call_firmware_op(get_cpu_boot_addr, core_id, boot_addr);
+ if (ret && ret != -ENOSYS)
+ goto fail;
+ if (ret == -ENOSYS) {
+ void __iomem *boot_reg = cpu_boot_reg(core_id);
+
+ if (IS_ERR(boot_reg)) {
+ ret = PTR_ERR(boot_reg);
+ goto fail;
+ }
+ *boot_addr = __raw_readl(boot_reg);
+ ret = 0;
+ }
+fail:
+ return ret;
+}
+
static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
unsigned long timeout;
@@ -341,22 +356,9 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
boot_addr = virt_to_phys(exynos4_secondary_startup);
- /*
- * Try to set boot address using firmware first
- * and fall back to boot register if it fails.
- */
- ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
- if (ret && ret != -ENOSYS)
+ ret = exynos_set_boot_addr(core_id, boot_addr);
+ if (ret)
goto fail;
- if (ret == -ENOSYS) {
- void __iomem *boot_reg = cpu_boot_reg(core_id);
-
- if (IS_ERR(boot_reg)) {
- ret = PTR_ERR(boot_reg);
- goto fail;
- }
- __raw_writel(boot_addr, boot_reg);
- }
call_firmware_op(cpu_boot, core_id);
@@ -371,8 +373,8 @@ static int exynos_boot_secondary(unsigned int cpu, struct task_struct *idle)
udelay(10);
}
- /* No harm if this is called during first boot of secondary CPU */
- exynos_set_delayed_reset_assertion(core_id, false);
+ if (pen_release != -1)
+ ret = -ETIMEDOUT;
/*
* now the secondary core is starting up let it run its
@@ -420,6 +422,8 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
exynos_sysram_init();
+ exynos_set_delayed_reset_assertion(true);
+
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
scu_enable(scu_base_addr());
@@ -442,16 +446,9 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
boot_addr = virt_to_phys(exynos4_secondary_startup);
- ret = call_firmware_op(set_cpu_boot_addr, core_id, boot_addr);
- if (ret && ret != -ENOSYS)
+ ret = exynos_set_boot_addr(core_id, boot_addr);
+ if (ret)
break;
- if (ret == -ENOSYS) {
- void __iomem *boot_reg = cpu_boot_reg(core_id);
-
- if (IS_ERR(boot_reg))
- break;
- __raw_writel(boot_addr, boot_reg);
- }
}
}
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index cc75ab448be3..9c1506b499bc 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -22,6 +22,7 @@
#include <asm/firmware.h>
#include <asm/smp_scu.h>
#include <asm/suspend.h>
+#include <asm/cacheflush.h>
#include <mach/map.h>
@@ -209,6 +210,8 @@ static int exynos_cpu0_enter_aftr(void)
* sequence, let's wait for one of these to happen
*/
while (exynos_cpu_power_state(1)) {
+ unsigned long boot_addr;
+
/*
* The other cpu may skip idle and boot back
* up again
@@ -221,7 +224,11 @@ static int exynos_cpu0_enter_aftr(void)
* boot back up again, getting stuck in the
* boot rom code
*/
- if (__raw_readl(cpu_boot_reg_base()) == 0)
+ ret = exynos_get_boot_addr(1, &boot_addr);
+ if (ret)
+ goto fail;
+ ret = -1;
+ if (boot_addr == 0)
goto abort;
cpu_relax();
@@ -233,11 +240,14 @@ static int exynos_cpu0_enter_aftr(void)
abort:
if (cpu_online(1)) {
+ unsigned long boot_addr = virt_to_phys(exynos_cpu_resume);
+
/*
* Set the boot vector to something non-zero
*/
- __raw_writel(virt_to_phys(exynos_cpu_resume),
- cpu_boot_reg_base());
+ ret = exynos_set_boot_addr(1, boot_addr);
+ if (ret)
+ goto fail;
dsb();
/*
@@ -247,22 +257,42 @@ abort:
while (exynos_cpu_power_state(1) != S5P_CORE_LOCAL_PWR_EN)
cpu_relax();
+ if (soc_is_exynos3250()) {
+ while (!pmu_raw_readl(S5P_PMU_SPARE2) &&
+ !atomic_read(&cpu1_wakeup))
+ cpu_relax();
+
+ if (!atomic_read(&cpu1_wakeup))
+ exynos_core_restart(1);
+ }
+
while (!atomic_read(&cpu1_wakeup)) {
+ smp_rmb();
+
/*
* Poke cpu1 out of the boot rom
*/
- __raw_writel(virt_to_phys(exynos_cpu_resume),
- cpu_boot_reg_base());
- arch_send_wakeup_ipi_mask(cpumask_of(1));
+ ret = exynos_set_boot_addr(1, boot_addr);
+ if (ret)
+ goto fail;
+
+ call_firmware_op(cpu_boot, 1);
+
+ if (soc_is_exynos3250())
+ dsb_sev();
+ else
+ arch_send_wakeup_ipi_mask(cpumask_of(1));
}
}
-
+fail:
return ret;
}
static int exynos_wfi_finisher(unsigned long flags)
{
+ if (soc_is_exynos3250())
+ flush_cache_all();
cpu_do_idle();
return -1;
@@ -283,6 +313,9 @@ static int exynos_cpu1_powerdown(void)
*/
exynos_cpu_power_down(1);
+ if (soc_is_exynos3250())
+ pmu_raw_writel(0, S5P_PMU_SPARE2);
+
ret = cpu_suspend(0, exynos_wfi_finisher);
cpu_pm_exit();
@@ -299,7 +332,9 @@ cpu1_aborted:
static void exynos_pre_enter_aftr(void)
{
- __raw_writel(virt_to_phys(exynos_cpu_resume), cpu_boot_reg_base());
+ unsigned long boot_addr = virt_to_phys(exynos_cpu_resume);
+
+ (void)exynos_set_boot_addr(1, boot_addr);
}
static void exynos_post_enter_aftr(void)
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c
index cbe56b35aea0..6001f1c9d136 100644
--- a/arch/arm/mach-exynos/pm_domains.c
+++ b/arch/arm/mach-exynos/pm_domains.c
@@ -62,6 +62,7 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
+ pd->pclk[i] = clk_get_parent(pd->clk[i]);
if (clk_set_parent(pd->clk[i], pd->oscclk))
pr_err("%s: error setting oscclk as parent to clock %d\n",
pd->name, i);
@@ -90,6 +91,9 @@ static int exynos_pd_power(struct generic_pm_domain *domain, bool power_on)
for (i = 0; i < MAX_CLK_PER_DOMAIN; i++) {
if (IS_ERR(pd->clk[i]))
break;
+
+ if (IS_ERR(pd->clk[i]))
+ continue; /* Skip on first power up */
if (clk_set_parent(pd->clk[i], pd->pclk[i]))
pr_err("%s: error setting parent to clock%d\n",
pd->name, i);
@@ -117,27 +121,37 @@ static int exynos_pd_power_off(struct generic_pm_domain *domain)
static __init int exynos4_pm_init_power_domain(void)
{
- struct platform_device *pdev;
struct device_node *np;
for_each_compatible_node(np, NULL, "samsung,exynos4210-pd") {
struct exynos_pm_domain *pd;
int on, i;
- struct device *dev;
-
- pdev = of_find_device_by_node(np);
- dev = &pdev->dev;
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
if (!pd) {
pr_err("%s: failed to allocate memory for domain\n",
__func__);
+ of_node_put(np);
+ return -ENOMEM;
+ }
+ pd->pd.name = kstrdup_const(strrchr(np->full_name, '/') + 1,
+ GFP_KERNEL);
+ if (!pd->pd.name) {
+ kfree(pd);
+ of_node_put(np);
return -ENOMEM;
}
- pd->pd.name = kstrdup(dev_name(dev), GFP_KERNEL);
pd->name = pd->pd.name;
pd->base = of_iomap(np, 0);
+ if (!pd->base) {
+ pr_warn("%s: failed to map memory\n", __func__);
+ kfree(pd->pd.name);
+ kfree(pd);
+ of_node_put(np);
+ continue;
+ }
+
pd->pd.power_off = exynos_pd_power_off;
pd->pd.power_on = exynos_pd_power_on;
@@ -145,12 +159,12 @@ static __init int exynos4_pm_init_power_domain(void)
char clk_name[8];
snprintf(clk_name, sizeof(clk_name), "asb%d", i);
- pd->asb_clk[i] = clk_get(dev, clk_name);
+ pd->asb_clk[i] = of_clk_get_by_name(np, clk_name);
if (IS_ERR(pd->asb_clk[i]))
break;
}
- pd->oscclk = clk_get(dev, "oscclk");
+ pd->oscclk = of_clk_get_by_name(np, "oscclk");
if (IS_ERR(pd->oscclk))
goto no_clk;
@@ -158,16 +172,14 @@ static __init int exynos4_pm_init_power_domain(void)
char clk_name[8];
snprintf(clk_name, sizeof(clk_name), "clk%d", i);
- pd->clk[i] = clk_get(dev, clk_name);
+ pd->clk[i] = of_clk_get_by_name(np, clk_name);
if (IS_ERR(pd->clk[i]))
break;
- snprintf(clk_name, sizeof(clk_name), "pclk%d", i);
- pd->pclk[i] = clk_get(dev, clk_name);
- if (IS_ERR(pd->pclk[i])) {
- clk_put(pd->clk[i]);
- pd->clk[i] = ERR_PTR(-EINVAL);
- break;
- }
+ /*
+ * Skip setting parent on first power up.
+ * The parent at this time may not be useful at all.
+ */
+ pd->pclk[i] = ERR_PTR(-EINVAL);
}
if (IS_ERR(pd->clk[0]))
@@ -188,16 +200,16 @@ no_clk:
args.np = np;
args.args_count = 0;
child_domain = of_genpd_get_from_provider(&args);
- if (!child_domain)
- continue;
+ if (IS_ERR(child_domain))
+ goto next_pd;
if (of_parse_phandle_with_args(np, "power-domains",
"#power-domain-cells", 0, &args) != 0)
- continue;
+ goto next_pd;
parent_domain = of_genpd_get_from_provider(&args);
- if (!parent_domain)
- continue;
+ if (IS_ERR(parent_domain))
+ goto next_pd;
if (pm_genpd_add_subdomain(parent_domain, child_domain))
pr_warn("%s failed to add subdomain: %s\n",
@@ -205,9 +217,10 @@ no_clk:
else
pr_info("%s has as child subdomain: %s.\n",
parent_domain->name, child_domain->name);
+next_pd:
of_node_put(np);
}
return 0;
}
-arch_initcall(exynos4_pm_init_power_domain);
+core_initcall(exynos4_pm_init_power_domain);
diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c
index c15761ca2f18..e812c1c85624 100644
--- a/arch/arm/mach-exynos/pmu.c
+++ b/arch/arm/mach-exynos/pmu.c
@@ -681,7 +681,7 @@ static unsigned int const exynos5420_list_disable_pmu_reg[] = {
EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
};
-static void exynos5_power_off(void)
+static void exynos_power_off(void)
{
unsigned int tmp;
@@ -872,8 +872,6 @@ static void exynos5420_pmu_init(void)
EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
-
- pm_power_off = exynos5_power_off;
pr_info("EXYNOS5420 PMU initialized\n");
}
@@ -984,6 +982,8 @@ static int exynos_pmu_probe(struct platform_device *pdev)
if (ret)
dev_warn(dev, "can't register restart handler err=%d\n", ret);
+ pm_power_off = exynos_power_off;
+
dev_dbg(dev, "Exynos PMU Driver probe done\n");
return 0;
}
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index 3e6aea7f83af..f7f6c13df65d 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -223,7 +223,7 @@ static int exynos_pmu_domain_alloc(struct irq_domain *domain,
return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &parent_args);
}
-static struct irq_domain_ops exynos_pmu_domain_ops = {
+static const struct irq_domain_ops exynos_pmu_domain_ops = {
.xlate = exynos_pmu_domain_xlate,
.alloc = exynos_pmu_domain_alloc,
.free = irq_domain_free_irqs_common,
@@ -342,6 +342,8 @@ static void exynos_pm_enter_sleep_mode(void)
static void exynos_pm_prepare(void)
{
+ exynos_set_delayed_reset_assertion(false);
+
/* Set wake-up mask registers */
exynos_pm_set_wakeup_mask();
@@ -482,6 +484,7 @@ early_wakeup:
/* Clear SLEEP mode set in INFORM1 */
pmu_raw_writel(0x0, S5P_INFORM1);
+ exynos_set_delayed_reset_assertion(true);
}
static void exynos3250_pm_resume(void)
@@ -723,8 +726,10 @@ void __init exynos_pm_init(void)
return;
}
- if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL)))
+ if (WARN_ON(!of_find_property(np, "interrupt-controller", NULL))) {
pr_warn("Outdated DT detected, suspend/resume will NOT work\n");
+ return;
+ }
pm_data = (const struct exynos_pm_data *) match->data;
diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h
index 38a45260a7c8..dd883698ff7e 100644
--- a/arch/arm/mach-gemini/common.h
+++ b/arch/arm/mach-gemini/common.h
@@ -12,6 +12,8 @@
#ifndef __GEMINI_COMMON_H__
#define __GEMINI_COMMON_H__
+#include <linux/reboot.h>
+
struct mtd_partition;
extern void gemini_map_io(void);
@@ -26,6 +28,6 @@ extern int platform_register_pflash(unsigned int size,
struct mtd_partition *parts,
unsigned int nr_parts);
-extern void gemini_restart(char mode, const char *cmd);
+extern void gemini_restart(enum reboot_mode mode, const char *cmd);
#endif /* __GEMINI_COMMON_H__ */
diff --git a/arch/arm/mach-gemini/reset.c b/arch/arm/mach-gemini/reset.c
index b26659759e27..21a6d6d4f9c4 100644
--- a/arch/arm/mach-gemini/reset.c
+++ b/arch/arm/mach-gemini/reset.c
@@ -14,7 +14,9 @@
#include <mach/hardware.h>
#include <mach/global_reg.h>
-void gemini_restart(char mode, const char *cmd)
+#include "common.h"
+
+void gemini_restart(enum reboot_mode mode, const char *cmd)
{
__raw_writel(RESET_GLOBAL | RESET_CPU1,
IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 355b08936871..752969ff9de0 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -171,6 +171,12 @@
*/
#define LINKS_PER_OCP_IF 2
+/*
+ * Address offset (in bytes) between the reset control and the reset
+ * status registers: 4 bytes on OMAP4
+ */
+#define OMAP4_RST_CTRL_ST_OFFSET 4
+
/**
* struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
* @enable_module: function to enable a module (via MODULEMODE)
@@ -3016,10 +3022,12 @@ static int _omap4_deassert_hardreset(struct omap_hwmod *oh,
if (ohri->st_shift)
pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
oh->name, ohri->name);
- return omap_prm_deassert_hardreset(ohri->rst_shift, 0,
+ return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->rst_shift,
oh->clkdm->pwrdm.ptr->prcm_partition,
oh->clkdm->pwrdm.ptr->prcm_offs,
- oh->prcm.omap4.rstctrl_offs, 0);
+ oh->prcm.omap4.rstctrl_offs,
+ oh->prcm.omap4.rstctrl_offs +
+ OMAP4_RST_CTRL_ST_OFFSET);
}
/**
@@ -3048,27 +3056,6 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
}
/**
- * _am33xx_assert_hardreset - call AM33XX PRM hardreset fn with hwmod args
- * @oh: struct omap_hwmod * to assert hardreset
- * @ohri: hardreset line data
- *
- * Call am33xx_prminst_assert_hardreset() with parameters extracted
- * from the hwmod @oh and the hardreset line data @ohri. Only
- * intended for use as an soc_ops function pointer. Passes along the
- * return value from am33xx_prminst_assert_hardreset(). XXX This
- * function is scheduled for removal when the PRM code is moved into
- * drivers/.
- */
-static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
- struct omap_hwmod_rst_info *ohri)
-
-{
- return omap_prm_assert_hardreset(ohri->rst_shift, 0,
- oh->clkdm->pwrdm.ptr->prcm_offs,
- oh->prcm.omap4.rstctrl_offs);
-}
-
-/**
* _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
* @oh: struct omap_hwmod * to deassert hardreset
* @ohri: hardreset line data
@@ -3083,32 +3070,13 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
struct omap_hwmod_rst_info *ohri)
{
- return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift, 0,
+ return omap_prm_deassert_hardreset(ohri->rst_shift, ohri->st_shift,
+ oh->clkdm->pwrdm.ptr->prcm_partition,
oh->clkdm->pwrdm.ptr->prcm_offs,
oh->prcm.omap4.rstctrl_offs,
oh->prcm.omap4.rstst_offs);
}
-/**
- * _am33xx_is_hardreset_asserted - call AM33XX PRM hardreset fn with hwmod args
- * @oh: struct omap_hwmod * to test hardreset
- * @ohri: hardreset line data
- *
- * Call am33xx_prminst_is_hardreset_asserted() with parameters
- * extracted from the hwmod @oh and the hardreset line data @ohri.
- * Only intended for use as an soc_ops function pointer. Passes along
- * the return value from am33xx_prminst_is_hardreset_asserted(). XXX
- * This function is scheduled for removal when the PRM code is moved
- * into drivers/.
- */
-static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh,
- struct omap_hwmod_rst_info *ohri)
-{
- return omap_prm_is_hardreset_asserted(ohri->rst_shift, 0,
- oh->clkdm->pwrdm.ptr->prcm_offs,
- oh->prcm.omap4.rstctrl_offs);
-}
-
/* Public functions */
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
@@ -3908,21 +3876,13 @@ void __init omap_hwmod_init(void)
soc_ops.init_clkdm = _init_clkdm;
soc_ops.update_context_lost = _omap4_update_context_lost;
soc_ops.get_context_lost = _omap4_get_context_lost;
- } else if (soc_is_am43xx()) {
+ } else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) {
soc_ops.enable_module = _omap4_enable_module;
soc_ops.disable_module = _omap4_disable_module;
soc_ops.wait_target_ready = _omap4_wait_target_ready;
soc_ops.assert_hardreset = _omap4_assert_hardreset;
- soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
- soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
- soc_ops.init_clkdm = _init_clkdm;
- } else if (cpu_is_ti816x() || soc_is_am33xx()) {
- soc_ops.enable_module = _omap4_enable_module;
- soc_ops.disable_module = _omap4_disable_module;
- soc_ops.wait_target_ready = _omap4_wait_target_ready;
- soc_ops.assert_hardreset = _am33xx_assert_hardreset;
soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
- soc_ops.is_hardreset_asserted = _am33xx_is_hardreset_asserted;
+ soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
soc_ops.init_clkdm = _init_clkdm;
} else {
WARN(1, "omap_hwmod: unknown SoC type\n");
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index e2223148ba4d..17e8004fc20f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -544,6 +544,44 @@ static struct omap_hwmod am43xx_hdq1w_hwmod = {
},
};
+static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x104,
+ .sysc_flags = SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_SMART | MSTANDBY_NO),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class am43xx_vpfe_hwmod_class = {
+ .name = "vpfe",
+ .sysc = &am43xx_vpfe_sysc,
+};
+
+static struct omap_hwmod am43xx_vpfe0_hwmod = {
+ .name = "vpfe0",
+ .class = &am43xx_vpfe_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ .clkctrl_offs = AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET,
+ },
+ },
+};
+
+static struct omap_hwmod am43xx_vpfe1_hwmod = {
+ .name = "vpfe1",
+ .class = &am43xx_vpfe_hwmod_class,
+ .clkdm_name = "l3s_clkdm",
+ .prcm = {
+ .omap4 = {
+ .modulemode = MODULEMODE_SWCTRL,
+ .clkctrl_offs = AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET,
+ },
+ },
+};
+
/* Interfaces */
static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = {
.master = &am33xx_l3_main_hwmod,
@@ -825,6 +863,34 @@ static struct omap_hwmod_ocp_if am43xx_l4_ls__hdq1w = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+static struct omap_hwmod_ocp_if am43xx_l3__vpfe0 = {
+ .master = &am43xx_vpfe0_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l3__vpfe1 = {
+ .master = &am43xx_vpfe1_hwmod,
+ .slave = &am33xx_l3_main_hwmod,
+ .clk = "l3_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe0 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_vpfe0_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = {
+ .master = &am33xx_l4_ls_hwmod,
+ .slave = &am43xx_vpfe1_hwmod,
+ .clk = "l4ls_gclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
&am33xx_l4_wkup__synctimer,
&am43xx_l4_ls__timer8,
@@ -925,6 +991,10 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
&am43xx_l4_ls__dss_dispc,
&am43xx_l4_ls__dss_rfbi,
&am43xx_l4_ls__hdq1w,
+ &am43xx_l3__vpfe0,
+ &am43xx_l3__vpfe1,
+ &am43xx_l4_ls__vpfe0,
+ &am43xx_l4_ls__vpfe1,
NULL,
};
diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h
index 48df3b55057e..d0261996db6d 100644
--- a/arch/arm/mach-omap2/prcm43xx.h
+++ b/arch/arm/mach-omap2/prcm43xx.h
@@ -144,5 +144,6 @@
#define AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET 0x05C0
#define AM43XX_CM_PER_DSS_CLKCTRL_OFFSET 0x0a20
#define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0
-
+#define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068
+#define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070
#endif
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
index c4859c4d3646..d0b15dbafa2e 100644
--- a/arch/arm/mach-omap2/prminst44xx.c
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -87,12 +87,6 @@ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
return v;
}
-/*
- * Address offset (in bytes) between the reset control and the reset
- * status registers: 4 bytes on OMAP4
- */
-#define OMAP4_RST_CTRL_ST_OFFSET 4
-
/**
* omap4_prminst_is_hardreset_asserted - read the HW reset line state of
* submodules contained in the hwmod module
@@ -141,11 +135,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
* omap4_prminst_deassert_hardreset - deassert a submodule hardreset line and
* wait
* @shift: register bit shift corresponding to the reset line to deassert
- * @st_shift: status bit offset, not used for OMAP4+
+ * @st_shift: status bit offset corresponding to the reset line
* @part: PRM partition
* @inst: PRM instance offset
* @rstctrl_offs: reset register offset
- * @st_offs: reset status register offset, not used for OMAP4+
+ * @rstst_offs: reset status register offset
*
* Some IPs like dsp, ipu or iva contain processors that require an HW
* reset line to be asserted / deasserted in order to fully enable the
@@ -157,11 +151,11 @@ int omap4_prminst_assert_hardreset(u8 shift, u8 part, s16 inst,
* of reset, or -EBUSY if the submodule did not exit reset promptly.
*/
int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
- u16 rstctrl_offs, u16 st_offs)
+ u16 rstctrl_offs, u16 rstst_offs)
{
int c;
u32 mask = 1 << shift;
- u16 rstst_offs = rstctrl_offs + OMAP4_RST_CTRL_ST_OFFSET;
+ u32 st_mask = 1 << st_shift;
/* Check the current status to avoid de-asserting the line twice */
if (omap4_prminst_is_hardreset_asserted(shift, part, inst,
@@ -169,13 +163,13 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 inst,
return -EEXIST;
/* Clear the reset status by writing 1 to the status bit */
- omap4_prminst_rmw_inst_reg_bits(0xffffffff, mask, part, inst,
+ omap4_prminst_rmw_inst_reg_bits(0xffffffff, st_mask, part, inst,
rstst_offs);
/* de-assert the reset control line */
omap4_prminst_rmw_inst_reg_bits(mask, 0, part, inst, rstctrl_offs);
/* wait the status to be set */
- omap_test_timeout(omap4_prminst_is_hardreset_asserted(shift, part, inst,
- rstst_offs),
+ omap_test_timeout(omap4_prminst_is_hardreset_asserted(st_shift, part,
+ inst, rstst_offs),
MAX_MODULE_HARDRESET_WAIT, c);
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index cef67af9e9b8..cac46d852da1 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -298,14 +298,11 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
if (IS_ERR(src))
return PTR_ERR(src);
- if (clk_get_parent(timer->fclk) != src) {
- r = clk_set_parent(timer->fclk, src);
- if (r < 0) {
- pr_warn("%s: %s cannot set source\n", __func__,
- oh->name);
- clk_put(src);
- return r;
- }
+ r = clk_set_parent(timer->fclk, src);
+ if (r < 0) {
+ pr_warn("%s: %s cannot set source\n", __func__, oh->name);
+ clk_put(src);
+ return r;
}
clk_put(src);
diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
index 22812fe06460..b0dcbe28f78c 100644
--- a/arch/arm/mach-rockchip/pm.c
+++ b/arch/arm/mach-rockchip/pm.c
@@ -44,11 +44,9 @@ static void __iomem *rk3288_bootram_base;
static phys_addr_t rk3288_bootram_phy;
static struct regmap *pmu_regmap;
-static struct regmap *grf_regmap;
static struct regmap *sgrf_regmap;
static u32 rk3288_pmu_pwr_mode_con;
-static u32 rk3288_grf_soc_con0;
static u32 rk3288_sgrf_soc_con0;
static inline u32 rk3288_l2_config(void)
@@ -72,26 +70,12 @@ static void rk3288_slp_mode_set(int level)
{
u32 mode_set, mode_set1;
- regmap_read(grf_regmap, RK3288_GRF_SOC_CON0, &rk3288_grf_soc_con0);
-
regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
&rk3288_pmu_pwr_mode_con);
/*
- * We need set this bit GRF_FORCE_JTAG here, for the debug module,
- * otherwise, it may become inaccessible after resume.
- * This creates a potential security issue, as the sdmmc pins may
- * accept jtag data for a short time during resume if no card is
- * inserted.
- * But this is of course also true for the regular boot, before we
- * turn of the jtag/sdmmc autodetect.
- */
- regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, GRF_FORCE_JTAG |
- GRF_FORCE_JTAG_WRITE);
-
- /*
* SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
* PCLK_WDT_GATE - disable WDT during suspend.
*/
@@ -151,9 +135,6 @@ static void rk3288_slp_mode_set_resume(void)
regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
| SGRF_FAST_BOOT_EN_WRITE);
-
- regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, rk3288_grf_soc_con0 |
- GRF_FORCE_JTAG_WRITE);
}
static int rockchip_lpmode_enter(unsigned long arg)
@@ -212,13 +193,6 @@ static int rk3288_suspend_init(struct device_node *np)
return PTR_ERR(pmu_regmap);
}
- grf_regmap = syscon_regmap_lookup_by_compatible(
- "rockchip,rk3288-grf");
- if (IS_ERR(grf_regmap)) {
- pr_err("%s: could not find grf regmap\n", __func__);
- return PTR_ERR(pmu_regmap);
- }
-
sram_np = of_find_compatible_node(NULL, NULL,
"rockchip,rk3288-pmu-sram");
if (!sram_np) {
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
index f8a747bc1437..3e8d39c0c3d5 100644
--- a/arch/arm/mach-rockchip/pm.h
+++ b/arch/arm/mach-rockchip/pm.h
@@ -48,10 +48,6 @@ static inline void rockchip_suspend_init(void)
#define RK3288_PMU_WAKEUP_RST_CLR_CNT 0x44
#define RK3288_PMU_PWRMODE_CON1 0x90
-#define RK3288_GRF_SOC_CON0 0x244
-#define GRF_FORCE_JTAG BIT(12)
-#define GRF_FORCE_JTAG_WRITE BIT(28)
-
#define RK3288_SGRF_SOC_CON0 (0x0000)
#define RK3288_SGRF_FAST_BOOT_ADDR (0x0120)
#define SGRF_PCLK_WDT_GATE BIT(6)
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index e1268f905026..e0e23582c8b4 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -54,6 +54,7 @@
#define SEEN_DATA (1 << (BPF_MEMWORDS + 3))
#define FLAG_NEED_X_RESET (1 << 0)
+#define FLAG_IMM_OVERFLOW (1 << 1)
struct jit_ctx {
const struct bpf_prog *skf;
@@ -293,6 +294,15 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx)
/* PC in ARM mode == address of the instruction + 8 */
imm = offset - (8 + ctx->idx * 4);
+ if (imm & ~0xfff) {
+ /*
+ * literal pool is too far, signal it into flags. we
+ * can only detect it on the second pass unfortunately.
+ */
+ ctx->flags |= FLAG_IMM_OVERFLOW;
+ return 0;
+ }
+
return imm;
}
@@ -449,10 +459,21 @@ static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx)
return;
}
#endif
- if (rm != ARM_R0)
- emit(ARM_MOV_R(ARM_R0, rm), ctx);
+
+ /*
+ * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4
+ * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into
+ * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm
+ * before using it as a source for ARM_R1.
+ *
+ * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is
+ * ARM_R5 (r_X) so there is no particular register overlap
+ * issues.
+ */
if (rn != ARM_R1)
emit(ARM_MOV_R(ARM_R1, rn), ctx);
+ if (rm != ARM_R0)
+ emit(ARM_MOV_R(ARM_R0, rm), ctx);
ctx->seen |= SEEN_CALL;
emit_mov_i(ARM_R3, (u32)jit_udiv, ctx);
@@ -855,6 +876,14 @@ b_epilogue:
default:
return -1;
}
+
+ if (ctx->flags & FLAG_IMM_OVERFLOW)
+ /*
+ * this instruction generated an overflow when
+ * trying to access the literal pool, so
+ * delegate this filter to the kernel interpreter.
+ */
+ return -1;
}
/* compute offsets only during the first pass */
@@ -917,7 +946,14 @@ void bpf_jit_compile(struct bpf_prog *fp)
ctx.idx = 0;
build_prologue(&ctx);
- build_body(&ctx);
+ if (build_body(&ctx) < 0) {
+#if __LINUX_ARM_ARCH__ < 7
+ if (ctx.imm_count)
+ kfree(ctx.imms);
+#endif
+ bpf_jit_binary_free(header);
+ goto out;
+ }
build_epilogue(&ctx);
flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx));
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index e2be70df06c6..efa6e85619ad 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -389,7 +389,7 @@ static int s3c_adc_probe(struct platform_device *pdev)
if (ret)
return ret;
- clk_enable(adc->clk);
+ clk_prepare_enable(adc->clk);
tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
@@ -413,7 +413,7 @@ static int s3c_adc_remove(struct platform_device *pdev)
{
struct adc_device *adc = platform_get_drvdata(pdev);
- clk_disable(adc->clk);
+ clk_disable_unprepare(adc->clk);
regulator_disable(adc->vdd);
return 0;
@@ -475,7 +475,7 @@ static int s3c_adc_resume(struct device *dev)
#define s3c_adc_resume NULL
#endif
-static struct platform_device_id s3c_adc_driver_ids[] = {
+static const struct platform_device_id s3c_adc_driver_ids[] = {
{
.name = "s3c24xx-adc",
.driver_data = TYPE_ADCV1,