diff options
| author | Mark Brown <broonie@kernel.org> | 2015-02-07 22:16:21 -0500 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-02-07 22:16:21 -0500 |
| commit | a9877b606ceb40e5b7e08b62d5f10c65b761dcff (patch) | |
| tree | 790fe9a40eec5e3962feb30f0e0779186c089292 /drivers/regulator | |
| parent | 36818b821bde4f81a174010a529833df2a7f9087 (diff) | |
| parent | 39f802d6b6d9a922f2c7a9165f0a7a5b819a1e3f (diff) | |
Merge remote-tracking branch 'regulator/topic/core' into regulator-next
Diffstat (limited to 'drivers/regulator')
| -rw-r--r-- | drivers/regulator/core.c | 241 |
1 files changed, 111 insertions, 130 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 9c48fb32f660..43644ba52aae 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -632,30 +632,6 @@ static ssize_t regulator_bypass_show(struct device *dev, | |||
| 632 | static DEVICE_ATTR(bypass, 0444, | 632 | static DEVICE_ATTR(bypass, 0444, |
| 633 | regulator_bypass_show, NULL); | 633 | regulator_bypass_show, NULL); |
| 634 | 634 | ||
| 635 | /* | ||
| 636 | * These are the only attributes are present for all regulators. | ||
| 637 | * Other attributes are a function of regulator functionality. | ||
| 638 | */ | ||
| 639 | static struct attribute *regulator_dev_attrs[] = { | ||
| 640 | &dev_attr_name.attr, | ||
| 641 | &dev_attr_num_users.attr, | ||
| 642 | &dev_attr_type.attr, | ||
| 643 | NULL, | ||
| 644 | }; | ||
| 645 | ATTRIBUTE_GROUPS(regulator_dev); | ||
| 646 | |||
| 647 | static void regulator_dev_release(struct device *dev) | ||
| 648 | { | ||
| 649 | struct regulator_dev *rdev = dev_get_drvdata(dev); | ||
| 650 | kfree(rdev); | ||
| 651 | } | ||
| 652 | |||
| 653 | static struct class regulator_class = { | ||
| 654 | .name = "regulator", | ||
| 655 | .dev_release = regulator_dev_release, | ||
| 656 | .dev_groups = regulator_dev_groups, | ||
| 657 | }; | ||
| 658 | |||
| 659 | /* Calculate the new optimum regulator operating mode based on the new total | 635 | /* Calculate the new optimum regulator operating mode based on the new total |
| 660 | * consumer load. All locks held by caller */ | 636 | * consumer load. All locks held by caller */ |
| 661 | static void drms_uA_update(struct regulator_dev *rdev) | 637 | static void drms_uA_update(struct regulator_dev *rdev) |
| @@ -3436,126 +3412,136 @@ int regulator_mode_to_status(unsigned int mode) | |||
| 3436 | } | 3412 | } |
| 3437 | EXPORT_SYMBOL_GPL(regulator_mode_to_status); | 3413 | EXPORT_SYMBOL_GPL(regulator_mode_to_status); |
| 3438 | 3414 | ||
| 3415 | static struct attribute *regulator_dev_attrs[] = { | ||
| 3416 | &dev_attr_name.attr, | ||
| 3417 | &dev_attr_num_users.attr, | ||
| 3418 | &dev_attr_type.attr, | ||
| 3419 | &dev_attr_microvolts.attr, | ||
| 3420 | &dev_attr_microamps.attr, | ||
| 3421 | &dev_attr_opmode.attr, | ||
| 3422 | &dev_attr_state.attr, | ||
| 3423 | &dev_attr_status.attr, | ||
| 3424 | &dev_attr_bypass.attr, | ||
| 3425 | &dev_attr_requested_microamps.attr, | ||
| 3426 | &dev_attr_min_microvolts.attr, | ||
| 3427 | &dev_attr_max_microvolts.attr, | ||
| 3428 | &dev_attr_min_microamps.attr, | ||
| 3429 | &dev_attr_max_microamps.attr, | ||
| 3430 | &dev_attr_suspend_standby_state.attr, | ||
| 3431 | &dev_attr_suspend_mem_state.attr, | ||
| 3432 | &dev_attr_suspend_disk_state.attr, | ||
| 3433 | &dev_attr_suspend_standby_microvolts.attr, | ||
| 3434 | &dev_attr_suspend_mem_microvolts.attr, | ||
| 3435 | &dev_attr_suspend_disk_microvolts.attr, | ||
| 3436 | &dev_attr_suspend_standby_mode.attr, | ||
| 3437 | &dev_attr_suspend_mem_mode.attr, | ||
| 3438 | &dev_attr_suspend_disk_mode.attr, | ||
| 3439 | NULL | ||
| 3440 | }; | ||
| 3441 | |||
| 3439 | /* | 3442 | /* |
| 3440 | * To avoid cluttering sysfs (and memory) with useless state, only | 3443 | * To avoid cluttering sysfs (and memory) with useless state, only |
| 3441 | * create attributes that can be meaningfully displayed. | 3444 | * create attributes that can be meaningfully displayed. |
| 3442 | */ | 3445 | */ |
| 3443 | static int add_regulator_attributes(struct regulator_dev *rdev) | 3446 | static umode_t regulator_attr_is_visible(struct kobject *kobj, |
| 3447 | struct attribute *attr, int idx) | ||
| 3444 | { | 3448 | { |
| 3445 | struct device *dev = &rdev->dev; | 3449 | struct device *dev = kobj_to_dev(kobj); |
| 3450 | struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev); | ||
| 3446 | const struct regulator_ops *ops = rdev->desc->ops; | 3451 | const struct regulator_ops *ops = rdev->desc->ops; |
| 3447 | int status = 0; | 3452 | umode_t mode = attr->mode; |
| 3453 | |||
| 3454 | /* these three are always present */ | ||
| 3455 | if (attr == &dev_attr_name.attr || | ||
| 3456 | attr == &dev_attr_num_users.attr || | ||
| 3457 | attr == &dev_attr_type.attr) | ||
| 3458 | return mode; | ||
| 3448 | 3459 | ||
| 3449 | /* some attributes need specific methods to be displayed */ | 3460 | /* some attributes need specific methods to be displayed */ |
| 3450 | if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || | 3461 | if (attr == &dev_attr_microvolts.attr) { |
| 3451 | (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || | 3462 | if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || |
| 3452 | (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || | 3463 | (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || |
| 3453 | (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1))) { | 3464 | (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || |
| 3454 | status = device_create_file(dev, &dev_attr_microvolts); | 3465 | (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)) |
| 3455 | if (status < 0) | 3466 | return mode; |
| 3456 | return status; | 3467 | return 0; |
| 3457 | } | ||
| 3458 | if (ops->get_current_limit) { | ||
| 3459 | status = device_create_file(dev, &dev_attr_microamps); | ||
| 3460 | if (status < 0) | ||
| 3461 | return status; | ||
| 3462 | } | ||
| 3463 | if (ops->get_mode) { | ||
| 3464 | status = device_create_file(dev, &dev_attr_opmode); | ||
| 3465 | if (status < 0) | ||
| 3466 | return status; | ||
| 3467 | } | ||
| 3468 | if (rdev->ena_pin || ops->is_enabled) { | ||
| 3469 | status = device_create_file(dev, &dev_attr_state); | ||
| 3470 | if (status < 0) | ||
| 3471 | return status; | ||
| 3472 | } | ||
| 3473 | if (ops->get_status) { | ||
| 3474 | status = device_create_file(dev, &dev_attr_status); | ||
| 3475 | if (status < 0) | ||
| 3476 | return status; | ||
| 3477 | } | ||
| 3478 | if (ops->get_bypass) { | ||
| 3479 | status = device_create_file(dev, &dev_attr_bypass); | ||
| 3480 | if (status < 0) | ||
| 3481 | return status; | ||
| 3482 | } | 3468 | } |
| 3483 | 3469 | ||
| 3470 | if (attr == &dev_attr_microamps.attr) | ||
| 3471 | return ops->get_current_limit ? mode : 0; | ||
| 3472 | |||
| 3473 | if (attr == &dev_attr_opmode.attr) | ||
| 3474 | return ops->get_mode ? mode : 0; | ||
| 3475 | |||
| 3476 | if (attr == &dev_attr_state.attr) | ||
| 3477 | return (rdev->ena_pin || ops->is_enabled) ? mode : 0; | ||
| 3478 | |||
| 3479 | if (attr == &dev_attr_status.attr) | ||
| 3480 | return ops->get_status ? mode : 0; | ||
| 3481 | |||
| 3482 | if (attr == &dev_attr_bypass.attr) | ||
| 3483 | return ops->get_bypass ? mode : 0; | ||
| 3484 | |||
| 3484 | /* some attributes are type-specific */ | 3485 | /* some attributes are type-specific */ |
| 3485 | if (rdev->desc->type == REGULATOR_CURRENT) { | 3486 | if (attr == &dev_attr_requested_microamps.attr) |
| 3486 | status = device_create_file(dev, &dev_attr_requested_microamps); | 3487 | return rdev->desc->type == REGULATOR_CURRENT ? mode : 0; |
| 3487 | if (status < 0) | ||
| 3488 | return status; | ||
| 3489 | } | ||
| 3490 | 3488 | ||
| 3491 | /* all the other attributes exist to support constraints; | 3489 | /* all the other attributes exist to support constraints; |
| 3492 | * don't show them if there are no constraints, or if the | 3490 | * don't show them if there are no constraints, or if the |
| 3493 | * relevant supporting methods are missing. | 3491 | * relevant supporting methods are missing. |
| 3494 | */ | 3492 | */ |
| 3495 | if (!rdev->constraints) | 3493 | if (!rdev->constraints) |
| 3496 | return status; | 3494 | return 0; |
| 3497 | 3495 | ||
| 3498 | /* constraints need specific supporting methods */ | 3496 | /* constraints need specific supporting methods */ |
| 3499 | if (ops->set_voltage || ops->set_voltage_sel) { | 3497 | if (attr == &dev_attr_min_microvolts.attr || |
| 3500 | status = device_create_file(dev, &dev_attr_min_microvolts); | 3498 | attr == &dev_attr_max_microvolts.attr) |
| 3501 | if (status < 0) | 3499 | return (ops->set_voltage || ops->set_voltage_sel) ? mode : 0; |
| 3502 | return status; | 3500 | |
| 3503 | status = device_create_file(dev, &dev_attr_max_microvolts); | 3501 | if (attr == &dev_attr_min_microamps.attr || |
| 3504 | if (status < 0) | 3502 | attr == &dev_attr_max_microamps.attr) |
| 3505 | return status; | 3503 | return ops->set_current_limit ? mode : 0; |
| 3506 | } | 3504 | |
| 3507 | if (ops->set_current_limit) { | 3505 | if (attr == &dev_attr_suspend_standby_state.attr || |
| 3508 | status = device_create_file(dev, &dev_attr_min_microamps); | 3506 | attr == &dev_attr_suspend_mem_state.attr || |
| 3509 | if (status < 0) | 3507 | attr == &dev_attr_suspend_disk_state.attr) |
| 3510 | return status; | 3508 | return mode; |
| 3511 | status = device_create_file(dev, &dev_attr_max_microamps); | ||
