From f4223ec219313d631c3f620220ed23670c158a34 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 14 Mar 2009 19:08:30 +0000 Subject: [PATCH] Overo broken after recent mainline merge Make the regulator setup code simpler and more consistent: - The only difference between "boot_on" and "always_on" is that an "always_on" regulator won't be disabled. Both will be active (and usecount will be 1) on return from setup. - Regulators not marked as "boot_on" or "always_on" won't be active (and usecount will be 0) on return from setup. The exception to that simple policy is when there's a non-Linux interface to the regulator ... e.g. if either a DSP or the CPU running Linux can enable the regulator, and the DSP needs it to be on, then it will be on. Signed-off-by: David Brownell Signed-off-by: Tony Lindgren --- drivers/regulator/core.c | 47 ++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 0f7cb38b069..b9de72c8fa8 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -711,6 +711,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, int ret = 0; const char *name; struct regulator_ops *ops = rdev->desc->ops; + int enable = 0; if (constraints->name) name = constraints->name; @@ -799,10 +800,6 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } - /* are we enabled at boot time by firmware / bootloader */ - if (rdev->constraints->boot_on) - rdev->use_count = 1; - /* do we need to setup our suspend state */ if (constraints->initial_state) { ret = suspend_prepare(rdev, constraints->initial_state); @@ -814,21 +811,39 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } - /* if always_on is set then turn the regulator on if it's not - * already on. */ - if (constraints->always_on && ops->enable && - ((ops->is_enabled && !ops->is_enabled(rdev)) || - (!ops->is_enabled && !constraints->boot_on))) { - ret = ops->enable(rdev); - if (ret < 0) { - printk(KERN_ERR "%s: failed to enable %s\n", - __func__, name); - rdev->constraints = NULL; - goto out; + /* Should this be enabled when we return from here? The difference + * between "boot_on" and "always_on" is that "always_on" regulators + * won't ever be disabled. + */ + if (constraints->boot_on || constraints->always_on) + enable = 1; + + /* Make sure the regulator isn't wrongly enabled or disabled. + * Bootloaders are often sloppy about leaving things on; and + * sometimes Linux wants to use a different model. + */ + if (enable) { + if (ops->enable) { + ret = ops->enable(rdev); + if (ret < 0) + pr_warning("%s: %s disable --> %d\n", + __func__, name, ret); + } + if (ret >= 0) + rdev->use_count = 1; + } else { + if (ops->disable) { + ret = ops->disable(rdev); + if (ret < 0) + pr_warning("%s: %s disable --> %d\n", + __func__, name, ret); } } - print_constraints(rdev); + if (ret < 0) + rdev->constraints = NULL; + else + print_constraints(rdev); out: return ret; } -- 2.41.0