Skip to content

Commit

Permalink
[ARM] 3803/2: S3C24XX: PM split S3C2410 out of core pm
Browse files Browse the repository at this point in the history
Remove the S3C2410 specific items out of the
core PM code. Add sysdev driver for all the
S3C24XX series that used the S3C2410 PM code.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Ben Dooks authored and Russell King committed Sep 25, 2006
1 parent 3434801 commit 0033a2f
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 49 deletions.
9 changes: 9 additions & 0 deletions arch/arm/mach-s3c2410/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ config S3C2410_CLOCK
help
Clock code for the S3C2410, and similar processors

config S3C2410_PM
bool
depends on CONFIG_PM
help
Power Management code common to S3C2410 and better

config CPU_S3C2410_DMA
bool
depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
Expand All @@ -144,6 +150,7 @@ config CPU_S3C2410
bool
depends on ARCH_S3C2410
select S3C2410_CLOCK
select S3C2410_PM
help
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
Expand Down Expand Up @@ -172,6 +179,7 @@ config CPU_S3C2440
bool
depends on ARCH_S3C2410
select S3C2410_CLOCK
select S3C2410_PM
select CPU_S3C244X
help
Support for S3C2440 Samsung Mobile CPU based systems.
Expand All @@ -180,6 +188,7 @@ config CPU_S3C2442
bool
depends on ARCH_S3C2420
select S3C2410_CLOCK
select S3C2410_PM
select CPU_S3C244X
help
Support for S3C2442 Samsung Mobile CPU based systems.
Expand Down
2 changes: 2 additions & 0 deletions arch/arm/mach-s3c2410/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o

obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o
obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o

# Power Management support
Expand Down
30 changes: 14 additions & 16 deletions arch/arm/mach-s3c2410/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static struct sleep_save uart_save[] = {

extern void printascii(const char *);

static void pm_dbg(const char *fmt, ...)
void pm_dbg(const char *fmt, ...)
{
va_list va;
char buff[256];
Expand Down Expand Up @@ -486,6 +486,9 @@ static void s3c2410_pm_configure_extint(void)
}
}

void (*pm_cpu_prep)(void);
void (*pm_cpu_sleep)(void);

#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))

/* s3c2410_pm_enter
Expand All @@ -496,14 +499,18 @@ static void s3c2410_pm_configure_extint(void)
static int s3c2410_pm_enter(suspend_state_t state)
{
unsigned long regs_save[16];
unsigned long tmp;

/* ensure the debug is initialised (if enabled) */

s3c2410_pm_debug_init();

DBG("s3c2410_pm_enter(%d)\n", state);

if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
return -EINVAL;
}

if (state != PM_SUSPEND_MEM) {
printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
return -EINVAL;
Expand Down Expand Up @@ -531,13 +538,6 @@ static int s3c2410_pm_enter(suspend_state_t state)

DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);

/* ensure at least GESTATUS3 has the resume address */

__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);

DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));

/* save all necessary core registers not covered by the drivers */

s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
Expand All @@ -558,6 +558,10 @@ static int s3c2410_pm_enter(suspend_state_t state)

__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);

/* call cpu specific preperation */

pm_cpu_prep();

/* flush cache back to ram */

flush_cache_all();
Expand All @@ -574,19 +578,13 @@ static int s3c2410_pm_enter(suspend_state_t state)

if (s3c2410_cpu_save(regs_save) == 0) {
flush_cache_all();
s3c2410_cpu_suspend();
pm_cpu_sleep();
}

/* restore the cpu state */

cpu_init();

/* unset the return-from-sleep flag, to ensure reset */

tmp = __raw_readl(S3C2410_GSTATUS2);
tmp &= S3C2410_GSTATUS2_OFFRESET;
__raw_writel(tmp, S3C2410_GSTATUS2);

/* restore the system state */

s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
Expand Down
5 changes: 5 additions & 0 deletions arch/arm/mach-s3c2410/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ extern unsigned long s3c_irqwake_eintmask;
extern unsigned long s3c_irqwake_intallow;
extern unsigned long s3c_irqwake_eintallow;

/* per-cpu sleep functions */

extern void (*pm_cpu_prep)(void);
extern void (*pm_cpu_sleep)(void);

/* Flags for PM Control */

extern unsigned long s3c_pm_flags;
Expand Down
111 changes: 111 additions & 0 deletions arch/arm/mach-s3c2410/s3c2410-pm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/init.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/sysdev.h>

#include <asm/hardware.h>
#include <asm/io.h>

#include <asm/arch/regs-gpio.h>

#include "cpu.h"
#include "pm.h"

#ifdef CONFIG_S3C2410_PM_DEBUG
extern void pm_dbg(const char *fmt, ...);
#define DBG(fmt...) pm_dbg(fmt)
#else
#define DBG(fmt...) printk(KERN_DEBUG fmt)
#endif

static void s3c2410_pm_prepare(void)
{
/* ensure at least GSTATUS3 has the resume address */

__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);

DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
}

int s3c2410_pm_resume(struct sys_device *dev)
{
unsigned long tmp;

/* unset the return-from-sleep flag, to ensure reset */

tmp = __raw_readl(S3C2410_GSTATUS2);
tmp &= S3C2410_GSTATUS2_OFFRESET;
__raw_writel(tmp, S3C2410_GSTATUS2);

return 0;
}

static int s3c2410_pm_add(struct sys_device *dev)
{
pm_cpu_prep = s3c2410_pm_prepare;
pm_cpu_sleep = s3c2410_cpu_suspend;

return 0;
}

static struct sysdev_driver s3c2410_pm_driver = {
.add = s3c2410_pm_add,
.resume = s3c2410_pm_resume,
};

/* register ourselves */

static int __init s3c2410_pm_drvinit(void)
{
return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
}

arch_initcall(s3c2410_pm_drvinit);

static struct sysdev_driver s3c2440_pm_driver = {
.add = s3c2410_pm_add,
.resume = s3c2410_pm_resume,
};

static int __init s3c2440_pm_drvinit(void)
{
return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
}

arch_initcall(s3c2440_pm_drvinit);

static struct sysdev_driver s3c2442_pm_driver = {
.add = s3c2410_pm_add,
.resume = s3c2410_pm_resume,
};

static int __init s3c2442_pm_drvinit(void)
{
return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
}

arch_initcall(s3c2442_pm_drvinit);
68 changes: 68 additions & 0 deletions arch/arm/mach-s3c2410/s3c2410-sleep.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
*
* Copyright (c) 2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 Power Manager (Suspend-To-RAM) support
*
* Based on PXA/SA1100 sleep code by:
* Nicolas Pitre, (c) 2002 Monta Vista Software Inc
* Cliff Brake, (c) 2001
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/hardware.h>
#include <asm/arch/map.h>

#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-mem.h>
#include <asm/arch/regs-serial.h>

/* s3c2410_cpu_suspend
*
* put the cpu into sleep mode
*/

ENTRY(s3c2410_cpu_suspend)
@@ prepare cpu to sleep

ldr r4, =S3C2410_REFRESH
ldr r5, =S3C24XX_MISCCR
ldr r6, =S3C2410_CLKCON
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)

orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
orr r9, r9, #S3C2410_CLKCON_POWER @ power down command

teq pc, #0 @ first as a trial-run to load cache
bl s3c2410_do_sleep
teq r0, r0 @ now do it for real
b s3c2410_do_sleep @

@@ align next bit of code to cache line
.align 8
s3c2410_do_sleep:
streq r7, [ r4 ] @ SDRAM sleep command
streq r8, [ r5 ] @ SDRAM power-down config
streq r9, [ r6 ] @ CPU sleep
1: beq 1b
mov pc, r14
33 changes: 0 additions & 33 deletions arch/arm/mach-s3c2410/sleep.S
Original file line number Diff line number Diff line change
Expand Up @@ -75,39 +75,6 @@ ENTRY(s3c2410_cpu_save)
mov r0, #0
ldmfd sp, { r4 - r12, pc }

/* s3c2410_cpu_suspend
*
* put the cpu into sleep mode
*/

ENTRY(s3c2410_cpu_suspend)
@@ prepare cpu to sleep

ldr r4, =S3C2410_REFRESH
ldr r5, =S3C24XX_MISCCR
ldr r6, =S3C2410_CLKCON
ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)

orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
orr r9, r9, #S3C2410_CLKCON_POWER @ power down command

teq pc, #0 @ first as a trial-run to load cache
bl s3c2410_do_sleep
teq r0, r0 @ now do it for real
b s3c2410_do_sleep @

@@ align next bit of code to cache line
.align 8
s3c2410_do_sleep:
streq r7, [ r4 ] @ SDRAM sleep command
streq r8, [ r5 ] @ SDRAM power-down config
streq r9, [ r6 ] @ CPU sleep
1: beq 1b
mov pc, r14

@@ return to the caller, after having the MMU
@@ turned on, this restores the last bits from the
@@ stack
Expand Down

0 comments on commit 0033a2f

Please sign in to comment.