From patchwork Fri Feb 28 11:49:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 3740221 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D7A24BF13A for ; Fri, 28 Feb 2014 11:49:11 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CC86F2026F for ; Fri, 28 Feb 2014 11:49:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9C8F820179 for ; Fri, 28 Feb 2014 11:49:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751651AbaB1LtH (ORCPT ); Fri, 28 Feb 2014 06:49:07 -0500 Received: from mail-lb0-f182.google.com ([209.85.217.182]:46992 "EHLO mail-lb0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751083AbaB1LtG (ORCPT ); Fri, 28 Feb 2014 06:49:06 -0500 Received: by mail-lb0-f182.google.com with SMTP id n15so2574838lbi.41 for ; Fri, 28 Feb 2014 03:49:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=/eT3qusBKxy8qJizDoC1BuNhlnYux/67wOfmlkIRODQ=; b=AUT2eFFyOPeCS4dVxIbOQhn/mwo2LOM8Ft701U8Gs69X2e0mxJpvY471XXLCplzmIG 4xR/3OuZxIr1JgzcN+9BVgwBtsgn+eeo9l1KBwrLsgfey6+gHU77JBZ95JD8cWTPg5BY GayA8Fr6k+aYi6ClBZTMgzWeRMGXprP1GeJrVr6UnNNEr5GVJRoqfnGREtDNTzhIE2sW paRa204sDhxZ7bP1OCvZcCler9jinUdaWd3fMXYEQ4WdEaihOuR0f47740P62uPOgDxB wtk0mgI8dW8sbCq4e4Rg/fTnvsDmJrmushcbfYTQkPlh6qI76+G4Zy4m+CoFgMAnQfXY PLtQ== X-Gm-Message-State: ALoCoQkDSdjAOqNPU8Hpgdw7L2xD5zgMhGGrp3vGzWHNNjNjbhV6WVArrL3sEw+S8OnWoYNxShaY X-Received: by 10.152.190.135 with SMTP id gq7mr3017557lac.28.1393588144661; Fri, 28 Feb 2014 03:49:04 -0800 (PST) Received: from linaro-ulf.lan (90-231-160-185-no158.tbcn.telia.com. [90.231.160.185]) by mx.google.com with ESMTPSA id k1sm3608709lbc.5.2014.02.28.03.49.02 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 28 Feb 2014 03:49:03 -0800 (PST) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Chris Ball Cc: linux-kernel@vger.kernel.org, Ulf Hansson , Aaron Lu , NeilBrown , "Rafael J. Wysocki" Subject: [RFC PATCH] mmc: core: Invoke sdio func driver's PM callbacks from the sdio bus Date: Fri, 28 Feb 2014 12:49:00 +0100 Message-Id: <1393588140-20605-1-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 The sdio func device is added to the driver model after the card device. This means the sdio func device will be suspend before the card device and thus resumed after. The consequence are the mmc core don't explicity need to protect itself from receiving sdio requests in suspended state. Instead that can be handled from the sdio bus, which is thus invokes the PM callbacks instead of old dummy function. In the case were the sdio func driver don't implement the PM callbacks the mmc core will in the early phase of system suspend, remove the card from the driver model and thus power off it. Cc: Aaron Lu Cc: NeilBrown Cc: Rafael J. Wysocki Signed-off-by: Ulf Hansson Reviewed-by: Aaron Lu Tested-by: xiaoming wang Tested-by: Chuanxiao Dong --- Note, this patch has only been compile tested. Would appreciate if some with SDIO and a sdio func driver could help out to test this. Especially the libertas driver would be nice. --- drivers/mmc/core/sdio.c | 45 ++++--------------------------------------- drivers/mmc/core/sdio_bus.c | 14 +------------- 2 files changed, 5 insertions(+), 54 deletions(-) diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4d721c6..9933e42 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -943,40 +943,21 @@ static int mmc_sdio_pre_suspend(struct mmc_host *host) */ static int mmc_sdio_suspend(struct mmc_host *host) { - int i, err = 0; - - for (i = 0; i < host->card->sdio_funcs; i++) { - struct sdio_func *func = host->card->sdio_func[i]; - if (func && sdio_func_present(func) && func->dev.driver) { - const struct dev_pm_ops *pmops = func->dev.driver->pm; - err = pmops->suspend(&func->dev); - if (err) - break; - } - } - while (err && --i >= 0) { - struct sdio_func *func = host->card->sdio_func[i]; - if (func && sdio_func_present(func) && func->dev.driver) { - const struct dev_pm_ops *pmops = func->dev.driver->pm; - pmops->resume(&func->dev); - } - } - - if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { + if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { mmc_claim_host(host); sdio_disable_wide(host->card); mmc_release_host(host); } - if (!err && !mmc_card_keep_power(host)) + if (!mmc_card_keep_power(host)) mmc_power_off(host); - return err; + return 0; } static int mmc_sdio_resume(struct mmc_host *host) { - int i, err = 0; + int err = 0; BUG_ON(!host); BUG_ON(!host->card); @@ -1019,24 +1000,6 @@ static int mmc_sdio_resume(struct mmc_host *host) wake_up_process(host->sdio_irq_thread); mmc_release_host(host); - /* - * If the card looked to be the same as before suspending, then - * we proceed to resume all card functions. If one of them returns - * an error then we simply return that error to the core and the - * card will be redetected as new. It is the responsibility of - * the function driver to perform further tests with the extra - * knowledge it has of the card to confirm the card is indeed the - * same as before suspending (same MAC address for network cards, - * etc.) and return an error otherwise. - */ - for (i = 0; !err && i < host->card->sdio_funcs; i++) { - struct sdio_func *func = host->card->sdio_func[i]; - if (func && sdio_func_present(func) && func->dev.driver) { - const struct dev_pm_ops *pmops = func->dev.driver->pm; - err = pmops->resume(&func->dev); - } - } - host->pm_flags &= ~MMC_PM_KEEP_POWER; return err; } diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 92d1ba8..4fa8fef9 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -197,20 +197,8 @@ static int sdio_bus_remove(struct device *dev) #ifdef CONFIG_PM -#ifdef CONFIG_PM_SLEEP -static int pm_no_operation(struct device *dev) -{ - /* - * Prevent the PM core from calling SDIO device drivers' suspend - * callback routines, which it is not supposed to do, by using this - * empty function as the bus type suspend callaback for SDIO. - */ - return 0; -} -#endif - static const struct dev_pm_ops sdio_bus_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation) + SET_SYSTEM_SLEEP_PM_OPS(pm_generic_suspend, pm_generic_resume) SET_RUNTIME_PM_OPS( pm_generic_runtime_suspend, pm_generic_runtime_resume,