From patchwork Wed Nov 3 22:13:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grazvydas Ignotas X-Patchwork-Id: 300592 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oA3MEBAq010228 for ; Wed, 3 Nov 2010 22:14:12 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753027Ab0KCWOK (ORCPT ); Wed, 3 Nov 2010 18:14:10 -0400 Received: from mail-ey0-f174.google.com ([209.85.215.174]:44763 "EHLO mail-ey0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752965Ab0KCWOI (ORCPT ); Wed, 3 Nov 2010 18:14:08 -0400 Received: by mail-ey0-f174.google.com with SMTP id 27so668478eye.19 for ; Wed, 03 Nov 2010 15:14:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=40bDsw08K5eMkB4G6axE9GNUJ3k88ONyOf3fcV3bctY=; b=caz1M80Brwjo8JURpZMw01o22skhqRF8KexJjfy6y0TXZjvfF/vNsRu/7bYyZ6iYWg thu8praNeP03N2o3N2E7xZaBE/ka8R1wkG85Qb370TBxGZUvxl6Oad3bEwxmsWVVi5oI H7e21zlXH3chx30ltWms4e0h5BUtnOnnE90OY= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=Gy17gsuDnkbtFR47+9xF6CES5JRSnPK852mCPa5//2fJSWv4Qoq01FECthaZNg8ccO VQjzYXOahrkRxOrw0VhFa8SNH3iRxMfWmyYi2QKfuTg0XKk04MIG1WwGtWvpsmnnKCX5 xrfB5hzKaFytVsynJLsLSNurSyOlxNsRwO/x0= Received: by 10.14.47.67 with SMTP id s43mr1144745eeb.13.1288822438434; Wed, 03 Nov 2010 15:13:58 -0700 (PDT) Received: from localhost.localdomain (ip-88-119-226-136.static.b4net.lt [88.119.226.136]) by mx.google.com with ESMTPS id b52sm7027768eei.1.2010.11.03.15.13.56 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 03 Nov 2010 15:13:57 -0700 (PDT) From: Grazvydas Ignotas To: linux-wireless@vger.kernel.org Cc: Kalle Valo , "John W. Linville" , Grazvydas Ignotas , Ohad Ben-Cohen Subject: [PATCH 2/3] wl1251: add runtime PM support for SDIO Date: Thu, 4 Nov 2010 00:13:48 +0200 Message-Id: <1288822429-24541-3-git-send-email-notasas@gmail.com> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <1288822429-24541-1-git-send-email-notasas@gmail.com> References: <1288822429-24541-1-git-send-email-notasas@gmail.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 03 Nov 2010 22:14:12 +0000 (UTC) diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c index 0285190..0a5db21 100644 --- a/drivers/net/wireless/wl1251/sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wl1251.h" @@ -173,10 +174,36 @@ static void wl1251_disable_line_irq(struct wl1251 *wl) static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable) { - if (wl->set_power) - wl->set_power(enable); + struct sdio_func *func = wl_to_func(wl); + int ret; - return 0; + if (enable) { + /* Power up the card */ + if (wl->set_power) + wl->set_power(true); + + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + } else { + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + ret = pm_runtime_put_sync(&func->dev); + if (ret < 0) + goto out; + + if (wl->set_power) + wl->set_power(false); + } + +out: + return ret; } static struct wl1251_if_operations wl1251_sdio_ops = { @@ -277,6 +304,10 @@ static int wl1251_sdio_probe(struct sdio_func *func, goto out_free_irq; sdio_set_drvdata(func, wl); + + /* Tell PM core that we don't need the card to be powered now */ + pm_runtime_put_noidle(&func->dev); + return ret; out_free_irq: @@ -298,6 +329,9 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) struct wl1251 *wl = sdio_get_drvdata(func); struct wl1251_sdio *wl_sdio = wl->if_priv; + /* Undo decrement done above in wl1271_probe */ + pm_runtime_get_noresume(&func->dev); + if (wl->irq) free_irq(wl->irq, wl); kfree(wl_sdio); @@ -309,11 +343,33 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) sdio_release_host(func); } +static int wl1251_suspend(struct device *dev) +{ + /* + * Tell MMC/SDIO core it's OK to power down the card + * (if it isn't already), but not to remove it completely + */ + return 0; +} + +static int wl1251_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wl1251_sdio_pm_ops = { + .suspend = wl1251_suspend, + .resume = wl1251_resume, +}; + static struct sdio_driver wl1251_sdio_driver = { .name = "wl1251_sdio", .id_table = wl1251_devices, .probe = wl1251_sdio_probe, .remove = __devexit_p(wl1251_sdio_remove), + .drv = { + .pm = &wl1251_sdio_pm_ops, + }, }; static int __init wl1251_sdio_init(void)