Skip to content

Commit

Permalink
Merge branch 'v3.19-next/cleanup-samsung' into v3.19-next/mach-exynos
Browse files Browse the repository at this point in the history
  • Loading branch information
kgene committed Nov 21, 2014
2 parents 03c1b76 + 13cfa6c commit 68847ed
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 96 deletions.
3 changes: 0 additions & 3 deletions arch/arm/mach-exynos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o

obj-$(CONFIG_SMP) += platsmp.o headsmp.o

obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
CFLAGS_hotplug.o += -march=armv7-a

plus_sec := $(call as-instr,.arch_extension sec,+sec)
AFLAGS_exynos-smc.o :=-Wa,-march=armv7-a$(plus_sec)
AFLAGS_sleep.o :=-Wa,-march=armv7-a$(plus_sec)
Expand Down
2 changes: 0 additions & 2 deletions arch/arm/mach-exynos/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ extern void exynos_cpu_resume_ns(void);

extern struct smp_operations exynos_smp_ops;

extern void exynos_cpu_die(unsigned int cpu);

/* PMU(Power Management Unit) support */

#define PMU_TABLE_END (-1U)
Expand Down
91 changes: 0 additions & 91 deletions arch/arm/mach-exynos/hotplug.c

This file was deleted.

113 changes: 113 additions & 0 deletions arch/arm/mach-exynos/platsmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/of_address.h>

#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
#include <asm/firmware.h>
Expand All @@ -33,6 +34,88 @@

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)
{
unsigned int v;

asm volatile(
"mrc p15, 0, %0, c1, c0, 0\n"
" orr %0, %0, %1\n"
" mcr p15, 0, %0, c1, c0, 0\n"
" mrc p15, 0, %0, c1, c0, 1\n"
" orr %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 1\n"
: "=&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)
{
u32 mpidr = cpu_logical_map(cpu);
u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);

for (;;) {

/* 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) {
/*
* OK, proper wakeup, we're done
*/
break;
}

/*
* Getting here, means that we have come out of WFI without
* having been woken up - this shouldn't happen
*
* Just note it happening - when we're woken, we can report
* its occurrence.
*/
(*spurious)++;
}
}
#endif /* CONFIG_HOTPLUG_CPU */

/**
* exynos_core_power_down : power down the specified cpu
* @cpu : the cpu to power down
Expand Down Expand Up @@ -260,6 +343,9 @@ 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);

/*
* now the secondary core is starting up let it run its
* calibrations, then wait for it to finish
Expand Down Expand Up @@ -341,6 +427,33 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
}
}

#ifdef CONFIG_HOTPLUG_CPU
/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
static void exynos_cpu_die(unsigned int cpu)
{
int spurious = 0;
u32 mpidr = cpu_logical_map(cpu);
u32 core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);

v7_exit_coherency_flush(louis);

platform_do_lowpower(cpu, &spurious);

/*
* bring this CPU back into the world of cache
* coherency, and then restore interrupts
*/
cpu_leave_lowpower(core_id);

if (spurious)
pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
}
#endif /* CONFIG_HOTPLUG_CPU */

struct smp_operations exynos_smp_ops __initdata = {
.smp_init_cpus = exynos_smp_init_cpus,
.smp_prepare_cpus = exynos_smp_prepare_cpus,
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/mach-exynos/regs-pmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#define S5P_USE_STANDBY_WFI0 (1 << 16)
#define S5P_USE_STANDBY_WFE0 (1 << 24)
#define S5P_USE_DELAYED_RESET_ASSERTION BIT(12)

#define EXYNOS_CORE_PO_RESET(n) ((1 << 4) << n)
#define EXYNOS_WAKEUP_FROM_LOWPWR (1 << 28)
Expand Down Expand Up @@ -108,6 +109,8 @@
(EXYNOS_ARM_CORE0_CONFIGURATION + (0x80 * (_nr)))
#define EXYNOS_ARM_CORE_STATUS(_nr) \
(EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x4)
#define EXYNOS_ARM_CORE_OPTION(_nr) \
(EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x8)

#define EXYNOS_ARM_COMMON_CONFIGURATION 0x2500
#define EXYNOS_COMMON_CONFIGURATION(_nr) \
Expand Down

0 comments on commit 68847ed

Please sign in to comment.