Skip to content

Commit

Permalink
Merge remote-tracking branch 'regulator/topic/optional' into regulato…
Browse files Browse the repository at this point in the history
…r-next
  • Loading branch information
broonie committed Sep 1, 2013
2 parents 6979380 + 9efdd27 commit f27a5fb
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 7 deletions.
2 changes: 1 addition & 1 deletion drivers/cpufreq/cpufreq-cpu0.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
cpu_dev = &pdev->dev;
cpu_dev->of_node = np;

cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
cpu_reg = devm_regulator_get_optional(cpu_dev, "cpu0");
if (IS_ERR(cpu_reg)) {
/*
* If cpu0 regulator supply node is present, but regulator is
Expand Down
2 changes: 1 addition & 1 deletion drivers/hwmon/sht15.c
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ static int sht15_probe(struct platform_device *pdev)
* If a regulator is available,
* query what the supply voltage actually is!
*/
data->reg = devm_regulator_get(data->dev, "vcc");
data->reg = devm_regulator_get_optional(data->dev, "vcc");
if (!IS_ERR(data->reg)) {
int voltage;

Expand Down
2 changes: 1 addition & 1 deletion drivers/mmc/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,7 @@ int mmc_regulator_get_supply(struct mmc_host *mmc)

supply = devm_regulator_get(dev, "vmmc");
mmc->supply.vmmc = supply;
mmc->supply.vqmmc = devm_regulator_get(dev, "vqmmc");
mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");

if (IS_ERR(supply))
return PTR_ERR(supply);
Expand Down
2 changes: 1 addition & 1 deletion drivers/mmc/host/dw_mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2231,7 +2231,7 @@ int dw_mci_probe(struct dw_mci *host)
}
}

host->vmmc = devm_regulator_get(host->dev, "vmmc");
host->vmmc = devm_regulator_get_optional(host->dev, "vmmc");
if (IS_ERR(host->vmmc)) {
ret = PTR_ERR(host->vmmc);
if (ret == -EPROBE_DEFER)
Expand Down
2 changes: 1 addition & 1 deletion drivers/mmc/host/pxamci.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct pxamci_host {
static inline void pxamci_init_ocr(struct pxamci_host *host)
{
#ifdef CONFIG_REGULATOR
host->vcc = regulator_get(mmc_dev(host->mmc), "vmmc");
host->vcc = regulator_get_optional(mmc_dev(host->mmc), "vmmc");

if (IS_ERR(host->vcc))
host->vcc = NULL;
Expand Down
4 changes: 2 additions & 2 deletions drivers/mmc/host/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2966,7 +2966,7 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->caps |= MMC_CAP_NEEDS_POLL;

/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
host->vqmmc = regulator_get_optional(mmc_dev(mmc), "vqmmc");
if (IS_ERR_OR_NULL(host->vqmmc)) {
if (PTR_ERR(host->vqmmc) < 0) {
pr_info("%s: no vqmmc regulator found\n",
Expand Down Expand Up @@ -3042,7 +3042,7 @@ int sdhci_add_host(struct sdhci_host *host)

ocr_avail = 0;

host->vmmc = regulator_get(mmc_dev(mmc), "vmmc");
host->vmmc = regulator_get_optional(mmc_dev(mmc), "vmmc");
if (IS_ERR_OR_NULL(host->vmmc)) {
if (PTR_ERR(host->vmmc) < 0) {
pr_info("%s: no vmmc regulator found\n",
Expand Down
89 changes: 89 additions & 0 deletions drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,65 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id)
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);

/**
* regulator_get_optional - obtain optional access to a regulator.
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
* or IS_ERR() condition containing errno. Other consumers will be
* unable to obtain this reference is held and the use count for the
* regulator will be initialised to reflect the current state of the
* regulator.
*
* This is intended for use by consumers for devices which can have
* some supplies unconnected in normal use, such as some MMC devices.
* It can allow the regulator core to provide stub supplies for other
* supplies requested using normal regulator_get() calls without
* disrupting the operation of drivers that can handle absent
* supplies.
*
* Use of supply names configured via regulator_set_device_supply() is
* strongly encouraged. It is recommended that the supply name used
* should match the name used for the supply and/or the relevant
* device pins in the datasheet.
*/
struct regulator *regulator_get_optional(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 0);
}
EXPORT_SYMBOL_GPL(regulator_get_optional);

/**
* devm_regulator_get_optional - Resource managed regulator_get_optional()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get_optional(). Regulators returned from this
* function are automatically regulator_put() on driver detach. See
* regulator_get_optional() for more information.
*/
struct regulator *devm_regulator_get_optional(struct device *dev,
const char *id)
{
struct regulator **ptr, *regulator;

ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);

regulator = regulator_get_optional(dev, id);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}

return regulator;
}
EXPORT_SYMBOL_GPL(devm_regulator_get_optional);

/* Locks held by regulator_put() */
static void _regulator_put(struct regulator *regulator)
{
Expand All @@ -1438,6 +1497,36 @@ static void _regulator_put(struct regulator *regulator)
module_put(rdev->owner);
}

/**
* devm_regulator_get_exclusive - Resource managed regulator_get_exclusive()
* @dev: device for regulator "consumer"
* @id: Supply name or regulator ID.
*
* Managed regulator_get_exclusive(). Regulators returned from this function
* are automatically regulator_put() on driver detach. See regulator_get() for
* more information.
*/
struct regulator *devm_regulator_get_exclusive(struct device *dev,
const char *id)
{
struct regulator **ptr, *regulator;

ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);

regulator = _regulator_get(dev, id, 1);
if (!IS_ERR(regulator)) {
*ptr = regulator;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}

return regulator;
}
EXPORT_SYMBOL_GPL(devm_regulator_get_exclusive);

/**
* regulator_put - "free" the regulator source
* @regulator: regulator source
Expand Down
25 changes: 25 additions & 0 deletions include/linux/regulator/consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ struct regulator *__must_check devm_regulator_get(struct device *dev,
const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
const char *id);
struct regulator *__must_check devm_regulator_get_exclusive(struct device *dev,
const char *id);
struct regulator *__must_check regulator_get_optional(struct device *dev,
const char *id);
struct regulator *__must_check devm_regulator_get_optional(struct device *dev,
const char *id);
void regulator_put(struct regulator *regulator);
void devm_regulator_put(struct regulator *regulator);

Expand Down Expand Up @@ -217,6 +223,25 @@ devm_regulator_get(struct device *dev, const char *id)
return NULL;
}

static inline struct regulator *__must_check
regulator_get_exclusive(struct device *dev, const char *id)
{
return NULL;
}

static inline struct regulator *__must_check
regulator_get_optional(struct device *dev, const char *id)
{
return NULL;
}


static inline struct regulator *__must_check
devm_regulator_get_optional(struct device *dev, const char *id)
{
return NULL;
}

static inline void regulator_put(struct regulator *regulator)
{
}
Expand Down

0 comments on commit f27a5fb

Please sign in to comment.