From patchwork Sat Jun 21 11:22:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell King X-Patchwork-Id: 4393841 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 938419F26E for ; Sat, 21 Jun 2014 11:22:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A799620270 for ; Sat, 21 Jun 2014 11:22:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A37EB2027D for ; Sat, 21 Jun 2014 11:22:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751486AbaFULWn (ORCPT ); Sat, 21 Jun 2014 07:22:43 -0400 Received: from gw-1.arm.linux.org.uk ([78.32.30.217]:37798 "EHLO pandora.arm.linux.org.uk" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751469AbaFULWm (ORCPT ); Sat, 21 Jun 2014 07:22:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=arm.linux.org.uk; s=pandora; h=Date:Sender:Message-Id:Subject:Cc:To:From:References:In-Reply-To; bh=CiYadaUKtJfO9VjqY1lIkIv37Hb7ZENKFQI3It/Mn3s=; b=n5szPcOe9VrX9DnVt1Ql1hUF15ejhoo6UGLumbHMSL41cL8IdRH+KmfgbBTK4f087gW5zuKvgILioeqbLYUGSra0SHz3y67QlHmCxT2tBo1VSaHxanIR/hm0BXgvxhHuyPeLHa2n3N3NAFs9R7OzBRUx8Ys+Bx5AStCsqmGwHDQ=; Received: from e0022681537dd.dyn.arm.linux.org.uk ([2002:4e20:1eda:1:222:68ff:fe15:37dd]:56326 helo=rmk-PC.arm.linux.org.uk) by pandora.arm.linux.org.uk with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.76) (envelope-from ) id 1WyJNW-0002iV-7E; Sat, 21 Jun 2014 12:22:38 +0100 Received: from rmk by rmk-PC.arm.linux.org.uk with local (Exim 4.76) (envelope-from ) id 1WyJNV-0004DZ-Sb; Sat, 21 Jun 2014 12:22:37 +0100 In-Reply-To: <20140621110339.GG5099@sirena.org.uk> References: <20140621110339.GG5099@sirena.org.uk> From: Russell King To: Mark Brown , Andrew Lunn , Jason Cooper Cc: linux-spi@vger.kernel.org Subject: [PATCH v2] SPI: spi-orion: add runtime PM support Message-Id: Date: Sat, 21 Jun 2014 12:22:37 +0100 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,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 trivial runtime PM support. This will only be of benefit on SoCs where the clock to the SPI interface can be shut down. Signed-off-by: Russell King --- drivers/spi/spi-orion.c | 59 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 24844984ef36..aa3ecfc6b466 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,9 @@ #define DRIVER_NAME "orion_spi" +/* Runtime PM autosuspend timeout: PM is fairly light on this driver */ +#define SPI_AUTOSUSPEND_TIMEOUT 200 + #define ORION_NUM_CHIPSELECTS 1 /* only one slave is supported*/ #define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */ @@ -277,7 +281,6 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) return xfer->len - count; } - static int orion_spi_transfer_one_message(struct spi_master *master, struct spi_message *m) { @@ -370,6 +373,7 @@ static int orion_spi_probe(struct platform_device *pdev) master->transfer_one_message = orion_spi_transfer_one_message; master->num_chipselect = ORION_NUM_CHIPSELECTS; master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16); + master->auto_runtime_pm = true; platform_set_drvdata(pdev, master); @@ -397,16 +401,26 @@ static int orion_spi_probe(struct platform_device *pdev) goto out_rel_clk; } + pm_runtime_set_active(&pdev->dev); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); + pm_runtime_enable(&pdev->dev); + if (orion_spi_reset(spi) < 0) - goto out_rel_clk; + goto out_rel_pm; + + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); master->dev.of_node = pdev->dev.of_node; - status = devm_spi_register_master(&pdev->dev, master); + status = spi_register_master(master); if (status < 0) - goto out_rel_clk; + goto out_rel_pm; return status; +out_rel_pm: + pm_runtime_disable(&pdev->dev); out_rel_clk: clk_disable_unprepare(spi->clk); out: @@ -417,19 +431,45 @@ static int orion_spi_probe(struct platform_device *pdev) static int orion_spi_remove(struct platform_device *pdev) { - struct spi_master *master; - struct orion_spi *spi; - - master = platform_get_drvdata(pdev); - spi = spi_master_get_devdata(master); + struct spi_master *master = platform_get_drvdata(pdev); + struct orion_spi *spi = spi_master_get_devdata(master); + pm_runtime_get_sync(&pdev->dev); clk_disable_unprepare(spi->clk); + spi_unregister_master(master); + pm_runtime_disable(&pdev->dev); + return 0; } MODULE_ALIAS("platform:" DRIVER_NAME); +#ifdef CONFIG_PM_RUNTIME +static int orion_spi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct orion_spi *spi = spi_master_get_devdata(master); + + clk_disable_unprepare(spi->clk); + return 0; +} + +static int orion_spi_runtime_resume(struct device *dev) +{ + struct spi_master *master = dev_get_drvdata(dev); + struct orion_spi *spi = spi_master_get_devdata(master); + + return clk_prepare_enable(spi->clk); +} +#endif + +static const struct dev_pm_ops orion_spi_pm_ops = { + SET_RUNTIME_PM_OPS(orion_spi_runtime_suspend, + orion_spi_runtime_resume, + NULL) +}; + static const struct of_device_id orion_spi_of_match_table[] = { { .compatible = "marvell,orion-spi", }, {} @@ -440,6 +480,7 @@ static struct platform_driver orion_spi_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .pm = &orion_spi_pm_ops, .of_match_table = of_match_ptr(orion_spi_of_match_table), }, .probe = orion_spi_probe,