Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 319314
b: refs/heads/master
c: 93bcfdc
h: refs/heads/master
v: v3
  • Loading branch information
Rafael J. Wysocki committed Jul 6, 2012
1 parent dc9d92e commit 33bf9d3
Show file tree
Hide file tree
Showing 14 changed files with 306 additions and 9 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: f65ad7e36cbae24f05ea2314ad63e9dd23294c60
refs/heads/master: 93bcfdc56522a88b440cf6c4fee09e9ecf6605da
2 changes: 2 additions & 0 deletions trunk/arch/arm/mach-shmobile/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ obj-$(CONFIG_ARCH_R8A7740) += entry-intc.o
# PM objects
obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o
obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o
obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o

# Board objects
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-shmobile/clock-r8a7740.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ void __init r8a7740_clock_init(u8 md_ck)
DIV6_REPARENT_NR);

if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);

for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-shmobile/clock-r8a7779.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void __init r8a7779_clock_init(void)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);

if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);

for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-shmobile/clock-sh7367.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ void __init sh7367_clock_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);

if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);

clkdev_add_table(lookups, ARRAY_SIZE(lookups));

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-shmobile/clock-sh7372.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ void __init sh7372_clock_init(void)
ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);

if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);

for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-shmobile/clock-sh7377.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ void __init sh7377_clock_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);

if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);

clkdev_add_table(lookups, ARRAY_SIZE(lookups));

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-shmobile/clock-sh73a0.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ void __init sh73a0_clock_init(void)
ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);

if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);

for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
Expand Down
44 changes: 44 additions & 0 deletions trunk/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2012 Renesas Solutions Corp.
*
* Kuninori Morimoto <morimoto.kuninori@renesas.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#ifndef PM_RMOBILE_H
#define PM_RMOBILE_H

#include <linux/pm_domain.h>

struct platform_device;

struct rmobile_pm_domain {
struct generic_pm_domain genpd;
struct dev_power_governor *gov;
int (*suspend)(void);
void (*resume)(void);
unsigned int bit_shift;
bool no_debug;
};

static inline
struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
{
return container_of(d, struct rmobile_pm_domain, genpd);
}

#ifdef CONFIG_PM
extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd);
extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
struct platform_device *pdev);
extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
struct rmobile_pm_domain *rmobile_sd);
#else
#define rmobile_init_pm_domain(pd) do { } while (0)
#define rmobile_add_device_to_domain(pd, pdev) do { } while (0)
#define rmobile_pm_add_subdomain(pd, sd) do { } while (0)
#endif /* CONFIG_PM */

#endif /* PM_RMOBILE_H */
8 changes: 8 additions & 0 deletions trunk/arch/arm/mach-shmobile/include/mach/r8a7740.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#ifndef __ASM_R8A7740_H__
#define __ASM_R8A7740_H__

#include <mach/pm-rmobile.h>

/*
* MD_CKx pin
*/
Expand Down Expand Up @@ -604,4 +606,10 @@ enum {
SHDMA_SLAVE_USBHS_RX,
};

#ifdef CONFIG_PM
extern struct rmobile_pm_domain r8a7740_pd_a4s;
extern struct rmobile_pm_domain r8a7740_pd_a3sp;
extern struct rmobile_pm_domain r8a7740_pd_a4lc;
#endif /* CONFIG_PM */

#endif /* __ASM_R8A7740_H__ */
4 changes: 2 additions & 2 deletions trunk/arch/arm/mach-shmobile/pfc-r8a7740.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(A21_MARK, PORT120_FN1),
PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2),
PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0),
PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_0),
PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_1),

/* Port121 */
PINMUX_DATA(A20_MARK, PORT121_FN1),
Expand Down Expand Up @@ -1623,7 +1623,7 @@ static pinmux_enum_t pinmux_data[] = {

/* Port209 */
PINMUX_DATA(VBUS_MARK, PORT209_FN1),
PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_1),
PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_0),

/* Port210 */
PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1),
Expand Down
54 changes: 54 additions & 0 deletions trunk/arch/arm/mach-shmobile/pm-r8a7740.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* r8a7740 power management support
*
* Copyright (C) 2012 Renesas Solutions Corp.
* Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/console.h>
#include <mach/pm-rmobile.h>

#ifdef CONFIG_PM
static int r8a7740_pd_a4s_suspend(void)
{
/*
* The A4S domain contains the CPU core and therefore it should
* only be turned off if the CPU is in use.
*/
return -EBUSY;
}

struct rmobile_pm_domain r8a7740_pd_a4s = {
.genpd.name = "A4S",
.bit_shift = 10,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
.suspend = r8a7740_pd_a4s_suspend,
};

static int r8a7740_pd_a3sp_suspend(void)
{
/*
* Serial consoles make use of SCIF hardware located in A3SP,
* keep such power domain on if "no_console_suspend" is set.
*/
return console_suspend_enabled ? 0 : -EBUSY;
}

struct rmobile_pm_domain r8a7740_pd_a3sp = {
.genpd.name = "A3SP",
.bit_shift = 11,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
.suspend = r8a7740_pd_a3sp_suspend,
};

struct rmobile_pm_domain r8a7740_pd_a4lc = {
.genpd.name = "A4LC",
.bit_shift = 1,
};

#endif /* CONFIG_PM */
167 changes: 167 additions & 0 deletions trunk/arch/arm/mach-shmobile/pm-rmobile.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* rmobile power management support
*
* Copyright (C) 2012 Renesas Solutions Corp.
* Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* based on pm-sh7372.c
* Copyright (C) 2011 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_clock.h>
#include <asm/io.h>
#include <mach/pm-rmobile.h>

/* SYSC */
#define SPDCR 0xe6180008
#define SWUCR 0xe6180014
#define PSTR 0xe6180080

#define PSTR_RETRIES 100
#define PSTR_DELAY_US 10

#ifdef CONFIG_PM
static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
{
struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
unsigned int mask = 1 << rmobile_pd->bit_shift;

if (rmobile_pd->suspend) {
int ret = rmobile_pd->suspend();

if (ret)
return ret;
}

if (__raw_readl(PSTR) & mask) {
unsigned int retry_count;
__raw_writel(mask, SPDCR);

for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
if (!(__raw_readl(SPDCR) & mask))
break;
cpu_relax();
}
}

if (!rmobile_pd->no_debug)
pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
genpd->name, mask, __raw_readl(PSTR));

return 0;
}

static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
bool do_resume)
{
unsigned int mask = 1 << rmobile_pd->bit_shift;
unsigned int retry_count;
int ret = 0;

if (__raw_readl(PSTR) & mask)
goto out;

__raw_writel(mask, SWUCR);

for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
if (!(__raw_readl(SWUCR) & mask))
break;
if (retry_count > PSTR_RETRIES)
udelay(PSTR_DELAY_US);
else
cpu_relax();
}
if (!retry_count)
ret = -EIO;

if (!rmobile_pd->no_debug)
pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
rmobile_pd->genpd.name, mask, __raw_readl(PSTR));

out:
if (ret == 0 && rmobile_pd->resume && do_resume)
rmobile_pd->resume();

return ret;
}

static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
{
return __rmobile_pd_power_up(to_rmobile_pd(genpd), true);
}

static bool rmobile_pd_active_wakeup(struct device *dev)
{
bool (*active_wakeup)(struct device *dev);

active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
return active_wakeup ? active_wakeup(dev) : true;
}

static int rmobile_pd_stop_dev(struct device *dev)
{
int (*stop)(struct device *dev);

stop = dev_gpd_data(dev)->ops.stop;
if (stop) {
int ret = stop(dev);
if (ret)
return ret;
}
return pm_clk_suspend(dev);
}

static int rmobile_pd_start_dev(struct device *dev)
{
int (*start)(struct device *dev);
int ret;

ret = pm_clk_resume(dev);
if (ret)
return ret;

start = dev_gpd_data(dev)->ops.start;
if (start)
ret = start(dev);

return ret;
}

void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
{
struct generic_pm_domain *genpd = &rmobile_pd->genpd;
struct dev_power_governor *gov = rmobile_pd->gov;

pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
genpd->dev_ops.stop = rmobile_pd_stop_dev;
genpd->dev_ops.start = rmobile_pd_start_dev;
genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
genpd->dev_irq_safe = true;
genpd->power_off = rmobile_pd_power_down;
genpd->power_on = rmobile_pd_power_up;
__rmobile_pd_power_up(rmobile_pd, false);
}

void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
struct platform_device *pdev)
{
struct device *dev = &pdev->dev;

pm_genpd_add_device(&rmobile_pd->genpd, dev);
if (pm_clk_no_clocks(dev))
pm_clk_add(dev, NULL);
}

void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
struct rmobile_pm_domain *rmobile_sd)
{
pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd);
}
#endif /* CONFIG_PM */
Loading

0 comments on commit 33bf9d3

Please sign in to comment.