Merge branch 'pm-cpufreq'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 8 Apr 2014 11:28:02 +0000 (13:28 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 8 Apr 2014 11:28:02 +0000 (13:28 +0200)
* pm-cpufreq:
  cpufreq: ppc: Remove duplicate inclusion of fsl_soc.h
  cpufreq: create another field .flags in cpufreq_frequency_table
  cpufreq: use kzalloc() to allocate memory for cpufreq_frequency_table
  cpufreq: don't print value of .driver_data from core
  cpufreq: ia64: don't set .driver_data to index
  cpufreq: powernv: Select CPUFreq related Kconfig options for powernv
  cpufreq: powernv: Use cpufreq_frequency_table.driver_data to store pstate ids
  cpufreq: powernv: cpufreq driver for powernv platform
  cpufreq: at32ap: don't declare local variable as static
  cpufreq: loongson2_cpufreq: don't declare local variable as static
  cpufreq: unicore32: fix typo issue for 'clk'
  cpufreq: exynos: Disable on multiplatform build

41 files changed:
arch/mips/loongson/lemote-2f/clock.c
arch/powerpc/configs/pseries_defconfig
arch/powerpc/configs/pseries_le_defconfig
arch/powerpc/include/asm/reg.h
arch/powerpc/platforms/powernv/Kconfig
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Kconfig.powerpc
drivers/cpufreq/Makefile
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/at32ap-cpufreq.c
drivers/cpufreq/cris-artpec3-cpufreq.c
drivers/cpufreq/cris-etraxfs-cpufreq.c
drivers/cpufreq/elanfreq.c
drivers/cpufreq/exynos4210-cpufreq.c
drivers/cpufreq/exynos4x12-cpufreq.c
drivers/cpufreq/exynos5250-cpufreq.c
drivers/cpufreq/freq_table.c
drivers/cpufreq/ia64-acpi-cpufreq.c
drivers/cpufreq/kirkwood-cpufreq.c
drivers/cpufreq/longhaul.c
drivers/cpufreq/loongson2_cpufreq.c
drivers/cpufreq/maple-cpufreq.c
drivers/cpufreq/p4-clockmod.c
drivers/cpufreq/pasemi-cpufreq.c
drivers/cpufreq/pmac32-cpufreq.c
drivers/cpufreq/pmac64-cpufreq.c
drivers/cpufreq/powernow-k6.c
drivers/cpufreq/powernow-k8.c
drivers/cpufreq/powernv-cpufreq.c [new file with mode: 0644]
drivers/cpufreq/ppc-corenet-cpufreq.c
drivers/cpufreq/ppc_cbe_cpufreq.c
drivers/cpufreq/s3c2416-cpufreq.c
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpufreq/s3c64xx-cpufreq.c
drivers/cpufreq/s5pv210-cpufreq.c
drivers/cpufreq/sc520_freq.c
drivers/cpufreq/spear-cpufreq.c
drivers/cpufreq/speedstep-ich.c
drivers/cpufreq/speedstep-smi.c
drivers/cpufreq/unicore2-cpufreq.c
include/linux/cpufreq.h

index aed32b8..e1f427f 100644 (file)
@@ -28,16 +28,16 @@ enum {
 };
 
 struct cpufreq_frequency_table loongson2_clockmod_table[] = {
-       {DC_RESV, CPUFREQ_ENTRY_INVALID},
-       {DC_ZERO, CPUFREQ_ENTRY_INVALID},
-       {DC_25PT, 0},
-       {DC_37PT, 0},
-       {DC_50PT, 0},
-       {DC_62PT, 0},
-       {DC_75PT, 0},
-       {DC_87PT, 0},
-       {DC_DISABLE, 0},
-       {DC_RESV, CPUFREQ_TABLE_END},
+       {0, DC_RESV, CPUFREQ_ENTRY_INVALID},
+       {0, DC_ZERO, CPUFREQ_ENTRY_INVALID},
+       {0, DC_25PT, 0},
+       {0, DC_37PT, 0},
+       {0, DC_50PT, 0},
+       {0, DC_62PT, 0},
+       {0, DC_75PT, 0},
+       {0, DC_87PT, 0},
+       {0, DC_DISABLE, 0},
+       {0, DC_RESV, CPUFREQ_TABLE_END},
 };
 EXPORT_SYMBOL_GPL(loongson2_clockmod_table);
 
index 9ea8342..a905063 100644 (file)
@@ -306,3 +306,4 @@ CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
index 3c84f9d..58e3dbf 100644 (file)
@@ -301,3 +301,4 @@ CONFIG_CRYPTO_LZO=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_NX=y
 CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
index 0dcc48a..e5d2e0b 100644 (file)
 #define SPRN_HSRR1     0x13B   /* Hypervisor Save/Restore 1 */
 #define SPRN_IC                0x350   /* Virtual Instruction Count */
 #define SPRN_VTB       0x351   /* Virtual Time Base */
+#define SPRN_PMICR     0x354   /* Power Management Idle Control Reg */
+#define SPRN_PMSR      0x355   /* Power Management Status Reg */
+#define SPRN_PMCR      0x374   /* Power Management Control Register */
+
 /* HFSCR and FSCR bit numbers are the same */
 #define FSCR_TAR_LG    8       /* Enable Target Address Register */
 #define FSCR_EBB_LG    7       /* Enable Event Based Branching */
index 895e8a2..c252ee9 100644 (file)
@@ -11,6 +11,12 @@ config PPC_POWERNV
        select PPC_UDBG_16550
        select PPC_SCOM
        select ARCH_RANDOM
+       select CPU_FREQ
+       select CPU_FREQ_GOV_PERFORMANCE
+       select CPU_FREQ_GOV_POWERSAVE
+       select CPU_FREQ_GOV_USERSPACE
+       select CPU_FREQ_GOV_ONDEMAND
+       select CPU_FREQ_GOV_CONSERVATIVE
        default y
 
 config PPC_POWERNV_RTAS
index 1e2b9db..0e9cce8 100644 (file)
@@ -30,7 +30,7 @@ config ARM_EXYNOS_CPUFREQ
 
 config ARM_EXYNOS4210_CPUFREQ
        bool "SAMSUNG EXYNOS4210"
-       depends on CPU_EXYNOS4210
+       depends on CPU_EXYNOS4210 && !ARCH_MULTIPLATFORM
        default y
        select ARM_EXYNOS_CPUFREQ
        help
@@ -41,7 +41,7 @@ config ARM_EXYNOS4210_CPUFREQ
 
 config ARM_EXYNOS4X12_CPUFREQ
        bool "SAMSUNG EXYNOS4x12"
-       depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412)
+       depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
        default y
        select ARM_EXYNOS_CPUFREQ
        help
@@ -52,7 +52,7 @@ config ARM_EXYNOS4X12_CPUFREQ
 
 config ARM_EXYNOS5250_CPUFREQ
        bool "SAMSUNG EXYNOS5250"
-       depends on SOC_EXYNOS5250
+       depends on SOC_EXYNOS5250 && !ARCH_MULTIPLATFORM
        default y
        select ARM_EXYNOS_CPUFREQ
        help
index ca0021a..72564b7 100644 (file)
@@ -54,3 +54,11 @@ config PPC_PASEMI_CPUFREQ
        help
          This adds the support for frequency switching on PA Semi
          PWRficient processors.
+
+config POWERNV_CPUFREQ
+       tristate "CPU frequency scaling for IBM POWERNV platform"
+       depends on PPC_POWERNV
+       default y
+       help
+        This adds support for CPU frequency switching on IBM POWERNV
+        platform
index 7494565..0dbb963 100644 (file)
@@ -86,6 +86,7 @@ obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC)            += pmac32-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC64)          += pmac64-cpufreq.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ)       += pasemi-cpufreq.o
+obj-$(CONFIG_POWERNV_CPUFREQ)          += powernv-cpufreq.o
 
 ##################################################################################
 # Other platform drivers
index d5eaedb..000e4e0 100644 (file)
@@ -754,7 +754,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
                goto err_unreg;
        }
 
-       data->freq_table = kmalloc(sizeof(*data->freq_table) *
+       data->freq_table = kzalloc(sizeof(*data->freq_table) *
                    (perf->state_count+1), GFP_KERNEL);
        if (!data->freq_table) {
                result = -ENOMEM;
index a1c79f5..7b612c8 100644 (file)
@@ -52,7 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
 static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
 {
        unsigned int frequency, rate, min_freq;
-       static struct clk *cpuclk;
+       struct clk *cpuclk;
        int retval, steps, i;
 
        if (policy->cpu != 0)
index d457303..601b88c 100644 (file)
@@ -15,9 +15,9 @@ static struct notifier_block cris_sdram_freq_notifier_block = {
 };
 
 static struct cpufreq_frequency_table cris_freq_table[] = {
-       {0x01,  6000},
-       {0x02,  200000},
-       {0,     CPUFREQ_TABLE_END},
+       {0, 0x01, 6000},
+       {0, 0x02, 200000},
+       {0, 0, CPUFREQ_TABLE_END},
 };
 
 static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
index 13c3361..22b2cdd 100644 (file)
@@ -15,9 +15,9 @@ static struct notifier_block cris_sdram_freq_notifier_block = {
 };
 
 static struct cpufreq_frequency_table cris_freq_table[] = {
-       {0x01, 6000},
-       {0x02, 200000},
-       {0, CPUFREQ_TABLE_END},
+       {0, 0x01, 6000},
+       {0, 0x02, 200000},
+       {0, 0, CPUFREQ_TABLE_END},
 };
 
 static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
index c987e94..7f5d2a6 100644 (file)
@@ -56,15 +56,15 @@ static struct s_elan_multiplier elan_multiplier[] = {
 };
 
 static struct cpufreq_frequency_table elanfreq_table[] = {
-       {0,     1000},
-       {1,     2000},
-       {2,     4000},
-       {3,     8000},
-       {4,     16000},
-       {5,     33000},
-       {6,     66000},
-       {7,     99000},
-       {0,     CPUFREQ_TABLE_END},
+       {0, 0,  1000},
+       {0, 1,  2000},
+       {0, 2,  4000},
+       {0, 3,  8000},
+       {0, 4,  16000},
+       {0, 5,  33000},
+       {0, 6,  66000},
+       {0, 7,  99000},
+       {0, 0,  CPUFREQ_TABLE_END},
 };
 
 
index 40d84c4..6384e5b 100644 (file)
@@ -29,12 +29,12 @@ static unsigned int exynos4210_volt_table[] = {
 };
 
 static struct cpufreq_frequency_table exynos4210_freq_table[] = {
-       {L0, 1200 * 1000},
-       {L1, 1000 * 1000},
-       {L2,  800 * 1000},
-       {L3,  500 * 1000},
-       {L4,  200 * 1000},
-       {0, CPUFREQ_TABLE_END},
+       {0, L0, 1200 * 1000},
+       {0, L1, 1000 * 1000},
+       {0, L2,  800 * 1000},
+       {0, L3,  500 * 1000},
+       {0, L4,  200 * 1000},
+       {0, 0, CPUFREQ_TABLE_END},
 };
 
 static struct apll_freq apll_freq_4210[] = {
index 7c11ace..466c76a 100644 (file)
@@ -30,21 +30,21 @@ static unsigned int exynos4x12_volt_table[] = {
 };
 
 static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
-       {CPUFREQ_BOOST_FREQ, 1500 * 1000},
-       {L1, 1400 * 1000},
-       {L2, 1300 * 1000},
-       {L3, 1200 * 1000},
-       {L4, 1100 * 1000},
-       {L5, 1000 * 1000},
-       {L6,  900 * 1000},
-       {L7,  800 * 1000},
-       {L8,  700 * 1000},
-       {L9,  600 * 1000},
-       {L10, 500 * 1000},
-       {L11, 400 * 1000},
-       {L12, 300 * 1000},
-       {L13, 200 * 1000},
-       {0, CPUFREQ_TABLE_END},
+       {CPUFREQ_BOOST_FREQ, L0, 1500 * 1000},
+       {0, L1, 1400 * 1000},
+       {0, L2, 1300 * 1000},
+       {0, L3, 1200 * 1000},
+       {0, L4, 1100 * 1000},
+       {0, L5, 1000 * 1000},
+       {0, L6,  900 * 1000},
+       {0, L7,  800 * 1000},
+       {0, L8,  700 * 1000},
+       {0, L9,  600 * 1000},
+       {0, L10, 500 * 1000},
+       {0, L11, 400 * 1000},
+       {0, L12, 300 * 1000},
+       {0, L13, 200 * 1000},
+       {0, 0, CPUFREQ_TABLE_END},
 };
 
 static struct apll_freq *apll_freq_4x12;
index 5f90b82..363a0b3 100644 (file)
@@ -34,23 +34,23 @@ static unsigned int exynos5250_volt_table[] = {
 };
 
 static struct cpufreq_frequency_table exynos5250_freq_table[] = {
-       {L0, 1700 * 1000},
-       {L1, 1600 * 1000},
-       {L2, 1500 * 1000},
-       {L3, 1400 * 1000},
-       {L4, 1300 * 1000},
-       {L5, 1200 * 1000},
-       {L6, 1100 * 1000},
-       {L7, 1000 * 1000},
-       {L8,  900 * 1000},
-       {L9,  800 * 1000},
-       {L10, 700 * 1000},
-       {L11, 600 * 1000},
-       {L12, 500 * 1000},
-       {L13, 400 * 1000},
-       {L14, 300 * 1000},
-       {L15, 200 * 1000},
-       {0, CPUFREQ_TABLE_END},
+       {0, L0, 1700 * 1000},
+       {0, L1, 1600 * 1000},
+       {0, L2, 1500 * 1000},
+       {0, L3, 1400 * 1000},
+       {0, L4, 1300 * 1000},
+       {0, L5, 1200 * 1000},
+       {0, L6, 1100 * 1000},
+       {0, L7, 1000 * 1000},
+       {0, L8,  900 * 1000},
+       {0, L9,  800 * 1000},
+       {0, L10, 700 * 1000},
+       {0, L11, 600 * 1000},
+       {0, L12, 500 * 1000},
+       {0, L13, 400 * 1000},
+       {0, L14, 300 * 1000},
+       {0, L15, 200 * 1000},
+       {0, 0, CPUFREQ_TABLE_END},
 };
 
 static struct apll_freq apll_freq_5250[] = {
index 65a4770..08e7bbc 100644 (file)
@@ -33,11 +33,10 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
                        continue;
                }
                if (!cpufreq_boost_enabled()
-                   && table[i].driver_data == CPUFREQ_BOOST_FREQ)
+                   && (table[i].flags & CPUFREQ_BOOST_FREQ))
                        continue;
 
-               pr_debug("table entry %u: %u kHz, %u driver_data\n",
-                                       i, freq, table[i].driver_data);
+               pr_debug("table entry %u: %u kHz\n", i, freq);
                if (freq < min_freq)
                        min_freq = freq;
                if (freq > max_freq)
@@ -175,8 +174,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
        } else
                *index = optimal.driver_data;
 
-       pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency,
-               table[*index].driver_data);
+       pr_debug("target index is %u, freq is:%u kHz\n", *index,
+                table[*index].frequency);
 
        return 0;
 }
@@ -230,7 +229,7 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
                 * show_boost = false and driver_data != BOOST freq
                 * display NON BOOST freqs
                 */
-               if (show_boost ^ (table[i].driver_data == CPUFREQ_BOOST_FREQ))
+               if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ))
                        continue;
 
                count += sprintf(&buf[count], "%d ", table[i].frequency);
index a22b5d1..c30aaa6 100644 (file)
@@ -254,7 +254,7 @@ acpi_cpufreq_cpu_init (
        }
 
        /* alloc freq_table */
-       data->freq_table = kmalloc(sizeof(*data->freq_table) *
+       data->freq_table = kzalloc(sizeof(*data->freq_table) *
                                   (data->acpi_data.state_count + 1),
                                   GFP_KERNEL);
        if (!data->freq_table) {
@@ -275,7 +275,6 @@ acpi_cpufreq_cpu_init (
        /* table init */
        for (i = 0; i <= data->acpi_data.state_count; i++)
        {
-               data->freq_table[i].driver_data = i;
                if (i < data->acpi_data.state_count) {
                        data->freq_table[i].frequency =
                              data->acpi_data.states[i].core_frequency * 1000;
index 3d114bc..37a4806 100644 (file)
@@ -43,9 +43,9 @@ static struct priv
  * table.
  */
 static struct cpufreq_frequency_table kirkwood_freq_table[] = {
-       {STATE_CPU_FREQ,        0}, /* CPU uses cpuclk */
-       {STATE_DDR_FREQ,        0}, /* CPU uses ddrclk */
-       {0,                     CPUFREQ_TABLE_END},
+       {0, STATE_CPU_FREQ,     0}, /* CPU uses cpuclk */
+       {0, STATE_DDR_FREQ,     0}, /* CPU uses ddrclk */
+       {0, 0,                  CPUFREQ_TABLE_END},
 };
 
 static unsigned int kirkwood_cpufreq_get_cpu_frequency(unsigned int cpu)
index 5c440f8..d00e5d1 100644 (file)
@@ -475,7 +475,7 @@ static int longhaul_get_ranges(void)
                return -EINVAL;
        }
 
-       longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
+       longhaul_table = kzalloc((numscales + 1) * sizeof(*longhaul_table),
                        GFP_KERNEL);
        if (!longhaul_table)
                return -ENOMEM;
index a3588d6..f0bc31f 100644 (file)
@@ -69,7 +69,7 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
 
 static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
-       static struct clk *cpuclk;
+       struct clk *cpuclk;
        int i;
        unsigned long rate;
        int ret;
index c4dfa42..cc3408f 100644 (file)
@@ -59,9 +59,9 @@
 #define CPUFREQ_LOW                   1
 
 static struct cpufreq_frequency_table maple_cpu_freqs[] = {
-       {CPUFREQ_HIGH,          0},
-       {CPUFREQ_LOW,           0},
-       {0,                     CPUFREQ_TABLE_END},
+       {0, CPUFREQ_HIGH,               0},
+       {0, CPUFREQ_LOW,                0},
+       {0, 0,                          CPUFREQ_TABLE_END},
 };
 
 /* Power mode data is an array of the 32 bits PCR values to use for
index 74f593e..529cfd9 100644 (file)
@@ -92,16 +92,16 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
 
 
 static struct cpufreq_frequency_table p4clockmod_table[] = {
-       {DC_RESV, CPUFREQ_ENTRY_INVALID},
-       {DC_DFLT, 0},
-       {DC_25PT, 0},
-       {DC_38PT, 0},
-       {DC_50PT, 0},
-       {DC_64PT, 0},
-       {DC_75PT, 0},
-       {DC_88PT, 0},
-       {DC_DISABLE, 0},
-       {DC_RESV, CPUFREQ_TABLE_END},
+       {0, DC_RESV, CPUFREQ_ENTRY_INVALID},
+       {0, DC_DFLT, 0},
+       {0, DC_25PT, 0},
+       {0, DC_38PT, 0},
+       {0, DC_50PT, 0},
+       {0, DC_64PT, 0},
+       {0, DC_75PT, 0},
+       {0, DC_88PT, 0},
+       {0, DC_DISABLE, 0},
+       {0, DC_RESV, CPUFREQ_TABLE_END},
 };
 
 
index 6a2b7d3..84c84b5 100644 (file)
@@ -60,12 +60,12 @@ static int current_astate;
 
 /* We support 5(A0-A4) power states excluding turbo(A5-A6) modes */
 static struct cpufreq_frequency_table pas_freqs[] = {
-       {0,     0},
-       {1,     0},
-       {2,     0},
-       {3,     0},
-       {4,     0},
-       {0,     CPUFREQ_TABLE_END},
+       {0, 0,  0},
+       {0, 1,  0},
+       {0, 2,  0},
+       {0, 3,  0},
+       {0, 4,  0},
+       {0, 0,  CPUFREQ_TABLE_END},
 };
 
 /*
index cf55d20..7615180 100644 (file)
@@ -81,9 +81,9 @@ static int is_pmu_based;
 #define CPUFREQ_LOW                   1
 
 static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
-       {CPUFREQ_HIGH,          0},
-       {CPUFREQ_LOW,           0},
-       {0,                     CPUFREQ_TABLE_END},
+       {0, CPUFREQ_HIGH,       0},
+       {0, CPUFREQ_LOW,        0},
+       {0, 0,                  CPUFREQ_TABLE_END},
 };
 
 static inline void local_delay(unsigned long ms)
index 6a338f8..8bc4229 100644 (file)
@@ -65,9 +65,9 @@
 #define CPUFREQ_LOW                   1
 
 static struct cpufreq_frequency_table g5_cpu_freqs[] = {
-       {CPUFREQ_HIGH,          0},
-       {CPUFREQ_LOW,           0},
-       {0,                     CPUFREQ_TABLE_END},
+       {0, CPUFREQ_HIGH,       0},
+       {0, CPUFREQ_LOW,        0},
+       {0, 0,                  CPUFREQ_TABLE_END},
 };
 
 /* Power mode data is an array of the 32 bits PCR values to use for
index 62c6f2e..49f120e 100644 (file)
@@ -37,15 +37,15 @@ MODULE_PARM_DESC(bus_frequency, "Bus frequency in kHz");
 
 /* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
 static struct cpufreq_frequency_table clock_ratio[] = {
-       {60,  /* 110 -> 6.0x */ 0},
-       {55,  /* 011 -> 5.5x */ 0},
-       {50,  /* 001 -> 5.0x */ 0},
-       {45,  /* 000 -> 4.5x */ 0},
-       {40,  /* 010 -> 4.0x */ 0},
-       {35,  /* 111 -> 3.5x */ 0},
-       {30,  /* 101 -> 3.0x */ 0},
-       {20,  /* 100 -> 2.0x */ 0},
-       {0, CPUFREQ_TABLE_END}
+       {0, 60,  /* 110 -> 6.0x */ 0},
+       {0, 55,  /* 011 -> 5.5x */ 0},
+       {0, 50,  /* 001 -> 5.0x */ 0},
+       {0, 45,  /* 000 -> 4.5x */ 0},
+       {0, 40,  /* 010 -> 4.0x */ 0},
+       {0, 35,  /* 111 -> 3.5x */ 0},
+       {0, 30,  /* 101 -> 3.0x */ 0},
+       {0, 20,  /* 100 -> 2.0x */ 0},
+       {0, 0, CPUFREQ_TABLE_END}
 };
 
 static const u8 index_to_register[8] = { 6, 3, 1, 0, 2, 7, 5, 4 };
index 770a9e1..1b6ae6b 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(*powernow_table)
+       powernow_table = kzalloc((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(*powernow_table)
+       powernow_table = kzalloc((sizeof(*powernow_table)
                * (data->acpi_data.state_count + 1)), GFP_KERNEL);
        if (!powernow_table) {
                pr_debug("powernow_table memory alloc failure\n");
@@ -810,7 +810,6 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 
        powernow_table[data->acpi_data.state_count].frequency =
                CPUFREQ_TABLE_END;
-       powernow_table[data->acpi_data.state_count].driver_data = 0;
        data->powernow_table = powernow_table;
 
        if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
new file mode 100644 (file)
index 0000000..9edccc6
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * POWERNV cpufreq driver for the IBM POWER processors
+ *
+ * (C) Copyright IBM 2014
+ *
+ * Author: Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt)    "powernv-cpufreq: " fmt
+
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/cpufreq.h>
+#include <linux/smp.h>
+#include <linux/of.h>
+
+#include <asm/cputhreads.h>
+#include <asm/reg.h>
+
+#define POWERNV_MAX_PSTATES    256
+
+static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
+
+/*
+ * Note: The set of pstates consists of contiguous integers, the
+ * smallest of which is indicated by powernv_pstate_info.min, the
+ * largest of which is indicated by powernv_pstate_info.max.
+ *
+ * The nominal pstate is the highest non-turbo pstate in this
+ * platform. This is indicated by powernv_pstate_info.nominal.
+ */
+static struct powernv_pstate_info {
+       int min;
+       int max;
+       int nominal;
+       int nr_pstates;
+} powernv_pstate_info;
+
+/*
+ * Initialize the freq table based on data obtained
+ * from the firmware passed via device-tree
+ */
+static int init_powernv_pstates(void)
+{
+       struct device_node *power_mgt;
+       int i, pstate_min, pstate_max, pstate_nominal, nr_pstates = 0;
+       const __be32 *pstate_ids, *pstate_freqs;
+       u32 len_ids, len_freqs;
+
+       power_mgt = of_find_node_by_path("/ibm,opal/power-mgt");
+       if (!power_mgt) {
+               pr_warn("power-mgt node not found\n");
+               return -ENODEV;
+       }
+
+       if (of_property_read_u32(power_mgt, "ibm,pstate-min", &pstate_min)) {
+               pr_warn("ibm,pstate-min node not found\n");
+               return -ENODEV;
+       }
+
+       if (of_property_read_u32(power_mgt, "ibm,pstate-max", &pstate_max)) {
+               pr_warn("ibm,pstate-max node not found\n");
+               return -ENODEV;
+       }
+
+       if (of_property_read_u32(power_mgt, "ibm,pstate-nominal",
+                                &pstate_nominal)) {
+               pr_warn("ibm,pstate-nominal not found\n");
+               return -ENODEV;
+       }
+       pr_info("cpufreq pstate min %d nominal %d max %d\n", pstate_min,
+               pstate_nominal, pstate_max);
+
+       pstate_ids = of_get_property(power_mgt, "ibm,pstate-ids", &len_ids);
+       if (!pstate_ids) {
+               pr_warn("ibm,pstate-ids not found\n");
+               return -ENODEV;
+       }
+
+       pstate_freqs = of_get_property(power_mgt, "ibm,pstate-frequencies-mhz",
+                                     &len_freqs);
+       if (!pstate_freqs) {
+               pr_warn("ibm,pstate-frequencies-mhz not found\n");
+               return -ENODEV;
+       }
+
+       WARN_ON(len_ids != len_freqs);
+       nr_pstates = min(len_ids, len_freqs) / sizeof(u32);
+       if (!nr_pstates) {
+               pr_warn("No PStates found\n");
+               return -ENODEV;
+       }
+
+       pr_debug("NR PStates %d\n", nr_pstates);
+       for (i = 0; i < nr_pstates; i++) {
+               u32 id = be32_to_cpu(pstate_ids[i]);
+               u32 freq = be32_to_cpu(pstate_freqs[i]);
+
+               pr_debug("PState id %d freq %d MHz\n", id, freq);
+               powernv_freqs[i].frequency = freq * 1000; /* kHz */
+               powernv_freqs[i].driver_data = id;
+       }
+       /* End of list marker entry */
+       powernv_freqs[i].frequency = CPUFREQ_TABLE_END;
+
+       powernv_pstate_info.min = pstate_min;
+       powernv_pstate_info.max = pstate_max;
+       powernv_pstate_info.nominal = pstate_nominal;
+       powernv_pstate_info.nr_pstates = nr_pstates;
+
+       return 0;
+}
+
+/* Returns the CPU frequency corresponding to the pstate_id. */
+static unsigned int pstate_id_to_freq(int pstate_id)
+{
+       int i;
+
+       i = powernv_pstate_info.max - pstate_id;
+       BUG_ON(i >= powernv_pstate_info.nr_pstates || i < 0);
+
+       return powernv_freqs[i].frequency;
+}
+
+/*
+ * cpuinfo_nominal_freq_show - Show the nominal CPU frequency as indicated by
+ * the firmware
+ */
+static ssize_t cpuinfo_nominal_freq_show(struct cpufreq_policy *policy,
+                                       char *buf)
+{
+       return sprintf(buf, "%u\n",
+               pstate_id_to_freq(powernv_pstate_info.nominal));
+}
+
+struct freq_attr cpufreq_freq_attr_cpuinfo_nominal_freq =
+       __ATTR_RO(cpuinfo_nominal_freq);
+
+static struct freq_attr *powernv_cpu_freq_attr[] = {
+       &cpufreq_freq_attr_scaling_available_freqs,
+       &cpufreq_freq_attr_cpuinfo_nominal_freq,
+       NULL,
+};
+
+/* Helper routines */
+
+/* Access helpers to power mgt SPR */
+
+static inline unsigned long get_pmspr(unsigned long sprn)
+{
+       switch (sprn) {
+       case SPRN_PMCR:
+               return mfspr(SPRN_PMCR);
+
+       case SPRN_PMICR:
+               return mfspr(SPRN_PMICR);
+
+       case SPRN_PMSR:
+               return mfspr(SPRN_PMSR);
+       }
+       BUG();
+}
+
+static inline void set_pmspr(unsigned long sprn, unsigned long val)
+{
+       switch (sprn) {
+       case SPRN_PMCR:
+               mtspr(SPRN_PMCR, val);
+               return;
+
+       case SPRN_PMICR:
+               mtspr(SPRN_PMICR, val);
+               return;
+       }
+       BUG();
+}
+
+/*
+ * Use objects of this type to query/update
+ * pstates on a remote CPU via smp_call_function.
+ */
+struct powernv_smp_call_data {
+       unsigned int freq;
+       int pstate_id;
+};
+
+/*
+ * powernv_read_cpu_freq: Reads the current frequency on this CPU.
+ *
+ * Called via smp_call_function.
+ *
+ * Note: The caller of the smp_call_function should pass an argument of
+ * the type 'struct powernv_smp_call_data *' along with this function.
+ *
+ * The current frequency on this CPU will be returned via
+ * ((struct powernv_smp_call_data *)arg)->freq;
+ */
+static void powernv_read_cpu_freq(void *arg)
+{
+       unsigned long pmspr_val;
+       s8 local_pstate_id;
+       struct powernv_smp_call_data *freq_data = arg;
+
+       pmspr_val = get_pmspr(SPRN_PMSR);
+
+       /*
+        * The local pstate id corresponds bits 48..55 in the PMSR.
+        * Note: Watch out for the sign!
+        */
+       local_pstate_id = (pmspr_val >> 48) & 0xFF;
+       freq_data->pstate_id = local_pstate_id;
+       freq_data->freq = pstate_id_to_freq(freq_data->pstate_id);
+
+       pr_debug("cpu %d pmsr %016lX pstate_id %d frequency %d kHz\n",
+               raw_smp_processor_id(), pmspr_val, freq_data->pstate_id,
+               freq_data->freq);
+}
+
+/*
+ * powernv_cpufreq_get: Returns the CPU frequency as reported by the
+ * firmware for CPU 'cpu'. This value is reported through the sysfs
+ * file cpuinfo_cur_freq.
+ */
+unsigned int powernv_cpufreq_get(unsigned int cpu)
+{
+       struct powernv_smp_call_data freq_data;
+
+       smp_call_function_any(cpu_sibling_mask(cpu), powernv_read_cpu_freq,
+                       &freq_data, 1);
+
+       return freq_data.freq;
+}
+
+/*
+ * set_pstate: Sets the pstate on this CPU.
+ *
+ * This is called via an smp_call_function.
+ *
+ * The caller must ensure that freq_data is of the type
+ * (struct powernv_smp_call_data *) and the pstate_id which needs to be set
+ * on this CPU should be present in freq_data->pstate_id.
+ */
+static void set_pstate(void *freq_data)
+{
+       unsigned long val;
+       unsigned long pstate_ul =
+               ((struct powernv_smp_call_data *) freq_data)->pstate_id;
+
+       val = get_pmspr(SPRN_PMCR);
+       val = val & 0x0000FFFFFFFFFFFFULL;
+
+       pstate_ul = pstate_ul & 0xFF;
+
+       /* Set both global(bits 56..63) and local(bits 48..55) PStates */
+       val = val | (pstate_ul << 56) | (pstate_ul << 48);
+
+       pr_debug("Setting cpu %d pmcr to %016lX\n",
+                       raw_smp_processor_id(), val);
+       set_pmspr(SPRN_PMCR, val);
+}
+
+/*
+ * powernv_cpufreq_target_index: Sets the frequency corresponding to
+ * the cpufreq table entry indexed by new_index on the cpus in the
+ * mask policy->cpus
+ */
+static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
+                                       unsigned int new_index)
+{
+       struct powernv_smp_call_data freq_data;
+
+       freq_data.pstate_id = powernv_freqs[new_index].driver_data;
+
+       /*
+        * Use smp_call_function to send IPI and execute the
+        * mtspr on target CPU.  We could do that without IPI
+        * if current CPU is within policy->cpus (core)
+        */
+       smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1);
+
+       return 0;
+}
+
+static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+       int base, i;
+
+       base = cpu_first_thread_sibling(policy->cpu);
+
+       for (i = 0; i < threads_per_core; i++)
+               cpumask_set_cpu(base + i, policy->cpus);
+
+       return cpufreq_table_validate_and_show(policy, powernv_freqs);
+}
+
+static struct cpufreq_driver powernv_cpufreq_driver = {
+       .name           = "powernv-cpufreq",
+       .flags          = CPUFREQ_CONST_LOOPS,
+       .init           = powernv_cpufreq_cpu_init,
+       .verify         = cpufreq_generic_frequency_table_verify,
+       .target_index   = powernv_cpufreq_target_index,
+       .get            = powernv_cpufreq_get,
+       .attr           = powernv_cpu_freq_attr,
+};
+
+static int __init powernv_cpufreq_init(void)
+{
+       int rc = 0;
+
+       /* Discover pstates from device tree and init */
+       rc = init_powernv_pstates();
+       if (rc) {
+               pr_info("powernv-cpufreq disabled. System does not support PState control\n");
+               return rc;
+       }
+
+       return cpufreq_register_driver(&powernv_cpufreq_driver);
+}
+module_init(powernv_cpufreq_init);
+
+static void __exit powernv_cpufreq_exit(void)
+{
+       cpufreq_unregister_driver(&powernv_cpufreq_driver);
+}
+module_exit(powernv_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vaidyanathan Srinivasan <svaidy at linux.vnet.ibm.com>");
index 3bd9123..b7e677b 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/errno.h>
-#include <sysdev/fsl_soc.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index af7b1ca..5be8a48 100644 (file)
 
 /* the CBE supports an 8 step frequency scaling */
 static struct cpufreq_frequency_table cbe_freqs[] = {
-       {1,     0},
-       {2,     0},
-       {3,     0},
-       {4,     0},
-       {5,     0},
-       {6,     0},
-       {8,     0},
-       {10,    0},
-       {0,     CPUFREQ_TABLE_END},
+       {0, 1,  0},
+       {0, 2,  0},
+       {0, 3,  0},
+       {0, 4,  0},
+       {0, 5,  0},
+       {0, 6,  0},
+       {0, 8,  0},
+       {0, 10, 0},
+       {0, 0,  CPUFREQ_TABLE_END},
 };
 
 /*
index 826b8be..4626f90 100644 (file)
@@ -72,19 +72,19 @@ static struct s3c2416_dvfs s3c2416_dvfs_table[] = {
 #endif
 
 static struct cpufreq_frequency_table s3c2416_freq_table[] = {
-       { SOURCE_HCLK, FREQ_DVS },
-       { SOURCE_ARMDIV, 133333 },
-       { SOURCE_ARMDIV, 266666 },
-       { SOURCE_ARMDIV, 400000 },
-       { 0, CPUFREQ_TABLE_END },
+       { 0, SOURCE_HCLK, FREQ_DVS },
+       { 0, SOURCE_ARMDIV, 133333 },
+       { 0, SOURCE_ARMDIV, 266666 },
+       { 0, SOURCE_ARMDIV, 400000 },
+       { 0, 0, CPUFREQ_TABLE_END },
 };
 
 static struct cpufreq_frequency_table s3c2450_freq_table[] = {
-       { SOURCE_HCLK, FREQ_DVS },
-       { SOURCE_ARMDIV, 133500 },
-       { SOURCE_ARMDIV, 267000 },
-       { SOURCE_ARMDIV, 534000 },
-       { 0, CPUFREQ_TABLE_END },
+       { 0, SOURCE_HCLK, FREQ_DVS },
+       { 0, SOURCE_ARMDIV, 133500 },
+       { 0, SOURCE_ARMDIV, 267000 },
+       { 0, SOURCE_ARMDIV, 534000 },
+       { 0, 0, CPUFREQ_TABLE_END },
 };
 
 static unsigned int s3c2416_cpufreq_get_speed(unsigned int cpu)
index a3dc192..be1b2b5 100644 (file)
@@ -586,7 +586,7 @@ static int s3c_cpufreq_build_freq(void)
        size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
        size++;
 
-       ftab = kmalloc(sizeof(*ftab) * size, GFP_KERNEL);
+       ftab = kzalloc(sizeof(*ftab) * size, GFP_KERNEL);
        if (!ftab) {
                printk(KERN_ERR "%s: no memory for tables\n", __func__);
                return -ENOMEM;
@@ -664,7 +664,7 @@ int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
 
        size = sizeof(*vals) * (plls_no + 1);
 
-       vals = kmalloc(size, GFP_KERNEL);
+       vals = kzalloc(size, GFP_KERNEL);
        if (vals) {
                memcpy(vals, plls, size);
                pll_reg = vals;
index c4226de..ff7d3ec 100644 (file)
@@ -37,19 +37,19 @@ static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
 };
 
 static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
-       { 0,  66000 },
-       { 0, 100000 },
-       { 0, 133000 },
-       { 1, 200000 },
-       { 1, 222000 },
-       { 1, 266000 },
-       { 2, 333000 },
-       { 2, 400000 },
-       { 2, 532000 },
-       { 2, 533000 },
-       { 3, 667000 },
-       { 4, 800000 },
-       { 0, CPUFREQ_TABLE_END },
+       { 0, 0,  66000 },
+       { 0, 0, 100000 },
+       { 0, 0, 133000 },
+       { 0, 1, 200000 },
+       { 0, 1, 222000 },
+       { 0, 1, 266000 },
+       { 0, 2, 333000 },
+       { 0, 2, 400000 },
+       { 0, 2, 532000 },
+       { 0, 2, 533000 },
+       { 0, 3, 667000 },
+       { 0, 4, 800000 },
+       { 0, 0, CPUFREQ_TABLE_END },
 };
 #endif
 
index 7242153..ab2c1a4 100644 (file)
@@ -64,12 +64,12 @@ enum s5pv210_dmc_port {
 };
 
 static struct cpufreq_frequency_table s5pv210_freq_table[] = {
-       {L0, 1000*1000},
-       {L1, 800*1000},
-       {L2, 400*1000},
-       {L3, 200*1000},
-       {L4, 100*1000},
-       {0, CPUFREQ_TABLE_END},
+       {0, L0, 1000*1000},
+       {0, L1, 800*1000},
+       {0, L2, 400*1000},
+       {0, L3, 200*1000},
+       {0, L4, 100*1000},
+       {0, 0, CPUFREQ_TABLE_END},
 };
 
 static struct regulator *arm_regulator;
index 69371bf..ac84e48 100644 (file)
@@ -33,9 +33,9 @@ static __u8 __iomem *cpuctl;
 #define PFX "sc520_freq: "
 
 static struct cpufreq_frequency_table sc520_freq_table[] = {
-       {0x01,  100000},
-       {0x02,  133000},
-       {0,     CPUFREQ_TABLE_END},
+       {0, 0x01,       100000},
+       {0, 0x02,       133000},
+       {0, 0,  CPUFREQ_TABLE_END},
 };
 
 static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
index 4cfdcff..3867839 100644 (file)
@@ -195,18 +195,15 @@ static int spear_cpufreq_probe(struct platform_device *pdev)
        cnt = prop->length / sizeof(u32);
        val = prop->value;
 
-       freq_tbl = kmalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL);
+       freq_tbl = kzalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL);
        if (!freq_tbl) {
                ret = -ENOMEM;
                goto out_put_node;
        }
 
-       for (i = 0; i < cnt; i++) {
-               freq_tbl[i].driver_data = i;
+       for (i = 0; i < cnt; i++)
                freq_tbl[i].frequency = be32_to_cpup(val++);
-       }
 
-       freq_tbl[i].driver_data = i;
        freq_tbl[i].frequency = CPUFREQ_TABLE_END;
 
        spear_cpufreq.freq_tbl = freq_tbl;
index 394ac15..1a07b59 100644 (file)
@@ -49,9 +49,9 @@ static u32 pmbase;
  * are in kHz for the time being.
  */
 static struct cpufreq_frequency_table speedstep_freqs[] = {
-       {SPEEDSTEP_HIGH,        0},
-       {SPEEDSTEP_LOW,         0},
-       {0,                     CPUFREQ_TABLE_END},
+       {0, SPEEDSTEP_HIGH,     0},
+       {0, SPEEDSTEP_LOW,      0},
+       {0, 0,                  CPUFREQ_TABLE_END},
 };
 
 
index db5d274..8635eec 100644 (file)
@@ -42,9 +42,9 @@ static enum speedstep_processor speedstep_processor;
  * are in kHz for the time being.
  */
 static struct cpufreq_frequency_table speedstep_freqs[] = {
-       {SPEEDSTEP_HIGH,        0},
-       {SPEEDSTEP_LOW,         0},
-       {0,                     CPUFREQ_TABLE_END},
+       {0, SPEEDSTEP_HIGH,     0},
+       {0, SPEEDSTEP_LOW,      0},
+       {0, 0,                  CPUFREQ_TABLE_END},
 };
 
 #define GET_SPEEDSTEP_OWNER 0
index 13be802..8d045af 100644 (file)
@@ -45,7 +45,7 @@ static int ucv2_target(struct cpufreq_policy *policy,
        freqs.new = target_freq;
 
        cpufreq_freq_transition_begin(policy, &freqs);
-       ret = clk_set_rate(policy->mclk, target_freq * 1000);
+       ret = clk_set_rate(policy->clk, target_freq * 1000);
        cpufreq_freq_transition_end(policy, &freqs, ret);
 
        return ret;
index c48e595..5ae5100 100644 (file)
@@ -455,11 +455,14 @@ extern struct cpufreq_governor cpufreq_gov_conservative;
  *                     FREQUENCY TABLE HELPERS                       *
  *********************************************************************/
 
-#define CPUFREQ_ENTRY_INVALID ~0
-#define CPUFREQ_TABLE_END     ~1
-#define CPUFREQ_BOOST_FREQ    ~2
+/* Special Values of .frequency field */
+#define CPUFREQ_ENTRY_INVALID  ~0
+#define CPUFREQ_TABLE_END      ~1
+/* Special Values of .flags field */
+#define CPUFREQ_BOOST_FREQ     (1 << 0)
 
 struct cpufreq_frequency_table {
+       unsigned int    flags;
        unsigned int    driver_data; /* driver specific data, not used by core */
        unsigned int    frequency; /* kHz - doesn't need to be in ascending
                                    * order */