'dev_id' in the comments of clk_register_clkdev should
be 'dev_fmt' here.
Signed-off-by: Hanjun Guo <hanjun.guo(a)linaro.org>
---
drivers/clk/clkdev.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 442a313..825b52b 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -270,9 +270,9 @@ EXPORT_SYMBOL(clkdev_drop);
* clk_register_clkdev - register one clock lookup for a struct clk
* @clk: struct clk to associate with all clk_lookups
* @con_id: connection ID string on device
- * @dev_id: format string describing device name
+ * @dev_fmt: format string describing device name
*
- * con_id or dev_id may be NULL as a wildcard, just as in the rest of
+ * con_id or dev_fmt may be NULL as a wildcard, just as in the rest of
* clkdev.
*
* To make things easier for mass registration, we detect error clks
--
1.7.9.5
policy->cur is now set by cpufreq core when cpufreq_driver->get() is defined and
so drivers aren't required to set it. When space_id is ACPI_ADR_SPACE_SYSTEM_IO
for acpi cpufreq driver it doesn't set ->get to a valid function pointer and so
policy->cur is required to be set by driver.
This is already followed in acpi-cpufreq driver. This patch adds a comment
describing why we need to set policy->cur from driver.
Suggested-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
This change was requested by Rafael here:
http://www.spinics.net/lists/linux-acpi/msg46748.html
drivers/cpufreq/acpi-cpufreq.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index a8dac7b..8ecd74e 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -838,6 +838,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
switch (perf->control_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
/* Current speed is unknown and not detectable by IO port */
+ /* ->cur wouldn't be set by core as ->get() is NULL */
policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
break;
case ACPI_ADR_SPACE_FIXED_HARDWARE:
--
1.7.12.rc2.18.g61b472e
Adds GPLL, APLL, KPLL, EPLL and VPLL freq table for exynos5420 and exynos5250.
changes since v1:
- addressed comments from Tomasz Figa <tomasz.figa(a)gmail.com>
is rebased on Mike's
https://git.linaro.org/gitweb?p=people/mturquette/linux.git;a=shortlog;h=re…
and on top of Tomasz Figa's clk clean-up patch series
http://www.spinics.net/lists/arm-kernel/msg269848.html
Vikas Sajjan (2):
clk: samsung: Add GPLL freq table for exynos5250 SoC
clk: samsung: Add APLL, KPLL, EPLL and VPLL freq table for exynos5420
SoC
drivers/clk/samsung/clk-exynos5250.c | 19 ++++++++-
drivers/clk/samsung/clk-exynos5420.c | 78 ++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+), 1 deletion(-)
--
1.7.9.5
We have per-CPU cpu_policy_rwsem for cpufreq core, but we never use
all of them. We always use rwsem of policy->cpu and so we can
actually make this rwsem per policy instead.
This patch does this change. With this change other tricky situations
are also avoided now, like which lock to take while we are changing
policy->cpu, etc.
Suggested-by: Srivatsa S. Bhat <srivatsa.bhat(a)linux.vnet.ibm.com>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
Reviewed-by: Srivatsa S. Bhat <srivatsa.bhat(a)linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
---
I thought I should send it formally as well. Though Andrew hasn't given his
tested by until now. Rebased over your bleeding-edge branch.
drivers/cpufreq/cpufreq.c | 110 +++++++++++++---------------------------------
include/linux/cpufreq.h | 14 ++++++
2 files changed, 45 insertions(+), 79 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index ec391d7..3f03dcb 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -48,47 +48,6 @@ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
#endif
/*
- * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
- * all cpufreq/hotplug/workqueue/etc related lock issues.
- *
- * The rules for this semaphore:
- * - Any routine that wants to read from the policy structure will
- * do a down_read on this semaphore.
- * - Any routine that will write to the policy structure and/or may take away
- * the policy altogether (eg. CPU hotplug), will hold this lock in write
- * mode before doing so.
- *
- * Additional rules:
- * - Governor routines that can be called in cpufreq hotplug path should not
- * take this sem as top level hotplug notifier handler takes this.
- * - Lock should not be held across
- * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
- */
-static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
-
-#define lock_policy_rwsem(mode, cpu) \
-static void lock_policy_rwsem_##mode(int cpu) \
-{ \
- struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \
- BUG_ON(!policy); \
- down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \
-}
-
-lock_policy_rwsem(read, cpu);
-lock_policy_rwsem(write, cpu);
-
-#define unlock_policy_rwsem(mode, cpu) \
-static void unlock_policy_rwsem_##mode(int cpu) \
-{ \
- struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \
- BUG_ON(!policy); \
- up_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \
-}
-
-unlock_policy_rwsem(read, cpu);
-unlock_policy_rwsem(write, cpu);
-
-/*
* rwsem to guarantee that cpufreq driver module doesn't unload during critical
* sections
*/
@@ -683,14 +642,14 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
if (!down_read_trylock(&cpufreq_rwsem))
return -EINVAL;
- lock_policy_rwsem_read(policy->cpu);
+ down_read(&policy->rwsem);
if (fattr->show)
ret = fattr->show(policy, buf);
else
ret = -EIO;
- unlock_policy_rwsem_read(policy->cpu);
+ up_read(&policy->rwsem);
up_read(&cpufreq_rwsem);
return ret;
@@ -711,14 +670,14 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
if (!down_read_trylock(&cpufreq_rwsem))
goto unlock;
- lock_policy_rwsem_write(policy->cpu);
+ down_write(&policy->rwsem);
if (fattr->store)
ret = fattr->store(policy, buf, count);
else
ret = -EIO;
- unlock_policy_rwsem_write(policy->cpu);
+ up_write(&policy->rwsem);
up_read(&cpufreq_rwsem);
unlock:
@@ -895,7 +854,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
}
}
- lock_policy_rwsem_write(policy->cpu);
+ down_write(&policy->rwsem);
write_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -903,7 +862,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
per_cpu(cpufreq_cpu_data, cpu) = policy;
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
- unlock_policy_rwsem_write(policy->cpu);
+ up_write(&policy->rwsem);
if (has_target) {
if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
@@ -950,6 +909,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
goto err_free_cpumask;
INIT_LIST_HEAD(&policy->policy_list);
+ init_rwsem(&policy->rwsem);
+
return policy;
err_free_cpumask:
@@ -972,19 +933,12 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
if (WARN_ON(cpu == policy->cpu))
return;
- /*
- * Take direct locks as lock_policy_rwsem_write wouldn't work here.
- * Also lock for last cpu is enough here as contention will happen only
- * after policy->cpu is changed and after it is changed, other threads
- * will try to acquire lock for new cpu. And policy is already updated
- * by then.
- */
- down_write(&per_cpu(cpu_policy_rwsem, policy->cpu));
+ down_write(&policy->rwsem);
policy->last_cpu = policy->cpu;
policy->cpu = cpu;
- up_write(&per_cpu(cpu_policy_rwsem, policy->last_cpu));
+ up_write(&policy->rwsem);
cpufreq_frequency_table_update_policy_cpu(policy);
blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
@@ -1176,9 +1130,9 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
if (ret) {
pr_err("%s: Failed to move kobj: %d", __func__, ret);
- lock_policy_rwsem_write(old_cpu);
+ down_write(&policy->rwsem);
cpumask_set_cpu(old_cpu, policy->cpus);
- unlock_policy_rwsem_write(old_cpu);
+ up_write(&policy->rwsem);
ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
"cpufreq");
@@ -1229,9 +1183,9 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
policy->governor->name, CPUFREQ_NAME_LEN);
#endif
- lock_policy_rwsem_read(cpu);
+ down_read(&policy->rwsem);
cpus = cpumask_weight(policy->cpus);
- unlock_policy_rwsem_read(cpu);
+ up_read(&policy->rwsem);
if (cpu != policy->cpu) {
if (!frozen)
@@ -1271,12 +1225,12 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
return -EINVAL;
}
- lock_policy_rwsem_write(cpu);
+ down_write(&policy->rwsem);
cpus = cpumask_weight(policy->cpus);
if (cpus > 1)
cpumask_clear_cpu(cpu, policy->cpus);
- unlock_policy_rwsem_write(cpu);
+ up_write(&policy->rwsem);
/* If cpu is last user of policy, free policy */
if (cpus == 1) {
@@ -1291,10 +1245,10 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
}
if (!frozen) {
- lock_policy_rwsem_read(cpu);
+ down_read(&policy->rwsem);
kobj = &policy->kobj;
cmp = &policy->kobj_unregister;
- unlock_policy_rwsem_read(cpu);
+ up_read(&policy->rwsem);
kobject_put(kobj);
/*
@@ -1474,19 +1428,22 @@ static unsigned int __cpufreq_get(unsigned int cpu)
*/
unsigned int cpufreq_get(unsigned int cpu)
{
+ struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
unsigned int ret_freq = 0;
if (cpufreq_disabled() || !cpufreq_driver)
return -ENOENT;
+ BUG_ON(!policy);
+
if (!down_read_trylock(&cpufreq_rwsem))
return 0;
- lock_policy_rwsem_read(cpu);
+ down_read(&policy->rwsem);
ret_freq = __cpufreq_get(cpu);
- unlock_policy_rwsem_read(cpu);
+ up_read(&policy->rwsem);
up_read(&cpufreq_rwsem);
return ret_freq;
@@ -1710,11 +1667,11 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
{
int ret = -EINVAL;
- lock_policy_rwsem_write(policy->cpu);
+ down_write(&policy->rwsem);
ret = __cpufreq_driver_target(policy, target_freq, relation);
- unlock_policy_rwsem_write(policy->cpu);
+ up_write(&policy->rwsem);
return ret;
}
@@ -1945,10 +1902,10 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
/* end old governor */
if (policy->governor) {
__cpufreq_governor(policy, CPUFREQ_GOV_STOP);
- unlock_policy_rwsem_write(new_policy->cpu);
+ up_write(&policy->rwsem);
__cpufreq_governor(policy,
CPUFREQ_GOV_POLICY_EXIT);
- lock_policy_rwsem_write(new_policy->cpu);
+ down_write(&policy->rwsem);
}
/* start new governor */
@@ -1957,10 +1914,10 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
failed = 0;
} else {
- unlock_policy_rwsem_write(new_policy->cpu);
+ up_write(&policy->rwsem);
__cpufreq_governor(policy,
CPUFREQ_GOV_POLICY_EXIT);
- lock_policy_rwsem_write(new_policy->cpu);
+ down_write(&policy->rwsem);
}
}
@@ -2006,7 +1963,7 @@ int cpufreq_update_policy(unsigned int cpu)
goto no_policy;
}
- lock_policy_rwsem_write(cpu);
+ down_write(&policy->rwsem);
pr_debug("updating policy for CPU %u\n", cpu);
memcpy(&new_policy, policy, sizeof(*policy));
@@ -2033,7 +1990,7 @@ int cpufreq_update_policy(unsigned int cpu)
ret = cpufreq_set_policy(policy, &new_policy);
- unlock_policy_rwsem_write(cpu);
+ up_write(&policy->rwsem);
cpufreq_cpu_put(policy);
no_policy:
@@ -2190,14 +2147,9 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
static int __init cpufreq_core_init(void)
{
- int cpu;
-
if (cpufreq_disabled())
return -ENODEV;
- for_each_possible_cpu(cpu)
- init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
-
cpufreq_global_kobject = kobject_create();
BUG_ON(!cpufreq_global_kobject);
register_syscore_ops(&cpufreq_syscore_ops);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 0aba2a6c..6b457d0 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -85,6 +85,20 @@ struct cpufreq_policy {
struct list_head policy_list;
struct kobject kobj;
struct completion kobj_unregister;
+
+ /*
+ * The rules for this semaphore:
+ * - Any routine that wants to read from the policy structure will
+ * do a down_read on this semaphore.
+ * - Any routine that will write to the policy structure and/or may take away
+ * the policy altogether (eg. CPU hotplug), will hold this lock in write
+ * mode before doing so.
+ *
+ * Additional rules:
+ * - Lock should not be held across
+ * __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
+ */
+ struct rw_semaphore rwsem;
};
/* Only for ACPI */
--
1.7.12.rc2.18.g61b472e
From: Mark Brown <broonie(a)linaro.org>
The conversion of the si476x to regmap removed locking of the core during
register updates, allowing things like power state changes for the MFD to
happen during a register update. Avoid this by taking the core lock in the
DAI operations (which are the only things that do register updates) as we
used to do in the open coded register I/O functions.
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
sound/soc/codecs/si476x.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c
index 03645ce..52e7cb0 100644
--- a/sound/soc/codecs/si476x.c
+++ b/sound/soc/codecs/si476x.c
@@ -73,6 +73,7 @@ static const struct snd_soc_dapm_route si476x_dapm_routes[] = {
static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
unsigned int fmt)
{
+ struct si476x_core *core = i2c_mfd_cell_to_core(codec_dai->dev);
int err;
u16 format = 0;
@@ -136,9 +137,14 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
+ si476x_core_lock(core);
+
err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
format);
+
+ si476x_core_unlock(core);
+
if (err < 0) {
dev_err(codec_dai->codec->dev, "Failed to set output format\n");
return err;
@@ -151,6 +157,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
+ struct si476x_core *core = i2c_mfd_cell_to_core(dai->dev);
int rate, width, err;
rate = params_rate(params);
@@ -176,11 +183,13 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
+ si476x_core_lock(core);
+
err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
rate);
if (err < 0) {
dev_err(dai->codec->dev, "Failed to set sample rate\n");
- return err;
+ goto out;
}
err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
@@ -189,10 +198,13 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
(width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
if (err < 0) {
dev_err(dai->codec->dev, "Failed to set output width\n");
- return err;
+ goto out;
}
- return 0;
+out:
+ si476x_core_unlock(core);
+
+ return err;
}
static int si476x_codec_probe(struct snd_soc_codec *codec)
--
1.8.4.rc3
From: Mark Brown <broonie(a)linaro.org>
Currently the imx DMA code is one of the few users relying on the fact
that the compat code uses the dma_data as the filter data for non-DT
channel requests. Since the rest of the core expects this to be a struct
snd_dmaengine_dai_data this isn't terribly helpful this will be changed to
use the already existing filter data so avoid breaking imx by open
coding the current behaviour.
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
sound/soc/fsl/imx-pcm-dma.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 4dc1296..318f1fc 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -35,6 +35,17 @@ static bool filter(struct dma_chan *chan, void *param)
return true;
}
+static struct dma_chan *imx_compat_request_channel(
+ struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_dmaengine_dai_dma_data *dma_data;
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
+ return snd_dmaengine_pcm_request_channel(filter, dma_data);
+}
+
static const struct snd_pcm_hardware imx_pcm_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -58,6 +69,7 @@ static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
.pcm_hardware = &imx_pcm_hardware,
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
.compat_filter_fn = filter,
+ .compat_request_channel = imx_compat_request_channel,
.prealloc_buffer_size = IMX_SSI_DMABUF_SIZE,
};
--
1.8.4.rc3