From patchwork Wed Aug 26 19:21:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 7079681 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 40A1C9F358 for ; Wed, 26 Aug 2015 19:23:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 27B4320968 for ; Wed, 26 Aug 2015 19:23:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0671D20969 for ; Wed, 26 Aug 2015 19:23:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752293AbbHZTXH (ORCPT ); Wed, 26 Aug 2015 15:23:07 -0400 Received: from mail-wi0-f179.google.com ([209.85.212.179]:33934 "EHLO mail-wi0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752200AbbHZTXG (ORCPT ); Wed, 26 Aug 2015 15:23:06 -0400 Received: by widdq5 with SMTP id dq5so56754868wid.1 for ; Wed, 26 Aug 2015 12:23:05 -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=DythC/24cfjWwfhXsHXlLYXAQrN4pf0J0t/EhbiCQX0=; b=wgzl2j9Ee0YK7gyxdlYG3Nskp2jhVqXlg6voy0j1G5rNjKy7EwE4jqnWYzvNPpnACS 7lLW3qotuJ2J/ItjmYf3SbqWSNBPMS/vve1g6yX0zSD2G03mHkOy2FDG9DFRqL/BW9oy /ALHsy4EZgdCFhnpqAoCp0Tg6MKZTxPR6msvZqMCRYOahFVXtfNohWIO7gXdixItWjdr XSHOjPem29OPzcN7iXir1fNVKrBzZQzPKhUSAREvCjNQOTw66zHcSnMCxcDoK3Vd++L3 0lnWbAqL8hDhiDxWNQ3XRMIgiK9FunZZuCBXkKI8Sfs2izNBiSbmtX2Pzle5x5/jbM/f k4Og== X-Received: by 10.180.74.167 with SMTP id u7mr14099758wiv.44.1440616985501; Wed, 26 Aug 2015 12:23:05 -0700 (PDT) Received: from ?IPv6:2003:62:5f33:d300:d9f5:3632:9aad:8006? (p200300625F33D300D9F536329AAD8006.dip0.t-ipconnect.de. [2003:62:5f33:d300:d9f5:3632:9aad:8006]) by smtp.googlemail.com with ESMTPSA id i6sm5264078wje.33.2015.08.26.12.23.04 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Aug 2015 12:23:05 -0700 (PDT) Message-ID: <55DE11D3.400@gmail.com> Date: Wed, 26 Aug 2015 21:21:55 +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 v2 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.2 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 --- v2: - rebased drivers/spi/spi-fsl-espi.c | 71 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index fe54e57..db82c87 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); @@ -725,14 +731,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: @@ -797,6 +816,13 @@ err: return ret; } +static int of_fsl_espi_remove(struct platform_device *dev) +{ + pm_runtime_disable(&dev->dev); + + return 0; +} + #ifdef CONFIG_PM_SLEEP static int of_fsl_espi_suspend(struct device *dev) { @@ -809,7 +835,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) @@ -819,7 +849,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; @@ -839,11 +869,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) }; @@ -860,6 +896,7 @@ static struct platform_driver fsl_espi_driver = { .pm = &espi_pm, }, .probe = of_fsl_espi_probe, + .remove = of_fsl_espi_remove, }; module_platform_driver(fsl_espi_driver);