Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8a497cfd
Commit
8a497cfd
authored
Dec 01, 2014
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back earlier cpufreq material for 3.19-rc1.
parents
009d0431
9a004428
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
543 additions
and
115 deletions
+543
-115
Documentation/cpu-freq/intel-pstate.txt
Documentation/cpu-freq/intel-pstate.txt
+25
-12
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+3
-0
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/cpufeature.h
+5
-0
arch/x86/include/uapi/asm/msr-index.h
arch/x86/include/uapi/asm/msr-index.h
+41
-0
arch/x86/kernel/cpu/scattered.c
arch/x86/kernel/cpu/scattered.c
+5
-0
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig
+27
-30
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Kconfig.arm
+8
-0
drivers/cpufreq/Makefile
drivers/cpufreq/Makefile
+2
-2
drivers/cpufreq/cpufreq-dt.c
drivers/cpufreq/cpufreq-dt.c
+39
-21
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+30
-23
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/intel_pstate.c
+99
-2
drivers/cpufreq/ls1x-cpufreq.c
drivers/cpufreq/ls1x-cpufreq.c
+223
-0
drivers/cpufreq/pcc-cpufreq.c
drivers/cpufreq/pcc-cpufreq.c
+7
-0
include/linux/cpufreq.h
include/linux/cpufreq.h
+29
-25
No files found.
Documentation/cpu-freq/intel-pstate.txt
View file @
8a497cfd
Intel P-state driver
Intel P-state driver
--------------------
--------------------
This driver implements a scaling driver with an internal governor for
This driver provides an interface to control the P state selection for
Intel Core processors. The driver follows the same model as the
SandyBridge+ Intel processors. The driver can operate two different
Transmeta scaling driver (longrun.c) and implements the setpolicy()
modes based on the processor model legacy and Hardware P state (HWP)
instead of target(). Scaling drivers that implement setpolicy() are
mode.
assumed to implement internal governors by the cpufreq core. All the
logic for selecting the current P state is contained within the
In legacy mode the driver implements a scaling driver with an internal
driver; no external governor is used by the cpufreq core.
governor for Intel Core processors. The driver follows the same model
as the Transmeta scaling driver (longrun.c) and implements the
Intel SandyBridge+ processors are supported.
setpolicy() instead of target(). Scaling drivers that implement
setpolicy() are assumed to implement internal governors by the cpufreq
New sysfs files for controlling P state selection have been added to
core. All the logic for selecting the current P state is contained
within the driver; no external governor is used by the cpufreq core.
In HWP mode P state selection is implemented in the processor
itself. The driver provides the interfaces between the cpufreq core and
the processor to control P state selection based on user preferences
and reporting frequency to the cpufreq core. In this mode the
internal governor code is disabled.
In addtion to the interfaces provided by the cpufreq core for
controlling frequency the driver provides sysfs files for
controlling P state selection. These files have been added to
/sys/devices/system/cpu/intel_pstate/
/sys/devices/system/cpu/intel_pstate/
max_perf_pct: limits the maximum P state that will be requested by
max_perf_pct: limits the maximum P state that will be requested by
...
@@ -33,7 +44,9 @@ frequency is fiction for Intel Core processors. Even if the scaling
...
@@ -33,7 +44,9 @@ frequency is fiction for Intel Core processors. Even if the scaling
driver selects a single P state the actual frequency the processor
driver selects a single P state the actual frequency the processor
will run at is selected by the processor itself.
will run at is selected by the processor itself.
New debugfs files have also been added to /sys/kernel/debug/pstate_snb/
For legacy mode debugfs files have also been added to allow tuning of
the internal governor algorythm. These files are located at
/sys/kernel/debug/pstate_snb/ These files are NOT present in HWP mode.
deadband
deadband
d_gain_pct
d_gain_pct
...
...
Documentation/kernel-parameters.txt
View file @
8a497cfd
...
@@ -1446,6 +1446,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
...
@@ -1446,6 +1446,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
disable
disable
Do not enable intel_pstate as the default
Do not enable intel_pstate as the default
scaling driver for the supported processors
scaling driver for the supported processors
no_hwp
Do not enable hardware P state control (HWP)
if available.
intremap= [X86-64, Intel-IOMMU]
intremap= [X86-64, Intel-IOMMU]
on enable Interrupt Remapping (default)
on enable Interrupt Remapping (default)
...
...
arch/x86/include/asm/cpufeature.h
View file @
8a497cfd
...
@@ -189,6 +189,11 @@
...
@@ -189,6 +189,11 @@
#define X86_FEATURE_DTHERM ( 7*32+ 7)
/* Digital Thermal Sensor */
#define X86_FEATURE_DTHERM ( 7*32+ 7)
/* Digital Thermal Sensor */
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8)
/* AMD HW-PState */
#define X86_FEATURE_HW_PSTATE ( 7*32+ 8)
/* AMD HW-PState */
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9)
/* AMD ProcFeedbackInterface */
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9)
/* AMD ProcFeedbackInterface */
#define X86_FEATURE_HWP ( 7*32+ 10)
/* "hwp" Intel HWP */
#define X86_FEATURE_HWP_NOITFY ( 7*32+ 11)
/* Intel HWP_NOTIFY */
#define X86_FEATURE_HWP_ACT_WINDOW ( 7*32+ 12)
/* Intel HWP_ACT_WINDOW */
#define X86_FEATURE_HWP_EPP ( 7*32+13)
/* Intel HWP_EPP */
#define X86_FEATURE_HWP_PKG_REQ ( 7*32+14)
/* Intel HWP_PKG_REQ */
/* Virtualization flags: Linux defined, word 8 */
/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0)
/* Intel TPR Shadow */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0)
/* Intel TPR Shadow */
...
...
arch/x86/include/uapi/asm/msr-index.h
View file @
8a497cfd
...
@@ -152,6 +152,45 @@
...
@@ -152,6 +152,45 @@
#define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668
#define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668
#define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669
#define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669
/* Hardware P state interface */
#define MSR_PPERF 0x0000064e
#define MSR_PERF_LIMIT_REASONS 0x0000064f
#define MSR_PM_ENABLE 0x00000770
#define MSR_HWP_CAPABILITIES 0x00000771
#define MSR_HWP_REQUEST_PKG 0x00000772
#define MSR_HWP_INTERRUPT 0x00000773
#define MSR_HWP_REQUEST 0x00000774
#define MSR_HWP_STATUS 0x00000777
/* CPUID.6.EAX */
#define HWP_BASE_BIT (1<<7)
#define HWP_NOTIFICATIONS_BIT (1<<8)
#define HWP_ACTIVITY_WINDOW_BIT (1<<9)
#define HWP_ENERGY_PERF_PREFERENCE_BIT (1<<10)
#define HWP_PACKAGE_LEVEL_REQUEST_BIT (1<<11)
/* IA32_HWP_CAPABILITIES */
#define HWP_HIGHEST_PERF(x) (x & 0xff)
#define HWP_GUARANTEED_PERF(x) ((x & (0xff << 8)) >>8)
#define HWP_MOSTEFFICIENT_PERF(x) ((x & (0xff << 16)) >>16)
#define HWP_LOWEST_PERF(x) ((x & (0xff << 24)) >>24)
/* IA32_HWP_REQUEST */
#define HWP_MIN_PERF(x) (x & 0xff)
#define HWP_MAX_PERF(x) ((x & 0xff) << 8)
#define HWP_DESIRED_PERF(x) ((x & 0xff) << 16)
#define HWP_ENERGY_PERF_PREFERENCE(x) ((x & 0xff) << 24)
#define HWP_ACTIVITY_WINDOW(x) ((x & 0xff3) << 32)
#define HWP_PACKAGE_CONTROL(x) ((x & 0x1) << 42)
/* IA32_HWP_STATUS */
#define HWP_GUARANTEED_CHANGE(x) (x & 0x1)
#define HWP_EXCURSION_TO_MINIMUM(x) (x & 0x4)
/* IA32_HWP_INTERRUPT */
#define HWP_CHANGE_TO_GUARANTEED_INT(x) (x & 0x1)
#define HWP_EXCURSION_TO_MINIMUM_INT(x) (x & 0x2)
#define MSR_AMD64_MC0_MASK 0xc0010044
#define MSR_AMD64_MC0_MASK 0xc0010044
#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x))
#define MSR_IA32_MCx_CTL(x) (MSR_IA32_MC0_CTL + 4*(x))
...
@@ -345,6 +384,8 @@
...
@@ -345,6 +384,8 @@
#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
#define MSR_MISC_PWR_MGMT 0x000001aa
#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
#define ENERGY_PERF_BIAS_PERFORMANCE 0
#define ENERGY_PERF_BIAS_PERFORMANCE 0
#define ENERGY_PERF_BIAS_NORMAL 6
#define ENERGY_PERF_BIAS_NORMAL 6
...
...
arch/x86/kernel/cpu/scattered.c
View file @
8a497cfd
...
@@ -36,6 +36,11 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c)
...
@@ -36,6 +36,11 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c)
{
X86_FEATURE_ARAT
,
CR_EAX
,
2
,
0x00000006
,
0
},
{
X86_FEATURE_ARAT
,
CR_EAX
,
2
,
0x00000006
,
0
},
{
X86_FEATURE_PLN
,
CR_EAX
,
4
,
0x00000006
,
0
},
{
X86_FEATURE_PLN
,
CR_EAX
,
4
,
0x00000006
,
0
},
{
X86_FEATURE_PTS
,
CR_EAX
,
6
,
0x00000006
,
0
},
{
X86_FEATURE_PTS
,
CR_EAX
,
6
,
0x00000006
,
0
},
{
X86_FEATURE_HWP
,
CR_EAX
,
7
,
0x00000006
,
0
},
{
X86_FEATURE_HWP_NOITFY
,
CR_EAX
,
8
,
0x00000006
,
0
},
{
X86_FEATURE_HWP_ACT_WINDOW
,
CR_EAX
,
9
,
0x00000006
,
0
},
{
X86_FEATURE_HWP_EPP
,
CR_EAX
,
10
,
0x00000006
,
0
},
{
X86_FEATURE_HWP_PKG_REQ
,
CR_EAX
,
11
,
0x00000006
,
0
},
{
X86_FEATURE_APERFMPERF
,
CR_ECX
,
0
,
0x00000006
,
0
},
{
X86_FEATURE_APERFMPERF
,
CR_ECX
,
0
,
0x00000006
,
0
},
{
X86_FEATURE_EPB
,
CR_ECX
,
3
,
0x00000006
,
0
},
{
X86_FEATURE_EPB
,
CR_ECX
,
3
,
0x00000006
,
0
},
{
X86_FEATURE_HW_PSTATE
,
CR_EDX
,
7
,
0x80000007
,
0
},
{
X86_FEATURE_HW_PSTATE
,
CR_EDX
,
7
,
0x80000007
,
0
},
...
...
drivers/cpufreq/Kconfig
View file @
8a497cfd
...
@@ -63,7 +63,6 @@ config CPU_FREQ_DEFAULT_GOV_PERFORMANCE
...
@@ -63,7 +63,6 @@ config CPU_FREQ_DEFAULT_GOV_PERFORMANCE
config CPU_FREQ_DEFAULT_GOV_POWERSAVE
config CPU_FREQ_DEFAULT_GOV_POWERSAVE
bool "powersave"
bool "powersave"
depends on EXPERT
select CPU_FREQ_GOV_POWERSAVE
select CPU_FREQ_GOV_POWERSAVE
help
help
Use the CPUFreq governor 'powersave' as default. This sets
Use the CPUFreq governor 'powersave' as default. This sets
...
@@ -183,6 +182,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
...
@@ -183,6 +182,8 @@ config CPU_FREQ_GOV_CONSERVATIVE
If in doubt, say N.
If in doubt, say N.
comment "CPU frequency scaling drivers"
config CPUFREQ_DT
config CPUFREQ_DT
tristate "Generic DT based cpufreq driver"
tristate "Generic DT based cpufreq driver"
depends on HAVE_CLK && OF
depends on HAVE_CLK && OF
...
@@ -196,19 +197,19 @@ config CPUFREQ_DT
...
@@ -196,19 +197,19 @@ config CPUFREQ_DT
If in doubt, say N.
If in doubt, say N.
menu "x86 CPU frequency scaling drivers"
if X86
depends on X86
source "drivers/cpufreq/Kconfig.x86"
source "drivers/cpufreq/Kconfig.x86"
end
menu
end
if
menu "ARM CPU frequency scaling drivers"
if ARM || ARM64
depends on ARM || ARM64
source "drivers/cpufreq/Kconfig.arm"
source "drivers/cpufreq/Kconfig.arm"
end
menu
end
if
menu "AVR32 CPU frequency scaling drivers"
if PPC32 || PPC64
depends on AVR32
source "drivers/cpufreq/Kconfig.powerpc"
endif
if AVR32
config AVR32_AT32AP_CPUFREQ
config AVR32_AT32AP_CPUFREQ
bool "CPU frequency driver for AT32AP"
bool "CPU frequency driver for AT32AP"
depends on PLATFORM_AT32AP
depends on PLATFORM_AT32AP
...
@@ -216,12 +217,9 @@ config AVR32_AT32AP_CPUFREQ
...
@@ -216,12 +217,9 @@ config AVR32_AT32AP_CPUFREQ
help
help
This enables the CPU frequency driver for AT32AP processors.
This enables the CPU frequency driver for AT32AP processors.
If in doubt, say N.
If in doubt, say N.
endif
endmenu
if IA64
menu "CPUFreq processor drivers"
depends on IA64
config IA64_ACPI_CPUFREQ
config IA64_ACPI_CPUFREQ
tristate "ACPI Processor P-States driver"
tristate "ACPI Processor P-States driver"
depends on ACPI_PROCESSOR
depends on ACPI_PROCESSOR
...
@@ -232,12 +230,9 @@ config IA64_ACPI_CPUFREQ
...
@@ -232,12 +230,9 @@ config IA64_ACPI_CPUFREQ
For details, take a look at <file:Documentation/cpu-freq/>.
For details, take a look at <file:Documentation/cpu-freq/>.
If in doubt, say N.
If in doubt, say N.
endif
endmenu
if MIPS
menu "MIPS CPUFreq processor drivers"
depends on MIPS
config LOONGSON2_CPUFREQ
config LOONGSON2_CPUFREQ
tristate "Loongson2 CPUFreq Driver"
tristate "Loongson2 CPUFreq Driver"
help
help
...
@@ -250,15 +245,18 @@ config LOONGSON2_CPUFREQ
...
@@ -250,15 +245,18 @@ config LOONGSON2_CPUFREQ
If in doubt, say N.
If in doubt, say N.
endmenu
config LOONGSON1_CPUFREQ
tristate "Loongson1 CPUFreq Driver"
help
This option adds a CPUFreq driver for loongson1 processors which
support software configurable cpu frequency.
menu "PowerPC CPU frequency scaling drivers"
For details, take a look at <file:Documentation/cpu-freq/>.
depends on PPC32 || PPC64
source "drivers/cpufreq/Kconfig.powerpc"
endmenu
menu "SPARC CPU frequency scaling drivers"
If in doubt, say N.
depends on SPARC64
endif
if SPARC64
config SPARC_US3_CPUFREQ
config SPARC_US3_CPUFREQ
tristate "UltraSPARC-III CPU Frequency driver"
tristate "UltraSPARC-III CPU Frequency driver"
help
help
...
@@ -276,10 +274,9 @@ config SPARC_US2E_CPUFREQ
...
@@ -276,10 +274,9 @@ config SPARC_US2E_CPUFREQ
For details, take a look at <file:Documentation/cpu-freq>.
For details, take a look at <file:Documentation/cpu-freq>.
If in doubt, say N.
If in doubt, say N.
end
menu
end
if
menu "SH CPU Frequency scaling"
if SUPERH
depends on SUPERH
config SH_CPU_FREQ
config SH_CPU_FREQ
tristate "SuperH CPU Frequency driver"
tristate "SuperH CPU Frequency driver"
help
help
...
@@ -293,7 +290,7 @@ config SH_CPU_FREQ
...
@@ -293,7 +290,7 @@ config SH_CPU_FREQ
For details, take a look at <file:Documentation/cpu-freq>.
For details, take a look at <file:Documentation/cpu-freq>.
If unsure, say N.
If unsure, say N.
end
menu
end
if
endif
endif
endmenu
endmenu
drivers/cpufreq/Kconfig.arm
View file @
8a497cfd
...
@@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
...
@@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
default y
default y
help
help
This adds the CPUFreq driver support for TEGRA SOCs.
This adds the CPUFreq driver support for TEGRA SOCs.
config ARM_PXA2xx_CPUFREQ
tristate "Intel PXA2xx CPUfreq driver"
depends on PXA27x || PXA25x
help
This add the CPUFreq driver support for Intel PXA2xx SOCs.
If in doubt, say N.
drivers/cpufreq/Makefile
View file @
8a497cfd
...
@@ -61,8 +61,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
...
@@ -61,8 +61,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
obj-$(CONFIG_ARM_INTEGRATOR)
+=
integrator-cpufreq.o
obj-$(CONFIG_ARM_INTEGRATOR)
+=
integrator-cpufreq.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)
+=
kirkwood-cpufreq.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)
+=
kirkwood-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)
+=
omap-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)
+=
omap-cpufreq.o
obj-$(CONFIG_PXA25x)
+=
pxa2xx-cpufreq.o
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)
+=
pxa2xx-cpufreq.o
obj-$(CONFIG_PXA27x)
+=
pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx)
+=
pxa3xx-cpufreq.o
obj-$(CONFIG_PXA3xx)
+=
pxa3xx-cpufreq.o
obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)
+=
s3c24xx-cpufreq.o
obj-$(CONFIG_ARM_S3C24XX_CPUFREQ)
+=
s3c24xx-cpufreq.o
obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS)
+=
s3c24xx-cpufreq-debugfs.o
obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS)
+=
s3c24xx-cpufreq-debugfs.o
...
@@ -98,6 +97,7 @@ obj-$(CONFIG_CRIS_MACH_ARTPEC3) += cris-artpec3-cpufreq.o
...
@@ -98,6 +97,7 @@ obj-$(CONFIG_CRIS_MACH_ARTPEC3) += cris-artpec3-cpufreq.o
obj-$(CONFIG_ETRAXFS)
+=
cris-etraxfs-cpufreq.o
obj-$(CONFIG_ETRAXFS)
+=
cris-etraxfs-cpufreq.o
obj-$(CONFIG_IA64_ACPI_CPUFREQ)
+=
ia64-acpi-cpufreq.o
obj-$(CONFIG_IA64_ACPI_CPUFREQ)
+=
ia64-acpi-cpufreq.o
obj-$(CONFIG_LOONGSON2_CPUFREQ)
+=
loongson2_cpufreq.o
obj-$(CONFIG_LOONGSON2_CPUFREQ)
+=
loongson2_cpufreq.o
obj-$(CONFIG_LOONGSON1_CPUFREQ)
+=
ls1x-cpufreq.o
obj-$(CONFIG_SH_CPU_FREQ)
+=
sh-cpufreq.o
obj-$(CONFIG_SH_CPU_FREQ)
+=
sh-cpufreq.o
obj-$(CONFIG_SPARC_US2E_CPUFREQ)
+=
sparc-us2e-cpufreq.o
obj-$(CONFIG_SPARC_US2E_CPUFREQ)
+=
sparc-us2e-cpufreq.o
obj-$(CONFIG_SPARC_US3_CPUFREQ)
+=
sparc-us3-cpufreq.o
obj-$(CONFIG_SPARC_US3_CPUFREQ)
+=
sparc-us3-cpufreq.o
...
...
drivers/cpufreq/cpufreq-dt.c
View file @
8a497cfd
...
@@ -58,6 +58,8 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
...
@@ -58,6 +58,8 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
old_freq
=
clk_get_rate
(
cpu_clk
)
/
1000
;
old_freq
=
clk_get_rate
(
cpu_clk
)
/
1000
;
if
(
!
IS_ERR
(
cpu_reg
))
{
if
(
!
IS_ERR
(
cpu_reg
))
{
unsigned
long
opp_freq
;
rcu_read_lock
();
rcu_read_lock
();
opp
=
dev_pm_opp_find_freq_ceil
(
cpu_dev
,
&
freq_Hz
);
opp
=
dev_pm_opp_find_freq_ceil
(
cpu_dev
,
&
freq_Hz
);
if
(
IS_ERR
(
opp
))
{
if
(
IS_ERR
(
opp
))
{
...
@@ -67,13 +69,16 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
...
@@ -67,13 +69,16 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
return
PTR_ERR
(
opp
);
return
PTR_ERR
(
opp
);
}
}
volt
=
dev_pm_opp_get_voltage
(
opp
);
volt
=
dev_pm_opp_get_voltage
(
opp
);
opp_freq
=
dev_pm_opp_get_freq
(
opp
);
rcu_read_unlock
();
rcu_read_unlock
();
tol
=
volt
*
priv
->
voltage_tolerance
/
100
;
tol
=
volt
*
priv
->
voltage_tolerance
/
100
;
volt_old
=
regulator_get_voltage
(
cpu_reg
);
volt_old
=
regulator_get_voltage
(
cpu_reg
);
dev_dbg
(
cpu_dev
,
"Found OPP: %ld kHz, %ld uV
\n
"
,
opp_freq
/
1000
,
volt
);
}
}
dev_dbg
(
cpu_dev
,
"%u MHz, %ld mV --> %u MHz, %ld mV
\n
"
,
dev_dbg
(
cpu_dev
,
"%u MHz, %ld mV --> %u MHz, %ld mV
\n
"
,
old_freq
/
1000
,
volt_old
?
volt_old
/
1000
:
-
1
,
old_freq
/
1000
,
(
volt_old
>
0
)
?
volt_old
/
1000
:
-
1
,
new_freq
/
1000
,
volt
?
volt
/
1000
:
-
1
);
new_freq
/
1000
,
volt
?
volt
/
1000
:
-
1
);
/* scaling up? scale voltage before frequency */
/* scaling up? scale voltage before frequency */
...
@@ -89,7 +94,7 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
...
@@ -89,7 +94,7 @@ static int set_target(struct cpufreq_policy *policy, unsigned int index)
ret
=
clk_set_rate
(
cpu_clk
,
freq_exact
);
ret
=
clk_set_rate
(
cpu_clk
,
freq_exact
);
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
cpu_dev
,
"failed to set clock rate: %d
\n
"
,
ret
);
dev_err
(
cpu_dev
,
"failed to set clock rate: %d
\n
"
,
ret
);
if
(
!
IS_ERR
(
cpu_reg
))
if
(
!
IS_ERR
(
cpu_reg
)
&&
volt_old
>
0
)
regulator_set_voltage_tol
(
cpu_reg
,
volt_old
,
tol
);
regulator_set_voltage_tol
(
cpu_reg
,
volt_old
,
tol
);
return
ret
;
return
ret
;
}
}
...
@@ -181,7 +186,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
...
@@ -181,7 +186,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
{
{
struct
cpufreq_dt_platform_data
*
pd
;
struct
cpufreq_dt_platform_data
*
pd
;
struct
cpufreq_frequency_table
*
freq_table
;
struct
cpufreq_frequency_table
*
freq_table
;
struct
thermal_cooling_device
*
cdev
;
struct
device_node
*
np
;
struct
device_node
*
np
;
struct
private_data
*
priv
;
struct
private_data
*
priv
;
struct
device
*
cpu_dev
;
struct
device
*
cpu_dev
;
...
@@ -264,20 +268,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
...
@@ -264,20 +268,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
goto
out_free_priv
;
goto
out_free_priv
;
}
}
/*
* For now, just loading the cooling device;
* thermal DT code takes care of matching them.
*/
if
(
of_find_property
(
np
,
"#cooling-cells"
,
NULL
))
{
cdev
=
of_cpufreq_cooling_register
(
np
,
cpu_present_mask
);
if
(
IS_ERR
(
cdev
))
dev_err
(
cpu_dev
,
"running cpufreq without cooling device: %ld
\n
"
,
PTR_ERR
(
cdev
));
else
priv
->
cdev
=
cdev
;
}
priv
->
cpu_dev
=
cpu_dev
;
priv
->
cpu_dev
=
cpu_dev
;
priv
->
cpu_reg
=
cpu_reg
;
priv
->
cpu_reg
=
cpu_reg
;
policy
->
driver_data
=
priv
;
policy
->
driver_data
=
priv
;
...
@@ -287,7 +277,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
...
@@ -287,7 +277,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
if
(
ret
)
{
if
(
ret
)
{
dev_err
(
cpu_dev
,
"%s: invalid frequency table: %d
\n
"
,
__func__
,
dev_err
(
cpu_dev
,
"%s: invalid frequency table: %d
\n
"
,
__func__
,
ret
);
ret
);
goto
out_
cooling_unregister
;
goto
out_
free_cpufreq_table
;
}
}
policy
->
cpuinfo
.
transition_latency
=
transition_latency
;
policy
->
cpuinfo
.
transition_latency
=
transition_latency
;
...
@@ -300,8 +290,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
...
@@ -300,8 +290,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
return
0
;
return
0
;
out_cooling_unregister:
out_free_cpufreq_table:
cpufreq_cooling_unregister
(
priv
->
cdev
);
dev_pm_opp_free_cpufreq_table
(
cpu_dev
,
&
freq_table
);
dev_pm_opp_free_cpufreq_table
(
cpu_dev
,
&
freq_table
);
out_free_priv:
out_free_priv:
kfree
(
priv
);
kfree
(
priv
);
...
@@ -319,7 +308,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
...
@@ -319,7 +308,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
{
{
struct
private_data
*
priv
=
policy
->
driver_data
;
struct
private_data
*
priv
=
policy
->
driver_data
;
cpufreq_cooling_unregister
(
priv
->
cdev
);
if
(
priv
->
cdev
)
cpufreq_cooling_unregister
(
priv
->
cdev
);
dev_pm_opp_free_cpufreq_table
(
priv
->
cpu_dev
,
&
policy
->
freq_table
);
dev_pm_opp_free_cpufreq_table
(
priv
->
cpu_dev
,
&
policy
->
freq_table
);
clk_put
(
policy
->
clk
);
clk_put
(
policy
->
clk
);
if
(
!
IS_ERR
(
priv
->
cpu_reg
))
if
(
!
IS_ERR
(
priv
->
cpu_reg
))
...
@@ -329,6 +319,33 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
...
@@ -329,6 +319,33 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
return
0
;
return
0
;
}
}
static
void
cpufreq_ready
(
struct
cpufreq_policy
*
policy
)
{
struct
private_data
*
priv
=
policy
->
driver_data
;
struct
device_node
*
np
=
of_node_get
(
priv
->
cpu_dev
->
of_node
);
if
(
WARN_ON
(
!
np
))
return
;
/*
* For now, just loading the cooling device;
* thermal DT code takes care of matching them.
*/
if
(
of_find_property
(
np
,
"#cooling-cells"
,
NULL
))
{
priv
->
cdev
=
of_cpufreq_cooling_register
(
np
,
policy
->
related_cpus
);
if
(
IS_ERR
(
priv
->
cdev
))
{
dev_err
(
priv
->
cpu_dev
,
"running cpufreq without cooling device: %ld
\n
"
,
PTR_ERR
(
priv
->
cdev
));
priv
->
cdev
=
NULL
;
}
}
of_node_put
(
np
);
}
static
struct
cpufreq_driver
dt_cpufreq_driver
=
{
static
struct
cpufreq_driver
dt_cpufreq_driver
=
{
.
flags
=
CPUFREQ_STICKY
|
CPUFREQ_NEED_INITIAL_FREQ_CHECK
,
.
flags
=
CPUFREQ_STICKY
|
CPUFREQ_NEED_INITIAL_FREQ_CHECK
,
.
verify
=
cpufreq_generic_frequency_table_verify
,
.
verify
=
cpufreq_generic_frequency_table_verify
,
...
@@ -336,6 +353,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
...
@@ -336,6 +353,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
.
get
=
cpufreq_generic_get
,
.
get
=
cpufreq_generic_get
,
.
init
=
cpufreq_init
,
.
init
=
cpufreq_init
,
.
exit
=
cpufreq_exit
,
.
exit
=
cpufreq_exit
,
.
ready
=
cpufreq_ready
,
.
name
=
"cpufreq-dt"
,
.
name
=
"cpufreq-dt"
,
.
attr
=
cpufreq_generic_attr
,
.
attr
=
cpufreq_generic_attr
,
};
};
...
...
drivers/cpufreq/cpufreq.c
View file @
8a497cfd
...
@@ -535,7 +535,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
...
@@ -535,7 +535,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
static ssize_t store_##file_name \
static ssize_t store_##file_name \
(struct cpufreq_policy *policy, const char *buf, size_t count) \
(struct cpufreq_policy *policy, const char *buf, size_t count) \
{ \
{ \
int ret; \
int ret
, temp
; \
struct cpufreq_policy new_policy; \
struct cpufreq_policy new_policy; \
\
\
ret = cpufreq_get_policy(&new_policy, policy->cpu); \
ret = cpufreq_get_policy(&new_policy, policy->cpu); \
...
@@ -546,8 +546,10 @@ static ssize_t store_##file_name \
...
@@ -546,8 +546,10 @@ static ssize_t store_##file_name \
if (ret != 1) \
if (ret != 1) \
return -EINVAL; \
return -EINVAL; \
\
\
temp = new_policy.object; \
ret = cpufreq_set_policy(policy, &new_policy); \
ret = cpufreq_set_policy(policy, &new_policy); \
policy->user_policy.object = policy->object; \
if (!ret) \
policy->user_policy.object = temp; \
\
\
return ret ? ret : count; \
return ret ? ret : count; \
}
}
...
@@ -898,46 +900,31 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
...
@@ -898,46 +900,31 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
struct
freq_attr
**
drv_attr
;
struct
freq_attr
**
drv_attr
;
int
ret
=
0
;
int
ret
=
0
;
/* prepare interface data */
ret
=
kobject_init_and_add
(
&
policy
->
kobj
,
&
ktype_cpufreq
,
&
dev
->
kobj
,
"cpufreq"
);
if
(
ret
)
return
ret
;
/* set up files for this cpu device */
/* set up files for this cpu device */
drv_attr
=
cpufreq_driver
->
attr
;
drv_attr
=
cpufreq_driver
->
attr
;
while
((
drv_attr
)
&&
(
*
drv_attr
))
{
while
((
drv_attr
)
&&
(
*
drv_attr
))
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
if
(
ret
)
if
(
ret
)
goto
err_out_kobj_pu
t
;
return
re
t
;
drv_attr
++
;
drv_attr
++
;
}
}
if
(
cpufreq_driver
->
get
)
{
if
(
cpufreq_driver
->
get
)
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
cpuinfo_cur_freq
.
attr
);
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
cpuinfo_cur_freq
.
attr
);
if
(
ret
)
if
(
ret
)
goto
err_out_kobj_pu
t
;
return
re
t
;
}
}
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
scaling_cur_freq
.
attr
);
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
scaling_cur_freq
.
attr
);
if
(
ret
)
if
(
ret
)
goto
err_out_kobj_pu
t
;
return
re
t
;
if
(
cpufreq_driver
->
bios_limit
)
{
if
(
cpufreq_driver
->
bios_limit
)
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
bios_limit
.
attr
);
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
bios_limit
.
attr
);
if
(
ret
)
if
(
ret
)
goto
err_out_kobj_pu
t
;
return
re
t
;
}
}
ret
=
cpufreq_add_dev_symlink
(
policy
);
return
cpufreq_add_dev_symlink
(
policy
);
if
(
ret
)
goto
err_out_kobj_put
;
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
)
static
void
cpufreq_init_policy
(
struct
cpufreq_policy
*
policy
)
...
@@ -1196,6 +1183,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
...
@@ -1196,6 +1183,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
goto
err_set_policy_cpu
;
goto
err_set_policy_cpu
;
}
}
down_write
(
&
policy
->
rwsem
);
/* related cpus should atleast have policy->cpus */
/* related cpus should atleast have policy->cpus */
cpumask_or
(
policy
->
related_cpus
,
policy
->
related_cpus
,
policy
->
cpus
);
cpumask_or
(
policy
->
related_cpus
,
policy
->
related_cpus
,
policy
->
cpus
);
...
@@ -1208,9 +1197,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
...
@@ -1208,9 +1197,17 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
if
(
!
recover_policy
)
{
if
(
!
recover_policy
)
{
policy
->
user_policy
.
min
=
policy
->
min
;
policy
->
user_policy
.
min
=
policy
->
min
;
policy
->
user_policy
.
max
=
policy
->
max
;
policy
->
user_policy
.
max
=
policy
->
max
;
/* prepare interface data */
ret
=
kobject_init_and_add
(
&
policy
->
kobj
,
&
ktype_cpufreq
,
&
dev
->
kobj
,
"cpufreq"
);
if
(
ret
)
{
pr_err
(
"%s: failed to init policy->kobj: %d
\n
"
,
__func__
,
ret
);
goto
err_init_policy_kobj
;
}
}
}
down_write
(
&
policy
->
rwsem
);
write_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
write_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
for_each_cpu
(
j
,
policy
->
cpus
)
for_each_cpu
(
j
,
policy
->
cpus
)
per_cpu
(
cpufreq_cpu_data
,
j
)
=
policy
;
per_cpu
(
cpufreq_cpu_data
,
j
)
=
policy
;
...
@@ -1288,8 +1285,13 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
...
@@ -1288,8 +1285,13 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
up_write
(
&
policy
->
rwsem
);
up_write
(
&
policy
->
rwsem
);
kobject_uevent
(
&
policy
->
kobj
,
KOBJ_ADD
);
kobject_uevent
(
&
policy
->
kobj
,
KOBJ_ADD
);
up_read
(
&
cpufreq_rwsem
);
up_read
(
&
cpufreq_rwsem
);
/* Callback for handling stuff after policy is ready */
if
(
cpufreq_driver
->
ready
)
cpufreq_driver
->
ready
(
policy
);
pr_debug
(
"initialization complete
\n
"
);
pr_debug
(
"initialization complete
\n
"
);
return
0
;
return
0
;
...
@@ -1301,6 +1303,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
...
@@ -1301,6 +1303,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
per_cpu
(
cpufreq_cpu_data
,
j
)
=
NULL
;
per_cpu
(
cpufreq_cpu_data
,
j
)
=
NULL
;
write_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
write_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
if
(
!
recover_policy
)
{
kobject_put
(
&
policy
->
kobj
);
wait_for_completion
(
&
policy
->
kobj_unregister
);
}
err_init_policy_kobj:
up_write
(
&
policy
->
rwsem
);
up_write
(
&
policy
->
rwsem
);
if
(
cpufreq_driver
->
exit
)
if
(
cpufreq_driver
->
exit
)
...
...
drivers/cpufreq/intel_pstate.c
View file @
8a497cfd
...
@@ -137,6 +137,7 @@ struct cpu_defaults {
...
@@ -137,6 +137,7 @@ struct cpu_defaults {
static
struct
pstate_adjust_policy
pid_params
;
static
struct
pstate_adjust_policy
pid_params
;
static
struct
pstate_funcs
pstate_funcs
;
static
struct
pstate_funcs
pstate_funcs
;
static
int
hwp_active
;
struct
perf_limits
{
struct
perf_limits
{
int
no_turbo
;
int
no_turbo
;
...
@@ -244,6 +245,34 @@ static inline void update_turbo_state(void)
...
@@ -244,6 +245,34 @@ static inline void update_turbo_state(void)
cpu
->
pstate
.
max_pstate
==
cpu
->
pstate
.
turbo_pstate
);
cpu
->
pstate
.
max_pstate
==
cpu
->
pstate
.
turbo_pstate
);
}
}
#define PCT_TO_HWP(x) (x * 255 / 100)
static
void
intel_pstate_hwp_set
(
void
)
{
int
min
,
max
,
cpu
;
u64
value
,
freq
;
get_online_cpus
();
for_each_online_cpu
(
cpu
)
{
rdmsrl_on_cpu
(
cpu
,
MSR_HWP_REQUEST
,
&
value
);
min
=
PCT_TO_HWP
(
limits
.
min_perf_pct
);
value
&=
~
HWP_MIN_PERF
(
~
0L
);
value
|=
HWP_MIN_PERF
(
min
);
max
=
PCT_TO_HWP
(
limits
.
max_perf_pct
);
if
(
limits
.
no_turbo
)
{
rdmsrl
(
MSR_HWP_CAPABILITIES
,
freq
);
max
=
HWP_GUARANTEED_PERF
(
freq
);
}
value
&=
~
HWP_MAX_PERF
(
~
0L
);
value
|=
HWP_MAX_PERF
(
max
);
wrmsrl_on_cpu
(
cpu
,
MSR_HWP_REQUEST
,
value
);
}
put_online_cpus
();
}
/************************** debugfs begin ************************/
/************************** debugfs begin ************************/
static
int
pid_param_set
(
void
*
data
,
u64
val
)
static
int
pid_param_set
(
void
*
data
,
u64
val
)
{
{
...
@@ -279,6 +308,8 @@ static void __init intel_pstate_debug_expose_params(void)
...
@@ -279,6 +308,8 @@ static void __init intel_pstate_debug_expose_params(void)
struct
dentry
*
debugfs_parent
;
struct
dentry
*
debugfs_parent
;
int
i
=
0
;
int
i
=
0
;
if
(
hwp_active
)
return
;
debugfs_parent
=
debugfs_create_dir
(
"pstate_snb"
,
NULL
);
debugfs_parent
=
debugfs_create_dir
(
"pstate_snb"
,
NULL
);
if
(
IS_ERR_OR_NULL
(
debugfs_parent
))
if
(
IS_ERR_OR_NULL
(
debugfs_parent
))
return
;
return
;
...
@@ -329,8 +360,12 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
...
@@ -329,8 +360,12 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
pr_warn
(
"Turbo disabled by BIOS or unavailable on processor
\n
"
);
pr_warn
(
"Turbo disabled by BIOS or unavailable on processor
\n
"
);
return
-
EPERM
;
return
-
EPERM
;
}
}
limits
.
no_turbo
=
clamp_t
(
int
,
input
,
0
,
1
);
limits
.
no_turbo
=
clamp_t
(
int
,
input
,
0
,
1
);
if
(
hwp_active
)
intel_pstate_hwp_set
();
return
count
;
return
count
;
}
}
...
@@ -348,6 +383,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
...
@@ -348,6 +383,8 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
limits
.
max_perf_pct
=
min
(
limits
.
max_policy_pct
,
limits
.
max_sysfs_pct
);
limits
.
max_perf_pct
=
min
(
limits
.
max_policy_pct
,
limits
.
max_sysfs_pct
);
limits
.
max_perf
=
div_fp
(
int_tofp
(
limits
.
max_perf_pct
),
int_tofp
(
100
));
limits
.
max_perf
=
div_fp
(
int_tofp
(
limits
.
max_perf_pct
),
int_tofp
(
100
));
if
(
hwp_active
)
intel_pstate_hwp_set
();
return
count
;
return
count
;
}
}
...
@@ -363,6 +400,8 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
...
@@ -363,6 +400,8 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
limits
.
min_perf_pct
=
clamp_t
(
int
,
input
,
0
,
100
);
limits
.
min_perf_pct
=
clamp_t
(
int
,
input
,
0
,
100
);
limits
.
min_perf
=
div_fp
(
int_tofp
(
limits
.
min_perf_pct
),
int_tofp
(
100
));
limits
.
min_perf
=
div_fp
(
int_tofp
(
limits
.
min_perf_pct
),
int_tofp
(
100
));
if
(
hwp_active
)
intel_pstate_hwp_set
();
return
count
;
return
count
;
}
}
...
@@ -395,8 +434,16 @@ static void __init intel_pstate_sysfs_expose_params(void)
...
@@ -395,8 +434,16 @@ static void __init intel_pstate_sysfs_expose_params(void)
rc
=
sysfs_create_group
(
intel_pstate_kobject
,
&
intel_pstate_attr_group
);
rc
=
sysfs_create_group
(
intel_pstate_kobject
,
&
intel_pstate_attr_group
);
BUG_ON
(
rc
);
BUG_ON
(
rc
);
}
}
/************************** sysfs end ************************/
/************************** sysfs end ************************/
static
void
intel_pstate_hwp_enable
(
void
)
{
hwp_active
++
;
pr_info
(
"intel_pstate HWP enabled
\n
"
);
wrmsrl
(
MSR_PM_ENABLE
,
0x1
);
}
static
int
byt_get_min_pstate
(
void
)
static
int
byt_get_min_pstate
(
void
)
{
{
u64
value
;
u64
value
;
...
@@ -648,6 +695,14 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
...
@@ -648,6 +695,14 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
cpu
->
prev_mperf
=
mperf
;
cpu
->
prev_mperf
=
mperf
;
}
}
static
inline
void
intel_hwp_set_sample_time
(
struct
cpudata
*
cpu
)
{
int
delay
;
delay
=
msecs_to_jiffies
(
50
);
mod_timer_pinned
(
&
cpu
->
timer
,
jiffies
+
delay
);
}
static
inline
void
intel_pstate_set_sample_time
(
struct
cpudata
*
cpu
)
static
inline
void
intel_pstate_set_sample_time
(
struct
cpudata
*
cpu
)
{
{
int
delay
;
int
delay
;
...
@@ -694,6 +749,14 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
...
@@ -694,6 +749,14 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
intel_pstate_set_pstate
(
cpu
,
cpu
->
pstate
.
current_pstate
-
ctl
);
intel_pstate_set_pstate
(
cpu
,
cpu
->
pstate
.
current_pstate
-
ctl
);
}
}
static
void
intel_hwp_timer_func
(
unsigned
long
__data
)
{
struct
cpudata
*
cpu
=
(
struct
cpudata
*
)
__data
;
intel_pstate_sample
(
cpu
);
intel_hwp_set_sample_time
(
cpu
);
}
static
void
intel_pstate_timer_func
(
unsigned
long
__data
)
static
void
intel_pstate_timer_func
(
unsigned
long
__data
)
{
{
struct
cpudata
*
cpu
=
(
struct
cpudata
*
)
__data
;
struct
cpudata
*
cpu
=
(
struct
cpudata
*
)
__data
;
...
@@ -730,6 +793,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
...
@@ -730,6 +793,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
ICPU
(
0x3f
,
core_params
),
ICPU
(
0x3f
,
core_params
),
ICPU
(
0x45
,
core_params
),
ICPU
(
0x45
,
core_params
),
ICPU
(
0x46
,
core_params
),
ICPU
(
0x46
,
core_params
),
ICPU
(
0x47
,
core_params
),
ICPU
(
0x4c
,
byt_params
),
ICPU
(
0x4c
,
byt_params
),
ICPU
(
0x4f
,
core_params
),
ICPU
(
0x4f
,
core_params
),
ICPU
(
0x56
,
core_params
),
ICPU
(
0x56
,
core_params
),
...
@@ -737,6 +801,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
...
@@ -737,6 +801,11 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
};
};
MODULE_DEVICE_TABLE
(
x86cpu
,
intel_pstate_cpu_ids
);
MODULE_DEVICE_TABLE
(
x86cpu
,
intel_pstate_cpu_ids
);
static
const
struct
x86_cpu_id
intel_pstate_cpu_oob_ids
[]
=
{
ICPU
(
0x56
,
core_params
),
{}
};
static
int
intel_pstate_init_cpu
(
unsigned
int
cpunum
)
static
int
intel_pstate_init_cpu
(
unsigned
int
cpunum
)
{
{
struct
cpudata
*
cpu
;
struct
cpudata
*
cpu
;
...
@@ -753,9 +822,14 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
...
@@ -753,9 +822,14 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
intel_pstate_get_cpu_pstates
(
cpu
);
intel_pstate_get_cpu_pstates
(
cpu
);
init_timer_deferrable
(
&
cpu
->
timer
);
init_timer_deferrable
(
&
cpu
->
timer
);
cpu
->
timer
.
function
=
intel_pstate_timer_func
;
cpu
->
timer
.
data
=
(
unsigned
long
)
cpu
;
cpu
->
timer
.
data
=
(
unsigned
long
)
cpu
;
cpu
->
timer
.
expires
=
jiffies
+
HZ
/
100
;
cpu
->
timer
.
expires
=
jiffies
+
HZ
/
100
;
if
(
!
hwp_active
)
cpu
->
timer
.
function
=
intel_pstate_timer_func
;
else
cpu
->
timer
.
function
=
intel_hwp_timer_func
;
intel_pstate_busy_pid_reset
(
cpu
);
intel_pstate_busy_pid_reset
(
cpu
);
intel_pstate_sample
(
cpu
);
intel_pstate_sample
(
cpu
);
...
@@ -792,6 +866,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
...
@@ -792,6 +866,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
limits
.
no_turbo
=
0
;
limits
.
no_turbo
=
0
;
return
0
;
return
0
;
}
}
limits
.
min_perf_pct
=
(
policy
->
min
*
100
)
/
policy
->
cpuinfo
.
max_freq
;
limits
.
min_perf_pct
=
(
policy
->
min
*
100
)
/
policy
->
cpuinfo
.
max_freq
;
limits
.
min_perf_pct
=
clamp_t
(
int
,
limits
.
min_perf_pct
,
0
,
100
);
limits
.
min_perf_pct
=
clamp_t
(
int
,
limits
.
min_perf_pct
,
0
,
100
);
limits
.
min_perf
=
div_fp
(
int_tofp
(
limits
.
min_perf_pct
),
int_tofp
(
100
));
limits
.
min_perf
=
div_fp
(
int_tofp
(
limits
.
min_perf_pct
),
int_tofp
(
100
));
...
@@ -801,6 +876,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
...
@@ -801,6 +876,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
limits
.
max_perf_pct
=
min
(
limits
.
max_policy_pct
,
limits
.
max_sysfs_pct
);
limits
.
max_perf_pct
=
min
(
limits
.
max_policy_pct
,
limits
.
max_sysfs_pct
);
limits
.
max_perf
=
div_fp
(
int_tofp
(
limits
.
max_perf_pct
),
int_tofp
(
100
));
limits
.
max_perf
=
div_fp
(
int_tofp
(
limits
.
max_perf_pct
),
int_tofp
(
100
));
if
(
hwp_active
)
intel_pstate_hwp_set
();
return
0
;
return
0
;
}
}
...
@@ -823,6 +901,9 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
...
@@ -823,6 +901,9 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
pr_info
(
"intel_pstate CPU %d exiting
\n
"
,
cpu_num
);
pr_info
(
"intel_pstate CPU %d exiting
\n
"
,
cpu_num
);
del_timer_sync
(
&
all_cpu_data
[
cpu_num
]
->
timer
);
del_timer_sync
(
&
all_cpu_data
[
cpu_num
]
->
timer
);
if
(
hwp_active
)
return
;
intel_pstate_set_pstate
(
cpu
,
cpu
->
pstate
.
min_pstate
);
intel_pstate_set_pstate
(
cpu
,
cpu
->
pstate
.
min_pstate
);
}
}
...
@@ -866,6 +947,7 @@ static struct cpufreq_driver intel_pstate_driver = {
...
@@ -866,6 +947,7 @@ static struct cpufreq_driver intel_pstate_driver = {
};
};
static
int
__initdata
no_load
;
static
int
__initdata
no_load
;
static
int
__initdata
no_hwp
;
static
int
intel_pstate_msrs_not_valid
(
void
)
static
int
intel_pstate_msrs_not_valid
(
void
)
{
{
...
@@ -959,6 +1041,15 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void)
...
@@ -959,6 +1041,15 @@ static bool intel_pstate_platform_pwr_mgmt_exists(void)
{
{
struct
acpi_table_header
hdr
;
struct
acpi_table_header
hdr
;
struct
hw_vendor_info
*
v_info
;
struct
hw_vendor_info
*
v_info
;
const
struct
x86_cpu_id
*
id
;
u64
misc_pwr
;
id
=
x86_match_cpu
(
intel_pstate_cpu_oob_ids
);
if
(
id
)
{
rdmsrl
(
MSR_MISC_PWR_MGMT
,
misc_pwr
);
if
(
misc_pwr
&
(
1
<<
8
))
return
true
;
}
if
(
acpi_disabled
||
if
(
acpi_disabled
||
ACPI_FAILURE
(
acpi_get_table_header
(
ACPI_SIG_FADT
,
0
,
&
hdr
)))
ACPI_FAILURE
(
acpi_get_table_header
(
ACPI_SIG_FADT
,
0
,
&
hdr
)))
...
@@ -982,6 +1073,7 @@ static int __init intel_pstate_init(void)
...
@@ -982,6 +1073,7 @@ static int __init intel_pstate_init(void)
int
cpu
,
rc
=
0
;
int
cpu
,
rc
=
0
;
const
struct
x86_cpu_id
*
id
;
const
struct
x86_cpu_id
*
id
;
struct
cpu_defaults
*
cpu_info
;
struct
cpu_defaults
*
cpu_info
;
struct
cpuinfo_x86
*
c
=
&
boot_cpu_data
;
if
(
no_load
)
if
(
no_load
)
return
-
ENODEV
;
return
-
ENODEV
;
...
@@ -1011,6 +1103,9 @@ static int __init intel_pstate_init(void)
...
@@ -1011,6 +1103,9 @@ static int __init intel_pstate_init(void)
if
(
!
all_cpu_data
)
if
(
!
all_cpu_data
)
return
-
ENOMEM
;
return
-
ENOMEM
;
if
(
cpu_has
(
c
,
X86_FEATURE_HWP
)
&&
!
no_hwp
)
intel_pstate_hwp_enable
();
rc
=
cpufreq_register_driver
(
&
intel_pstate_driver
);
rc
=
cpufreq_register_driver
(
&
intel_pstate_driver
);
if
(
rc
)
if
(
rc
)
goto
out
;
goto
out
;
...
@@ -1041,6 +1136,8 @@ static int __init intel_pstate_setup(char *str)
...
@@ -1041,6 +1136,8 @@ static int __init intel_pstate_setup(char *str)
if
(
!
strcmp
(
str
,
"disable"
))
if
(
!
strcmp
(
str
,
"disable"
))
no_load
=
1
;
no_load
=
1
;
if
(
!
strcmp
(
str
,
"no_hwp"
))
no_hwp
=
1
;
return
0
;
return
0
;
}
}
early_param
(
"intel_pstate"
,
intel_pstate_setup
);
early_param
(
"intel_pstate"
,
intel_pstate_setup
);
...
...
drivers/cpufreq/ls1x-cpufreq.c
0 → 100644
View file @
8a497cfd
/*
* CPU Frequency Scaling for Loongson 1 SoC
*
* Copyright (C) 2014 Zhang, Keguang <keguang.zhang@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/mach-loongson1/cpufreq.h>
#include <asm/mach-loongson1/loongson1.h>
static
struct
{
struct
device
*
dev
;
struct
clk
*
clk
;
/* CPU clk */
struct
clk
*
mux_clk
;
/* MUX of CPU clk */
struct
clk
*
pll_clk
;
/* PLL clk */
struct
clk
*
osc_clk
;
/* OSC clk */
unsigned
int
max_freq
;
unsigned
int
min_freq
;
}
ls1x_cpufreq
;
static
int
ls1x_cpufreq_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
void
*
data
)
{
if
(
val
==
CPUFREQ_POSTCHANGE
)
current_cpu_data
.
udelay_val
=
loops_per_jiffy
;
return
NOTIFY_OK
;
}
static
struct
notifier_block
ls1x_cpufreq_notifier_block
=
{
.
notifier_call
=
ls1x_cpufreq_notifier
};
static
int
ls1x_cpufreq_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
index
)
{
unsigned
int
old_freq
,
new_freq
;
old_freq
=
policy
->
cur
;
new_freq
=
policy
->
freq_table
[
index
].
frequency
;
/*
* The procedure of reconfiguring CPU clk is as below.
*
* - Reparent CPU clk to OSC clk
* - Reset CPU clock (very important)
* - Reconfigure CPU DIV
* - Reparent CPU clk back to CPU DIV clk
*/
dev_dbg
(
ls1x_cpufreq
.
dev
,
"%u KHz --> %u KHz
\n
"
,
old_freq
,
new_freq
);
clk_set_parent
(
policy
->
clk
,
ls1x_cpufreq
.
osc_clk
);
__raw_writel
(
__raw_readl
(
LS1X_CLK_PLL_DIV
)
|
RST_CPU_EN
|
RST_CPU
,
LS1X_CLK_PLL_DIV
);
__raw_writel
(
__raw_readl
(
LS1X_CLK_PLL_DIV
)
&
~
(
RST_CPU_EN
|
RST_CPU
),
LS1X_CLK_PLL_DIV
);
clk_set_rate
(
ls1x_cpufreq
.
mux_clk
,
new_freq
*
1000
);
clk_set_parent
(
policy
->
clk
,
ls1x_cpufreq
.
mux_clk
);
return
0
;
}
static
int
ls1x_cpufreq_init
(
struct
cpufreq_policy
*
policy
)
{
struct
cpufreq_frequency_table
*
freq_tbl
;
unsigned
int
pll_freq
,
freq
;
int
steps
,
i
,
ret
;
pll_freq
=
clk_get_rate
(
ls1x_cpufreq
.
pll_clk
)
/
1000
;
steps
=
1
<<
DIV_CPU_WIDTH
;
freq_tbl
=
kzalloc
(
sizeof
(
*
freq_tbl
)
*
steps
,
GFP_KERNEL
);
if
(
!
freq_tbl
)
{
dev_err
(
ls1x_cpufreq
.
dev
,
"failed to alloc cpufreq_frequency_table
\n
"
);
ret
=
-
ENOMEM
;
goto
out
;
}
for
(
i
=
0
;
i
<
(
steps
-
1
);
i
++
)
{
freq
=
pll_freq
/
(
i
+
1
);
if
((
freq
<
ls1x_cpufreq
.
min_freq
)
||
(
freq
>
ls1x_cpufreq
.
max_freq
))
freq_tbl
[
i
].
frequency
=
CPUFREQ_ENTRY_INVALID
;
else
freq_tbl
[
i
].
frequency
=
freq
;
dev_dbg
(
ls1x_cpufreq
.
dev
,
"cpufreq table: index %d: frequency %d
\n
"
,
i
,
freq_tbl
[
i
].
frequency
);
}
freq_tbl
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
policy
->
clk
=
ls1x_cpufreq
.
clk
;
ret
=
cpufreq_generic_init
(
policy
,
freq_tbl
,
0
);
if
(
ret
)
kfree
(
freq_tbl
);
out:
return
ret
;
}
static
int
ls1x_cpufreq_exit
(
struct
cpufreq_policy
*
policy
)
{
kfree
(
policy
->
freq_table
);
return
0
;
}
static
struct
cpufreq_driver
ls1x_cpufreq_driver
=
{
.
name
=
"cpufreq-ls1x"
,
.
flags
=
CPUFREQ_STICKY
|
CPUFREQ_NEED_INITIAL_FREQ_CHECK
,
.
verify
=
cpufreq_generic_frequency_table_verify
,
.
target_index
=
ls1x_cpufreq_target
,
.
get
=
cpufreq_generic_get
,
.
init
=
ls1x_cpufreq_init
,
.
exit
=
ls1x_cpufreq_exit
,
.
attr
=
cpufreq_generic_attr
,
};
static
int
ls1x_cpufreq_remove
(
struct
platform_device
*
pdev
)
{
cpufreq_unregister_notifier
(
&
ls1x_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
cpufreq_unregister_driver
(
&
ls1x_cpufreq_driver
);
return
0
;
}
static
int
ls1x_cpufreq_probe
(
struct
platform_device
*
pdev
)
{
struct
plat_ls1x_cpufreq
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
clk
*
clk
;
int
ret
;
if
(
!
pdata
||
!
pdata
->
clk_name
||
!
pdata
->
osc_clk_name
)
return
-
EINVAL
;
ls1x_cpufreq
.
dev
=
&
pdev
->
dev
;
clk
=
devm_clk_get
(
&
pdev
->
dev
,
pdata
->
clk_name
);
if
(
IS_ERR
(
clk
))
{
dev_err
(
ls1x_cpufreq
.
dev
,
"unable to get %s clock
\n
"
,
pdata
->
clk_name
);
ret
=
PTR_ERR
(
clk
);
goto
out
;
}
ls1x_cpufreq
.
clk
=
clk
;
clk
=
clk_get_parent
(
clk
);
if
(
IS_ERR
(
clk
))
{
dev_err
(
ls1x_cpufreq
.
dev
,
"unable to get parent of %s clock
\n
"
,
__clk_get_name
(
ls1x_cpufreq
.
clk
));
ret
=
PTR_ERR
(
clk
);
goto
out
;
}
ls1x_cpufreq
.
mux_clk
=
clk
;
clk
=
clk_get_parent
(
clk
);
if
(
IS_ERR
(
clk
))
{
dev_err
(
ls1x_cpufreq
.
dev
,
"unable to get parent of %s clock
\n
"
,
__clk_get_name
(
ls1x_cpufreq
.
mux_clk
));
ret
=
PTR_ERR
(
clk
);
goto
out
;
}
ls1x_cpufreq
.
pll_clk
=
clk
;
clk
=
devm_clk_get
(
&
pdev
->
dev
,
pdata
->
osc_clk_name
);
if
(
IS_ERR
(
clk
))
{
dev_err
(
ls1x_cpufreq
.
dev
,
"unable to get %s clock
\n
"
,
pdata
->
osc_clk_name
);
ret
=
PTR_ERR
(
clk
);
goto
out
;
}
ls1x_cpufreq
.
osc_clk
=
clk
;
ls1x_cpufreq
.
max_freq
=
pdata
->
max_freq
;
ls1x_cpufreq
.
min_freq
=
pdata
->
min_freq
;
ret
=
cpufreq_register_driver
(
&
ls1x_cpufreq_driver
);
if
(
ret
)
{
dev_err
(
ls1x_cpufreq
.
dev
,
"failed to register cpufreq driver: %d
\n
"
,
ret
);
goto
out
;
}
ret
=
cpufreq_register_notifier
(
&
ls1x_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
if
(
!
ret
)
goto
out
;
dev_err
(
ls1x_cpufreq
.
dev
,
"failed to register cpufreq notifier: %d
\n
"
,
ret
);
cpufreq_unregister_driver
(
&
ls1x_cpufreq_driver
);
out:
return
ret
;
}
static
struct
platform_driver
ls1x_cpufreq_platdrv
=
{
.
driver
=
{
.
name
=
"ls1x-cpufreq"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
ls1x_cpufreq_probe
,
.
remove
=
ls1x_cpufreq_remove
,
};
module_platform_driver
(
ls1x_cpufreq_platdrv
);
MODULE_AUTHOR
(
"Kelvin Cheung <keguang.zhang@gmail.com>"
);
MODULE_DESCRIPTION
(
"Loongson 1 CPUFreq driver"
);
MODULE_LICENSE
(
"GPL"
);
drivers/cpufreq/pcc-cpufreq.c
View file @
8a497cfd
...
@@ -603,6 +603,13 @@ static void __exit pcc_cpufreq_exit(void)
...
@@ -603,6 +603,13 @@ static void __exit pcc_cpufreq_exit(void)
free_percpu
(
pcc_cpu_info
);
free_percpu
(
pcc_cpu_info
);
}
}
static
const
struct
acpi_device_id
processor_device_ids
[]
=
{
{
ACPI_PROCESSOR_OBJECT_HID
,
},
{
ACPI_PROCESSOR_DEVICE_HID
,
},
{},
};
MODULE_DEVICE_TABLE
(
acpi
,
processor_device_ids
);
MODULE_AUTHOR
(
"Matthew Garrett, Naga Chumbalkar"
);
MODULE_AUTHOR
(
"Matthew Garrett, Naga Chumbalkar"
);
MODULE_VERSION
(
PCC_VERSION
);
MODULE_VERSION
(
PCC_VERSION
);
MODULE_DESCRIPTION
(
"Processor Clocking Control interface driver"
);
MODULE_DESCRIPTION
(
"Processor Clocking Control interface driver"
);
...
...
include/linux/cpufreq.h
View file @
8a497cfd
...
@@ -217,26 +217,26 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
...
@@ -217,26 +217,26 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
struct
cpufreq_driver
{
struct
cpufreq_driver
{
char
name
[
CPUFREQ_NAME_LEN
];
char
name
[
CPUFREQ_NAME_LEN
];
u8
flags
;
u8
flags
;
void
*
driver_data
;
void
*
driver_data
;
/* needed by all drivers */
/* needed by all drivers */
int
(
*
init
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
init
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
verify
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
verify
)
(
struct
cpufreq_policy
*
policy
);
/* define one out of two */
/* define one out of two */
int
(
*
setpolicy
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
setpolicy
)
(
struct
cpufreq_policy
*
policy
);
/*
/*
* On failure, should always restore frequency to policy->restore_freq
* On failure, should always restore frequency to policy->restore_freq
* (i.e. old freq).
* (i.e. old freq).
*/
*/
int
(
*
target
)
(
struct
cpufreq_policy
*
policy
,
/* Deprecated */
int
(
*
target
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
target_freq
,
unsigned
int
relation
);
unsigned
int
relation
);
/* Deprecated */
int
(
*
target_index
)
(
struct
cpufreq_policy
*
policy
,
int
(
*
target_index
)
(
struct
cpufreq_policy
*
policy
,
unsigned
int
index
);
unsigned
int
index
);
/*
/*
* Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION
* Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION
* unset.
* unset.
...
@@ -252,27 +252,31 @@ struct cpufreq_driver {
...
@@ -252,27 +252,31 @@ struct cpufreq_driver {
* wish to switch to intermediate frequency for some target frequency.
* wish to switch to intermediate frequency for some target frequency.
* In that case core will directly call ->target_index().
* In that case core will directly call ->target_index().
*/
*/
unsigned
int
(
*
get_intermediate
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
(
*
get_intermediate
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
index
);
unsigned
int
index
);
int
(
*
target_intermediate
)(
struct
cpufreq_policy
*
policy
,
int
(
*
target_intermediate
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
index
);
unsigned
int
index
);
/* should be defined, if possible */
/* should be defined, if possible */
unsigned
int
(
*
get
)
(
unsigned
int
cpu
);
unsigned
int
(
*
get
)(
unsigned
int
cpu
);
/* optional */
/* optional */
int
(
*
bios_limit
)
(
int
cpu
,
unsigned
int
*
limit
);
int
(
*
bios_limit
)(
int
cpu
,
unsigned
int
*
limit
);
int
(
*
exit
)(
struct
cpufreq_policy
*
policy
);
void
(
*
stop_cpu
)(
struct
cpufreq_policy
*
policy
);
int
(
*
suspend
)(
struct
cpufreq_policy
*
policy
);
int
(
*
resume
)(
struct
cpufreq_policy
*
policy
);
/* Will be called after the driver is fully initialized */
void
(
*
ready
)(
struct
cpufreq_policy
*
policy
);
int
(
*
exit
)
(
struct
cpufreq_policy
*
policy
);
struct
freq_attr
**
attr
;
void
(
*
stop_cpu
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
suspend
)
(
struct
cpufreq_policy
*
policy
);
int
(
*
resume
)
(
struct
cpufreq_policy
*
policy
);
struct
freq_attr
**
attr
;
/* platform specific boost support code */
/* platform specific boost support code */
bool
boost_supported
;
bool
boost_supported
;
bool
boost_enabled
;
bool
boost_enabled
;
int
(
*
set_boost
)
(
int
state
);
int
(
*
set_boost
)
(
int
state
);
};
};
/* flags */
/* flags */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment