From patchwork Fri Jul 22 05:55:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nishanth Menon X-Patchwork-Id: 998312 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p6M5uDYv025760 for ; Fri, 22 Jul 2011 05:56:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753274Ab1GVF4P (ORCPT ); Fri, 22 Jul 2011 01:56:15 -0400 Received: from na3sys009aog125.obsmtp.com ([74.125.149.153]:54171 "EHLO na3sys009aog125.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753196Ab1GVF4P (ORCPT ); Fri, 22 Jul 2011 01:56:15 -0400 Received: from mail-gx0-f180.google.com ([209.85.161.180]) (using TLSv1) by na3sys009aob125.postini.com ([74.125.148.12]) with SMTP ID DSNKTikQ/ujJXHs32fG3GWzCzcL7aEPTpYg1@postini.com; Thu, 21 Jul 2011 22:56:15 PDT Received: by mail-gx0-f180.google.com with SMTP id 10so1625426gxk.11 for ; Thu, 21 Jul 2011 22:56:14 -0700 (PDT) Received: by 10.91.161.16 with SMTP id n16mr1533949ago.16.1311314174351; Thu, 21 Jul 2011 22:56:14 -0700 (PDT) Received: from localhost (dragon.ti.com [192.94.94.33]) by mx.google.com with ESMTPS id e21sm450731ano.25.2011.07.21.22.56.12 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 21 Jul 2011 22:56:13 -0700 (PDT) From: Nishanth Menon To: Kevin Cc: Colin , linux-arm , linux-omap , Nishanth Menon Subject: [PATCH 2/2] OMAP2+: PM: SR: add suspend/resume handlers Date: Fri, 22 Jul 2011 00:55:53 -0500 Message-Id: <1311314153-23531-3-git-send-email-nm@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1311314153-23531-1-git-send-email-nm@ti.com> References: <1311314153-23531-1-git-send-email-nm@ti.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 22 Jul 2011 05:56:16 +0000 (UTC) Suspend and Resume paths are safe enough to do it in the standard LDM suspend/resume handlers where one can sleep. Add suspend/resume handlers for SmartReflex. Signed-off-by: Nishanth Menon --- arch/arm/mach-omap2/smartreflex.c | 87 +++++++++++++++++++++++++++++++++++++ 1 files changed, 87 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 33a027f..fb90bd2 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c @@ -39,6 +39,7 @@ struct omap_sr { int ip_type; int nvalue_count; bool autocomp_active; + bool is_suspended; u32 clk_length; u32 err_weight; u32 err_minlimit; @@ -684,6 +685,12 @@ void omap_sr_enable(struct voltagedomain *voltdm) if (!sr->autocomp_active) return; + if (sr->is_suspended) { + dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__); + return; + } + + if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) { dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" "registered\n", __func__); @@ -717,6 +724,11 @@ void omap_sr_disable(struct voltagedomain *voltdm) if (!sr->autocomp_active) return; + if (sr->is_suspended) { + dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__); + return; + } + if (!sr_class || !(sr_class->disable)) { dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" "registered\n", __func__); @@ -750,6 +762,11 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm) if (!sr->autocomp_active) return; + if (sr->is_suspended) { + dev_dbg(&sr->pdev->dev, "%s: in suspended state\n", __func__); + return; + } + if (!sr_class || !(sr_class->disable)) { dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not" "registered\n", __func__); @@ -808,6 +825,11 @@ static int omap_sr_autocomp_store(void *data, u64 val) return -EINVAL; } + if (sr_info->is_suspended) { + pr_warning("%s: in suspended state\n", __func__); + return -EBUSY; + } + if (!val) sr_stop_vddautocomp(sr_info); else @@ -998,8 +1020,73 @@ static int __devexit omap_sr_remove(struct platform_device *pdev) return 0; } +static int omap_sr_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct omap_sr_data *pdata = pdev->dev.platform_data; + struct omap_sr *sr_info; + + if (!pdata) { + dev_err(&pdev->dev, "%s: platform data missing\n", __func__); + return -EINVAL; + } + + sr_info = _sr_lookup(pdata->voltdm); + if (IS_ERR(sr_info)) { + dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", + __func__); + return -EINVAL; + } + + if (!sr_info->autocomp_active) + return 0; + + if (sr_info->is_suspended) + return 0; + + omap_sr_disable_reset_volt(pdata->voltdm); + sr_info->is_suspended = true; + /* Flag the same info to the other CPUs */ + smp_wmb(); + + return 0; +} + +static int omap_sr_resume(struct platform_device *pdev) +{ + struct omap_sr_data *pdata = pdev->dev.platform_data; + struct omap_sr *sr_info; + + if (!pdata) { + dev_err(&pdev->dev, "%s: platform data missing\n", __func__); + return -EINVAL; + } + + sr_info = _sr_lookup(pdata->voltdm); + if (IS_ERR(sr_info)) { + dev_warn(&pdev->dev, "%s: omap_sr struct not found\n", + __func__); + return -EINVAL; + } + + if (!sr_info->autocomp_active) + return 0; + + if (!sr_info->is_suspended) + return 0; + + sr_info->is_suspended = false; + /* Flag the same info to the other CPUs */ + smp_wmb(); + omap_sr_enable(pdata->voltdm); + + return 0; +} + + static struct platform_driver smartreflex_driver = { .remove = omap_sr_remove, + .suspend = omap_sr_suspend, + .resume = omap_sr_resume, .driver = { .name = "smartreflex", },