From: Mark Brown <broonie(a)linaro.org>
Many regulators have several linear ranges of selector with different
step sizes, for example offering better resolution at lower voltages.
Provide regulator_{map,list}_voltage_linear_range() allowing these
regulators to use generic code. To do so a table of regulator_linear_range
structs needs to be pointed to from the descriptor.
This was inspired by similar code included in a driver submission from
Chao Xie and Yi Zhang at Marvell.
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
drivers/regulator/core.c | 87 ++++++++++++++++++++++++++++++++++++++++
include/linux/regulator/driver.h | 25 ++++++++++++
2 files changed, 112 insertions(+)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 288c75a..e8604be 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2079,6 +2079,43 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev,
EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
/**
+ * regulator_list_voltage_linear_range - List voltages for linear ranges
+ *
+ * @rdev: Regulator device
+ * @selector: Selector to convert into a voltage
+ *
+ * Regulators with a series of simple linear mappings between voltages
+ * and selectors can set linear_ranges in the regulator descriptor and
+ * then use this function as their list_voltage() operation,
+ */
+int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ const struct regulator_linear_range *range;
+ int i;
+
+ if (!rdev->desc->n_linear_ranges) {
+ BUG_ON(!rdev->desc->n_linear_ranges);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
+ range = &rdev->desc->linear_ranges[i];
+
+ if (!(selector >= range->min_sel &&
+ selector <= range->max_sel))
+ continue;
+
+ selector -= range->min_sel;
+
+ return range->min_uV + (range->uV_step * selector);
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
+
+/**
* regulator_list_voltage_table - List voltages with table based mapping
*
* @rdev: Regulator device
@@ -2368,6 +2405,56 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev,
}
EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
+/**
+ * regulator_map_voltage_linear - map_voltage() for multiple linear ranges
+ *
+ * @rdev: Regulator to operate on
+ * @min_uV: Lower bound for voltage
+ * @max_uV: Upper bound for voltage
+ *
+ * Drivers providing linear_ranges in their descriptor can use this as
+ * their map_voltage() callback.
+ */
+int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ const struct regulator_linear_range *range;
+ int ret = -EINVAL;
+ int voltage, i;
+
+ if (!rdev->desc->n_linear_ranges) {
+ BUG_ON(!rdev->desc->n_linear_ranges);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
+ range = &rdev->desc->linear_ranges[i];
+
+ if (!(min_uV <= range->max_uV && max_uV >= range->min_uV))
+ continue;
+
+ if (min_uV <= range->min_uV)
+ min_uV = range->min_uV;
+
+ ret = DIV_ROUND_UP(min_uV - range->min_uV, range->uV_step);
+ if (ret < 0)
+ return ret;
+
+ break;
+ }
+
+ if (i == rdev->desc->n_linear_ranges)
+ return -EINVAL;
+
+ /* Map back into a voltage to verify we're still in bounds */
+ voltage = rdev->desc->ops->list_voltage(rdev, ret);
+ if (voltage < min_uV || voltage > max_uV)
+ return -EINVAL;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
+
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 6700cc9..67e13aa 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -40,6 +40,24 @@ enum regulator_status {
};
/**
+ * Specify a range of voltages for regulator_map_linar_range() and
+ * regulator_list_linear_range().
+ *
+ * @min_uV: Lowest voltage in range
+ * @max_uV: Highest voltage in range
+ * @min_sel: Lowest selector for range
+ * @max_sel: Highest selector for range
+ * @uV_step: Step size
+ */
+struct regulator_linear_range {
+ unsigned int min_uV;
+ unsigned int max_uV;
+ unsigned int min_sel;
+ unsigned int max_sel;
+ unsigned int uV_step;
+};
+
+/**
* struct regulator_ops - regulator operations.
*
* @enable: Configure the regulator as enabled.
@@ -223,6 +241,9 @@ struct regulator_desc {
unsigned int linear_min_sel;
unsigned int ramp_delay;
+ const struct regulator_linear_range *linear_ranges;
+ int n_linear_ranges;
+
const unsigned int *volt_table;
unsigned int vsel_reg;
@@ -326,10 +347,14 @@ int regulator_mode_to_status(unsigned int);
int regulator_list_voltage_linear(struct regulator_dev *rdev,
unsigned int selector);
+int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
+ unsigned int selector);
int regulator_list_voltage_table(struct regulator_dev *rdev,
unsigned int selector);
int regulator_map_voltage_linear(struct regulator_dev *rdev,
int min_uV, int max_uV);
+int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
+ int min_uV, int max_uV);
int regulator_map_voltage_iterate(struct regulator_dev *rdev,
int min_uV, int max_uV);
int regulator_map_voltage_ascend(struct regulator_dev *rdev,
--
1.8.3.1
Commit 7c30ed ("cpufreq: make sure frequency transitions are serialized")
interacts poorly with systems that have a single core freqency for all
cores. On such systems we have a single policy for all cores with
several CPUs. When we do a frequency transition the governor calls the
pre and post change notifiers which causes cpufreq_notify_transition()
per CPU. Since the policy is the same for all of them all CPUs after
the first and the warnings added are generated by checking a per-policy
flag the warnings will be triggered for all cores after the first.
Fix this by allowing notifier to be called for n times. Where n is the number of
cpus in policy->cpus.
Reported-and-Tested-by: Mark Brown <broonie(a)linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
Hi Rafael,
This is a fix for 3.11.
drivers/cpufreq/cpufreq.c | 7 ++++---
include/linux/cpufreq.h | 2 +-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index b557503..b7bda8d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -312,11 +312,12 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
switch (state) {
case CPUFREQ_PRECHANGE:
- if (WARN(policy->transition_ongoing,
+ if (WARN(policy->transition_ongoing ==
+ cpumask_weight(policy->cpus),
"In middle of another frequency transition\n"))
return;
- policy->transition_ongoing = true;
+ policy->transition_ongoing++;
/* detect if the driver reported a value as "old frequency"
* which is not equal to what the cpufreq core thinks is
@@ -341,7 +342,7 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
"No frequency transition in progress\n"))
return;
- policy->transition_ongoing = false;
+ policy->transition_ongoing--;
adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 4d7390b..90d5a15 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -119,7 +119,7 @@ struct cpufreq_policy {
struct kobject kobj;
struct completion kobj_unregister;
- bool transition_ongoing; /* Tracks transition status */
+ int transition_ongoing; /* Tracks transition status */
};
#define CPUFREQ_ADJUST (0)
--
1.7.12.rc2.18.g61b472e
Hi all,
Just wanted to make sure everyone interested in virtualization
was aware that we are bootstrapping a VIRTIO Technical Committee over at
OASIS. All welcome!
http://www.oasis-open.org/committees/virtio
Cheers,
Rusty.
Enable the Versatile Express voltage regulators by default.
This should work on all verstatile express platforms and not enabling it
prevents a defconfig'ed kernel from using the SD card controller on the
qemu emulated platform, which is unfortunate for first-time casual
users.
Cc: Peter Maydell <peter.maydell(a)linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall(a)linaro.org>
---
arch/arm/configs/vexpress_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
index f2de51f..17104d9 100644
--- a/arch/arm/configs/vexpress_defconfig
+++ b/arch/arm/configs/vexpress_defconfig
@@ -138,3 +138,6 @@ CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_VEXPRESS=y
--
1.7.9.5
From: Naresh Bhat <naresh.bhat(a)linaro.org>
CC drivers/acpi/fan.o
drivers/acpi/fan.c: In function ‘fan_get_cur_state’:
drivers/acpi/fan.c:96:9: warning: ‘acpi_state’ may be used uninitialized in this function [-Wuninitialized]
---
drivers/acpi/fan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index f815da8..f961435 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -84,7 +84,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
{
struct acpi_device *device = cdev->devdata;
int result;
- int acpi_state;
+ int acpi_state = ACPI_STATE_D0;
if (!device)
return -EINVAL;
--
1.7.9.5
On 10 October 2012 19:37, Viresh Kumar <viresh.kumar(a)linaro.org> wrote:
> On 10 October 2012 19:14, Sudeep KarkadaNagesha
> <Sudeep.KarkadaNagesha(a)arm.com> wrote:
>> Here is my understanding on this patch. This change is closely related
>> to ACPI cpufreq driver(used mostly on Intel cores). This change was
>> introduced to keep track of the related cpus as returned by ACPI
>> firmware along with affected cpus as imposed by SW. I don't understand
>> the exact difference in Intel cores.
>> I believe it's just for tracking and not used much in the driver.
>
> Then i believe we shouldn't fill the related_cpus field for ARM cores. As anyway
> the show_related_cpus will pick affected cpus in that case.
Ahh, I was searching for something in my Archives and found this old
unanswered mail. As I have understood the difference between between
these two variables (affected and related cpus) now until this happened:
951fc5f4 (in v3.9). I thought it would be good to bury the actual answers
somewhere in Archives so that somebody looking for the answer can find
it easily.
What it was:
Affected CPUs: List of CPUs which share clock domain and s/w was responsible
to managing these.
Related CPUs: List of CPUs which share clock domain and only h/w was
responsible for managing these.
What do we mean by software and hardware managed stuff?
It was specific for acpi-cpufreq driver and nobody else :)
The firmware below kernel layer for hardware using this driver wanted to
manage cpus (sharing clock domain) by itself. i.e. It wanted the actual freq
request to go to it, it will then pick the highest freq requested for a clock
domain and set it for all cpus under policy->cpus. But kernel wouldn't know
these details at all. CPUFreq core would think that these cores don't
actually share clock line and so are independent.
Then there were some user space applications (like DVFS controllers),
which wanted to know the exact hardware coordination details rather than
what is present with cpufreq core. And so related_cpus was created for
them with this commit: e8628dd06d66f2e3965ec9742029b401d63434f1
related_cpus wasn't used in making kernel decisions at all and was only
for the applications who want to know exact hardware details.
As it didn't make sense to keep acpi-cpufreq specific stuff in CPUFreq core,
it was eventually moved into acpi-cpufreq driver with the name:
freqdomain_cpus in 3.11. related_cpus was kept in kernel but its meaning
is now changed.
affected_cpus: List of Online CPUs that require software coordination
of frequency.
related_cpus: List of Online + Offline CPUs that need software
coordination of frequency.
--
viresh
There has long been a syntax problem in iop3xx_i2c_wait_event() which
has been somehow hidden by the macros in <linux/wait.h>. After some
recent cleanup/rework of the wait_event_* helpers, the bug has come
out from hiding and now results in build failure:
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c: In function 'iop3xx_i2c_wait_event':
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:143: error: expected ')' before ';' token
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:157: error: expected ')' before ';' token
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:213: error: expected ')' before ';' token
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:291: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:551: error: expected ')' before ';' token
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:565: error: expected ')' before ';' token
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:764: error: expected ')' before ';' token
/work/kernel/next/drivers/i2c/busses/i2c-iop3xx.c:176:778: error: expected ')' b
Fix by removing stray ';'
Signed-off-by: Kevin Hilman <khilman(a)linaro.org>
---
Discovered in new build failure of iop32xx_defconfig with next-20130628
drivers/i2c/busses/i2c-iop3xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index bc99333..dd24aa0 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -176,7 +176,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
interrupted = wait_event_interruptible_timeout (
iop3xx_adap->waitq,
(done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
- 1 * HZ;
+ 1 * HZ
);
if ((rc = iop3xx_i2c_error(sr)) < 0) {
*status = sr;
--
1.8.3