Merge branch 'pm-cpufreq'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Aug 2013 23:44:40 +0000 (01:44 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Aug 2013 23:44:40 +0000 (01:44 +0200)
* pm-cpufreq: (60 commits)
  cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes
  cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes
  cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes
  cpufreq: arm_big_little: remove device tree parsing for cpu nodes
  cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes
  cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes
  cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes
  cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes
  cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes
  drivers/bus: arm-cci: avoid parsing DT for cpu device nodes
  ARM: mvebu: remove device tree parsing for cpu nodes
  ARM: topology: remove hwid/MPIDR dependency from cpu_capacity
  of/device: add helper to get cpu device node from logical cpu index
  driver/core: cpu: initialize of_node in cpu's device struture
  ARM: DT/kernel: define ARM specific arch_match_cpu_phys_id
  of: move of_get_cpu_node implementation to DT core library
  powerpc: refactor of_get_cpu_node to support other architectures
  openrisc: remove undefined of_get_cpu_node declaration
  microblaze: remove undefined of_get_cpu_node declaration
  cpufreq: fix bad unlock balance on !CONFIG_SMP
  ...

77 files changed:
Documentation/cpu-freq/cpu-drivers.txt
arch/arm/kernel/devtree.c
arch/arm/kernel/topology.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-mvebu/platsmp.c
arch/microblaze/include/asm/prom.h
arch/openrisc/include/asm/prom.h
arch/powerpc/include/asm/prom.h
arch/powerpc/kernel/prom.c
arch/x86/include/asm/processor.h
drivers/base/cpu.c
drivers/bus/arm-cci.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/arm_big_little_dt.c
drivers/cpufreq/at32ap-cpufreq.c
drivers/cpufreq/blackfin-cpufreq.c
drivers/cpufreq/cpufreq-cpu0.c
drivers/cpufreq/cpufreq-nforce2.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_performance.c
drivers/cpufreq/cpufreq_powersave.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/cris-artpec3-cpufreq.c
drivers/cpufreq/cris-etraxfs-cpufreq.c
drivers/cpufreq/e_powersaver.c
drivers/cpufreq/elanfreq.c
drivers/cpufreq/exynos-cpufreq.c
drivers/cpufreq/exynos-cpufreq.h
drivers/cpufreq/exynos5440-cpufreq.c
drivers/cpufreq/freq_table.c
drivers/cpufreq/gx-suspmod.c
drivers/cpufreq/highbank-cpufreq.c
drivers/cpufreq/ia64-acpi-cpufreq.c
drivers/cpufreq/imx6q-cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/kirkwood-cpufreq.c
drivers/cpufreq/longhaul.c
drivers/cpufreq/longrun.c
drivers/cpufreq/loongson2_cpufreq.c
drivers/cpufreq/maple-cpufreq.c
drivers/cpufreq/mperf.c [deleted file]
drivers/cpufreq/mperf.h [deleted file]
drivers/cpufreq/p4-clockmod.c
drivers/cpufreq/pasemi-cpufreq.c
drivers/cpufreq/pcc-cpufreq.c
drivers/cpufreq/pmac32-cpufreq.c
drivers/cpufreq/pmac64-cpufreq.c
drivers/cpufreq/powernow-k6.c
drivers/cpufreq/powernow-k7.c
drivers/cpufreq/powernow-k8.c
drivers/cpufreq/ppc-corenet-cpufreq.c
drivers/cpufreq/ppc_cbe_cpufreq.c
drivers/cpufreq/pxa2xx-cpufreq.c
drivers/cpufreq/pxa3xx-cpufreq.c
drivers/cpufreq/s3c2416-cpufreq.c
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpufreq/s3c64xx-cpufreq.c
drivers/cpufreq/sc520_freq.c
drivers/cpufreq/sh-cpufreq.c
drivers/cpufreq/sparc-us2e-cpufreq.c
drivers/cpufreq/sparc-us3-cpufreq.c
drivers/cpufreq/spear-cpufreq.c
drivers/cpufreq/speedstep-centrino.c
drivers/cpufreq/speedstep-ich.c
drivers/cpufreq/speedstep-smi.c
drivers/cpufreq/unicore2-cpufreq.c
drivers/of/base.c
include/linux/cpu.h
include/linux/cpufreq.h
include/linux/of.h
include/linux/of_device.h

index 19fa98e07bf7fe79f403042d14858677f4474839..40282e6179135abc353bc8b04a86137820794468 100644 (file)
@@ -50,8 +50,6 @@ What shall this struct cpufreq_driver contain?
 
 cpufreq_driver.name -          The name of this driver.
 
-cpufreq_driver.owner -         THIS_MODULE;
-
 cpufreq_driver.init -          A pointer to the per-CPU initialization 
                                function.
 
index 5859c8bc727c4254bc7e8fa254a4271d6b214242..2ee8a17d2b01c41216ba26cf74f5379114e634b9 100644 (file)
@@ -169,6 +169,11 @@ void __init arm_dt_init_cpu_maps(void)
        }
 }
 
+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+       return (phys_id & MPIDR_HWID_BITMASK) == cpu_logical_map(cpu);
+}
+
 /**
  * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
  * @dt_phys: physical address of dt blob
index c5a59546a256c9b3720022265eb08fcde0dc4f68..85a87370f144a4b383c390c39c7fa18a4be87dcb 100644 (file)
@@ -74,12 +74,8 @@ struct cpu_efficiency table_efficiency[] = {
        {NULL, },
 };
 
-struct cpu_capacity {
-       unsigned long hwid;
-       unsigned long capacity;
-};
-
-struct cpu_capacity *cpu_capacity;
+unsigned long *__cpu_capacity;
+#define cpu_capacity(cpu)      __cpu_capacity[cpu]
 
 unsigned long middle_capacity = 1;
 
@@ -100,15 +96,19 @@ static void __init parse_dt_topology(void)
        unsigned long capacity = 0;
        int alloc_size, cpu = 0;
 
-       alloc_size = nr_cpu_ids * sizeof(struct cpu_capacity);
-       cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
+       alloc_size = nr_cpu_ids * sizeof(*__cpu_capacity);
+       __cpu_capacity = kzalloc(alloc_size, GFP_NOWAIT);
 
-       while ((cn = of_find_node_by_type(cn, "cpu"))) {
-               const u32 *rate, *reg;
+       for_each_possible_cpu(cpu) {
+               const u32 *rate;
                int len;
 
-               if (cpu >= num_possible_cpus())
-                       break;
+               /* too early to use cpu->of_node */
+               cn = of_get_cpu_node(cpu, NULL);
+               if (!cn) {
+                       pr_err("missing device node for CPU %d\n", cpu);
+                       continue;
+               }
 
                for (cpu_eff = table_efficiency; cpu_eff->compatible; cpu_eff++)
                        if (of_device_is_compatible(cn, cpu_eff->compatible))
@@ -124,12 +124,6 @@ static void __init parse_dt_topology(void)
                        continue;
                }
 
-               reg = of_get_property(cn, "reg", &len);
-               if (!reg || len != 4) {
-                       pr_err("%s missing reg property\n", cn->full_name);
-                       continue;
-               }
-
                capacity = ((be32_to_cpup(rate)) >> 20) * cpu_eff->efficiency;
 
                /* Save min capacity of the system */
@@ -140,13 +134,9 @@ static void __init parse_dt_topology(void)
                if (capacity > max_capacity)
                        max_capacity = capacity;
 
-               cpu_capacity[cpu].capacity = capacity;
-               cpu_capacity[cpu++].hwid = be32_to_cpup(reg);
+               cpu_capacity(cpu) = capacity;
        }
 
-       if (cpu < num_possible_cpus())
-               cpu_capacity[cpu].hwid = (unsigned long)(-1);
-
        /* If min and max capacities are equals, we bypass the update of the
         * cpu_scale because all CPUs have the same capacity. Otherwise, we
         * compute a middle_capacity factor that will ensure that the capacity
@@ -154,9 +144,7 @@ static void __init parse_dt_topology(void)
         * SCHED_POWER_SCALE, which is the default value, but with the
         * constraint explained near table_efficiency[].
         */
-       if (min_capacity == max_capacity)
-               cpu_capacity[0].hwid = (unsigned long)(-1);
-       else if (4*max_capacity < (3*(max_capacity + min_capacity)))
+       if (4*max_capacity < (3*(max_capacity + min_capacity)))
                middle_capacity = (min_capacity + max_capacity)
                                >> (SCHED_POWER_SHIFT+1);
        else
@@ -170,23 +158,12 @@ static void __init parse_dt_topology(void)
  * boot. The update of all CPUs is in O(n^2) for heteregeneous system but the
  * function returns directly for SMP system.
  */
-void update_cpu_power(unsigned int cpu, unsigned long hwid)
+void update_cpu_power(unsigned int cpu)
 {
-       unsigned int idx = 0;
-
-       /* look for the cpu's hwid in the cpu capacity table */
-       for (idx = 0; idx < num_possible_cpus(); idx++) {
-               if (cpu_capacity[idx].hwid == hwid)
-                       break;
-
-               if (cpu_capacity[idx].hwid == -1)
-                       return;
-       }
-
-       if (idx == num_possible_cpus())
+       if (!cpu_capacity(cpu))
                return;
 
-       set_power_scale(cpu, cpu_capacity[idx].capacity / middle_capacity);
+       set_power_scale(cpu, cpu_capacity(cpu) / middle_capacity);
 
        printk(KERN_INFO "CPU%u: update cpu_power %lu\n",
                cpu, arch_scale_freq_power(NULL, cpu));
@@ -194,7 +171,7 @@ void update_cpu_power(unsigned int cpu, unsigned long hwid)
 
 #else
 static inline void parse_dt_topology(void) {}
-static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
+static inline void update_cpu_power(unsigned int cpuid) {}
 #endif
 
  /*
@@ -281,7 +258,7 @@ void store_cpu_topology(unsigned int cpuid)
 
        update_siblings_masks(cpuid);
 
-       update_cpu_power(cpuid, mpidr & MPIDR_HWID_BITMASK);
+       update_cpu_power(cpuid);
 
        printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
                cpuid, cpu_topology[cpuid].thread_id,
index 7be13f8e69a01f22b43d28b4b22a42a23f006c8d..a02f275a198d4fbf38101ee5544110db8cb39936 100644 (file)
@@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev)
 {
        struct device_node *np;
 
-       np = of_find_node_by_path("/cpus/cpu@0");
+       np = of_node_get(cpu_dev->of_node);
        if (!np) {
                pr_warn("failed to find cpu0 node\n");
                return;
        }
 
-       cpu_dev->of_node = np;
        if (of_init_opp_table(cpu_dev)) {
                pr_warn("failed to init OPP table\n");
                goto put_node;
index ce81d303140598debb8e5cb9c6bb557e28268f49..594b63db421597f78021a3bf736fa81de6a79afe 100644 (file)
 #include "pmsu.h"
 #include "coherency.h"
 
+static struct clk *__init get_cpu_clk(int cpu)
+{
+       struct clk *cpu_clk;
+       struct device_node *np = of_get_cpu_node(cpu, NULL);
+
+       if (WARN(!np, "missing cpu node\n"))
+               return NULL;
+       cpu_clk = of_clk_get(np, 0);
+       if (WARN_ON(IS_ERR(cpu_clk)))
+               return NULL;
+       return cpu_clk;
+}
+
 void __init set_secondary_cpus_clock(void)
 {
-       int thiscpu;
+       int thiscpu, cpu;
        unsigned long rate;
-       struct clk *cpu_clk = NULL;
-       struct device_node *np = NULL;
+       struct clk *cpu_clk;
 
        thiscpu = smp_processor_id();
-       for_each_node_by_type(np, "cpu") {
-               int err;
-               int cpu;
-
-               err = of_property_read_u32(np, "reg", &cpu);
-               if (WARN_ON(err))
-                       return;
-
-               if (cpu == thiscpu) {
-                       cpu_clk = of_clk_get(np, 0);
-                       break;
-               }
-       }
-       if (WARN_ON(IS_ERR(cpu_clk)))
+       cpu_clk = get_cpu_clk(thiscpu);
+       if (!cpu_clk)
                return;
        clk_prepare_enable(cpu_clk);
        rate = clk_get_rate(cpu_clk);
 
        /* set all the other CPU clk to the same rate than the boot CPU */
-       for_each_node_by_type(np, "cpu") {
-               int err;
-               int cpu;
-
-               err = of_property_read_u32(np, "reg", &cpu);
-               if (WARN_ON(err))
+       for_each_possible_cpu(cpu) {
+               if (cpu == thiscpu)
+                       continue;
+               cpu_clk = get_cpu_clk(cpu);
+               if (!cpu_clk)
                        return;
-
-               if (cpu != thiscpu) {
-                       cpu_clk = of_clk_get(np, 0);
-                       clk_set_rate(cpu_clk, rate);
-               }
+               clk_set_rate(cpu_clk, rate);
        }
 }
 
index 20c5e8e5121bc6a807262870cb199a43c18fd15b..9977816c5ad3bd75aac4780f6c8d3bbdf034b3c8 100644 (file)
@@ -50,9 +50,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 
 extern void kdump_move_device_tree(void);
 
-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 
index bbb34e5343a2f5efb5c6611717dd5a1c151435e3..eb59bfe23e8510c7c812d43496860bcee37974b7 100644 (file)
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 
 extern void kdump_move_device_tree(void);
 
-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
 /* Get the MAC address */
 extern const void *of_get_mac_address(struct device_node *np);
 
index bc2da154f68be579d19e81e5789073e436ac838b..ac204e0229220bd15cd1dfb550e355eed3020962 100644 (file)
@@ -43,9 +43,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
 
 extern void kdump_move_device_tree(void);
 
-/* CPU OF node matching */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
-
 /* cache lookup */
 struct device_node *of_find_next_cache_node(struct device_node *np);
 
index eb23ac92abb9089cea9ebc7fa19fd3a7e1404dbd..1c14cd4a5e05972bf45fc31a5535aa97df96f025 100644 (file)
@@ -865,49 +865,10 @@ static int __init prom_reconfig_setup(void)
 __initcall(prom_reconfig_setup);
 #endif
 
-/* Find the device node for a given logical cpu number, also returns the cpu
- * local thread number (index in ibm,interrupt-server#s) if relevant and
- * asked for (non NULL)
- */
-struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
 {
-       int hardid;
-       struct device_node *np;
-
-       hardid = get_hard_smp_processor_id(cpu);
-
-       for_each_node_by_type(np, "cpu") {
-               const u32 *intserv;
-               unsigned int plen, t;
-
-               /* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
-                * fallback to "reg" property and assume no threads
-                */
-               intserv = of_get_property(np, "ibm,ppc-interrupt-server#s",
-                               &plen);
-               if (intserv == NULL) {
-                       const u32 *reg = of_get_property(np, "reg", NULL);
-                       if (reg == NULL)
-                               continue;
-                       if (*reg == hardid) {
-                               if (thread)
-                                       *thread = 0;
-                               return np;
-                       }
-               } else {
-                       plen /= sizeof(u32);
-                       for (t = 0; t < plen; t++) {
-                               if (hardid == intserv[t]) {
-                                       if (thread)
-                                               *thread = t;
-                                       return np;
-                               }
-                       }
-               }
-       }
-       return NULL;
+       return (int)phys_id == get_hard_smp_processor_id(cpu);
 }
-EXPORT_SYMBOL(of_get_cpu_node);
 
 #if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
 static struct debugfs_blob_wrapper flat_dt_blob;
index 24cf5aefb7048b496082fd271755e3b186e23540..4f4a3d98c170477caff77d71693f203ae9a6fb34 100644 (file)
@@ -942,35 +942,6 @@ extern int set_tsc_mode(unsigned int val);
 
 extern u16 amd_get_nb_id(int cpu);
 
-struct aperfmperf {
-       u64 aperf, mperf;
-};
-
-static inline void get_aperfmperf(struct aperfmperf *am)
-{
-       WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF));
-
-       rdmsrl(MSR_IA32_APERF, am->aperf);
-       rdmsrl(MSR_IA32_MPERF, am->mperf);
-}
-
-#define APERFMPERF_SHIFT 10
-
-static inline
-unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
-                                   struct aperfmperf *new)
-{
-       u64 aperf = new->aperf - old->aperf;
-       u64 mperf = new->mperf - old->mperf;
-       unsigned long ratio = aperf;
-
-       mperf >>= APERFMPERF_SHIFT;
-       if (mperf)
-               ratio = div64_u64(aperf, mperf);
-
-       return ratio;
-}
-
 extern unsigned long arch_align_stack(unsigned long sp);
 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 
index 4c358bc44c72b1082d5576ed2ba6a93415b00563..4cf071764be388a1bdad0e274f2b1884676554c8 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/percpu.h>
 #include <linux/acpi.h>
+#include <linux/of.h>
 
 #include "base.h"
 
@@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num)
        cpu->dev.release = cpu_device_release;
        cpu->dev.offline_disabled = !cpu->hotpluggable;
        cpu->dev.offline = !cpu_online(num);
+       cpu->dev.of_node = of_get_cpu_node(num, NULL);
 #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
        cpu->dev.bus->uevent = arch_cpu_uevent;
 #endif
index 733288967d4d87f81711c1b6508c74629949bdff..200926699778e2a0ec2605429362f92282494a56 100644 (file)
@@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port);
 
 static void __init cci_ace_init_ports(void)
 {
-       int port, ac, cpu;
-       u64 hwid;
-       const u32 *cell;
-       struct device_node *cpun, *cpus;
-
-       cpus = of_find_node_by_path("/cpus");
-       if (WARN(!cpus, "Missing cpus node, bailing out\n"))
-               return;
-
-       if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac)))
-               ac = of_n_addr_cells(cpus);
+       int port, cpu;
+       struct device_node *cpun;
 
        /*
         * Port index look-up speeds up the function disabling ports by CPU,
@@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void)
         * The stashed index array is initialized for all possible CPUs
         * at probe time.
         */
-       for_each_child_of_node(cpus, cpun) {
-               if (of_node_cmp(cpun->type, "cpu"))
-                       continue;
-               cell = of_get_property(cpun, "reg", NULL);
-               if (WARN(!cell, "%s: missing reg property\n", cpun->full_name))
-                       continue;
-
-               hwid = of_read_number(cell, ac);
-               cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK);
+       for_each_possible_cpu(cpu) {
+               /* too early to use cpu->of_node */
+               cpun = of_get_cpu_node(cpu, NULL);
 
-               if (cpu < 0 || !cpu_possible(cpu))
+               if (WARN(!cpun, "Missing cpu device node\n"))
                        continue;
+
                port = __cci_ace_get_port(cpun, ACE_PORT);
                if (port < 0)
                        continue;
index de4d5d93c3fdc826ae013c6f7e0652b13e550f2d..0fa204b244bd2df52974a50fc4290e9fa77d287c 100644 (file)
@@ -17,37 +17,47 @@ config ARM_DT_BL_CPUFREQ
          big.LITTLE platform. This gets frequency tables from DT.
 
 config ARM_EXYNOS_CPUFREQ
-       bool "SAMSUNG EXYNOS SoCs"
-       depends on ARCH_EXYNOS
+       bool
        select CPU_FREQ_TABLE
-       default y
-       help
-         This adds the CPUFreq driver common part for Samsung
-         EXYNOS SoCs.
-
-         If in doubt, say N.
 
 config ARM_EXYNOS4210_CPUFREQ
-       def_bool CPU_EXYNOS4210
+       bool "SAMSUNG EXYNOS4210"
+       depends on CPU_EXYNOS4210
+       default y
+       select ARM_EXYNOS_CPUFREQ
        help
          This adds the CPUFreq driver for Samsung EXYNOS4210
          SoC (S5PV310 or S5PC210).
 
+         If in doubt, say N.
+
 config ARM_EXYNOS4X12_CPUFREQ
-       def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412)
+       bool "SAMSUNG EXYNOS4x12"
+       depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
+       default y
+       select ARM_EXYNOS_CPUFREQ
        help
          This adds the CPUFreq driver for Samsung EXYNOS4X12
          SoC (EXYNOS4212 or EXYNOS4412).
 
+         If in doubt, say N.
+
 config ARM_EXYNOS5250_CPUFREQ
-       def_bool SOC_EXYNOS5250
+       bool "SAMSUNG EXYNOS5250"
+       depends on SOC_EXYNOS5250
+       default y
+       select ARM_EXYNOS_CPUFREQ
        help
          This adds the CPUFreq driver for Samsung EXYNOS5250
          SoC.
 
+         If in doubt, say N.
+
 config ARM_EXYNOS5440_CPUFREQ
-       def_bool SOC_EXYNOS5440
+       bool "SAMSUNG EXYNOS5440"
+       depends on SOC_EXYNOS5440
        depends on HAVE_CLK && PM_OPP && OF
+       default y
        select CPU_FREQ_TABLE
        help
          This adds the CPUFreq driver for Samsung EXYNOS5440
@@ -55,6 +65,8 @@ config ARM_EXYNOS5440_CPUFREQ
          different than previous exynos controllers so not using
          the common exynos framework.
 
+         If in doubt, say N.
+
 config ARM_HIGHBANK_CPUFREQ
        tristate "Calxeda Highbank-based"
        depends on ARCH_HIGHBANK
index d345b5a7aa719e52fd660013afdf96b4d3da6335..ad5866c2ada0a5bd219305954682dbc7aae4f5a2 100644 (file)
@@ -23,7 +23,7 @@ obj-$(CONFIG_GENERIC_CPUFREQ_CPU0)    += cpufreq-cpu0.o
 # powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers.
 # speedstep-* is preferred over p4-clockmod.
 
-obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o mperf.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o
 obj-$(CONFIG_X86_PCC_CPUFREQ)          += pcc-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K6)          += powernow-k6.o
index 39264020b88a1b2e7d461a8d0a3f2f909a31dbb4..a1260b4549db647336192d24b3471b6b627897af 100644 (file)
@@ -45,7 +45,6 @@
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
-#include "mperf.h"
 
 MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
@@ -198,7 +197,7 @@ static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
        return sprintf(buf, "%u\n", boost_enabled);
 }
 
-static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb);
+cpufreq_freq_attr_rw(cpb);
 #endif
 
 static int check_est_cpu(unsigned int cpuid)
@@ -710,7 +709,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
                return blacklisted;
 #endif
 
-       data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -800,7 +799,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
                goto err_unreg;
        }
 
-       data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
+       data->freq_table = kmalloc(sizeof(*data->freq_table) *
                    (perf->state_count+1), GFP_KERNEL);
        if (!data->freq_table) {
                result = -ENOMEM;
@@ -861,10 +860,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
 
-       /* Check for APERF/MPERF support in hardware */
-       if (boot_cpu_has(X86_FEATURE_APERFMPERF))
-               acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
-
        pr_debug("CPU%u - ACPI performance management activated.\n", cpu);
        for (i = 0; i < perf->state_count; i++)
                pr_debug("     %cP%d: %d MHz, %d mW, %d uS\n",
@@ -941,7 +936,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
        .exit           = acpi_cpufreq_cpu_exit,
        .resume         = acpi_cpufreq_resume,
        .name           = "acpi-cpufreq",
-       .owner          = THIS_MODULE,
        .attr           = acpi_cpufreq_attr,
 };
 
index fd9e3ea6a480aad30c0f9c593eb683470605e36d..480c0bd0468d7c0fbbed9e0872cd9adb4fb77244 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/opp.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 /* get cpu node with valid operating-points */
 static struct device_node *get_cpu_node_with_valid_op(int cpu)
 {
-       struct device_node *np = NULL, *parent;
-       int count = 0;
+       struct device_node *np = of_cpu_device_node_get(cpu);
 
-       parent = of_find_node_by_path("/cpus");
-       if (!parent) {
-               pr_err("failed to find OF /cpus\n");
-               return NULL;
+       if (!of_get_property(np, "operating-points", NULL)) {
+               of_node_put(np);
+               np = NULL;
        }
 
-       for_each_child_of_node(parent, np) {
-               if (count++ != cpu)
-                       continue;
-               if (!of_get_property(np, "operating-points", NULL)) {
-                       of_node_put(np);
-                       np = NULL;
-               }
-
-               break;
-       }
-
-       of_node_put(parent);
        return np;
 }
 
@@ -63,11 +48,12 @@ static int dt_init_opp_table(struct device *cpu_dev)
        struct device_node *np;
        int ret;
 
-       np = get_cpu_node_with_valid_op(cpu_dev->id);
-       if (!np)
-               return -ENODATA;
+       np = of_node_get(cpu_dev->of_node);
+       if (!np) {
+               pr_err("failed to find cpu%d node\n", cpu_dev->id);
+               return -ENOENT;
+       }
 
-       cpu_dev->of_node = np;
        ret = of_init_opp_table(cpu_dev);
        of_node_put(np);
 
@@ -79,9 +65,11 @@ static int dt_get_transition_latency(struct device *cpu_dev)
        struct device_node *np;
        u32 transition_latency = CPUFREQ_ETERNAL;
 
-       np = get_cpu_node_with_valid_op(cpu_dev->id);
-       if (!np)
+       np = of_node_get(cpu_dev->of_node);
+       if (!np) {
+               pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n");
                return CPUFREQ_ETERNAL;
+       }
 
        of_property_read_u32(np, "clock-latency", &transition_latency);
        of_node_put(np);
index 654488723cb5d00746b5e08ebb5f88e9beac8cd0..e0c38d9389979b2f1b9a503d36c8e12364ecc188 100644 (file)
@@ -108,7 +108,6 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver at32_driver = {
        .name           = "at32ap",
-       .owner          = THIS_MODULE,
        .init           = at32_cpufreq_driver_init,
        .verify         = at32_verify_speed,
        .target         = at32_set_target,
index 9cdbbd278a800da1587eae1fdb6314d23d0a9b9d..ef05978a723702de29da757eda20edec7d21c3d6 100644 (file)
@@ -225,7 +225,6 @@ static struct cpufreq_driver bfin_driver = {
        .get = bfin_getfreq_khz,
        .init = __bfin_cpu_init,
        .name = "bfin cpufreq",
-       .owner = THIS_MODULE,
        .attr = bfin_freq_attr,
 };
 
index ad1fde277661e617fd4f19e01f34cd963f1349f4..bad620e996e50f9c8603d98435849adfa5b820b3 100644 (file)
@@ -69,7 +69,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
 
        cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
-       if (cpu_reg) {
+       if (!IS_ERR(cpu_reg)) {
                rcu_read_lock();
                opp = opp_find_freq_ceil(cpu_dev, &freq_Hz);
                if (IS_ERR(opp)) {
@@ -90,7 +90,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
                 freqs.new / 1000, volt ? volt / 1000 : -1);
 
        /* scaling up?  scale voltage before frequency */
-       if (cpu_reg && freqs.new > freqs.old) {
+       if (!IS_ERR(cpu_reg) && freqs.new > freqs.old) {
                ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
                if (ret) {
                        pr_err("failed to scale voltage up: %d\n", ret);
@@ -102,14 +102,14 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
        ret = clk_set_rate(cpu_clk, freq_exact);
        if (ret) {
                pr_err("failed to set clock rate: %d\n", ret);
-               if (cpu_reg)
+               if (!IS_ERR(cpu_reg))
                        regulator_set_voltage_tol(cpu_reg, volt_old, tol);
                freqs.new = freqs.old;
                goto post_notify;
        }
 
        /* scaling down?  scale voltage after frequency */
-       if (cpu_reg && freqs.new < freqs.old) {
+       if (!IS_ERR(cpu_reg) && freqs.new < freqs.old) {
                ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
                if (ret) {
                        pr_err("failed to scale voltage down: %d\n", ret);
@@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
 
 static int cpu0_cpufreq_probe(struct platform_device *pdev)
 {
-       struct device_node *np, *parent;
+       struct device_node *np;
        int ret;
 
-       parent = of_find_node_by_path("/cpus");
-       if (!parent) {
-               pr_err("failed to find OF /cpus\n");
-               return -ENOENT;
-       }
-
-       for_each_child_of_node(parent, np) {
-               if (of_get_property(np, "operating-points", NULL))
-                       break;
-       }
+       cpu_dev = &pdev->dev;
 
+       np = of_node_get(cpu_dev->of_node);
        if (!np) {
                pr_err("failed to find cpu0 node\n");
-               ret = -ENOENT;
-               goto out_put_parent;
+               return -ENOENT;
        }
 
-       cpu_dev = &pdev->dev;
-       cpu_dev->of_node = np;
-
        cpu_reg = devm_regulator_get(cpu_dev, "cpu0");
        if (IS_ERR(cpu_reg)) {
                /*
@@ -210,7 +198,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
                }
                pr_warn("failed to get cpu0 regulator: %ld\n",
                        PTR_ERR(cpu_reg));
-               cpu_reg = NULL;
        }
 
        cpu_clk = devm_clk_get(cpu_dev, NULL);
@@ -269,15 +256,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
        }
 
        of_node_put(np);
-       of_node_put(parent);
        return 0;
 
 out_free_table:
        opp_free_cpufreq_table(cpu_dev, &freq_table);
 out_put_node:
        of_node_put(np);
-out_put_parent:
-       of_node_put(parent);
        return ret;
 }
 
index af1542d414408f0e8df9d561522479501ada341b..b83d45f6857495083163e13336027ef4449b5da2 100644 (file)
@@ -379,7 +379,6 @@ static struct cpufreq_driver nforce2_driver = {
        .get = nforce2_get,
        .init = nforce2_cpu_init,
        .exit = nforce2_cpu_exit,
-       .owner = THIS_MODULE,
 };
 
 #ifdef MODULE
index f0a5e2b0eb8a9584f1e1d55ffac92bfd2800fbba..5c75e3147a607ca70a6d880500f9a9b6fb336316 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <asm/cputime.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/notifier.h>
+#include <linux/cpu.h>
 #include <linux/cpufreq.h>
 #include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/tick.h>
 #include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/cpu.h>
-#include <linux/completion.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/syscore_ops.h>
-
+#include <linux/tick.h>
 #include <trace/events/power.h>
 
 /**
  */
 static struct cpufreq_driver *cpufreq_driver;
 static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
+static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback);
 static DEFINE_RWLOCK(cpufreq_driver_lock);
 static DEFINE_MUTEX(cpufreq_governor_lock);
+static LIST_HEAD(cpufreq_policy_list);
 
 #ifdef CONFIG_HOTPLUG_CPU
 /* This one keeps track of the previously set governor of a removed CPU */
@@ -69,15 +64,14 @@ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
  * - Lock should not be held across
  *     __cpufreq_governor(data, CPUFREQ_GOV_STOP);
  */
-static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
 static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
 
 #define lock_policy_rwsem(mode, cpu)                                   \
 static int lock_policy_rwsem_##mode(int cpu)                           \
 {                                                                      \
-       int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);              \
-       BUG_ON(policy_cpu == -1);                                       \
-       down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));            \
+       struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \
+       BUG_ON(!policy);                                                \
+       down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu));           \
                                                                        \
        return 0;                                                       \
 }
@@ -88,14 +82,20 @@ lock_policy_rwsem(write, cpu);
 #define unlock_policy_rwsem(mode, cpu)                                 \
 static void unlock_policy_rwsem_##mode(int cpu)                                \
 {                                                                      \
-       int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);              \
-       BUG_ON(policy_cpu == -1);                                       \
-       up_##mode(&per_cpu(cpu_policy_rwsem, policy_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
+ */
+static DECLARE_RWSEM(cpufreq_rwsem);
+
 /* internal prototypes */
 static int __cpufreq_governor(struct cpufreq_policy *policy,
                unsigned int event);
@@ -183,78 +183,46 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
 }
 EXPORT_SYMBOL_GPL(get_cpu_idle_time);
 
-static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
 {
-       struct cpufreq_policy *data;
+       struct cpufreq_policy *policy = NULL;
        unsigned long flags;
 
-       if (cpu >= nr_cpu_ids)
-               goto err_out;
+       if (cpufreq_disabled() || (cpu >= nr_cpu_ids))
+               return NULL;
+
+       if (!down_read_trylock(&cpufreq_rwsem))
+               return NULL;
 
        /* get the cpufreq driver */
        read_lock_irqsave(&cpufreq_driver_lock, flags);
 
-       if (!cpufreq_driver)
-               goto err_out_unlock;
-
-       if (!try_module_get(cpufreq_driver->owner))
-               goto err_out_unlock;
-
-       /* get the CPU */
-       data = per_cpu(cpufreq_cpu_data, cpu);
-
-       if (!data)
-               goto err_out_put_module;
-
-       if (!sysfs && !kobject_get(&data->kobj))
-               goto err_out_put_module;
+       if (cpufreq_driver) {
+               /* get the CPU */
+               policy = per_cpu(cpufreq_cpu_data, cpu);
+               if (policy)
+                       kobject_get(&policy->kobj);
+       }
 
        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
-       return data;
 
-err_out_put_module:
-       module_put(cpufreq_driver->owner);
-err_out_unlock:
-       read_unlock_irqrestore(&cpufreq_driver_lock, flags);
-err_out:
-       return NULL;
-}
-
-struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
-{
-       if (cpufreq_disabled())
-               return NULL;
+       if (!policy)
+               up_read(&cpufreq_rwsem);
 
-       return __cpufreq_cpu_get(cpu, false);
+       return policy;
 }
 EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
 
-static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
-{
-       return __cpufreq_cpu_get(cpu, true);
-}
-
-static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
-{
-       if (!sysfs)
-               kobject_put(&data->kobj);
-       module_put(cpufreq_driver->owner);
-}
-
-void cpufreq_cpu_put(struct cpufreq_policy *data)
+void cpufreq_cpu_put(struct cpufreq_policy *policy)
 {
        if (cpufreq_disabled())
                return;
 
-       __cpufreq_cpu_put(data, false);
+       kobject_put(&policy->kobj);
+       up_read(&cpufreq_rwsem);
 }
 EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
 
-static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
-{
-       __cpufreq_cpu_put(data, true);
-}
-
 /*********************************************************************
  *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
  *********************************************************************/
@@ -459,8 +427,8 @@ show_one(scaling_min_freq, min);
 show_one(scaling_max_freq, max);
 show_one(scaling_cur_freq, cur);
 
-static int __cpufreq_set_policy(struct cpufreq_policy *data,
-                               struct cpufreq_policy *policy);
+static int __cpufreq_set_policy(struct cpufreq_policy *policy,
+                               struct cpufreq_policy *new_policy);
 
 /**
  * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
@@ -699,12 +667,12 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
        struct cpufreq_policy *policy = to_policy(kobj);
        struct freq_attr *fattr = to_attr(attr);
        ssize_t ret = -EINVAL;
-       policy = cpufreq_cpu_get_sysfs(policy->cpu);
-       if (!policy)
-               goto no_policy;
+
+       if (!down_read_trylock(&cpufreq_rwsem))
+               goto exit;
 
        if (lock_policy_rwsem_read(policy->cpu) < 0)
-               goto fail;
+               goto up_read;
 
        if (fattr->show)
                ret = fattr->show(policy, buf);
@@ -712,9 +680,10 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
                ret = -EIO;
 
        unlock_policy_rwsem_read(policy->cpu);
-fail:
-       cpufreq_cpu_put_sysfs(policy);
-no_policy:
+
+up_read:
+       up_read(&cpufreq_rwsem);
+exit:
        return ret;
 }
 
@@ -724,12 +693,12 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
        struct cpufreq_policy *policy = to_policy(kobj);
        struct freq_attr *fattr = to_attr(attr);
        ssize_t ret = -EINVAL;
-       policy = cpufreq_cpu_get_sysfs(policy->cpu);
-       if (!policy)
-               goto no_policy;
+
+       if (!down_read_trylock(&cpufreq_rwsem))
+               goto exit;
 
        if (lock_policy_rwsem_write(policy->cpu) < 0)
-               goto fail;
+               goto up_read;
 
        if (fattr->store)
                ret = fattr->store(policy, buf, count);
@@ -737,9 +706,10 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
                ret = -EIO;
 
        unlock_policy_rwsem_write(policy->cpu);
-fail:
-       cpufreq_cpu_put_sysfs(policy);
-no_policy:
+
+up_read:
+       up_read(&cpufreq_rwsem);
+exit:
        return ret;
 }
 
@@ -805,41 +775,32 @@ void cpufreq_sysfs_remove_file(const struct attribute *attr)
 EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
 
 /* symlink affected CPUs */
-static int cpufreq_add_dev_symlink(unsigned int cpu,
-                                  struct cpufreq_policy *policy)
+static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy)
 {
        unsigned int j;
        int ret = 0;
 
        for_each_cpu(j, policy->cpus) {
-               struct cpufreq_policy *managed_policy;
                struct device *cpu_dev;
 
-               if (j == cpu)
+               if (j == policy->cpu)
                        continue;
 
-               pr_debug("CPU %u already managed, adding link\n", j);
-               managed_policy = cpufreq_cpu_get(cpu);
+               pr_debug("Adding link for CPU: %u\n", j);
                cpu_dev = get_cpu_device(j);
                ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
                                        "cpufreq");
-               if (ret) {
-                       cpufreq_cpu_put(managed_policy);
-                       return ret;
-               }
+               if (ret)
+                       break;
        }
        return ret;
 }
 
-static int cpufreq_add_dev_interface(unsigned int cpu,
-                                    struct cpufreq_policy *policy,
+static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
                                     struct device *dev)
 {
-       struct cpufreq_policy new_policy;
        struct freq_attr **drv_attr;
-       unsigned long flags;
        int ret = 0;
-       unsigned int j;
 
        /* prepare interface data */
        ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
@@ -871,18 +832,24 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
                        goto err_out_kobj_put;
        }
 
-       write_lock_irqsave(&cpufreq_driver_lock, flags);
-       for_each_cpu(j, policy->cpus) {
-               per_cpu(cpufreq_cpu_data, j) = policy;
-               per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
-       }
-       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
-       ret = cpufreq_add_dev_symlink(cpu, policy);
+       ret = cpufreq_add_dev_symlink(policy);
        if (ret)
                goto err_out_kobj_put;
 
-       memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+       return ret;
+
+err_out_kobj_put:
+       kobject_put(&policy->kobj);
+       wait_for_completion(&policy->kobj_unregister);
+       return ret;
+}
+
+static void cpufreq_init_policy(struct cpufreq_policy *policy)
+{
+       struct cpufreq_policy new_policy;
+       int ret = 0;
+
+       memcpy(&new_policy, policy, sizeof(*policy));
        /* assure that the starting sequence is run in __cpufreq_set_policy */
        policy->governor = NULL;
 
@@ -896,72 +863,106 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
                if (cpufreq_driver->exit)
                        cpufreq_driver->exit(policy);
        }
-       return ret;
-
-err_out_kobj_put:
-       kobject_put(&policy->kobj);
-       wait_for_completion(&policy->kobj_unregister);
-       return ret;
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
-                                 struct device *dev)
+static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
+                                 unsigned int cpu, struct device *dev,
+                                 bool frozen)
 {
-       struct cpufreq_policy *policy;
        int ret = 0, has_target = !!cpufreq_driver->target;
        unsigned long flags;
 
-       policy = cpufreq_cpu_get(sibling);
-       WARN_ON(!policy);
-
-       if (has_target)
-               __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+       if (has_target) {
+               ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+               if (ret) {
+                       pr_err("%s: Failed to stop governor\n", __func__);
+                       return ret;
+               }
+       }
 
-       lock_policy_rwsem_write(sibling);
+       lock_policy_rwsem_write(policy->cpu);
 
        write_lock_irqsave(&cpufreq_driver_lock, flags);
 
        cpumask_set_cpu(cpu, policy->cpus);
-       per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
        per_cpu(cpufreq_cpu_data, cpu) = policy;
        write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       unlock_policy_rwsem_write(sibling);
+       unlock_policy_rwsem_write(policy->cpu);
 
        if (has_target) {
-               __cpufreq_governor(policy, CPUFREQ_GOV_START);
-               __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
+               if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
+                       (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
+                       pr_err("%s: Failed to start governor\n", __func__);
+                       return ret;
+               }
        }
 
-       ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
-       if (ret) {
-               cpufreq_cpu_put(policy);
-               return ret;
-       }
+       /* Don't touch sysfs links during light-weight init */
+       if (!frozen)
+               ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
 
-       return 0;
+       return ret;
 }
 #endif
 
-/**
- * cpufreq_add_dev - add a CPU device
- *
- * Adds the cpufreq interface for a CPU device.
- *
- * The Oracle says: try running cpufreq registration/unregistration concurrently
- * with with cpu hotplugging and all hell will break loose. Tried to clean this
- * mess up, but more thorough testing is needed. - Mathieu
- */
-static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
+static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
+{
+       struct cpufreq_policy *policy;
+       unsigned long flags;
+
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
+
+       policy = per_cpu(cpufreq_cpu_data_fallback, cpu);
+
+       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+       return policy;
+}
+
+static struct cpufreq_policy *cpufreq_policy_alloc(void)
+{
+       struct cpufreq_policy *policy;
+
+       policy = kzalloc(sizeof(*policy), GFP_KERNEL);
+       if (!policy)
+               return NULL;
+
+       if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
+               goto err_free_policy;
+
+       if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
+               goto err_free_cpumask;
+
+       INIT_LIST_HEAD(&policy->policy_list);
+       return policy;
+
+err_free_cpumask:
+       free_cpumask_var(policy->cpus);
+err_free_policy:
+       kfree(policy);
+
+       return NULL;
+}
+
+static void cpufreq_policy_free(struct cpufreq_policy *policy)
+{
+       free_cpumask_var(policy->related_cpus);
+       free_cpumask_var(policy->cpus);
+       kfree(policy);
+}
+
+static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
+                            bool frozen)
 {
        unsigned int j, cpu = dev->id;
        int ret = -ENOMEM;
        struct cpufreq_policy *policy;
        unsigned long flags;
 #ifdef CONFIG_HOTPLUG_CPU
+       struct cpufreq_policy *tpolicy;
        struct cpufreq_governor *gov;
-       int sibling;
 #endif
 
        if (cpu_is_offline(cpu))
@@ -977,43 +978,38 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
                cpufreq_cpu_put(policy);
                return 0;
        }
+#endif
+
+       if (!down_read_trylock(&cpufreq_rwsem))
+               return 0;
 
 #ifdef CONFIG_HOTPLUG_CPU
        /* Check if this cpu was hot-unplugged earlier and has siblings */
        read_lock_irqsave(&cpufreq_driver_lock, flags);
-       for_each_online_cpu(sibling) {
-               struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
-               if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
+       list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) {
+               if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) {
                        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
-                       return cpufreq_add_policy_cpu(cpu, sibling, dev);
+                       ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen);
+                       up_read(&cpufreq_rwsem);
+                       return ret;
                }
        }
        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
-#endif
 #endif
 
-       if (!try_module_get(cpufreq_driver->owner)) {
-               ret = -EINVAL;
-               goto module_out;
-       }
+       if (frozen)
+               /* Restore the saved policy when doing light-weight init */
+               policy = cpufreq_policy_restore(cpu);
+       else
+               policy = cpufreq_policy_alloc();
 
-       policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
        if (!policy)
                goto nomem_out;
 
-       if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
-               goto err_free_policy;
-
-       if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
-               goto err_free_cpumask;
-
        policy->cpu = cpu;
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        cpumask_copy(policy->cpus, cpumask_of(cpu));
 
-       /* Initially set CPU itself as the policy_cpu */
-       per_cpu(cpufreq_policy_cpu, cpu) = cpu;
-
        init_completion(&policy->kobj_unregister);
        INIT_WORK(&policy->update, handle_update);
 
@@ -1050,12 +1046,26 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
        }
 #endif
 
-       ret = cpufreq_add_dev_interface(cpu, policy, dev);
-       if (ret)
-               goto err_out_unregister;
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
+       for_each_cpu(j, policy->cpus)
+               per_cpu(cpufreq_cpu_data, j) = policy;
+       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+       if (!frozen) {
+               ret = cpufreq_add_dev_interface(policy, dev);
+               if (ret)
+                       goto err_out_unregister;
+       }
+
+       write_lock_irqsave(&cpufreq_driver_lock, flags);
+       list_add(&policy->policy_list, &cpufreq_policy_list);
+       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+       cpufreq_init_policy(policy);
 
        kobject_uevent(&policy->kobj, KOBJ_ADD);
-       module_put(cpufreq_driver->owner);
+       up_read(&cpufreq_rwsem);
+
        pr_debug("initialization complete\n");
 
        return 0;
@@ -1066,32 +1076,33 @@ err_out_unregister:
                per_cpu(cpufreq_cpu_data, j) = NULL;
        write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       kobject_put(&policy->kobj);
-       wait_for_completion(&policy->kobj_unregister);
-
 err_set_policy_cpu:
-       per_cpu(cpufreq_policy_cpu, cpu) = -1;
-       free_cpumask_var(policy->related_cpus);
-err_free_cpumask:
-       free_cpumask_var(policy->cpus);
-err_free_policy:
-       kfree(policy);
+       cpufreq_policy_free(policy);
 nomem_out:
-       module_put(cpufreq_driver->owner);
-module_out:
+       up_read(&cpufreq_rwsem);
+
        return ret;
 }
 
-static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
+/**
+ * cpufreq_add_dev - add a CPU device
+ *
+ * Adds the cpufreq interface for a CPU device.
+ *
+ * The Oracle says: try running cpufreq registration/unregistration concurrently
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
+ */
+static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
 {
-       int j;
+       return __cpufreq_add_dev(dev, sif, false);
+}
 
+static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
+{
        policy->last_cpu = policy->cpu;
        policy->cpu = cpu;
 
-       for_each_cpu(j, policy->cpus)
-               per_cpu(cpufreq_policy_cpu, j) = cpu;
-
 #ifdef CONFIG_CPU_FREQ_TABLE
        cpufreq_frequency_table_update_policy_cpu(policy);
 #endif
@@ -1099,6 +1110,37 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
                        CPUFREQ_UPDATE_POLICY_CPU, policy);
 }
 
+static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
+                                          unsigned int old_cpu, bool frozen)
+{
+       struct device *cpu_dev;
+       int ret;
+
+       /* first sibling now owns the new sysfs dir */
+       cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
+
+       /* Don't touch sysfs files during light-weight tear-down */
+       if (frozen)
+               return cpu_dev->id;
+
+       sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
+       ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
+       if (ret) {
+               pr_err("%s: Failed to move kobj: %d", __func__, ret);
+
+               WARN_ON(lock_policy_rwsem_write(old_cpu));
+               cpumask_set_cpu(old_cpu, policy->cpus);
+               unlock_policy_rwsem_write(old_cpu);
+
+               ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
+                                       "cpufreq");
+
+               return -EINVAL;
+       }
+
+       return cpu_dev->id;
+}
+
 /**
  * __cpufreq_remove_dev - remove a CPU device
  *
@@ -1107,111 +1149,126 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
  * This routine frees the rwsem before returning.
  */
 static int __cpufreq_remove_dev(struct device *dev,
-               struct subsys_interface *sif)
+                               struct subsys_interface *sif, bool frozen)
 {
-       unsigned int cpu = dev->id, ret, cpus;
+       unsigned int cpu = dev->id, cpus;
+       int new_cpu, ret;
        unsigned long flags;
-       struct cpufreq_policy *data;
+       struct cpufreq_policy *policy;
        struct kobject *kobj;
        struct completion *cmp;
-       struct device *cpu_dev;
 
        pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
 
        write_lock_irqsave(&cpufreq_driver_lock, flags);
 
-       data = per_cpu(cpufreq_cpu_data, cpu);
-       per_cpu(cpufreq_cpu_data, cpu) = NULL;
+       policy = per_cpu(cpufreq_cpu_data, cpu);
+
+       /* Save the policy somewhere when doing a light-weight tear-down */
+       if (frozen)
+               per_cpu(cpufreq_cpu_data_fallback, cpu) = policy;
 
        write_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       if (!data) {
+       if (!policy) {
                pr_debug("%s: No cpu_data found\n", __func__);
                return -EINVAL;
        }
 
-       if (cpufreq_driver->target)
-               __cpufreq_governor(data, CPUFREQ_GOV_STOP);
+       if (cpufreq_driver->target) {
+               ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+               if (ret) {
+                       pr_err("%s: Failed to stop governor\n", __func__);
+                       return ret;
+               }
+       }
 
 #ifdef CONFIG_HOTPLUG_CPU
        if (!cpufreq_driver->setpolicy)
                strncpy(per_cpu(cpufreq_cpu_governor, cpu),
-                       data->governor->name, CPUFREQ_NAME_LEN);
+                       policy->governor->name, CPUFREQ_NAME_LEN);
 #endif
 
        WARN_ON(lock_policy_rwsem_write(cpu));
-       cpus = cpumask_weight(data->cpus);
+       cpus = cpumask_weight(policy->cpus);
 
        if (cpus > 1)
-               cpumask_clear_cpu(cpu, data->cpus);
+               cpumask_clear_cpu(cpu, policy->cpus);
        unlock_policy_rwsem_write(cpu);
 
-       if (cpu != data->cpu) {
+       if (cpu != policy->cpu && !frozen) {
                sysfs_remove_link(&dev->kobj, "cpufreq");
        } else if (cpus > 1) {
-               /* first sibling now owns the new sysfs dir */
-               cpu_dev = get_cpu_device(cpumask_first(data->cpus));
-               sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
-               ret = kobject_move(&data->kobj, &cpu_dev->kobj);
-               if (ret) {
-                       pr_err("%s: Failed to move kobj: %d", __func__, ret);
 
+               new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
+               if (new_cpu >= 0) {
                        WARN_ON(lock_policy_rwsem_write(cpu));
-                       cpumask_set_cpu(cpu, data->cpus);
-
-                       write_lock_irqsave(&cpufreq_driver_lock, flags);
-                       per_cpu(cpufreq_cpu_data, cpu) = data;
-                       write_unlock_irqrestore(&cpufreq_driver_lock, flags);
-
+                       update_policy_cpu(policy, new_cpu);
                        unlock_policy_rwsem_write(cpu);
 
-                       ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
-                                       "cpufreq");
-                       return -EINVAL;
+                       if (!frozen) {
+                               pr_debug("%s: policy Kobject moved to cpu: %d "
+                                        "from: %d\n",__func__, new_cpu, cpu);
+                       }
                }
-
-               WARN_ON(lock_policy_rwsem_write(cpu));
-               update_policy_cpu(data, cpu_dev->id);
-               unlock_policy_rwsem_write(cpu);
-               pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
-                               __func__, cpu_dev->id, cpu);
        }
 
        /* If cpu is last user of policy, free policy */
        if (cpus == 1) {
-               if (cpufreq_driver->target)
-                       __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
-
-               lock_policy_rwsem_read(cpu);
-               kobj = &data->kobj;
-               cmp = &data->kobj_unregister;
-               unlock_policy_rwsem_read(cpu);
-               kobject_put(kobj);
-
-               /* we need to make sure that the underlying kobj is actually
-                * not referenced anymore by anybody before we proceed with
-                * unloading.
-                */
-               pr_debug("waiting for dropping of refcount\n");
-               wait_for_completion(cmp);
-               pr_debug("wait complete\n");
+               if (cpufreq_driver->target) {
+                       ret = __cpufreq_governor(policy,
+                                       CPUFREQ_GOV_POLICY_EXIT);
+                       if (ret) {
+                               pr_err("%s: Failed to exit governor\n",
+                                               __func__);
+                               return ret;
+                       }
+               }
+
+               if (!frozen) {
+                       lock_policy_rwsem_read(cpu);
+                       kobj = &policy->kobj;
+                       cmp = &policy->kobj_unregister;
+                       unlock_policy_rwsem_read(cpu);
+                       kobject_put(kobj);
+
+                       /*
+                        * We need to make sure that the underlying kobj is
+                        * actually not referenced anymore by anybody before we
+                        * proceed with unloading.
+                        */
+                       pr_debug("waiting for dropping of refcount\n");
+                       wait_for_completion(cmp);
+                       pr_debug("wait complete\n");
+               }
 
+               /*
+                * Perform the ->exit() even during light-weight tear-down,
+                * since this is a core component, and is essential for the
+                * subsequent light-weight ->init() to succeed.
+                */
                if (cpufreq_driver->exit)
-                       cpufreq_driver->exit(data);
+                       cpufreq_driver->exit(policy);
 
-               free_cpumask_var(data->related_cpus);
-               free_cpumask_var(data->cpus);
-               kfree(data);
+               /* Remove policy from list of active policies */
+               write_lock_irqsave(&cpufreq_driver_lock, flags);
+               list_del(&policy->policy_list);
+               write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+
+               if (!frozen)
+                       cpufreq_policy_free(policy);
        } else {
-               pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
-               cpufreq_cpu_put(data);
                if (cpufreq_driver->target) {
-                       __cpufreq_governor(data, CPUFREQ_GOV_START);
-                       __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
+                       if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
+                                       (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
+                               pr_err("%s: Failed to start governor\n",
+                                               __func__);
+                               return ret;
+                       }
                }
        }
 
-       per_cpu(cpufreq_policy_cpu, cpu) = -1;
+       per_cpu(cpufreq_cpu_data, cpu) = NULL;
        return 0;
 }
 
@@ -1223,7 +1280,7 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
        if (cpu_is_offline(cpu))
                return 0;
 
-       retval = __cpufreq_remove_dev(dev, sif);
+       retval = __cpufreq_remove_dev(dev, sif, false);
        return retval;
 }
 
@@ -1344,10 +1401,9 @@ static unsigned int __cpufreq_get(unsigned int cpu)
 unsigned int cpufreq_get(unsigned int cpu)
 {
        unsigned int ret_freq = 0;
-       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
 
-       if (!policy)
-               goto out;
+       if (!down_read_trylock(&cpufreq_rwsem))
+               return 0;
 
        if (unlikely(lock_policy_rwsem_read(cpu)))
                goto out_policy;
@@ -1357,8 +1413,8 @@ unsigned int cpufreq_get(unsigned int cpu)
        unlock_policy_rwsem_read(cpu);
 
 out_policy:
-       cpufreq_cpu_put(policy);
-out:
+       up_read(&cpufreq_rwsem);
+
        return ret_freq;
 }
 EXPORT_SYMBOL(cpufreq_get);
@@ -1381,23 +1437,23 @@ static int cpufreq_bp_suspend(void)
        int ret = 0;
 
        int cpu = smp_processor_id();
-       struct cpufreq_policy *cpu_policy;
+       struct cpufreq_policy *policy;
 
        pr_debug("suspending cpu %u\n", cpu);
 
        /* If there's no policy for the boot CPU, we have nothing to do. */
-       cpu_policy = cpufreq_cpu_get(cpu);
-       if (!cpu_policy)
+       policy = cpufreq_cpu_get(cpu);
+       if (!policy)
                return 0;
 
        if (cpufreq_driver->suspend) {
-               ret = cpufreq_driver->suspend(cpu_policy);
+               ret = cpufreq_driver->suspend(policy);
                if (ret)
                        printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
-                                       "step on CPU %u\n", cpu_policy->cpu);
+                                       "step on CPU %u\n", policy->cpu);
        }
 
-       cpufreq_cpu_put(cpu_policy);
+       cpufreq_cpu_put(policy);
        return ret;
 }
 
@@ -1419,28 +1475,28 @@ static void cpufreq_bp_resume(void)
        int ret = 0;
 
        int cpu = smp_processor_id();
-       struct cpufreq_policy *cpu_policy;
+       struct cpufreq_policy *policy;
 
        pr_debug("resuming cpu %u\n", cpu);
 
        /* If there's no policy for the boot CPU, we have nothing to do. */
-       cpu_policy = cpufreq_cpu_get(cpu);
-       if (!cpu_policy)
+       policy = cpufreq_cpu_get(cpu);
+       if (!policy)
                return;
 
        if (cpufreq_driver->resume) {
-               ret = cpufreq_driver->resume(cpu_policy);
+               ret = cpufreq_driver->resume(policy);
                if (ret) {
                        printk(KERN_ERR "cpufreq: resume failed in ->resume "
-                                       "step on CPU %u\n", cpu_policy->cpu);
+                                       "step on CPU %u\n", policy->cpu);
                        goto fail;
                }
        }
 
-       schedule_work(&cpu_policy->update);
+       schedule_work(&policy->update);
 
 fail:
-       cpufreq_cpu_put(cpu_policy);
+       cpufreq_cpu_put(policy);
 }
 
 static struct syscore_ops cpufreq_syscore_ops = {
@@ -1594,18 +1650,6 @@ fail:
 }
 EXPORT_SYMBOL_GPL(cpufreq_driver_target);
 
-int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
-{
-       if (cpufreq_disabled())
-               return 0;
-
-       if (!cpufreq_driver->getavg)
-               return 0;
-
-       return cpufreq_driver->getavg(policy, cpu);
-}
-EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
-
 /*
  * when "event" is CPUFREQ_GOV_LIMITS
  */
@@ -1640,8 +1684,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
                }
        }
 
-       if (!try_module_get(policy->governor->owner))
-               return -EINVAL;
+       if (event == CPUFREQ_GOV_POLICY_INIT)
+               if (!try_module_get(policy->governor->owner))
+                       return -EINVAL;
 
        pr_debug("__cpufreq_governor for CPU %u, event %u\n",
                                                policy->cpu, event);
@@ -1677,11 +1722,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy,
                mutex_unlock(&cpufreq_governor_lock);
        }
 
-       /* we keep one module reference alive for
-                       each CPU governed by this CPU */
-       if ((event != CPUFREQ_GOV_START) || ret)
-               module_put(policy->governor->owner);
-       if ((event == CPUFREQ_GOV_STOP) && !ret)
+       if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
+                       ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
                module_put(policy->governor->owner);
 
        return ret;
@@ -1761,7 +1803,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
        if (!cpu_policy)
                return -EINVAL;
 
-       memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
+       memcpy(policy, cpu_policy, sizeof(*policy));
 
        cpufreq_cpu_put(cpu_policy);
        return 0;
@@ -1772,95 +1814,94 @@ EXPORT_SYMBOL(cpufreq_get_policy);
  * data   : current policy.
  * policy : policy to be set.
  */
-static int __cpufreq_set_policy(struct cpufreq_policy *data,
-                               struct cpufreq_policy *policy)
+static int __cpufreq_set_policy(struct cpufreq_policy *policy,
+                               struct cpufreq_policy *new_policy)
 {
        int ret = 0, failed = 1;
 
-       pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
-               policy->min, policy->max);
+       pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
+               new_policy->min, new_policy->max);
 
-       memcpy(&policy->cpuinfo, &data->cpuinfo,
-                               sizeof(struct cpufreq_cpuinfo));
+       memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
 
-       if (policy->min > data->max || policy->max < data->min) {
+       if (new_policy->min > policy->max || new_policy->max < policy->min) {
                ret = -EINVAL;
                goto error_out;
        }
 
        /* verify the cpu speed can be set within this limit */
-       ret = cpufreq_driver->verify(policy);
+       ret = cpufreq_driver->verify(new_policy);
        if (ret)
                goto error_out;
 
        /* adjust if necessary - all reasons */
        blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
-                       CPUFREQ_ADJUST, policy);
+                       CPUFREQ_ADJUST, new_policy);
 
        /* adjust if necessary - hardware incompatibility*/
        blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
-                       CPUFREQ_INCOMPATIBLE, policy);
+                       CPUFREQ_INCOMPATIBLE, new_policy);
 
        /*
         * verify the cpu speed can be set within this limit, which might be
         * different to the first one
         */
-       ret = cpufreq_driver->verify(policy);
+       ret = cpufreq_driver->verify(new_policy);
        if (ret)
                goto error_out;
 
        /* notification of the new policy */
        blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
-                       CPUFREQ_NOTIFY, policy);
+                       CPUFREQ_NOTIFY, new_policy);
 
-       data->min = policy->min;
-       data->max = policy->max;
+       policy->min = new_policy->min;
+       policy->max = new_policy->max;
 
        pr_debug("new min and max freqs are %u - %u kHz\n",
-                                       data->min, data->max);
+                                       policy->min, policy->max);
 
        if (cpufreq_driver->setpolicy) {
-               data->policy = policy->policy;
+               policy->policy = new_policy->policy;
                pr_debug("setting range\n");
-               ret = cpufreq_driver->setpolicy(policy);
+               ret = cpufreq_driver->setpolicy(new_policy);
        } else {
-               if (policy->governor != data->governor) {
+               if (new_policy->governor != policy->governor) {
                        /* save old, working values */
-                       struct cpufreq_governor *old_gov = data->governor;
+                       struct cpufreq_governor *old_gov = policy->governor;
 
                        pr_debug("governor switch\n");
 
                        /* end old governor */
-                       if (data->governor) {
-                               __cpufreq_governor(data, CPUFREQ_GOV_STOP);
-                               unlock_policy_rwsem_write(policy->cpu);
-                               __cpufreq_governor(data,
+                       if (policy->governor) {
+                               __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
+                               unlock_policy_rwsem_write(new_policy->cpu);
+                               __cpufreq_governor(policy,
                                                CPUFREQ_GOV_POLICY_EXIT);
-                               lock_policy_rwsem_write(policy->cpu);
+                               lock_policy_rwsem_write(new_policy->cpu);
                        }
 
                        /* start new governor */
-                       data->governor = policy->governor;
-                       if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
-                               if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {
+                       policy->governor = new_policy->governor;
+                       if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
+                               if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
                                        failed = 0;
                                } else {
-                                       unlock_policy_rwsem_write(policy->cpu);
-                                       __cpufreq_governor(data,
+                                       unlock_policy_rwsem_write(new_policy->cpu);
+                                       __cpufreq_governor(policy,
                                                        CPUFREQ_GOV_POLICY_EXIT);
-                                       lock_policy_rwsem_write(policy->cpu);
+                                       lock_policy_rwsem_write(new_policy->cpu);
                                }
                        }
 
                        if (failed) {
                                /* new governor failed, so re-start old one */
                                pr_debug("starting governor %s failed\n",
-                                                       data->governor->name);
+                                                       policy->governor->name);
                                if (old_gov) {
-                                       data->governor = old_gov;
-                                       __cpufreq_governor(data,
+                                       policy->governor = old_gov;
+                                       __cpufreq_governor(policy,
                                                        CPUFREQ_GOV_POLICY_INIT);
-                                       __cpufreq_governor(data,
+                                       __cpufreq_governor(policy,
                                                           CPUFREQ_GOV_START);
                                }
                                ret = -EINVAL;
@@ -1869,7 +1910,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
                        /* might be a policy change, too, so fall through */
                }
                pr_debug("governor: change or update limits\n");
-               __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
+               ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
        }
 
 error_out:
@@ -1885,11 +1926,11 @@ error_out:
  */
 int cpufreq_update_policy(unsigned int cpu)
 {
-       struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
-       struct cpufreq_policy policy;
+       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+       struct cpufreq_policy new_policy;
        int ret;
 
-       if (!data) {
+       if (!policy) {
                ret = -ENODEV;
                goto no_policy;
        }
@@ -1900,34 +1941,34 @@ int cpufreq_update_policy(unsigned int cpu)
        }
 
        pr_debug("updating policy for CPU %u\n", cpu);
-       memcpy(&policy, data, sizeof(struct cpufreq_policy));
-       policy.min = data->user_policy.min;
-       policy.max = data->user_policy.max;
-       policy.policy = data->user_policy.policy;
-       policy.governor = data->user_policy.governor;
+       memcpy(&new_policy, policy, sizeof(*policy));
+       new_policy.min = policy->user_policy.min;
+       new_policy.max = policy->user_policy.max;
+       new_policy.policy = policy->user_policy.policy;
+       new_policy.governor = policy->user_policy.governor;
 
        /*
         * BIOS might change freq behind our back
         * -> ask driver for current freq and notify governors about a change
         */
        if (cpufreq_driver->get) {
-               policy.cur = cpufreq_driver->get(cpu);
-               if (!data->cur) {
+               new_policy.cur = cpufreq_driver->get(cpu);
+               if (!policy->cur) {
                        pr_debug("Driver did not initialize current freq");
-                       data->cur = policy.cur;
+                       policy->cur = new_policy.cur;
                } else {
-                       if (data->cur != policy.cur && cpufreq_driver->target)
-                               cpufreq_out_of_sync(cpu, data->cur,
-                                                               policy.cur);
+                       if (policy->cur != new_policy.cur && cpufreq_driver->target)
+                               cpufreq_out_of_sync(cpu, policy->cur,
+                                                               new_policy.cur);
                }
        }
 
-       ret = __cpufreq_set_policy(data, &policy);
+       ret = __cpufreq_set_policy(policy, &new_policy);
 
        unlock_policy_rwsem_write(cpu);
 
 fail:
-       cpufreq_cpu_put(data);
+       cpufreq_cpu_put(policy);
 no_policy:
        return ret;
 }
@@ -1938,21 +1979,26 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb,
 {
        unsigned int cpu = (unsigned long)hcpu;
        struct device *dev;
+       bool frozen = false;
 
        dev = get_cpu_device(cpu);
        if (dev) {
-               switch (action) {
+
+               if (action & CPU_TASKS_FROZEN)
+                       frozen = true;
+
+               switch (action & ~CPU_TASKS_FROZEN) {
                case CPU_ONLINE:
-               case CPU_ONLINE_FROZEN:
-                       cpufreq_add_dev(dev, NULL);
+                       __cpufreq_add_dev(dev, NULL, frozen);
+                       cpufreq_update_policy(cpu);
                        break;
+
                case CPU_DOWN_PREPARE:
-               case CPU_DOWN_PREPARE_FROZEN:
-                       __cpufreq_remove_dev(dev, NULL);
+                       __cpufreq_remove_dev(dev, NULL, frozen);
                        break;
+
                case CPU_DOWN_FAILED:
-               case CPU_DOWN_FAILED_FROZEN:
-                       cpufreq_add_dev(dev, NULL);
+                       __cpufreq_add_dev(dev, NULL, frozen);
                        break;
                }
        }
@@ -2059,9 +2105,13 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
        subsys_interface_unregister(&cpufreq_interface);
        unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
 
+       down_write(&cpufreq_rwsem);
        write_lock_irqsave(&cpufreq_driver_lock, flags);
+
        cpufreq_driver = NULL;
+
        write_unlock_irqrestore(&cpufreq_driver_lock, flags);
+       up_write(&cpufreq_rwsem);
 
        return 0;
 }
@@ -2074,10 +2124,8 @@ static int __init cpufreq_core_init(void)
        if (cpufreq_disabled())
                return -ENODEV;
 
-       for_each_possible_cpu(cpu) {
-               per_cpu(cpufreq_policy_cpu, cpu) = -1;
+       for_each_possible_cpu(cpu)
                init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
-       }
 
        cpufreq_global_kobject = kobject_create();
        BUG_ON(!cpufreq_global_kobject);
index f97cb3d8c5a232a60f319e04da5c0616624925d4..7f67a75b3c3c635a8c10e952c3be3b5549809b01 100644 (file)
  * published by the Free Software Foundation.
  */
 
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/kobject.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/notifier.h>
-#include <linux/percpu-defs.h>
 #include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/types.h>
-
 #include "cpufreq_governor.h"
 
 /* Conservative governor macros */
@@ -329,7 +317,7 @@ static int cs_init(struct dbs_data *dbs_data)
 {
        struct cs_dbs_tuners *tuners;
 
-       tuners = kzalloc(sizeof(struct cs_dbs_tuners), GFP_KERNEL);
+       tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
        if (!tuners) {
                pr_err("%s: kzalloc failed\n", __func__);
                return -ENOMEM;
index e59afaa9da23af0dfd826751e817ab6b41e94a0b..87427360c77f95ad095d10da10568c923cb87a6c 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <asm/cputime.h>
-#include <linux/cpufreq.h>
-#include <linux/cpumask.h>
 #include <linux/export.h>
 #include <linux/kernel_stat.h>
-#include <linux/mutex.h>
 #include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/workqueue.h>
 
 #include "cpufreq_governor.h"
 
@@ -53,7 +47,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
 
        policy = cdbs->cur_policy;
 
-       /* Get Absolute Load (in terms of freq for ondemand gov) */
+       /* Get Absolute Load */
        for_each_cpu(j, policy->cpus) {
                struct cpu_dbs_common_info *j_cdbs;
                u64 cur_wall_time, cur_idle_time;
@@ -104,14 +98,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu)
 
                load = 100 * (wall_time - idle_time) / wall_time;
 
-               if (dbs_data->cdata->governor == GOV_ONDEMAND) {
-                       int freq_avg = __cpufreq_driver_getavg(policy, j);
-                       if (freq_avg <= 0)
-                               freq_avg = policy->cur;
-
-                       load *= freq_avg;
-               }
-
                if (load > max_load)
                        max_load = load;
        }
index d5f12b4b11b8af09c608bd6f74f01601e0a91f2d..a02d78b258982d36d13724879c6b719376c2e7ab 100644 (file)
 #define _CPUFREQ_GOVERNOR_H
 
 #include <linux/cpufreq.h>
-#include <linux/kobject.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
-#include <linux/workqueue.h>
-#include <linux/sysfs.h>
 
 /*
  * The polling frequency depends on the capability of the processor. Default
@@ -169,7 +168,6 @@ struct od_dbs_tuners {
        unsigned int sampling_rate;
        unsigned int sampling_down_factor;
        unsigned int up_threshold;
-       unsigned int adj_up_threshold;
        unsigned int powersave_bias;
        unsigned int io_is_busy;
 };
@@ -223,7 +221,7 @@ struct od_ops {
        void (*powersave_bias_init_cpu)(int cpu);
        unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,
                        unsigned int freq_next, unsigned int relation);
-       void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq);
+       void (*freq_increase)(struct cpufreq_policy *policy, unsigned int freq);
 };
 
 struct cs_ops {
index c087347d66884f03a4f1b2a94bf4fcbaceeda7a0..87f3305e80a69fb02001dbaaf2b398c1c2e9dede 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/kernel_stat.h>
-#include <linux/kobject.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
+#include <linux/cpu.h>
 #include <linux/percpu-defs.h>
 #include <linux/slab.h>
-#include <linux/sysfs.h>
 #include <linux/tick.h>
-#include <linux/types.h>
-#include <linux/cpu.h>
-
 #include "cpufreq_governor.h"
 
 /* On-demand governor macros */
-#define DEF_FREQUENCY_DOWN_DIFFERENTIAL                (10)
 #define DEF_FREQUENCY_UP_THRESHOLD             (80)
 #define DEF_SAMPLING_DOWN_FACTOR               (1)
 #define MAX_SAMPLING_DOWN_FACTOR               (100000)
-#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL      (3)
 #define MICRO_FREQUENCY_UP_THRESHOLD           (95)
 #define MICRO_FREQUENCY_MIN_SAMPLE_RATE                (10000)
 #define MIN_FREQUENCY_UP_THRESHOLD             (11)
@@ -144,31 +132,27 @@ static void ondemand_powersave_bias_init(void)
        }
 }
 
-static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
+static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq)
 {
-       struct dbs_data *dbs_data = p->governor_data;
+       struct dbs_data *dbs_data = policy->governor_data;
        struct od_dbs_tuners *od_tuners = dbs_data->tuners;
 
        if (od_tuners->powersave_bias)
-               freq = od_ops.powersave_bias_target(p, freq,
+               freq = od_ops.powersave_bias_target(policy, freq,
                                CPUFREQ_RELATION_H);
-       else if (p->cur == p->max)
+       else if (policy->cur == policy->max)
                return;
 
-       __cpufreq_driver_target(p, freq, od_tuners->powersave_bias ?
+       __cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ?
                        CPUFREQ_RELATION_L : CPUFREQ_RELATION_H);
 }
 
 /*
  * Every sampling_rate, we check, if current idle time is less than 20%
- * (default), then we try to increase frequency. Every sampling_rate, we look
- * for the lowest frequency which can sustain the load while keeping idle time
- * over 30%. If such a frequency exist, we try to decrease to this frequency.
- *
- * Any frequency increase takes it to the maximum frequency. Frequency reduction
- * happens at minimum steps of 5% (default) of current frequency
+ * (default), then we try to increase frequency. Else, we adjust the frequency
+ * proportional to load.
  */
-static void od_check_cpu(int cpu, unsigned int load_freq)
+static void od_check_cpu(int cpu, unsigned int load)
 {
        struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
        struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy;
@@ -178,29 +162,17 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
        dbs_info->freq_lo = 0;
 
        /* Check for frequency increase */
-       if (load_freq > od_tuners->up_threshold * policy->cur) {
+       if (load > od_tuners->up_threshold) {
                /* If switching to max speed, apply sampling_down_factor */
                if (policy->cur < policy->max)
                        dbs_info->rate_mult =
                                od_tuners->sampling_down_factor;
                dbs_freq_increase(policy, policy->max);
                return;
-       }
-
-       /* Check for frequency decrease */
-       /* if we cannot reduce the frequency anymore, break out early */
-       if (policy->cur == policy->min)
-               return;
-
-       /*
-        * The optimal frequency is the frequency that is the lowest that can
-        * support the current CPU usage without triggering the up policy. To be
-        * safe, we focus 10 points under the threshold.
-        */
-       if (load_freq < od_tuners->adj_up_threshold
-                       * policy->cur) {
+       } else {
+               /* Calculate the next frequency proportional to load */
                unsigned int freq_next;
-               freq_next = load_freq / od_tuners->adj_up_threshold;
+               freq_next = load * policy->cpuinfo.max_freq / 100;
 
                /* No longer fully busy, reset rate_mult */
                dbs_info->rate_mult = 1;
@@ -374,9 +346,6 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf,
                        input < MIN_FREQUENCY_UP_THRESHOLD) {
                return -EINVAL;
        }
-       /* Calculate the new adj_up_threshold */
-       od_tuners->adj_up_threshold += input;
-       od_tuners->adj_up_threshold -= od_tuners->up_threshold;
 
        od_tuners->up_threshold = input;
        return count;
@@ -513,7 +482,7 @@ static int od_init(struct dbs_data *dbs_data)
        u64 idle_time;
        int cpu;
 
-       tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL);
+       tuners = kzalloc(sizeof(*tuners), GFP_KERNEL);
        if (!tuners) {
                pr_err("%s: kzalloc failed\n", __func__);
                return -ENOMEM;
@@ -525,8 +494,6 @@ static int od_init(struct dbs_data *dbs_data)
        if (idle_time != -1ULL) {
                /* Idle micro accounting is supported. Use finer thresholds */
                tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD;
-               tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD -
-                       MICRO_FREQUENCY_DOWN_DIFFERENTIAL;
                /*
                 * In nohz/micro accounting case we set the minimum frequency
                 * not depending on HZ, but fixed (very low). The deferred
@@ -535,8 +502,6 @@ static int od_init(struct dbs_data *dbs_data)
                dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE;
        } else {
                tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD;
-               tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD -
-                       DEF_FREQUENCY_DOWN_DIFFERENTIAL;
 
                /* For correct statistics, we need 10 ticks for each measure */
                dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
index 9fef7d6e4e6a6f05a96e7b8153ecb0043e7a4f6e..cf117deb39b1f45c53ade61086236eb888d24a71 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 static int cpufreq_governor_performance(struct cpufreq_policy *policy,
                                        unsigned int event)
index 32109a14f5dc04e0d99c89a8113428afa545bbb7..e3b874c235eada5d353f4b02831140c6a244af68 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/kernel.h>
-#include <linux/module.h>
 #include <linux/cpufreq.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
                                        unsigned int event)
index d37568c5ca9c36b32dc69a8361337450c0ca1ddc..04452f026ed085a7b61f87c623c8677a2e242864 100644 (file)
@@ -9,17 +9,10 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/cpu.h>
-#include <linux/sysfs.h>
 #include <linux/cpufreq.h>
 #include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/percpu.h>
-#include <linux/kobject.h>
-#include <linux/spinlock.h>
-#include <linux/notifier.h>
+#include <linux/slab.h>
 #include <asm/cputime.h>
 
 static spinlock_t cpufreq_stats_lock;
@@ -200,22 +193,22 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
 {
        unsigned int i, j, count = 0, ret = 0;
        struct cpufreq_stats *stat;
-       struct cpufreq_policy *data;
+       struct cpufreq_policy *current_policy;
        unsigned int alloc_size;
        unsigned int cpu = policy->cpu;
        if (per_cpu(cpufreq_stats_table, cpu))
                return -EBUSY;
-       stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL);
+       stat = kzalloc(sizeof(*stat), GFP_KERNEL);
        if ((stat) == NULL)
                return -ENOMEM;
 
-       data = cpufreq_cpu_get(cpu);
-       if (data == NULL) {
+       current_policy = cpufreq_cpu_get(cpu);
+       if (current_policy == NULL) {
                ret = -EINVAL;
                goto error_get_fail;
        }
 
-       ret = sysfs_create_group(&data->kobj, &stats_attr_group);
+       ret = sysfs_create_group(&current_policy->kobj, &stats_attr_group);
        if (ret)
                goto error_out;
 
@@ -258,10 +251,10 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
        stat->last_time = get_jiffies_64();
        stat->last_index = freq_table_get_index(stat, policy->cur);
        spin_unlock(&cpufreq_stats_lock);
-       cpufreq_cpu_put(data);
+       cpufreq_cpu_put(current_policy);
        return 0;
 error_out:
-       cpufreq_cpu_put(data);
+       cpufreq_cpu_put(current_policy);
 error_get_fail:
        kfree(stat);
        per_cpu(cpufreq_stats_table, cpu) = NULL;
@@ -348,16 +341,10 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb,
        unsigned int cpu = (unsigned long)hcpu;
 
        switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               cpufreq_update_policy(cpu);
-               break;
        case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
                cpufreq_stats_free_sysfs(cpu);
                break;
        case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
                cpufreq_stats_free_table(cpu);
                break;
        }
@@ -390,8 +377,6 @@ static int __init cpufreq_stats_init(void)
                return ret;
 
        register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
-       for_each_online_cpu(cpu)
-               cpufreq_update_policy(cpu);
 
        ret = cpufreq_register_notifier(&notifier_trans_block,
                                CPUFREQ_TRANSITION_NOTIFIER);
index ee142c4905756afe79e0c034acb2351f278594ac..cb8276dd19caee0a5e2756883148a2d70a7132f2 100644 (file)
@@ -111,7 +111,6 @@ static struct cpufreq_driver cris_freq_driver = {
        .init   = cris_freq_cpu_init,
        .exit   = cris_freq_cpu_exit,
        .name   = "cris_freq",
-       .owner  = THIS_MODULE,
        .attr   = cris_freq_attr,
 };
 
index 12952235d5dbc69bc6f83c0efb34bd7c8663f253..72328f77dc53bdef993173a1832d3159ac3fd03c 100644 (file)
@@ -108,7 +108,6 @@ static struct cpufreq_driver cris_freq_driver = {
        .init = cris_freq_cpu_init,
        .exit = cris_freq_cpu_exit,
        .name = "cris_freq",
-       .owner = THIS_MODULE,
        .attr = cris_freq_attr,
 };
 
index a60efaeb4cf8c17291ec97a0ba86bb383fe81d55..09f64cc830197fc1f80f605e41d73be6b0441435 100644 (file)
@@ -54,7 +54,7 @@ static struct acpi_processor_performance *eps_acpi_cpu_perf;
 /* Minimum necessary to get acpi_processor_get_bios_limit() working */
 static int eps_acpi_init(void)
 {
-       eps_acpi_cpu_perf = kzalloc(sizeof(struct acpi_processor_performance),
+       eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf),
                                      GFP_KERNEL);
        if (!eps_acpi_cpu_perf)
                return -ENOMEM;
@@ -366,7 +366,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
                states = 2;
 
        /* Allocate private data and frequency table for current cpu */
-       centaur = kzalloc(sizeof(struct eps_cpu_data)
+       centaur = kzalloc(sizeof(*centaur)
                    + (states + 1) * sizeof(struct cpufreq_frequency_table),
                    GFP_KERNEL);
        if (!centaur)
@@ -436,7 +436,6 @@ static struct cpufreq_driver eps_driver = {
        .exit           = eps_cpu_exit,
        .get            = eps_get,
        .name           = "e_powersaver",
-       .owner          = THIS_MODULE,
        .attr           = eps_attr,
 };
 
index 658d860344b0df71bd8dd59751f3e5281ca34637..823a400d98fd6bc5f8c627db8151df572ffc68b9 100644 (file)
@@ -274,7 +274,6 @@ static struct cpufreq_driver elanfreq_driver = {
        .init           = elanfreq_cpu_init,
        .exit           = elanfreq_cpu_exit,
        .name           = "elanfreq",
-       .owner          = THIS_MODULE,
        .attr           = elanfreq_attr,
 };
 
index 0d32f02ef4d644e5ec915b9205fd5fdf929b30b0..0fac34439e3171dbc97b8f717a935b691657cba9 100644 (file)
@@ -289,7 +289,7 @@ static int __init exynos_cpufreq_init(void)
 {
        int ret = -EINVAL;
 
-       exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL);
+       exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL);
        if (!exynos_info)
                return -ENOMEM;
 
@@ -332,7 +332,6 @@ err_cpufreq:
        regulator_put(arm_regulator);
 err_vdd_arm:
        kfree(exynos_info);
-       pr_debug("%s: failed initialization\n", __func__);
        return -EINVAL;
 }
 late_initcall(exynos_cpufreq_init);
index 92b852ee5ddcca037bcbf9d2376ff3a4cb3a62c2..7f25cee8cec275692ee685a8b9bbccaf501b6a09 100644 (file)
@@ -43,6 +43,27 @@ struct exynos_dvfs_info {
        bool (*need_apll_change)(unsigned int, unsigned int);
 };
 
+#ifdef CONFIG_ARM_EXYNOS4210_CPUFREQ
 extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
+#else
+static inline int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
+{
+       return -EOPNOTSUPP;
+}
+#endif
+#ifdef CONFIG_ARM_EXYNOS4X12_CPUFREQ
 extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
+#else
+static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
+{
+       return -EOPNOTSUPP;
+}
+#endif
+#ifdef CONFIG_ARM_EXYNOS5250_CPUFREQ
 extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
+#else
+static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
+{
+       return -EOPNOTSUPP;
+}
+#endif
index 0c74018eda47e1fd2d09ef0db1baaf8595a70547..d514c152fd1a43041e8ff570fca7f9cc2b28f58d 100644 (file)
@@ -238,6 +238,9 @@ static int exynos_target(struct cpufreq_policy *policy,
        freqs.old = dvfs_info->cur_frequency;
        freqs.new = freq_table[index].frequency;
 
+       if (freqs.old == freqs.new)
+               goto out;
+
        cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
        /* Set the target frequency in all C0_3_PSTATE register */
index f0d87412cc91742a73fa40a500b160387af9fb28..f111454a7aeace94454e3c8eff6e7e45360380d7 100644 (file)
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/cpufreq.h>
+#include <linux/module.h>
 
 /*********************************************************************
  *                     FREQUENCY TABLE HELPERS                       *
index 3dfc99b9ca86f3228d0f0a8d8b600bd7ae11f260..70442c7b5e71aed7e57ce61b20893e42dc36a215 100644 (file)
@@ -183,7 +183,7 @@ static void gx_write_byte(int reg, int value)
  * gx_detect_chipset:
  *
  **/
-static __init struct pci_dev *gx_detect_chipset(void)
+static struct pci_dev * __init gx_detect_chipset(void)
 {
        struct pci_dev *gx_pci = NULL;
 
@@ -446,7 +446,6 @@ static struct cpufreq_driver gx_suspmod_driver = {
        .target         = cpufreq_gx_target,
        .init           = cpufreq_gx_cpu_init,
        .name           = "gx-suspmod",
-       .owner          = THIS_MODULE,
 };
 
 static int __init cpufreq_gx_init(void)
@@ -466,7 +465,7 @@ static int __init cpufreq_gx_init(void)
 
        pr_debug("geode suspend modulation available.\n");
 
-       params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
+       params = kzalloc(sizeof(*params), GFP_KERNEL);
        if (params == NULL)
                return -ENOMEM;
 
index b61b5a3fad64983cc1681f89dc599649bf129bde..794123fcf3e3ebce87cdbcbf0a66b60f4b70db2c 100644 (file)
@@ -69,23 +69,17 @@ static int hb_cpufreq_driver_init(void)
        if (!of_machine_is_compatible("calxeda,highbank"))
                return -ENODEV;
 
-       for_each_child_of_node(of_find_node_by_path("/cpus"), np)
-               if (of_get_property(np, "operating-points", NULL))
-                       break;
-
-       if (!np) {
-               pr_err("failed to find highbank cpufreq node\n");
-               return -ENOENT;
-       }
-
        cpu_dev = get_cpu_device(0);
        if (!cpu_dev) {
                pr_err("failed to get highbank cpufreq device\n");
-               ret = -ENODEV;
-               goto out_put_node;
+               return -ENODEV;
        }
 
-       cpu_dev->of_node = np;
+       np = of_node_get(cpu_dev->of_node);
+       if (!np) {
+               pr_err("failed to find highbank cpufreq node\n");
+               return -ENOENT;
+       }
 
        cpu_clk = clk_get(cpu_dev, NULL);
        if (IS_ERR(cpu_clk)) {
index 573c14ea802df7690f0e57ff3d8764b46305e51c..3e14f03171759bcdbd8a0501bc1ff38fee86d4c0 100644 (file)
@@ -274,7 +274,7 @@ acpi_cpufreq_cpu_init (
 
        pr_debug("acpi_cpufreq_cpu_init\n");
 
-       data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return (-ENOMEM);
 
@@ -304,7 +304,7 @@ acpi_cpufreq_cpu_init (
        }
 
        /* alloc freq_table */
-       data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
+       data->freq_table = kmalloc(sizeof(*data->freq_table) *
                                   (data->acpi_data.state_count + 1),
                                   GFP_KERNEL);
        if (!data->freq_table) {
@@ -409,7 +409,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
        .init           = acpi_cpufreq_cpu_init,
        .exit           = acpi_cpufreq_cpu_exit,
        .name           = "acpi-cpufreq",
-       .owner          = THIS_MODULE,
        .attr           = acpi_cpufreq_attr,
 };
 
index e37cdaedbb5b39b244e3aa6caec947721297999d..b16632bb5a567b945f412c721ccdac42639b219d 100644 (file)
@@ -221,14 +221,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
 
        cpu_dev = &pdev->dev;
 
-       np = of_find_node_by_path("/cpus/cpu@0");
+       np = of_node_get(cpu_dev->of_node);
        if (!np) {
                dev_err(cpu_dev, "failed to find cpu0 node\n");
                return -ENOENT;
        }
 
-       cpu_dev->of_node = np;
-
        arm_clk = devm_clk_get(cpu_dev, "arm");
        pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
        pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
index 7cde885011ed3d1b15809f6d25c1a7f3ddc3adf1..6efd96c196b2efff80e41b1851e4b445350ccf5b 100644 (file)
@@ -665,7 +665,6 @@ static struct cpufreq_driver intel_pstate_driver = {
        .init           = intel_pstate_cpu_init,
        .exit           = intel_pstate_cpu_exit,
        .name           = "intel_pstate",
-       .owner          = THIS_MODULE,
 };
 
 static int __initdata no_load;
index c233ea617366fad2c7e4a3ed1b2bc0a7f500fda1..ba10658a93949fe9adca0863c7c8926a11fe1676 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/cpufreq.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <asm/proc-fns.h>
@@ -158,7 +158,6 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = {
        .init   = kirkwood_cpufreq_cpu_init,
        .exit   = kirkwood_cpufreq_cpu_exit,
        .name   = "kirkwood-cpufreq",
-       .owner  = THIS_MODULE,
        .attr   = kirkwood_cpufreq_attr,
 };
 
@@ -175,9 +174,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev)
        if (IS_ERR(priv.base))
                return PTR_ERR(priv.base);
 
-       np = of_find_node_by_path("/cpus/cpu@0");
-       if (!np)
+       np = of_cpu_device_node_get(0);
+       if (!np) {
+               dev_err(&pdev->dev, "failed to get cpu device node\n");
                return -ENODEV;
+       }
 
        priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk");
        if (IS_ERR(priv.cpu_clk)) {
index 8c49261df57dff642f63921d08a9d61ee41d95e3..4ada1cccb0523632e72c016e9a511dd38b08d33d 100644 (file)
@@ -948,7 +948,6 @@ static struct cpufreq_driver longhaul_driver = {
        .init   = longhaul_cpu_init,
        .exit   = longhaul_cpu_exit,
        .name   = "longhaul",
-       .owner  = THIS_MODULE,
        .attr   = longhaul_attr,
 };
 
index 0fe041d1f77f4a48f84542b11db0c4d07ee97b46..5aa031612d5393ff08d196f83b8701ac8c8f5e12 100644 (file)
@@ -286,7 +286,6 @@ static struct cpufreq_driver longrun_driver = {
        .get            = longrun_get,
        .init           = longrun_cpu_init,
        .name           = "longrun",
-       .owner          = THIS_MODULE,
 };
 
 static const struct x86_cpu_id longrun_ids[] = {
index 9536852c504a559865bc023a2d75ebed22a0ffd9..7bc3c44d34e2f0ec5493ad9fdf0c8467ccd8a037 100644 (file)
@@ -158,7 +158,6 @@ static struct freq_attr *loongson2_table_attr[] = {
 };
 
 static struct cpufreq_driver loongson2_cpufreq_driver = {
-       .owner = THIS_MODULE,
        .name = "loongson2",
        .init = loongson2_cpufreq_cpu_init,
        .verify = loongson2_cpufreq_verify,
index cdd62915efafbc1708ee68d4d71d99c20d741b9e..6168d77b296d78b7d1a452bae6f3ae34c7e036c3 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/completion.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
 
 #define DBG(fmt...) pr_debug(fmt)
 
@@ -190,7 +190,6 @@ static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver maple_cpufreq_driver = {
        .name           = "maple",
-       .owner          = THIS_MODULE,
        .flags          = CPUFREQ_CONST_LOOPS,
        .init           = maple_cpufreq_cpu_init,
        .verify         = maple_cpufreq_verify,
@@ -201,7 +200,6 @@ static struct cpufreq_driver maple_cpufreq_driver = {
 
 static int __init maple_cpufreq_init(void)
 {
-       struct device_node *cpus;
        struct device_node *cpunode;
        unsigned int psize;
        unsigned long max_freq;
@@ -217,24 +215,11 @@ static int __init maple_cpufreq_init(void)
            !of_machine_is_compatible("Momentum,Apache"))
                return 0;
 
-       cpus = of_find_node_by_path("/cpus");
-       if (cpus == NULL) {
-               DBG("No /cpus node !\n");
-               return -ENODEV;
-       }
-
        /* Get first CPU node */
-       for (cpunode = NULL;
-            (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
-               const u32 *reg = of_get_property(cpunode, "reg", NULL);
-               if (reg == NULL || (*reg) != 0)
-                       continue;
-               if (!strcmp(cpunode->type, "cpu"))
-                       break;
-       }
+       cpunode = of_cpu_device_node_get(0);
        if (cpunode == NULL) {
                printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
-               goto bail_cpus;
+               goto bail_noprops;
        }
 
        /* Check 970FX for now */
@@ -290,14 +275,11 @@ static int __init maple_cpufreq_init(void)
        rc = cpufreq_register_driver(&maple_cpufreq_driver);
 
        of_node_put(cpunode);
-       of_node_put(cpus);
 
        return rc;
 
 bail_noprops:
        of_node_put(cpunode);
-bail_cpus:
-       of_node_put(cpus);
 
        return rc;
 }
diff --git a/drivers/cpufreq/mperf.c b/drivers/cpufreq/mperf.c
deleted file mode 100644 (file)
index 911e193..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/slab.h>
-
-#include "mperf.h"
-
-static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
-
-/* Called via smp_call_function_single(), on the target CPU */
-static void read_measured_perf_ctrs(void *_cur)
-{
-       struct aperfmperf *am = _cur;
-
-       get_aperfmperf(am);
-}
-
-/*
- * Return the measured active (C0) frequency on this CPU since last call
- * to this function.
- * Input: cpu number
- * Return: Average CPU frequency in terms of max frequency (zero on error)
- *
- * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
- * over a period of time, while CPU is in C0 state.
- * IA32_MPERF counts at the rate of max advertised frequency
- * IA32_APERF counts at the rate of actual CPU frequency
- * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
- * no meaning should be associated with absolute values of these MSRs.
- */
-unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
-                                       unsigned int cpu)
-{
-       struct aperfmperf perf;
-       unsigned long ratio;
-       unsigned int retval;
-
-       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
-               return 0;
-
-       ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
-       per_cpu(acfreq_old_perf, cpu) = perf;
-
-       retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
-
-       return retval;
-}
-EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf);
-MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/mperf.h b/drivers/cpufreq/mperf.h
deleted file mode 100644 (file)
index 5dbf295..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- *  (c) 2010 Advanced Micro Devices, Inc.
- *  Your use of this code is subject to the terms and conditions of the
- *  GNU general public license version 2. See "COPYING" or
- *  http://www.gnu.org/licenses/gpl.html
- */
-
-unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
-                                       unsigned int cpu);
index 9ee78170ff862a20cd7439e78d9ef0d71b542e77..2f0a2a65c37f67eeae9789ed12afa20627fd3503 100644 (file)
@@ -279,7 +279,6 @@ static struct cpufreq_driver p4clockmod_driver = {
        .exit           = cpufreq_p4_cpu_exit,
        .get            = cpufreq_p4_get,
        .name           = "p4-clockmod",
-       .owner          = THIS_MODULE,
        .attr           = p4clockmod_attr,
 };
 
index b704da404067061a4acd831e78b63572b54afc8c..534e43a60d1f9a80b2a952abe254fb01e06c0f12 100644 (file)
@@ -297,7 +297,6 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy,
 
 static struct cpufreq_driver pas_cpufreq_driver = {
        .name           = "pas-cpufreq",
-       .owner          = THIS_MODULE,
        .flags          = CPUFREQ_CONST_LOOPS,
        .init           = pas_cpufreq_cpu_init,
        .exit           = pas_cpufreq_cpu_exit,
index 1581fcc4cf4a9f3cf8de7b782abe932328584ef0..d81c4e5ea0ada8c49afac790f1107bc5ce8f11e6 100644 (file)
@@ -587,7 +587,6 @@ static struct cpufreq_driver pcc_cpufreq_driver = {
        .init = pcc_cpufreq_cpu_init,
        .exit = pcc_cpufreq_cpu_exit,
        .name = "pcc-cpufreq",
-       .owner = THIS_MODULE,
 };
 
 static int __init pcc_cpufreq_init(void)
index 3104fad824801d1e9b03480a9757317f3a602fba..a096cd3fa23d1aaef19b3ae27ecd87037f01ba6f 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/hardirq.h>
+#include <linux/of_device.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/irq.h>
@@ -477,7 +478,6 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
        .flags          = CPUFREQ_PM_NO_WARN,
        .attr           = pmac_cpu_freqs_attr,
        .name           = "powermac",
-       .owner          = THIS_MODULE,
 };
 
 
@@ -649,8 +649,8 @@ static int __init pmac_cpufreq_setup(void)
        if (strstr(cmd_line, "nocpufreq"))
                return 0;
 
-       /* Assume only one CPU */
-       cpunode = of_find_node_by_type(NULL, "cpu");
+       /* Get first CPU node */
+       cpunode = of_cpu_device_node_get(0);
        if (!cpunode)
                goto out;
 
index 7ba423431cfe0dfb53fcbe3c7f7195882c36ac3d..3a51ad7e47c8c67c95da5f3691d7f89e397c34a6 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/completion.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/irq.h>
@@ -371,7 +372,6 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver g5_cpufreq_driver = {
        .name           = "powermac",
-       .owner          = THIS_MODULE,
        .flags          = CPUFREQ_CONST_LOOPS,
        .init           = g5_cpufreq_cpu_init,
        .verify         = g5_cpufreq_verify,
@@ -383,9 +383,8 @@ static struct cpufreq_driver g5_cpufreq_driver = {
 
 #ifdef CONFIG_PMAC_SMU
 
-static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
+static int __init g5_neo2_cpufreq_init(struct device_node *cpunode)
 {
-       struct device_node *cpunode;
        unsigned int psize, ssize;
        unsigned long max_freq;
        char *freq_method, *volt_method;
@@ -405,20 +404,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
        else
                return -ENODEV;
 
-       /* Get first CPU node */
-       for (cpunode = NULL;
-            (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
-               const u32 *reg = of_get_property(cpunode, "reg", NULL);
-               if (reg == NULL || (*reg) != 0)
-                       continue;
-               if (!strcmp(cpunode->type, "cpu"))
-                       break;
-       }
-       if (cpunode == NULL) {
-               printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
-               return -ENODEV;
-       }
-
        /* Check 970FX for now */
        valp = of_get_property(cpunode, "cpu-version", NULL);
        if (!valp) {
@@ -447,9 +432,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
                if (!shdr)
                        goto bail_noprops;
                g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
-               ssize = (shdr->len * sizeof(u32)) -
-                       sizeof(struct smu_sdbp_header);
-               g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
+               ssize = (shdr->len * sizeof(u32)) - sizeof(*shdr);
+               g5_fvt_count = ssize / sizeof(*g5_fvt_table);
                g5_fvt_cur = 0;
 
                /* Sanity checking */
@@ -537,9 +521,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
 #endif /* CONFIG_PMAC_SMU */
 
 
-static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
+static int __init g5_pm72_cpufreq_init(struct device_node *cpunode)
 {
-       struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
+       struct device_node *cpuid = NULL, *hwclock = NULL;
        const u8 *eeprom = NULL;
        const u32 *valp;
        u64 max_freq, min_freq, ih, il;
@@ -548,17 +532,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
        DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
            " RackMac3,1...\n");
 
-       /* Get first CPU node */
-       for (cpunode = NULL;
-            (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
-               if (!strcmp(cpunode->type, "cpu"))
-                       break;
-       }
-       if (cpunode == NULL) {
-               printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
-               return -ENODEV;
-       }
-
        /* Lookup the cpuid eeprom node */
         cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
        if (cpuid != NULL)
@@ -718,25 +691,25 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
 
 static int __init g5_cpufreq_init(void)
 {
-       struct device_node *cpus;
+       struct device_node *cpunode;
        int rc = 0;
 
-       cpus = of_find_node_by_path("/cpus");
-       if (cpus == NULL) {
-               DBG("No /cpus node !\n");
+       /* Get first CPU node */
+       cpunode = of_cpu_device_node_get(0);
+       if (cpunode == NULL) {
+               pr_err("cpufreq: Can't find any CPU node\n");
                return -ENODEV;
        }
 
        if (of_machine_is_compatible("PowerMac7,2") ||
            of_machine_is_compatible("PowerMac7,3") ||
            of_machine_is_compatible("RackMac3,1"))
-               rc = g5_pm72_cpufreq_init(cpus);
+               rc = g5_pm72_cpufreq_init(cpunode);
 #ifdef CONFIG_PMAC_SMU
        else
-               rc = g5_neo2_cpufreq_init(cpus);
+               rc = g5_neo2_cpufreq_init(cpunode);
 #endif /* CONFIG_PMAC_SMU */
 
-       of_node_put(cpus);
        return rc;
 }
 
index ea8e10382ec56b46c6a378d0bf84801a1a221108..85f1c8c25ddc5d20a361e219d023548b356b835b 100644 (file)
@@ -207,7 +207,6 @@ static struct cpufreq_driver powernow_k6_driver = {
        .exit           = powernow_k6_cpu_exit,
        .get            = powernow_k6_get,
        .name           = "powernow-k6",
-       .owner          = THIS_MODULE,
        .attr           = powernow_k6_attr,
 };
 
index 9558708779350a9b00ee6951241ac9bf24551766..14ce480be8ab2503515cb1d61b8f30b5892d85d2 100644 (file)
@@ -177,7 +177,7 @@ static int get_ranges(unsigned char *pst)
        unsigned int speed;
        u8 fid, vid;
 
-       powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+       powernow_table = kzalloc((sizeof(*powernow_table) *
                                (number_scales + 1)), GFP_KERNEL);
        if (!powernow_table)
                return -ENOMEM;
@@ -309,8 +309,7 @@ static int powernow_acpi_init(void)
                goto err0;
        }
 
-       acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance),
-                                     GFP_KERNEL);
+       acpi_processor_perf = kzalloc(sizeof(*acpi_processor_perf), GFP_KERNEL);
        if (!acpi_processor_perf) {
                retval = -ENOMEM;
                goto err0;
@@ -346,7 +345,7 @@ static int powernow_acpi_init(void)
                goto err2;
        }
 
-       powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+       powernow_table = kzalloc((sizeof(*powernow_table) *
                                (number_scales + 1)), GFP_KERNEL);
        if (!powernow_table) {
                retval = -ENOMEM;
@@ -497,7 +496,7 @@ static int powernow_decode_bios(int maxfid, int startvid)
                                        "relevant to this CPU).\n",
                                        psb->numpst);
 
-                       p += sizeof(struct psb_s);
+                       p += sizeof(*psb);
 
                        pst = (struct pst_s *) p;
 
@@ -510,12 +509,12 @@ static int powernow_decode_bios(int maxfid, int startvid)
                                    (maxfid == pst->maxfid) &&
                                    (startvid == pst->startvid)) {
                                        print_pst_entry(pst, j);
-                                       p = (char *)pst + sizeof(struct pst_s);
+                                       p = (char *)pst + sizeof(*pst);
                                        ret = get_ranges(p);
                                        return ret;
                                } else {
                                        unsigned int k;
-                                       p = (char *)pst + sizeof(struct pst_s);
+                                       p = (char *)pst + sizeof(*pst);
                                        for (k = 0; k < number_scales; k++)
                                                p += 2;
                                }
@@ -717,7 +716,6 @@ static struct cpufreq_driver powernow_driver = {
        .init           = powernow_cpu_init,
        .exit           = powernow_cpu_exit,
        .name           = "powernow-k7",
-       .owner          = THIS_MODULE,
        .attr           = powernow_table_attr,
 };
 
index c39d189217cb6d5fedd521c602464d296b4d47bf..2344a9ed17f3c38017701e075c945df8ae0f4bdf 100644 (file)
@@ -623,7 +623,7 @@ static int fill_powernow_table(struct powernow_k8_data *data,
        if (check_pst_table(data, pst, maxvid))
                return -EINVAL;
 
-       powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
+       powernow_table = kmalloc((sizeof(*powernow_table)
                * (data->numps + 1)), GFP_KERNEL);
        if (!powernow_table) {
                printk(KERN_ERR PFX "powernow_table memory alloc failure\n");
@@ -793,7 +793,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        }
 
        /* fill in data->powernow_table */
-       powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
+       powernow_table = kmalloc((sizeof(*powernow_table)
                * (data->acpi_data.state_count + 1)), GFP_KERNEL);
        if (!powernow_table) {
                pr_debug("powernow_table memory alloc failure\n");
@@ -1106,7 +1106,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
        if (rc)
                return -ENODEV;
 
-       data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data) {
                printk(KERN_ERR PFX "unable to alloc powernow_k8_data");
                return -ENOMEM;
@@ -1240,7 +1240,6 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
        .exit           = powernowk8_cpu_exit,
        .get            = powernowk8_get,
        .name           = "powernow-k8",
-       .owner          = THIS_MODULE,
        .attr           = powernow_k8_attr,
 };
 
index 3cae4529f959259f6554283c5d843ef8744046a4..60e81d524ea8231666210ecca2c97407c0a5a279 100644 (file)
@@ -300,7 +300,6 @@ static struct freq_attr *corenet_cpufreq_attr[] = {
 
 static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
        .name           = "ppc_cpufreq",
-       .owner          = THIS_MODULE,
        .flags          = CPUFREQ_CONST_LOOPS,
        .init           = corenet_cpufreq_cpu_init,
        .exit           = __exit_p(corenet_cpufreq_cpu_exit),
index 5936f8d6f2cc3e855ce52a814705ee9d1e35b10b..2e448f0bbdc583465672e7ec40804f1d01467224 100644 (file)
@@ -181,7 +181,6 @@ static struct cpufreq_driver cbe_cpufreq_driver = {
        .init           = cbe_cpufreq_cpu_init,
        .exit           = cbe_cpufreq_cpu_exit,
        .name           = "cbe-cpufreq",
-       .owner          = THIS_MODULE,
        .flags          = CPUFREQ_CONST_LOOPS,
 };
 
index fb3981ac829fdb0a1eb73483ee3484fe7426990c..8749eaf1879338ad331f587c9a716a501ab0c701 100644 (file)
@@ -191,7 +191,7 @@ static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
        return ret;
 }
 
-static __init void pxa_cpufreq_init_voltages(void)
+static void __init pxa_cpufreq_init_voltages(void)
 {
        vcc_core = regulator_get(NULL, "vcc_core");
        if (IS_ERR(vcc_core)) {
@@ -207,7 +207,7 @@ static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
        return 0;
 }
 
-static __init void pxa_cpufreq_init_voltages(void) { }
+static void __init pxa_cpufreq_init_voltages(void) { }
 #endif
 
 static void find_freq_tables(struct cpufreq_frequency_table **freq_table,
index 9c92ef032a9e978800e4897a2a3e8322c0d1c031..d26306fb00d2e8a749ed044c816533f101defd11 100644 (file)
@@ -213,10 +213,12 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
        policy->cur = policy->min = policy->max;
 
        if (cpu_is_pxa300() || cpu_is_pxa310())
-               ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs));
+               ret = setup_freqs_table(policy, pxa300_freqs,
+                                       ARRAY_SIZE(pxa300_freqs));
 
        if (cpu_is_pxa320())
-               ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa320_freqs));
+               ret = setup_freqs_table(policy, pxa320_freqs,
+                                       ARRAY_SIZE(pxa320_freqs));
 
        if (ret) {
                pr_err("failed to setup frequency table\n");
index ce5b9fca9c1871eed562add6fb35f3979ab7fd8a..22dcb81ef9d0e9069b8fc4d49249713d59d41dd9 100644 (file)
@@ -524,7 +524,6 @@ static struct freq_attr *s3c2416_cpufreq_attr[] = {
 };
 
 static struct cpufreq_driver s3c2416_cpufreq_driver = {
-       .owner          = THIS_MODULE,
        .flags          = 0,
        .verify         = s3c2416_cpufreq_verify_speed,
        .target         = s3c2416_cpufreq_set_target,
index 87781eb20d6dce41c4b6c376f4937f67d808d0be..b0f343fcb7eefdfe40b942b202398372a618df44 100644 (file)
@@ -392,7 +392,7 @@ static int s3c_cpufreq_init(struct cpufreq_policy *policy)
        return 0;
 }
 
-static __init int s3c_cpufreq_initclks(void)
+static int __init s3c_cpufreq_initclks(void)
 {
        _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
        _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
@@ -522,7 +522,7 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
        /* Copy the board information so that each board can make this
         * initdata. */
 
-       ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
+       ours = kzalloc(sizeof(*ours), GFP_KERNEL);
        if (ours == NULL) {
                printk(KERN_ERR "%s: no memory\n", __func__);
                return -ENOMEM;
@@ -615,7 +615,7 @@ static int s3c_cpufreq_build_freq(void)
        size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
        size++;
 
-       ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
+       ftab = kmalloc(sizeof(*ftab) * size, GFP_KERNEL);
        if (!ftab) {
                printk(KERN_ERR "%s: no memory for tables\n", __func__);
                return -ENOMEM;
@@ -691,7 +691,7 @@ int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
        struct cpufreq_frequency_table *vals;
        unsigned int size;
 
-       size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
+       size = sizeof(*vals) * (plls_no + 1);
 
        vals = kmalloc(size, GFP_KERNEL);
        if (vals) {
index 13bb4bae64ee11505fb8a072d041ec9a8268bf84..8a72b0c555f846da21d25d02d9f94d427a7796b5 100644 (file)
@@ -263,7 +263,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
 }
 
 static struct cpufreq_driver s3c64xx_cpufreq_driver = {
-       .owner          = THIS_MODULE,
        .flags          = 0,
        .verify         = s3c64xx_cpufreq_verify_speed,
        .target         = s3c64xx_cpufreq_set_target,
index 77a210975fc4b66ce737703f6904483d45368776..d6f6c6f4efa76ac6f82a97ddeff3292a06cfd18c 100644 (file)
@@ -147,7 +147,6 @@ static struct cpufreq_driver sc520_freq_driver = {
        .init   = sc520_freq_cpu_init,
        .exit   = sc520_freq_cpu_exit,
        .name   = "sc520_freq",
-       .owner  = THIS_MODULE,
        .attr   = sc520_freq_attr,
 };
 
index 73adb64651e86a8123e7b8bb41080a2e138eaefe..ffc6d24b0cfbed764db6b6c8e2015330e6fb9fbd 100644 (file)
@@ -160,7 +160,6 @@ static struct freq_attr *sh_freq_attr[] = {
 };
 
 static struct cpufreq_driver sh_cpufreq_driver = {
-       .owner          = THIS_MODULE,
        .name           = "sh",
        .get            = sh_cpufreq_get,
        .target         = sh_cpufreq_target,
index 93061a40877383b09ceff0cb7bd0bc2bba60a08a..cf5bc2ca16fa11f4155d757c6d5219b6691a6b81 100644 (file)
@@ -351,12 +351,11 @@ static int __init us2e_freq_init(void)
                struct cpufreq_driver *driver;
 
                ret = -ENOMEM;
-               driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL);
+               driver = kzalloc(sizeof(*driver), GFP_KERNEL);
                if (!driver)
                        goto err_out;
 
-               us2e_freq_table = kzalloc(
-                       (NR_CPUS * sizeof(struct us2e_freq_percpu_info)),
+               us2e_freq_table = kzalloc((NR_CPUS * sizeof(*us2e_freq_table)),
                        GFP_KERNEL);
                if (!us2e_freq_table)
                        goto err_out;
@@ -366,7 +365,6 @@ static int __init us2e_freq_init(void)
                driver->target = us2e_freq_target;
                driver->get = us2e_freq_get;
                driver->exit = us2e_freq_cpu_exit;
-               driver->owner = THIS_MODULE,
                strcpy(driver->name, "UltraSPARC-IIe");
 
                cpufreq_us2e_driver = driver;
index 880ee293d61eda8c131187d65579a5216ce2b00d..ac76b489979d48cac1278525ab861f46b69f8c86 100644 (file)
@@ -212,12 +212,11 @@ static int __init us3_freq_init(void)
                struct cpufreq_driver *driver;
 
                ret = -ENOMEM;
-               driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL);
+               driver = kzalloc(sizeof(*driver), GFP_KERNEL);
                if (!driver)
                        goto err_out;
 
-               us3_freq_table = kzalloc(
-                       (NR_CPUS * sizeof(struct us3_freq_percpu_info)),
+               us3_freq_table = kzalloc((NR_CPUS * sizeof(*us3_freq_table)),
                        GFP_KERNEL);
                if (!us3_freq_table)
                        goto err_out;
@@ -227,7 +226,6 @@ static int __init us3_freq_init(void)
                driver->target = us3_freq_target;
                driver->get = us3_freq_get;
                driver->exit = us3_freq_cpu_exit;
-               driver->owner = THIS_MODULE,
                strcpy(driver->name, "UltraSPARC-III");
 
                cpufreq_us3_driver = driver;
index c3efa7f2a9088d9ea43f68e149632939e357a8dd..19e364fa59559cd6bf3e0ec77d9e5bb7c391aafa 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 
@@ -223,7 +223,7 @@ static int spear_cpufreq_driver_init(void)
        const __be32 *val;
        int cnt, i, ret;
 
-       np = of_find_node_by_path("/cpus/cpu@0");
+       np = of_cpu_device_node_get(0);
        if (!np) {
                pr_err("No cpu node found");
                return -ENODEV;
index 0915e712fbdcc3a6393c1974c12394e060cc3c1f..f897d510584285bea376474ca6a3198eeef7d74f 100644 (file)
@@ -575,7 +575,6 @@ static struct cpufreq_driver centrino_driver = {
        .target         = centrino_target,
        .get            = get_cur_freq,
        .attr           = centrino_attr,
-       .owner          = THIS_MODULE,
 };
 
 /*
index e2e5aa97145275a0b860ba119d736cc444a3fd2f..5355abb69afc972d88c9f509924d3e779fa0cdac 100644 (file)
@@ -378,7 +378,6 @@ static struct cpufreq_driver speedstep_driver = {
        .init   = speedstep_cpu_init,
        .exit   = speedstep_cpu_exit,
        .get    = speedstep_get,
-       .owner  = THIS_MODULE,
        .attr   = speedstep_attr,
 };
 
index f5a6b70ee6c0f1965a2794ace8d66c2c7e1aec38..abfba4f731ebdc4212696732a765b56083bc8252 100644 (file)
@@ -375,7 +375,6 @@ static struct cpufreq_driver speedstep_driver = {
        .exit           = speedstep_cpu_exit,
        .get            = speedstep_get,
        .resume         = speedstep_resume,
-       .owner          = THIS_MODULE,
        .attr           = speedstep_attr,
 };
 
index 12fc904d7dabea615955f1f8449b4bc670849ed7..b225f04d8ae5c55bcfee26f644812d3d1100cc04 100644 (file)
@@ -24,7 +24,7 @@ static struct cpufreq_driver ucv2_driver;
 /* make sure that only the "userspace" governor is run
  * -- anything else wouldn't make sense on this platform, anyway.
  */
-int ucv2_verify_speed(struct cpufreq_policy *policy)
+static int ucv2_verify_speed(struct cpufreq_policy *policy)
 {
        if (policy->cpu)
                return -EINVAL;
index 5c5427918eb2f54b6a22d766aa7e697ca21c7666..605afa9fbe5e089776f04d8c1ae24484fca52384 100644 (file)
@@ -18,6 +18,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 #include <linux/ctype.h>
+#include <linux/cpu.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/spinlock.h>
@@ -230,6 +231,100 @@ const void *of_get_property(const struct device_node *np, const char *name,
 }
 EXPORT_SYMBOL(of_get_property);
 
+/*
+ * arch_match_cpu_phys_id - Match the given logical CPU and physical id
+ *
+ * @cpu: logical cpu index of a core/thread
+ * @phys_id: physical identifier of a core/thread
+ *
+ * CPU logical to physical index mapping is architecture specific.
+ * However this __weak function provides a default match of physical
+ * id to logical cpu index. phys_id provided here is usually values read
+ * from the device tree which must match the hardware internal registers.
+ *
+ * Returns true if the physical identifier and the logical cpu index
+ * correspond to the same core/thread, false otherwise.
+ */
+bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
+{
+       return (u32)phys_id == cpu;
+}
+
+/**
+ * Checks if the given "prop_name" property holds the physical id of the
+ * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not
+ * NULL, local thread number within the core is returned in it.
+ */
+static bool __of_find_n_match_cpu_property(struct device_node *cpun,
+                       const char *prop_name, int cpu, unsigned int *thread)
+{
+       const __be32 *cell;
+       int ac, prop_len, tid;
+       u64 hwid;
+
+       ac = of_n_addr_cells(cpun);
+       cell = of_get_property(cpun, prop_name, &prop_len);
+       if (!cell)
+               return false;
+       prop_len /= sizeof(*cell);
+       for (tid = 0; tid < prop_len; tid++) {
+               hwid = of_read_number(cell, ac);
+               if (arch_match_cpu_phys_id(cpu, hwid)) {
+                       if (thread)
+                               *thread = tid;
+                       return true;
+               }
+               cell += ac;
+       }
+       return false;
+}
+
+/**
+ * of_get_cpu_node - Get device node associated with the given logical CPU
+ *
+ * @cpu: CPU number(logical index) for which device node is required
+ * @thread: if not NULL, local thread number within the physical core is
+ *          returned
+ *
+ * The main purpose of this function is to retrieve the device node for the
+ * given logical CPU index. It should be used to initialize the of_node in
+ * cpu device. Once of_node in cpu device is populated, all the further
+ * references can use that instead.
+ *
+ * CPU logical to physical index mapping is architecture specific and is built
+ * before booting secondary cores. This function uses arch_match_cpu_phys_id
+ * which can be overridden by architecture specific implementation.
+ *
+ * Returns a node pointer for the logical cpu if found, else NULL.
+ */
+struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
+{
+       struct device_node *cpun, *cpus;
+
+       cpus = of_find_node_by_path("/cpus");
+       if (!cpus) {
+               pr_warn("Missing cpus node, bailing out\n");
+               return NULL;
+       }
+
+       for_each_child_of_node(cpus, cpun) {
+               if (of_node_cmp(cpun->type, "cpu"))
+                       continue;
+               /* Check for non-standard "ibm,ppc-interrupt-server#s" property
+                * for thread ids on PowerPC. If it doesn't exist fallback to
+                * standard "reg" property.
+                */
+               if (IS_ENABLED(CONFIG_PPC) &&
+                       __of_find_n_match_cpu_property(cpun,
+                               "ibm,ppc-interrupt-server#s", cpu, thread))
+                       return cpun;
+               if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread))
+                       return cpun;
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(of_get_cpu_node);
+
 /** Checks if the given "compat" string matches one of the strings in
  * the device's "compatible" property
  */
index 956c0a16566f828a37773b8a913423921f3a3079..801ff9e73679a00d7f945d82253454a236319966 100644 (file)
@@ -28,6 +28,7 @@ struct cpu {
 extern int register_cpu(struct cpu *cpu, int num);
 extern struct device *get_cpu_device(unsigned cpu);
 extern bool cpu_is_hotpluggable(unsigned cpu);
+extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);
 
 extern int cpu_add_dev_attr(struct device_attribute *attr);
 extern void cpu_remove_dev_attr(struct device_attribute *attr);
index 90d5a15120d592eedeff5de22cd33fe61fe98351..d568f3975eeb66125a28aa8a31ccbb712de56807 100644 (file)
 #ifndef _LINUX_CPUFREQ_H
 #define _LINUX_CPUFREQ_H
 
-#include <asm/cputime.h>
-#include <linux/mutex.h>
-#include <linux/notifier.h>
-#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/completion.h>
 #include <linux/kobject.h>
+#include <linux/notifier.h>
 #include <linux/sysfs.h>
-#include <linux/completion.h>
-#include <linux/workqueue.h>
-#include <linux/cpumask.h>
-#include <asm/div64.h>
-
-#define CPUFREQ_NAME_LEN 16
-/* Print length for names. Extra 1 space for accomodating '\n' in prints */
-#define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1)
 
 /*********************************************************************
- *                     CPUFREQ NOTIFIER INTERFACE                    *
+ *                        CPUFREQ INTERFACE                          *
  *********************************************************************/
-
-#define CPUFREQ_TRANSITION_NOTIFIER    (0)
-#define CPUFREQ_POLICY_NOTIFIER                (1)
-
-#ifdef CONFIG_CPU_FREQ
-int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);
-int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
-extern void disable_cpufreq(void);
-#else          /* CONFIG_CPU_FREQ */
-static inline int cpufreq_register_notifier(struct notifier_block *nb,
-                                               unsigned int list)
-{
-       return 0;
-}
-static inline int cpufreq_unregister_notifier(struct notifier_block *nb,
-                                               unsigned int list)
-{
-       return 0;
-}
-static inline void disable_cpufreq(void) { }
-#endif         /* CONFIG_CPU_FREQ */
-
-/* if (cpufreq_driver->target) exists, the ->governor decides what frequency
- * within the limits is used. If (cpufreq_driver->setpolicy> exists, these
- * two generic policies are available:
- */
-
-#define CPUFREQ_POLICY_POWERSAVE       (1)
-#define CPUFREQ_POLICY_PERFORMANCE     (2)
-
-/* Frequency values here are CPU kHz so that hardware which doesn't run
- * with some frequencies can complain without having to guess what per
- * cent / per mille means.
+/*
+ * Frequency values here are CPU kHz
+ *
  * Maximum transition latency is in nanoseconds - if it's unknown,
  * CPUFREQ_ETERNAL shall be used.
  */
 
+#define CPUFREQ_ETERNAL                        (-1)
+#define CPUFREQ_NAME_LEN               16
+/* Print length for names. Extra 1 space for accomodating '\n' in prints */
+#define CPUFREQ_NAME_PLEN              (CPUFREQ_NAME_LEN + 1)
+
 struct cpufreq_governor;
 
-/* /sys/devices/system/cpu/cpufreq: entry point for global variables */
-extern struct kobject *cpufreq_global_kobject;
-int cpufreq_get_global_kobject(void);
-void cpufreq_put_global_kobject(void);
-int cpufreq_sysfs_create_file(const struct attribute *attr);
-void cpufreq_sysfs_remove_file(const struct attribute *attr);
+struct cpufreq_freqs {
+       unsigned int cpu;       /* cpu nr */
+       unsigned int old;
+       unsigned int new;
+       u8 flags;               /* flags of cpufreq_driver, see below. */
+};
 
-#define CPUFREQ_ETERNAL                        (-1)
 struct cpufreq_cpuinfo {
        unsigned int            max_freq;
        unsigned int            min_freq;
@@ -117,123 +82,103 @@ struct cpufreq_policy {
 
        struct cpufreq_real_policy      user_policy;
 
+       struct list_head        policy_list;
        struct kobject          kobj;
        struct completion       kobj_unregister;
        int                     transition_ongoing; /* Tracks transition status */
 };
 
-#define CPUFREQ_ADJUST                 (0)
-#define CPUFREQ_INCOMPATIBLE           (1)
-#define CPUFREQ_NOTIFY                 (2)
-#define CPUFREQ_START                  (3)
-#define CPUFREQ_UPDATE_POLICY_CPU      (4)
-
 /* Only for ACPI */
 #define CPUFREQ_SHARED_TYPE_NONE (0) /* None */
 #define CPUFREQ_SHARED_TYPE_HW  (1) /* HW does needed coordination */
 #define CPUFREQ_SHARED_TYPE_ALL         (2) /* All dependent CPUs should set freq */
 #define CPUFREQ_SHARED_TYPE_ANY         (3) /* Freq can be set from any dependent CPU*/
 
+struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
+void cpufreq_cpu_put(struct cpufreq_policy *policy);
+
 static inline bool policy_is_shared(struct cpufreq_policy *policy)
 {
        return cpumask_weight(policy->cpus) > 1;
 }
 
-/******************** cpufreq transition notifiers *******************/
-
-#define CPUFREQ_PRECHANGE      (0)
-#define CPUFREQ_POSTCHANGE     (1)
-#define CPUFREQ_RESUMECHANGE   (8)
-#define CPUFREQ_SUSPENDCHANGE  (9)
+/* /sys/devices/system/cpu/cpufreq: entry point for global variables */
+extern struct kobject *cpufreq_global_kobject;
+int cpufreq_get_global_kobject(void);
+void cpufreq_put_global_kobject(void);
+int cpufreq_sysfs_create_file(const struct attribute *attr);
+void cpufreq_sysfs_remove_file(const struct attribute *attr);
 
-struct cpufreq_freqs {
-       unsigned int cpu;       /* cpu nr */
-       unsigned int old;
-       unsigned int new;
-       u8 flags;               /* flags of cpufreq_driver, see below. */
-};
+#ifdef CONFIG_CPU_FREQ
+unsigned int cpufreq_get(unsigned int cpu);
+unsigned int cpufreq_quick_get(unsigned int cpu);
+unsigned int cpufreq_quick_get_max(unsigned int cpu);
+void disable_cpufreq(void);
 
-/**
- * cpufreq_scale - "old * mult / div" calculation for large values (32-bit-arch
- * safe)
- * @old:   old value
- * @div:   divisor
- * @mult:  multiplier
- *
- *
- * new = old * mult / div
- */
-static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
-               u_int mult)
+u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy);
+int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
+int cpufreq_update_policy(unsigned int cpu);
+bool have_governor_per_policy(void);
+struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy);
+#else
+static inline unsigned int cpufreq_get(unsigned int cpu)
 {
-#if BITS_PER_LONG == 32
-
-       u64 result = ((u64) old) * ((u64) mult);
-       do_div(result, div);
-       return (unsigned long) result;
-
-#elif BITS_PER_LONG == 64
-
-       unsigned long result = old * ((u64) mult);
-       result /= div;
-       return result;
-
+       return 0;
+}
+static inline unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+       return 0;
+}
+static inline unsigned int cpufreq_quick_get_max(unsigned int cpu)
+{
+       return 0;
+}
+static inline void disable_cpufreq(void) { }
 #endif
-};
 
 /*********************************************************************
- *                          CPUFREQ GOVERNORS                        *
+ *                      CPUFREQ DRIVER INTERFACE                     *
  *********************************************************************/
 
-#define CPUFREQ_GOV_START      1
-#define CPUFREQ_GOV_STOP       2
-#define CPUFREQ_GOV_LIMITS     3
-#define CPUFREQ_GOV_POLICY_INIT        4
-#define CPUFREQ_GOV_POLICY_EXIT        5
+#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
+#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
 
-struct cpufreq_governor {
-       char    name[CPUFREQ_NAME_LEN];
-       int     initialized;
-       int     (*governor)     (struct cpufreq_policy *policy,
-                                unsigned int event);
-       ssize_t (*show_setspeed)        (struct cpufreq_policy *policy,
-                                        char *buf);
-       int     (*store_setspeed)       (struct cpufreq_policy *policy,
-                                        unsigned int freq);
-       unsigned int max_transition_latency; /* HW must be able to switch to
-                       next freq faster than this value in nano secs or we
-                       will fallback to performance governor */
-       struct list_head        governor_list;
-       struct module           *owner;
+struct freq_attr {
+       struct attribute attr;
+       ssize_t (*show)(struct cpufreq_policy *, char *);
+       ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
 };
 
-/*
- * Pass a target to the cpufreq driver.
- */
-extern int cpufreq_driver_target(struct cpufreq_policy *policy,
-                                unsigned int target_freq,
-                                unsigned int relation);
-extern int __cpufreq_driver_target(struct cpufreq_policy *policy,
-                                  unsigned int target_freq,
-                                  unsigned int relation);
+#define cpufreq_freq_attr_ro(_name)            \
+static struct freq_attr _name =                        \
+__ATTR(_name, 0444, show_##_name, NULL)
 
-extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy,
-                                  unsigned int cpu);
+#define cpufreq_freq_attr_ro_perm(_name, _perm)        \
+static struct freq_attr _name =                        \
+__ATTR(_name, _perm, show_##_name, NULL)
 
-int cpufreq_register_governor(struct cpufreq_governor *governor);
-void cpufreq_unregister_governor(struct cpufreq_governor *governor);
+#define cpufreq_freq_attr_rw(_name)            \
+static struct freq_attr _name =                        \
+__ATTR(_name, 0644, show_##_name, store_##_name)
 
-/*********************************************************************
- *                      CPUFREQ DRIVER INTERFACE                     *
- *********************************************************************/
+struct global_attr {
+       struct attribute attr;
+       ssize_t (*show)(struct kobject *kobj,
+                       struct attribute *attr, char *buf);
+       ssize_t (*store)(struct kobject *a, struct attribute *b,
+                        const char *c, size_t count);
+};
 
-#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
-#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
+#define define_one_global_ro(_name)            \
+static struct global_attr _name =              \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+#define define_one_global_rw(_name)            \
+static struct global_attr _name =              \
+__ATTR(_name, 0644, show_##_name, store_##_name)
 
-struct freq_attr;
 
 struct cpufreq_driver {
-       struct module           *owner;
        char                    name[CPUFREQ_NAME_LEN];
        u8                      flags;
        /*
@@ -258,8 +203,6 @@ struct cpufreq_driver {
        unsigned int    (*get)  (unsigned int cpu);
 
        /* optional */
-       unsigned int (*getavg)  (struct cpufreq_policy *policy,
-                                unsigned int cpu);
        int     (*bios_limit)   (int cpu, unsigned int *limit);
 
        int     (*exit)         (struct cpufreq_policy *policy);
@@ -269,7 +212,6 @@ struct cpufreq_driver {
 };
 
 /* flags */
-
 #define CPUFREQ_STICKY         0x01    /* the driver isn't removed even if
                                         * all ->init() calls failed */
 #define CPUFREQ_CONST_LOOPS    0x02    /* loops_per_jiffy or other kernel
@@ -281,8 +223,7 @@ struct cpufreq_driver {
 int cpufreq_register_driver(struct cpufreq_driver *driver_data);
 int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
 
-void cpufreq_notify_transition(struct cpufreq_policy *policy,
-               struct cpufreq_freqs *freqs, unsigned int state);
+const char *cpufreq_get_current_driver(void);
 
 static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
                unsigned int min, unsigned int max)
@@ -300,86 +241,117 @@ static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy,
        return;
 }
 
-struct freq_attr {
-       struct attribute attr;
-       ssize_t (*show)(struct cpufreq_policy *, char *);
-       ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
-};
-
-#define cpufreq_freq_attr_ro(_name)            \
-static struct freq_attr _name =                        \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-#define cpufreq_freq_attr_ro_perm(_name, _perm)        \
-static struct freq_attr _name =                        \
-__ATTR(_name, _perm, show_##_name, NULL)
-
-#define cpufreq_freq_attr_rw(_name)            \
-static struct freq_attr _name =                        \
-__ATTR(_name, 0644, show_##_name, store_##_name)
+/*********************************************************************
+ *                     CPUFREQ NOTIFIER INTERFACE                    *
+ *********************************************************************/
 
-struct global_attr {
-       struct attribute attr;
-       ssize_t (*show)(struct kobject *kobj,
-                       struct attribute *attr, char *buf);
-       ssize_t (*store)(struct kobject *a, struct attribute *b,
-                        const char *c, size_t count);
-};
+#define CPUFREQ_TRANSITION_NOTIFIER    (0)
+#define CPUFREQ_POLICY_NOTIFIER                (1)
 
-#define define_one_global_ro(_name)            \
-static struct global_attr _name =              \
-__ATTR(_name, 0444, show_##_name, NULL)
+/* Transition notifiers */
+#define CPUFREQ_PRECHANGE              (0)
+#define CPUFREQ_POSTCHANGE             (1)
+#define CPUFREQ_RESUMECHANGE           (8)
+#define CPUFREQ_SUSPENDCHANGE          (9)
 
-#define define_one_global_rw(_name)            \
-static struct global_attr _name =              \
-__ATTR(_name, 0644, show_##_name, store_##_name)
+/* Policy Notifiers  */
+#define CPUFREQ_ADJUST                 (0)
+#define CPUFREQ_INCOMPATIBLE           (1)
+#define CPUFREQ_NOTIFY                 (2)
+#define CPUFREQ_START                  (3)
+#define CPUFREQ_UPDATE_POLICY_CPU      (4)
 
-struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu);
-void cpufreq_cpu_put(struct cpufreq_policy *data);
-const char *cpufreq_get_current_driver(void);
+#ifdef CONFIG_CPU_FREQ
+int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);
+int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
 
-/*********************************************************************
- *                        CPUFREQ 2.6. INTERFACE                     *
- *********************************************************************/
-u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy);
-int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
-int cpufreq_update_policy(unsigned int cpu);
-bool have_governor_per_policy(void);
-struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy);
+void cpufreq_notify_transition(struct cpufreq_policy *policy,
+               struct cpufreq_freqs *freqs, unsigned int state);
 
-#ifdef CONFIG_CPU_FREQ
-/*
- * query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it
- */
-unsigned int cpufreq_get(unsigned int cpu);
-#else
-static inline unsigned int cpufreq_get(unsigned int cpu)
+#else /* CONFIG_CPU_FREQ */
+static inline int cpufreq_register_notifier(struct notifier_block *nb,
+                                               unsigned int list)
 {
        return 0;
 }
-#endif
-
-/*
- * query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it
- */
-#ifdef CONFIG_CPU_FREQ
-unsigned int cpufreq_quick_get(unsigned int cpu);
-unsigned int cpufreq_quick_get_max(unsigned int cpu);
-#else
-static inline unsigned int cpufreq_quick_get(unsigned int cpu)
+static inline int cpufreq_unregister_notifier(struct notifier_block *nb,
+                                               unsigned int list)
 {
        return 0;
 }
-static inline unsigned int cpufreq_quick_get_max(unsigned int cpu)
+#endif /* !CONFIG_CPU_FREQ */
+
+/**
+ * cpufreq_scale - "old * mult / div" calculation for large values (32-bit-arch
+ * safe)
+ * @old:   old value
+ * @div:   divisor
+ * @mult:  multiplier
+ *
+ *
+ * new = old * mult / div
+ */
+static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
+               u_int mult)
 {
-       return 0;
-}
+#if BITS_PER_LONG == 32
+       u64 result = ((u64) old) * ((u64) mult);
+       do_div(result, div);
+       return (unsigned long) result;
+
+#elif BITS_PER_LONG == 64
+       unsigned long result = old * ((u64) mult);
+       result /= div;
+       return result;
 #endif
+}
 
 /*********************************************************************
- *                       CPUFREQ DEFAULT GOVERNOR                    *
+ *                          CPUFREQ GOVERNORS                        *
  *********************************************************************/
 
+/*
+ * If (cpufreq_driver->target) exists, the ->governor decides what frequency
+ * within the limits is used. If (cpufreq_driver->setpolicy> exists, these
+ * two generic policies are available:
+ */
+#define CPUFREQ_POLICY_POWERSAVE       (1)
+#define CPUFREQ_POLICY_PERFORMANCE     (2)
+
+/* Governor Events */
+#define CPUFREQ_GOV_START      1
+#define CPUFREQ_GOV_STOP       2
+#define CPUFREQ_GOV_LIMITS     3
+#define CPUFREQ_GOV_POLICY_INIT        4
+#define CPUFREQ_GOV_POLICY_EXIT        5
+
+struct cpufreq_governor {
+       char    name[CPUFREQ_NAME_LEN];
+       int     initialized;
+       int     (*governor)     (struct cpufreq_policy *policy,
+                                unsigned int event);
+       ssize_t (*show_setspeed)        (struct cpufreq_policy *policy,
+                                        char *buf);
+       int     (*store_setspeed)       (struct cpufreq_policy *policy,
+                                        unsigned int freq);
+       unsigned int max_transition_latency; /* HW must be able to switch to
+                       next freq faster than this value in nano secs or we
+                       will fallback to performance governor */
+       struct list_head        governor_list;
+       struct module           *owner;
+};
+
+/* Pass a target to the cpufreq driver */
+int cpufreq_driver_target(struct cpufreq_policy *policy,
+                                unsigned int target_freq,
+                                unsigned int relation);
+int __cpufreq_driver_target(struct cpufreq_policy *policy,
+                                  unsigned int target_freq,
+                                  unsigned int relation);
+int cpufreq_register_governor(struct cpufreq_governor *governor);
+void cpufreq_unregister_governor(struct cpufreq_governor *governor);
+
+/* CPUFREQ DEFAULT GOVERNOR */
 /*
  * Performance governor is fallback governor if any other gov failed to auto
  * load due latency restrictions
@@ -428,18 +400,16 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
                                   unsigned int relation,
                                   unsigned int *index);
 
-/* the following 3 funtions are for cpufreq core use only */
+void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy);
+ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf);
+
+/* the following funtion is for cpufreq core use only */
 struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
-
 void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
                                      unsigned int cpu);
-void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy);
-
 void cpufreq_frequency_table_put_attr(unsigned int cpu);
 
-ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf);
-
 #endif /* _LINUX_CPUFREQ_H */
index 1fd08ca23106df836678989d96e2a16824b1a932..c0bb2f188048b21df8a401de13644a3de3c8e22d 100644 (file)
@@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device);
 extern const void *of_get_property(const struct device_node *node,
                                const char *name,
                                int *lenp);
+extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 #define for_each_property_of_node(dn, pp) \
        for (pp = dn->properties; pp != NULL; pp = pp->next)
 
@@ -459,6 +460,12 @@ static inline const void *of_get_property(const struct device_node *node,
        return NULL;
 }
 
+static inline struct device_node *of_get_cpu_node(int cpu,
+                                       unsigned int *thread)
+{
+       return NULL;
+}
+
 static inline int of_property_read_u64(const struct device_node *np,
                                       const char *propname, u64 *out_value)
 {
index 9d27475feec1768dab059a038d19af5ea10b67e2..82ce324fdce7f47a8ac0ba87c31525887d6628bb 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_OF_DEVICE_H
 #define _LINUX_OF_DEVICE_H
 
+#include <linux/cpu.h>
 #include <linux/platform_device.h>
 #include <linux/of_platform.h> /* temporary until merge */
 
@@ -43,6 +44,15 @@ static inline void of_device_node_put(struct device *dev)
        of_node_put(dev->of_node);
 }
 
+static inline struct device_node *of_cpu_device_node_get(int cpu)
+{
+       struct device *cpu_dev;
+       cpu_dev = get_cpu_device(cpu);
+       if (!cpu_dev)
+               return NULL;
+       return of_node_get(cpu_dev->of_node);
+}
+
 #else /* CONFIG_OF */
 
 static inline int of_driver_match_device(struct device *dev,
@@ -67,6 +77,11 @@ static inline const struct of_device_id *of_match_device(
 {
        return NULL;
 }
+
+static inline struct device_node *of_cpu_device_node_get(int cpu)
+{
+       return NULL;
+}
 #endif /* CONFIG_OF */
 
 #endif /* _LINUX_OF_DEVICE_H */