From patchwork Tue Mar 10 13:19:50 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Francesco VIRLINZI X-Patchwork-Id: 10869 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n2ADK0kO014050 for ; Tue, 10 Mar 2009 13:20:00 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751466AbZCJNUB (ORCPT ); Tue, 10 Mar 2009 09:20:01 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752384AbZCJNUB (ORCPT ); Tue, 10 Mar 2009 09:20:01 -0400 Received: from eu1sys200aog119.obsmtp.com ([207.126.144.147]:49117 "EHLO eu1sys200aog119.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751466AbZCJNUA (ORCPT ); Tue, 10 Mar 2009 09:20:00 -0400 Received: from source ([164.129.1.35]) (using TLSv1) by eu1sys200aob119.postini.com ([207.126.147.11]) with SMTP ID DSNKSbZo+kgB2TJTcXrPTVP46eguGrNY5TS3@postini.com; Tue, 10 Mar 2009 13:19:58 UTC Received: from zeta.dmz-eu.st.com (ns2.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 735BADA7E; Tue, 10 Mar 2009 13:18:59 +0000 (GMT) Received: from mail1.ctn.st.com (mail1.ctn.st.com [164.130.116.128]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 182E24C3C8; Tue, 10 Mar 2009 13:19:53 +0000 (GMT) Received: from [10.52.139.41] (mdt-dhcp41.ctn.st.com [10.52.139.41]) by mail1.ctn.st.com (MOS 3.8.7a) with ESMTP id CZV03038 (AUTH virlinzi); Tue, 10 Mar 2009 14:19:52 +0100 (CET) Message-ID: <49B668F6.3020405@st.com> Date: Tue, 10 Mar 2009 14:19:50 +0100 From: Francesco VIRLINZI User-Agent: Thunderbird 2.0.0.19 (X11/20090105) MIME-Version: 1.0 To: Magnus Damm Cc: linux-sh@vger.kernel.org, lethal@linux-sh.org Subject: Re: [PATCH] sh: hibernation support References: <20090306064156.27281.35572.sendpatchset@rx1.opensource.se> <49B0CB82.7030708@st.com> <49B0F56F.2090806@st.com> <49B4E982.4060107@st.com> In-Reply-To: Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org Hi Magnus In the clock framework I would propose the attached solution Regards Francesco Magnus Damm ha scritto: > On Mon, Mar 9, 2009 at 7:03 PM, Francesco VIRLINZI > wrote: > >> I'm sorry if I'm stressing you but you will have similar problem also with >> the clock framework. >> A simple >> - clk_get_rate(...) >> could return a wrong value if in the previous session someone changed the >> clock rate (from init value) and >> you don't force again in the hw the resumed "clk->rate". >> > > Yeah, the clock framework needs more work. =) > > / magnus > -- > To unsubscribe from this list: send the line "unsubscribe linux-sh" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > From 7d2249e98d304181b3deaa806ee475873e822328 Mon Sep 17 00:00:00 2001 From: Francesco Virlinzi Date: Tue, 10 Mar 2009 10:23:23 +0100 Subject: [PATCH] sh_clk: Added clks sysdevice to support hibernation This patch adds the clk_sysdev device to restore the right clocks setting after a resume from hibernation. Signed-off-by: Francesco Virlinzi --- arch/sh/kernel/cpu/clock.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 62 insertions(+), 0 deletions(-) diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index dc53def..06fcbf0 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -382,6 +384,56 @@ static int show_clocks(char *buf, char **start, off_t off, return p - buf; } +static int clks_suspend(struct sys_device *dev, pm_message_t state) +{ + static pm_message_t prev_state; + struct clk *clkp; + + switch (state.event) { + case PM_EVENT_ON: + /* Resumeing from hibernation */ + if (prev_state.event == PM_EVENT_FREEZE) { + list_for_each_entry(clkp, &clock_list, node) + if (likely(clkp->ops)) { + if (likely(clkp->ops->set_parent)) + clkp->ops->set_parent(clkp, + clkp->parent); + if (likely(clkp->ops->set_rate)) + clkp->ops->set_rate(clkp, + clkp->rate, NO_CHANGE); + if (likely(clkp->ops->recalc)) + clkp->ops->recalc(clkp); + } + } + break; + case PM_EVENT_FREEZE: + break; + case PM_EVENT_SUSPEND: + break; + } + + prev_state = state; + return 0; +} + +static int clks_resume(struct sys_device *dev) +{ + return clks_suspend(dev, PMSG_ON); +} + +static struct sysdev_class clks_class = { + .kset.kobj.name = "clks", +}; + +static struct sysdev_driver clks_driver = { + .suspend = clks_suspend, + .resume = clks_resume, +}; + +static struct sys_device clks_dev = { + .cls = &clks_class, +}; + int __init clk_init(void) { int i, ret = 0; @@ -404,6 +456,16 @@ int __init clk_init(void) return ret; } +static int __init clk_sysdev_init(void) +{ + + sysdev_class_register(&clks_class); + sysdev_driver_register(&clks_class, &clks_driver); + sysdev_register(&clks_dev); + return 0; +} +subsys_initcall(clk_sysdev_init); + static int __init clk_proc_init(void) { struct proc_dir_entry *p; -- 1.5.6.6