From patchwork Sun Aug 23 12:22:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 7057631 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id DA92BC05AC for ; Sun, 23 Aug 2015 12:23:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E13DC20374 for ; Sun, 23 Aug 2015 12:23:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DAB072040F for ; Sun, 23 Aug 2015 12:22:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752432AbbHWMW6 (ORCPT ); Sun, 23 Aug 2015 08:22:58 -0400 Received: from mail-wi0-f177.google.com ([209.85.212.177]:36233 "EHLO mail-wi0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752422AbbHWMW5 (ORCPT ); Sun, 23 Aug 2015 08:22:57 -0400 Received: by wicja10 with SMTP id ja10so49277351wic.1 for ; Sun, 23 Aug 2015 05:22:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :content-type:content-transfer-encoding; bh=INXRAhNzBYTMJzLhBRFxoMu81TN/9vm1iXzwYkmzS0g=; b=0xMRC22r0KjCfEaycJ8YuI56qFViUsXSJg7ON+KNLqS2RObpshG7RWoO+bxujaUBfe eNKXCQ75K/CfwoU3nr9tF7F7kcs/kFfEFa4bujSsXo4wcf+xP7/ZFdlzrP06PmJ3WCjR xCm7Va+xQa+DBf/tIK1yetPsSrsMO0xT7ZPkEwd8NUJzL2j08ighKULmvk0bxFKmPA4N KqL6QJ8/FDZJxEZAF1GrzcI6tVEC1rlXQZj7johI3j58/XKLWZuyx+9XVP0AlaxTe73r c3CrwrYrB/H25k2WsxXD96Iaf/cpJF5QNfurCo7vZ6SV2cV+GOqbc0/Iq1f4490VIoca 2qzw== X-Received: by 10.180.76.177 with SMTP id l17mr20894590wiw.14.1440332575654; Sun, 23 Aug 2015 05:22:55 -0700 (PDT) Received: from ?IPv6:2003:62:5f33:d300:2820:d22e:6dc:c1e4? (p200300625F33D3002820D22E06DCC1E4.dip0.t-ipconnect.de. [2003:62:5f33:d300:2820:d22e:6dc:c1e4]) by smtp.googlemail.com with ESMTPSA id du6sm11409234wib.24.2015.08.23.05.22.54 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Aug 2015 05:22:55 -0700 (PDT) Message-ID: <55D9BB0D.7080604@gmail.com> Date: Sun, 23 Aug 2015 14:22:37 +0200 From: Heiner Kallweit User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Mark Brown CC: "linux-spi@vger.kernel.org" Subject: [PATCH 3/3] spi: fsl-espi: add runtime PM Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-8.0 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add runtime PM and use autosuspend instead of suspending the SPI controller after each transfer. Signed-off-by: Heiner Kallweit --- drivers/spi/spi-fsl-espi.c | 65 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index fdd85be..5678cbd 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "spi-fsl-lib.h" @@ -85,6 +86,8 @@ struct fsl_espi_transfer { #define SPCOM_TRANLEN(x) ((x) << 0) #define SPCOM_TRANLEN_MAX 0xFFFF /* Max transaction length */ +#define AUTOSUSPEND_TIMEOUT 2000 + static void fsl_espi_change_mode(struct spi_device *spi) { struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); @@ -485,6 +488,8 @@ static int fsl_espi_setup(struct spi_device *spi) mpc8xxx_spi = spi_master_get_devdata(spi->master); reg_base = mpc8xxx_spi->reg_base; + pm_runtime_get_sync(mpc8xxx_spi->dev); + hw_mode = cs->hw_mode; /* Save original settings */ cs->hw_mode = mpc8xxx_spi_read_reg( ®_base->csmode[spi->chip_select]); @@ -507,6 +512,10 @@ static int fsl_espi_setup(struct spi_device *spi) mpc8xxx_spi_write_reg(®_base->mode, loop_mode); retval = fsl_espi_setup_transfer(spi, NULL); + + pm_runtime_mark_last_busy(mpc8xxx_spi->dev); + pm_runtime_put_autosuspend(mpc8xxx_spi->dev); + if (retval < 0) { cs->hw_mode = hw_mode; /* Restore settings */ return retval; @@ -604,15 +613,14 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) return ret; } -static int fsl_espi_suspend(struct spi_master *master) +#ifdef CONFIG_PM +static int fsl_espi_runtime_suspend(struct device *dev) { - struct mpc8xxx_spi *mpc8xxx_spi; - struct fsl_espi_reg *reg_base; + struct spi_master *master = dev_get_drvdata(dev); + struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); + struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base; u32 regval; - mpc8xxx_spi = spi_master_get_devdata(master); - reg_base = mpc8xxx_spi->reg_base; - regval = mpc8xxx_spi_read_reg(®_base->mode); regval &= ~SPMODE_ENABLE; mpc8xxx_spi_write_reg(®_base->mode, regval); @@ -620,21 +628,20 @@ static int fsl_espi_suspend(struct spi_master *master) return 0; } -static int fsl_espi_resume(struct spi_master *master) +static int fsl_espi_runtime_resume(struct device *dev) { - struct mpc8xxx_spi *mpc8xxx_spi; - struct fsl_espi_reg *reg_base; + struct spi_master *master = dev_get_drvdata(dev); + struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); + struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base; u32 regval; - mpc8xxx_spi = spi_master_get_devdata(master); - reg_base = mpc8xxx_spi->reg_base; - regval = mpc8xxx_spi_read_reg(®_base->mode); regval |= SPMODE_ENABLE; mpc8xxx_spi_write_reg(®_base->mode, regval); return 0; } +#endif static struct spi_master * fsl_espi_probe(struct device *dev, struct resource *mem, unsigned int irq) @@ -662,8 +669,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, master->setup = fsl_espi_setup; master->cleanup = fsl_espi_cleanup; master->transfer_one_message = fsl_espi_do_one_msg; - master->prepare_transfer_hardware = fsl_espi_resume; - master->unprepare_transfer_hardware = fsl_espi_suspend; + master->auto_runtime_pm = true; mpc8xxx_spi = spi_master_get_devdata(master); @@ -726,14 +732,27 @@ static struct spi_master * fsl_espi_probe(struct device *dev, mpc8xxx_spi_write_reg(®_base->mode, regval); + pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + ret = devm_spi_register_master(dev, master); if (ret < 0) - goto err_probe; + goto err_pm; dev_info(dev, "at 0x%p (irq = %d)\n", reg_base, mpc8xxx_spi->irq); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return master; +err_pm: + pm_runtime_put_noidle(dev); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); err_probe: spi_master_put(master); err: @@ -800,6 +819,8 @@ err: static int of_fsl_espi_remove(struct platform_device *dev) { + pm_runtime_disable(&dev->dev); + return 0; } @@ -815,7 +836,11 @@ static int of_fsl_espi_suspend(struct device *dev) return ret; } - return fsl_espi_suspend(master); + ret = pm_runtime_force_suspend(dev); + if (ret < 0) + return ret; + + return 0; } static int of_fsl_espi_resume(struct device *dev) @@ -825,7 +850,7 @@ static int of_fsl_espi_resume(struct device *dev) struct mpc8xxx_spi *mpc8xxx_spi; struct fsl_espi_reg *reg_base; u32 regval; - int i; + int i, ret; mpc8xxx_spi = spi_master_get_devdata(master); reg_base = mpc8xxx_spi->reg_base; @@ -845,11 +870,17 @@ static int of_fsl_espi_resume(struct device *dev) mpc8xxx_spi_write_reg(®_base->mode, regval); + ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret; + return spi_master_resume(master); } #endif /* CONFIG_PM_SLEEP */ static const struct dev_pm_ops espi_pm = { + SET_RUNTIME_PM_OPS(fsl_espi_runtime_suspend, + fsl_espi_runtime_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(of_fsl_espi_suspend, of_fsl_espi_resume) };