Skip to content

Commit

Permalink
Merge branch 'pm-cpufreq'
Browse files Browse the repository at this point in the history
* pm-cpufreq: (55 commits)
  cpufreq / intel_pstate: Fix 32 bit build
  cpufreq: conservative: Fix typos in comments
  cpufreq: ondemand: Fix typos in comments
  cpufreq: exynos: simplify .init() for setting policy->cpus
  cpufreq: kirkwood: Add a cpufreq driver for Marvell Kirkwood SoCs
  cpufreq/x86: Add P-state driver for sandy bridge.
  cpufreq_stats: do not remove sysfs files if frequency table is not present
  cpufreq: Do not track governor name for scaling drivers with internal governors.
  cpufreq: Only call cpufreq_out_of_sync() for driver that implement cpufreq_driver.target()
  cpufreq: Retrieve current frequency from scaling drivers with internal governors
  cpufreq: Fix locking issues
  cpufreq: Create a macro for unlock_policy_rwsem{read,write}
  cpufreq: Remove unused HOTPLUG_CPU code
  cpufreq: governors: Fix WARN_ON() for multi-policy platforms
  cpufreq: ondemand: Replace down_differential tuner with adj_up_threshold
  cpufreq / stats: Get rid of CPUFREQ_STATDEVICE_ATTR
  cpufreq: Don't check cpu_online(policy->cpu)
  cpufreq: add imx6q-cpufreq driver
  cpufreq: Don't remove sysfs link for policy->cpu
  cpufreq: Remove unnecessary use of policy->shared_type
  ...
  • Loading branch information
Rafael J. Wysocki committed Feb 15, 2013
2 parents 95ecb40 + 191e5ed commit 4419fbd
Show file tree
Hide file tree
Showing 41 changed files with 2,399 additions and 473 deletions.
6 changes: 6 additions & 0 deletions Documentation/cpu-freq/cpu-drivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ policy->governor must contain the "default policy" for
For setting some of these values, the frequency table helpers might be
helpful. See the section 2 for more information on them.

SMP systems normally have same clock source for a group of cpus. For these the
.init() would be called only once for the first online cpu. Here the .init()
routine must initialize policy->cpus with mask of all possible cpus (Online +
Offline) that share the clock. Then the core would copy this mask onto
policy->related_cpus and will reset policy->cpus to carry only online cpus.


1.3 verify
------------
Expand Down
8 changes: 4 additions & 4 deletions Documentation/cpu-freq/user-guide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ scaling_max_freq show the current "policy limits" (in
first set scaling_max_freq, then
scaling_min_freq.

affected_cpus : List of CPUs that require software coordination
of frequency.
affected_cpus : List of Online CPUs that require software
coordination of frequency.

related_cpus : List of CPUs that need some sort of frequency
coordination, whether software or hardware.
related_cpus : List of Online + Offline CPUs that need software
coordination of frequency.

scaling_driver : Hardware driver for cpufreq.

Expand Down
27 changes: 27 additions & 0 deletions Documentation/devicetree/bindings/arm/kirkwood.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Marvell Kirkwood Platforms Device Tree Bindings
-----------------------------------------------

Boards with a SoC of the Marvell Kirkwood
shall have the following property:

Required root node property:

compatible: must contain "marvell,kirkwood";

In order to support the kirkwood cpufreq driver, there must be a node
cpus/cpu@0 with three clocks, "cpu_clk", "ddrclk" and "powersave",
where the "powersave" clock is a gating clock used to switch the CPU
between the "cpu_clk" and the "ddrclk".

Example:

cpus {
#address-cells = <1>;
#size-cells = <0>;

cpu@0 {
device_type = "cpu";
compatible = "marvell,sheeva-88SV131";
clocks = <&core_clk 1>, <&core_clk 3>, <&gate_clk 11>;
clock-names = "cpu_clk", "ddrclk", "powersave";
};
10 changes: 10 additions & 0 deletions arch/arm/boot/dts/highbank.dts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@
next-level-cache = <&L2>;
clocks = <&a9pll>;
clock-names = "cpu";
operating-points = <
/* kHz ignored */
1300000 1000000
1200000 1000000
1100000 1000000
800000 1000000
400000 1000000
200000 1000000
>;
clock-latency = <100000>;
};

cpu@901 {
Expand Down
53 changes: 19 additions & 34 deletions arch/arm/kernel/smp_twd.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ static void __iomem *twd_base;

static struct clk *twd_clk;
static unsigned long twd_timer_rate;
static bool common_setup_called;
static DEFINE_PER_CPU(bool, percpu_setup_called);

static struct clock_event_device __percpu **twd_evt;
Expand Down Expand Up @@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
return IRQ_NONE;
}

static struct clk *twd_get_clock(void)
static void twd_get_clock(struct device_node *np)
{
struct clk *clk;
int err;

clk = clk_get_sys("smp_twd", NULL);
if (IS_ERR(clk)) {
pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
return clk;
if (np)
twd_clk = of_clk_get(np, 0);
else
twd_clk = clk_get_sys("smp_twd", NULL);

if (IS_ERR(twd_clk)) {
pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
return;
}

err = clk_prepare_enable(clk);
err = clk_prepare_enable(twd_clk);
if (err) {
pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
clk_put(clk);
return ERR_PTR(err);
clk_put(twd_clk);
return;
}

return clk;
twd_timer_rate = clk_get_rate(twd_clk);
}

/*
Expand All @@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
}
per_cpu(percpu_setup_called, cpu) = true;

/*
* This stuff only need to be done once for the entire TWD cluster
* during the runtime of the system.
*/
if (!common_setup_called) {
twd_clk = twd_get_clock();

/*
* We use IS_ERR_OR_NULL() here, because if the clock stubs
* are active we will get a valid clk reference which is
* however NULL and will return the rate 0. In that case we
* need to calibrate the rate instead.
*/
if (!IS_ERR_OR_NULL(twd_clk))
twd_timer_rate = clk_get_rate(twd_clk);
else
twd_calibrate_rate();

common_setup_called = true;
}
twd_calibrate_rate();

/*
* The following is done once per CPU the first time .setup() is
Expand Down Expand Up @@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
.stop = twd_timer_stop,
};

static int __init twd_local_timer_common_register(void)
static int __init twd_local_timer_common_register(struct device_node *np)
{
int err;

Expand All @@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void)
if (err)
goto out_irq;

twd_get_clock(np);

return 0;

out_irq:
Expand All @@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
if (!twd_base)
return -ENOMEM;

return twd_local_timer_common_register();
return twd_local_timer_common_register(NULL);
}

#ifdef CONFIG_OF
Expand Down Expand Up @@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void)
goto out;
}

err = twd_local_timer_common_register();
err = twd_local_timer_common_register(np);

out:
WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
Expand Down
4 changes: 4 additions & 0 deletions arch/arm/mach-highbank/Kconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
config ARCH_HIGHBANK
bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
select ARCH_HAS_CPUFREQ
select ARCH_HAS_OPP
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_AMBA
select ARM_GIC
Expand All @@ -11,5 +13,7 @@ config ARCH_HIGHBANK
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
select HAVE_SMP
select MAILBOX
select PL320_MBOX
select SPARSE_IRQ
select USE_OF
3 changes: 1 addition & 2 deletions arch/arm/mach-tegra/cpu-tegra.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
/* FIXME: what's the actual transition time? */
policy->cpuinfo.transition_latency = 300 * 1000;

policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
cpumask_copy(policy->related_cpus, cpu_possible_mask);
cpumask_copy(policy->cpus, cpu_possible_mask);

if (policy->cpu == 0)
register_pm_notifier(&tegra_cpu_pm_notifier);
Expand Down
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ source "drivers/hwspinlock/Kconfig"

source "drivers/clocksource/Kconfig"

source "drivers/mailbox/Kconfig"

source "drivers/iommu/Kconfig"

source "drivers/remoteproc/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ obj-y += platform/
#common clk code
obj-y += clk/

obj-$(CONFIG_MAILBOX) += mailbox/
obj-$(CONFIG_HWSPINLOCK) += hwspinlock/
obj-$(CONFIG_NFC) += nfc/
obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
Expand Down
19 changes: 11 additions & 8 deletions drivers/base/power/opp.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ unsigned long opp_get_voltage(struct opp *opp)

return v;
}
EXPORT_SYMBOL(opp_get_voltage);
EXPORT_SYMBOL_GPL(opp_get_voltage);

/**
* opp_get_freq() - Gets the frequency corresponding to an available opp
Expand Down Expand Up @@ -192,7 +192,7 @@ unsigned long opp_get_freq(struct opp *opp)

return f;
}
EXPORT_SYMBOL(opp_get_freq);
EXPORT_SYMBOL_GPL(opp_get_freq);

/**
* opp_get_opp_count() - Get number of opps available in the opp list
Expand Down Expand Up @@ -225,7 +225,7 @@ int opp_get_opp_count(struct device *dev)

return count;
}
EXPORT_SYMBOL(opp_get_opp_count);
EXPORT_SYMBOL_GPL(opp_get_opp_count);

/**
* opp_find_freq_exact() - search for an exact frequency
Expand Down Expand Up @@ -276,7 +276,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq,

return opp;
}
EXPORT_SYMBOL(opp_find_freq_exact);
EXPORT_SYMBOL_GPL(opp_find_freq_exact);

/**
* opp_find_freq_ceil() - Search for an rounded ceil freq
Expand Down Expand Up @@ -323,7 +323,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq)

return opp;
}
EXPORT_SYMBOL(opp_find_freq_ceil);
EXPORT_SYMBOL_GPL(opp_find_freq_ceil);

/**
* opp_find_freq_floor() - Search for a rounded floor freq
Expand Down Expand Up @@ -374,7 +374,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq)

return opp;
}
EXPORT_SYMBOL(opp_find_freq_floor);
EXPORT_SYMBOL_GPL(opp_find_freq_floor);

/**
* opp_add() - Add an OPP table from a table definitions
Expand Down Expand Up @@ -568,7 +568,7 @@ int opp_enable(struct device *dev, unsigned long freq)
{
return opp_set_availability(dev, freq, true);
}
EXPORT_SYMBOL(opp_enable);
EXPORT_SYMBOL_GPL(opp_enable);

/**
* opp_disable() - Disable a specific OPP
Expand All @@ -590,7 +590,7 @@ int opp_disable(struct device *dev, unsigned long freq)
{
return opp_set_availability(dev, freq, false);
}
EXPORT_SYMBOL(opp_disable);
EXPORT_SYMBOL_GPL(opp_disable);

#ifdef CONFIG_CPU_FREQ
/**
Expand Down Expand Up @@ -661,6 +661,7 @@ int opp_init_cpufreq_table(struct device *dev,

return 0;
}
EXPORT_SYMBOL_GPL(opp_init_cpufreq_table);

/**
* opp_free_cpufreq_table() - free the cpufreq table
Expand All @@ -678,6 +679,7 @@ void opp_free_cpufreq_table(struct device *dev,
kfree(*table);
*table = NULL;
}
EXPORT_SYMBOL_GPL(opp_free_cpufreq_table);
#endif /* CONFIG_CPU_FREQ */

/**
Expand Down Expand Up @@ -738,4 +740,5 @@ int of_init_opp_table(struct device *dev)

return 0;
}
EXPORT_SYMBOL_GPL(of_init_opp_table);
#endif
2 changes: 2 additions & 0 deletions drivers/clk/clk-highbank.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,10 @@ static int clk_pll_set_rate(struct clk_hw *hwclk, unsigned long rate,
reg |= HB_PLL_EXT_ENA;
reg &= ~HB_PLL_EXT_BYPASS;
} else {
writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
reg &= ~HB_PLL_DIVQ_MASK;
reg |= divq << HB_PLL_DIVQ_SHIFT;
writel(reg | HB_PLL_EXT_BYPASS, hbclk->reg);
}
writel(reg, hbclk->reg);

Expand Down
1 change: 1 addition & 0 deletions drivers/clk/mvebu/clk-gating-ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ static const struct mvebu_soc_descr __initconst kirkwood_gating_descr[] = {
{ "runit", NULL, 7 },
{ "xor0", NULL, 8 },
{ "audio", NULL, 9 },
{ "powersave", "cpuclk", 11 },
{ "sata0", NULL, 14 },
{ "sata1", NULL, 15 },
{ "xor1", NULL, 16 },
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
If in doubt, say N.

config GENERIC_CPUFREQ_CPU0
bool "Generic CPU0 cpufreq driver"
tristate "Generic CPU0 cpufreq driver"
depends on HAVE_CLK && REGULATOR && PM_OPP && OF
select CPU_FREQ_TABLE
help
Expand Down
30 changes: 30 additions & 0 deletions drivers/cpufreq/Kconfig.arm
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,39 @@ config ARM_EXYNOS5250_CPUFREQ
This adds the CPUFreq driver for Samsung EXYNOS5250
SoC.

config ARM_KIRKWOOD_CPUFREQ
def_bool ARCH_KIRKWOOD && OF
help
This adds the CPUFreq driver for Marvell Kirkwood
SoCs.

config ARM_IMX6Q_CPUFREQ
tristate "Freescale i.MX6Q cpufreq support"
depends on SOC_IMX6Q
depends on REGULATOR_ANATOP
help
This adds cpufreq driver support for Freescale i.MX6Q SOC.

If in doubt, say N.

config ARM_SPEAR_CPUFREQ
bool "SPEAr CPUFreq support"
depends on PLAT_SPEAR
default y
help
This adds the CPUFreq driver support for SPEAr SOCs.

config ARM_HIGHBANK_CPUFREQ
tristate "Calxeda Highbank-based"
depends on ARCH_HIGHBANK
select CPU_FREQ_TABLE
select GENERIC_CPUFREQ_CPU0
select PM_OPP
select REGULATOR

default m
help
This adds the CPUFreq driver for Calxeda Highbank SoC
based boards.

If in doubt, say N.
Loading

0 comments on commit 4419fbd

Please sign in to comment.