From patchwork Mon May 23 15:10:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Ospite X-Patchwork-Id: 809062 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p4NFAdww011768 for ; Mon, 23 May 2011 15:10:39 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755671Ab1EWPKi (ORCPT ); Mon, 23 May 2011 11:10:38 -0400 Received: from smtp206.alice.it ([82.57.200.102]:39857 "EHLO smtp206.alice.it" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755436Ab1EWPKi (ORCPT ); Mon, 23 May 2011 11:10:38 -0400 Received: from jcn (87.6.146.159) by smtp206.alice.it (8.5.124.08) (authenticated as fospite@alice.it) id 4D49918D09905564; Mon, 23 May 2011 17:10:32 +0200 Date: Mon, 23 May 2011 17:10:23 +0200 From: Antonio Ospite To: Mark Brown Cc: linux-mmc@vger.kernel.org, Chris Ball , Grant Likely , openezx-devel@lists.openezx.org, spi-devel-general@lists.sourceforge.net Subject: Re: [PATCH v3] mmc_spi.c: add support for the regulator framework Message-Id: <20110523171023.4df5af10.ospite@studenti.unina.it> In-Reply-To: <20110518194211.GA5077@opensource.wolfsonmicro.com> References: <1303476191-20663-1-git-send-email-ospite@studenti.unina.it> <1305110379-17218-1-git-send-email-ospite@studenti.unina.it> <20110511130852.GB12469@opensource.wolfsonmicro.com> <20110511225337.094839a2.ospite@studenti.unina.it> <20110511205703.GA24486@opensource.wolfsonmicro.com> <20110518192320.9dd69cb5.ospite@studenti.unina.it> <20110518194211.GA5077@opensource.wolfsonmicro.com> X-Mailer: Sylpheed 3.1.1 (GTK+ 2.24.4; x86_64-pc-linux-gnu) X-Face: z*RaLf`X<@C75u6Ig9}{oW$H; 1_\2t5)({*|jhM/Vb; ]yA5\I~93>J<_`<4)A{':UrE Mime-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 23 May 2011 15:10:39 +0000 (UTC) On Wed, 18 May 2011 12:42:12 -0700 Mark Brown wrote: > On Wed, May 18, 2011 at 07:23:20PM +0200, Antonio Ospite wrote: > [...] > > 2. Add a proper function with all the needed parameters to abstract > > the actual var names, this would be something like: > > mmc_regulator_set_power(mmc, power_mode, vdd, vcc, pdata) > > and yet checking for pdata->setpower can be tricky as 'setpower' > > is an arbitrary name. > > This would be good. A WIP patch, I don't have a lot of time to spend on this, I tried to handle the driver specific 'setpower' callback with a macro, let me know if you have a better idea: diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index bcb793e..dbbe535 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -298,6 +298,32 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc, } #endif +#define STRUCT_FIELD(s, f) ((s) && (s)->f ? (s)->f : NULL ) + +static inline int mmc_regulator_set_power(struct mmc_host *mmc, + unsigned char power_mode, + struct regulator *supply, + unsigned short vdd_bit, + struct device *device, + void (*setpower_cb)(struct device *, unsigned int)) +{ + if (supply) { + int ret; + + if (power_mode == MMC_POWER_OFF) + vdd_bit = 0; + + ret = mmc_regulator_set_ocr(mmc, supply, vdd_bit); + if (ret) + return ret; + } else { + if (setpower_cb) + setpower_cb(device, vdd_bit); + } + + return 0; +} + int mmc_card_awake(struct mmc_host *host); int mmc_card_sleep(struct mmc_host *host); int mmc_card_can_sleep(struct mmc_host *host); diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 2e8db20..c9a229f 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1231,21 +1231,18 @@ static inline int mmc_spi_setpower(struct mmc_spi_host *host, unsigned char power_mode, unsigned int vdd) { + int ret; + if (!mmc_spi_canpower(host)) return -ENOSYS; - if (host->vcc) { - int ret; - if (power_mode == MMC_POWER_OFF) - vdd = 0; + ret = mmc_regulator_set_power(host->mmc, power_mode, host->vcc, vdd, + &host->spi->dev, + STRUCT_FIELD(host->pdata, setpower)); + if (ret) + return ret; - ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); - if (ret) - return ret; - } else { - host->pdata->setpower(&host->spi->dev, vdd); - } if (power_mode == MMC_POWER_UP) msleep(host->powerup_msecs); diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index fbdb21e..f5d9529 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c @@ -103,29 +103,20 @@ static inline int pxamci_set_power(struct pxamci_host *host, unsigned int vdd) { int on; + int ret; - if (host->vcc) { - int ret; + ret = mmc_regulator_set_power(host->mmc, power_mode, host->vcc, vdd, + mmc_dev(host->mmc), + STRUCT_FIELD(host->pdata, setpower)); + if (ret) + return ret; - if (power_mode == MMC_POWER_UP) { - ret = mmc_regulator_set_ocr(host->mmc, host->vcc, vdd); - if (ret) - return ret; - } else if (power_mode == MMC_POWER_OFF) { - ret = mmc_regulator_set_ocr(host->mmc, host->vcc, 0); - if (ret) - return ret; - } - } if (!host->vcc && host->pdata && gpio_is_valid(host->pdata->gpio_power)) { on = ((1 << vdd) & host->pdata->ocr_mask); gpio_set_value(host->pdata->gpio_power, !!on ^ host->pdata->gpio_power_invert); } - if (!host->vcc && host->pdata && host->pdata->setpower) - host->pdata->setpower(mmc_dev(host->mmc), vdd); - return 0; }