From patchwork Wed Sep 19 12:23:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 11505 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 5458623E42 for ; Wed, 19 Sep 2012 12:24:34 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id A5B9FA18AC1 for ; Wed, 19 Sep 2012 12:24:32 +0000 (UTC) Received: by ieje10 with SMTP id e10so898410iej.11 for ; Wed, 19 Sep 2012 05:24:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=e/1LLd0HW0q6MQtjQ6F1nlW7QHLB3c/iUXScmIPubK8=; b=PEXYhwhFxlvOgtrEGwUbYgdJQ+avs2el8rAuyMK727nNCeiSGPWAym/v5FaK2lcKME olClMfGkTgNlYkuVfHHxRSCK/EAabeWp/gT70bXhJJF99jAa/me5A/a++NQFF+wHEzg/ KjoEBvDEPJKHwOz2DqrgSomrZoLGC8w9reiVuv3rcxBJPrfxpjqW1llvMOVKrlxG/tFR ZE2xTIW9XjN0PvJfRfApa6KX2pj3R6TrNhJB5zmpLdYPt/3htvlP0NxfMlnVwHNxEJYw Q1aHaGVIGQrTLcK4i1bPAATkWUCKCEuj0f+J3WHLqZKqLYhDRePsPla5N6YlFP5sUW5G it0A== Received: by 10.50.0.193 with SMTP id 1mr2722054igg.0.1348057471968; Wed, 19 Sep 2012 05:24:31 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp18053igc; Wed, 19 Sep 2012 05:24:30 -0700 (PDT) Received: by 10.14.209.5 with SMTP id r5mr3404134eeo.28.1348057469646; Wed, 19 Sep 2012 05:24:29 -0700 (PDT) Received: from eu1sys200aog117.obsmtp.com (eu1sys200aog117.obsmtp.com [207.126.144.143]) by mx.google.com with SMTP id z2si1580091eel.8.2012.09.19.05.24.16 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 19 Sep 2012 05:24:29 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.143 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.143; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.143 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob117.postini.com ([207.126.147.11]) with SMTP ID DSNKUFm5bugKcsxonoJCoJoLbSeZ2WGHwwhU@postini.com; Wed, 19 Sep 2012 12:24:29 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 22B652B4; Wed, 19 Sep 2012 12:23:57 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id AD18D2BC1; Wed, 19 Sep 2012 12:23:57 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id A88D224C080; Wed, 19 Sep 2012 14:23:50 +0200 (CEST) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Wed, 19 Sep 2012 14:23:56 +0200 From: Linus Walleij To: Grant Likely , Mark Brown , Cc: Anmar Oueja , Patrice Chotard , Pawel Moll , Roland Stigge , Shiraz Hashim , Vinit Kamalaksha Shenoy , Viresh Kumar , Linus Walleij Subject: [PATCH] spi/pl022: adopt pinctrl support Date: Wed, 19 Sep 2012 14:23:46 +0200 Message-ID: <1348057426-24898-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQl0zG0CyPVZ+oZcttyiT5loroAia4k72SGuzwxlhA8x8Ba71hZgPS+LfWHBkiLU/4v+ffEB From: Patrice Chotard Amend the PL022 pin controller to optionally take a pin control handle and set the state of the pins to "default" on boot and runtime resume, and to "sleep" at runtime suspend. This way we will dynamically save power on the SPI busses, for example some electronic designs may be able to ground the pins when unused instead of pull-up. Some pin controllers may want to set the pins as wake-up sources when sleeping. Effect on platforms using the PL022 driver: - If the platform does not use pin control - no semantic effect, the pinctrl stubs will kick in and resolve the situation. - Platforms using this driver and have pin control but no function defined for the PL022 need to either supply a "default" function in their map or enable pinctrl dummies so the driver is satisfied. - Platforms using this driver with hogs for setting up the PL022 pin control - stop using hogs to take the pl022 pin control handle, let the driver handle this. I'be looked at some platforms that may be affected: - SPEAr: appears to define the proper functions in their device trees and not hogging them, so things should be smooth, the driver will simply start to take its pins. - Ux500: the proper function is defined and will be taken properly by the driver. New sleep states introduced by a separate patch to ux500 but no regression, since the default state is sufficient. - U300: old hog deleted as part of this patch. - LPC32xx: does not appear to be using pinctrl. - ARM Integrator IMPD1, RealView & Versatile: does not use pinctrl. Cc: Pawel Moll Cc: Roland Stigge Cc: Shiraz Hashim Cc: Mark Brown Cc: Vinit Kamalaksha Shenoy Cc: Viresh Kumar Signed-off-by: Patrice Chotard Signed-off-by: Linus Walleij --- arch/arm/mach-u300/core.c | 3 --- drivers/spi/spi-pl022.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 03acf18..281292e 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1605,9 +1605,6 @@ static struct u300_mux_hog u300_mux_hogs[] = { .dev = &uart0_device.dev, }, { - .dev = &pl022_device.dev, - }, - { .dev = &mmcsd_device.dev, }, }; diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index e43b610..423513c 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -42,6 +42,7 @@ #include #include #include +#include /* * This macro is used to define some register default values. @@ -367,6 +368,10 @@ struct pl022 { resource_size_t phybase; void __iomem *virtbase; struct clk *clk; + /* Two optional pin states - default & sleep */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; struct spi_master *master; struct pl022_ssp_controller *master_info; /* Message per-transfer pump */ @@ -2068,6 +2073,28 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) pl022->chipselects = devm_kzalloc(dev, num_cs * sizeof(int), GFP_KERNEL); + pl022->pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pl022->pinctrl)) { + status = PTR_ERR(pl022->pinctrl); + goto err_no_pinctrl; + } + + pl022->pins_default = pinctrl_lookup_state(pl022->pinctrl, + PINCTRL_STATE_DEFAULT); + /* enable pins to be muxed in and configured */ + if (!IS_ERR(pl022->pins_default)) { + status = pinctrl_select_state(pl022->pinctrl, + pl022->pins_default); + if (status) + dev_err(dev, "could not set default pins\n"); + } else + dev_err(dev, "could not get default pinstate\n"); + + pl022->pins_sleep = pinctrl_lookup_state(pl022->pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR(pl022->pins_sleep)) + dev_dbg(dev, "could not get sleep pinstate\n"); + /* * Bus Number Which has been Assigned to this SSP controller * on this board @@ -2217,6 +2244,7 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) amba_release_regions(adev); err_no_ioregion: err_no_gpio: + err_no_pinctrl: spi_master_put(master); err_no_master: err_no_pdata: @@ -2290,15 +2318,33 @@ static int pl022_resume(struct device *dev) static int pl022_runtime_suspend(struct device *dev) { struct pl022 *pl022 = dev_get_drvdata(dev); + int status = 0; clk_disable(pl022->clk); + /* Optionally let pins go into sleep states */ + if (!IS_ERR(pl022->pins_sleep)) { + status = pinctrl_select_state(pl022->pinctrl, + pl022->pins_sleep); + if (status) + dev_err(dev, "could not set pins to sleep state\n"); + } + return 0; } static int pl022_runtime_resume(struct device *dev) { struct pl022 *pl022 = dev_get_drvdata(dev); + int status = 0; + + /* Optionaly enable pins to be muxed in and configured */ + if (!IS_ERR(pl022->pins_default)) { + status = pinctrl_select_state(pl022->pinctrl, + pl022->pins_default); + if (status) + dev_err(dev, "could not set default pins\n"); + } clk_enable(pl022->clk);