Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280421
b: refs/heads/master
c: c656c30
h: refs/heads/master
i:
  280419: 6dc7a21
v: v3
  • Loading branch information
Mark Brown authored and Rafael J. Wysocki committed Dec 9, 2011
1 parent db5417a commit 11f135c
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a87dc8fdc250f6416b522a3eb302c8cf95c2317c
refs/heads/master: c656c30668b9408c46d6bfbd1eea472f39a3155d
1 change: 1 addition & 0 deletions trunk/arch/arm/mach-s3c64xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ config PLAT_S3C64XX
bool
depends on ARCH_S3C64XX
select SAMSUNG_WAKEMASK
select PM_GENERIC_DOMAINS
default y
help
Base platform code for any Samsung S3C64XX device
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-s3c64xx/mach-crag6410.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ static void __init crag6410_machine_init(void)

regulator_has_full_constraints();

s3c_pm_init();
s3c64xx_pm_init();
}

MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
Expand Down
176 changes: 174 additions & 2 deletions trunk/arch/arm/mach-s3c64xx/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
#include <linux/serial_core.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/pm_domain.h>

#include <mach/map.h>
#include <mach/irqs.h>

#include <plat/devs.h>
#include <plat/pm.h>
#include <plat/wakeup-mask.h>

Expand All @@ -31,6 +33,148 @@
#include <mach/regs-gpio-memport.h>
#include <mach/regs-modem.h>

struct s3c64xx_pm_domain {
char *const name;
u32 ena;
u32 pwr_stat;
struct generic_pm_domain pd;
};

static int s3c64xx_pd_off(struct generic_pm_domain *domain)
{
struct s3c64xx_pm_domain *pd;
u32 val;

pd = container_of(domain, struct s3c64xx_pm_domain, pd);

val = __raw_readl(S3C64XX_NORMAL_CFG);
val &= ~(pd->ena);
__raw_writel(val, S3C64XX_NORMAL_CFG);

return 0;
}

static int s3c64xx_pd_on(struct generic_pm_domain *domain)
{
struct s3c64xx_pm_domain *pd;
u32 val;
long retry = 1000000L;

pd = container_of(domain, struct s3c64xx_pm_domain, pd);

val = __raw_readl(S3C64XX_NORMAL_CFG);
val |= pd->ena;
__raw_writel(val, S3C64XX_NORMAL_CFG);

/* Not all domains provide power status readback */
if (pd->pwr_stat) {
do {
cpu_relax();
if (__raw_readl(S3C64XX_BLK_PWR_STAT) & pd->pwr_stat)
break;
} while (retry--);

if (!retry) {
pr_err("Failed to start domain %s\n", pd->name);
return -EBUSY;
}
}

return 0;
}

static struct s3c64xx_pm_domain s3c64xx_pm_irom = {
.name = "IROM",
.ena = S3C64XX_NORMALCFG_IROM_ON,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_etm = {
.name = "ETM",
.ena = S3C64XX_NORMALCFG_DOMAIN_ETM_ON,
.pwr_stat = S3C64XX_BLKPWRSTAT_ETM,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_s = {
.name = "S",
.ena = S3C64XX_NORMALCFG_DOMAIN_S_ON,
.pwr_stat = S3C64XX_BLKPWRSTAT_S,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_f = {
.name = "F",
.ena = S3C64XX_NORMALCFG_DOMAIN_F_ON,
.pwr_stat = S3C64XX_BLKPWRSTAT_F,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_p = {
.name = "P",
.ena = S3C64XX_NORMALCFG_DOMAIN_P_ON,
.pwr_stat = S3C64XX_BLKPWRSTAT_P,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_i = {
.name = "I",
.ena = S3C64XX_NORMALCFG_DOMAIN_I_ON,
.pwr_stat = S3C64XX_BLKPWRSTAT_I,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_g = {
.name = "G",
.ena = S3C64XX_NORMALCFG_DOMAIN_G_ON,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain s3c64xx_pm_v = {
.name = "V",
.ena = S3C64XX_NORMALCFG_DOMAIN_V_ON,
.pwr_stat = S3C64XX_BLKPWRSTAT_V,
.pd = {
.power_off = s3c64xx_pd_off,
.power_on = s3c64xx_pd_on,
},
};

static struct s3c64xx_pm_domain *s3c64xx_always_on_pm_domains[] = {
&s3c64xx_pm_irom,
};

static struct s3c64xx_pm_domain *s3c64xx_pm_domains[] = {
&s3c64xx_pm_etm,
&s3c64xx_pm_g,
&s3c64xx_pm_v,
&s3c64xx_pm_i,
&s3c64xx_pm_p,
&s3c64xx_pm_s,
&s3c64xx_pm_f,
};

#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
void s3c_pm_debug_smdkled(u32 set, u32 clear)
{
Expand Down Expand Up @@ -89,6 +233,8 @@ static struct sleep_save misc_save[] = {

SAVE_ITEM(S3C64XX_SDMA_SEL),
SAVE_ITEM(S3C64XX_MODEM_MIFPCON),

SAVE_ITEM(S3C64XX_NORMAL_CFG),
};

void s3c_pm_configure_extint(void)
Expand Down Expand Up @@ -179,7 +325,26 @@ static void s3c64xx_pm_prepare(void)
__raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
}

static int s3c64xx_pm_init(void)
int __init s3c64xx_pm_init(void)
{
int i;

s3c_pm_init();

for (i = 0; i < ARRAY_SIZE(s3c64xx_always_on_pm_domains); i++)
pm_genpd_init(&s3c64xx_always_on_pm_domains[i]->pd,
&pm_domain_always_on_gov, false);

for (i = 0; i < ARRAY_SIZE(s3c64xx_pm_domains); i++)
pm_genpd_init(&s3c64xx_pm_domains[i]->pd, NULL, false);

if (dev_get_platdata(&s3c_device_fb.dev))
pm_genpd_add_device(&s3c64xx_pm_f.pd, &s3c_device_fb.dev);

return 0;
}

static __init int s3c64xx_pm_initcall(void)
{
pm_cpu_prep = s3c64xx_pm_prepare;
pm_cpu_sleep = s3c64xx_cpu_suspend;
Expand All @@ -198,5 +363,12 @@ static int s3c64xx_pm_init(void)

return 0;
}
arch_initcall(s3c64xx_pm_initcall);

static __init int s3c64xx_pm_late_initcall(void)
{
pm_genpd_poweroff_unused();

arch_initcall(s3c64xx_pm_init);
return 0;
}
late_initcall(s3c64xx_pm_late_initcall);
6 changes: 6 additions & 0 deletions trunk/arch/arm/plat-samsung/include/plat/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ struct sys_device;
#ifdef CONFIG_PM

extern __init int s3c_pm_init(void);
extern __init int s3c64xx_pm_init(void);

#else

static inline int s3c_pm_init(void)
{
return 0;
}

static inline int s3c64xx_pm_init(void)
{
return 0;
}
#endif

/* configuration for the IRQ mask over sleep */
Expand Down

0 comments on commit 11f135c

Please sign in to comment.