Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165379
b: refs/heads/master
c: 5ffbd13
h: refs/heads/master
i:
  165377: 34a1ba1
  165375: f5d0b40
v: v3
  • Loading branch information
Mark Brown authored and Liam Girdwood committed Sep 22, 2009
1 parent d1ceff6 commit 906e6a7
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c1b60873ca2078bfca94b73bc88ef1c5adcc928b
refs/heads/master: 5ffbd136e6c51c8d1eec7a4a0c5d2180c81aea30
88 changes: 74 additions & 14 deletions trunk/drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,25 +1025,15 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
return NULL;
}

/**
* regulator_get - lookup and obtain a reference 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.
*
* 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(struct device *dev, const char *id)
/* Internal regulator request function */
static struct regulator *_regulator_get(struct device *dev, const char *id,
int exclusive)
{
struct regulator_dev *rdev;
struct regulator_map *map;
struct regulator *regulator = ERR_PTR(-ENODEV);
const char *devname = NULL;
int ret;

if (id == NULL) {
printk(KERN_ERR "regulator: get() with no identifier\n");
Expand All @@ -1070,6 +1060,16 @@ struct regulator *regulator_get(struct device *dev, const char *id)
return regulator;

found:
if (rdev->exclusive) {
regulator = ERR_PTR(-EPERM);
goto out;
}

if (exclusive && rdev->open_count) {
regulator = ERR_PTR(-EBUSY);
goto out;
}

if (!try_module_get(rdev->owner))
goto out;

Expand All @@ -1079,12 +1079,69 @@ struct regulator *regulator_get(struct device *dev, const char *id)
module_put(rdev->owner);
}

rdev->open_count++;
if (exclusive) {
rdev->exclusive = 1;

ret = _regulator_is_enabled(rdev);
if (ret > 0)
rdev->use_count = 1;
else
rdev->use_count = 0;
}

out:
mutex_unlock(&regulator_list_mutex);

return regulator;
}

/**
* regulator_get - lookup and obtain a reference 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.
*
* 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(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 0);
}
EXPORT_SYMBOL_GPL(regulator_get);

/**
* regulator_get_exclusive - obtain exclusive 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 which cannot tolerate shared
* use of the regulator such as those which need to force the
* regulator off for correct operation of the hardware they are
* controlling.
*
* 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_exclusive(struct device *dev, const char *id)
{
return _regulator_get(dev, id, 1);
}
EXPORT_SYMBOL_GPL(regulator_get_exclusive);

/**
* regulator_put - "free" the regulator source
* @regulator: regulator source
Expand Down Expand Up @@ -1113,6 +1170,9 @@ void regulator_put(struct regulator *regulator)
list_del(&regulator->list);
kfree(regulator);

rdev->open_count--;
rdev->exclusive = 0;

module_put(rdev->owner);
mutex_unlock(&regulator_list_mutex);
}
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/regulator/consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ struct regulator_bulk_data {
/* regulator get and put */
struct regulator *__must_check regulator_get(struct device *dev,
const char *id);
struct regulator *__must_check regulator_get_exclusive(struct device *dev,
const char *id);
void regulator_put(struct regulator *regulator);

/* regulator output control and status */
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/regulator/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ struct regulator_desc {
struct regulator_dev {
struct regulator_desc *desc;
int use_count;
int open_count;
int exclusive;

/* lists we belong to */
struct list_head list; /* list of all regulators */
Expand Down

0 comments on commit 906e6a7

Please sign in to comment.