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
0a8c7fbf
Commit
0a8c7fbf
authored
Jan 30, 2004
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.1
into intel.com:/home/lenb/src/linux-acpi-test-2.6.2
parents
659f7c1a
1e1b8dae
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
472 additions
and
440 deletions
+472
-440
arch/i386/kernel/cpu/cpufreq/acpi.c
arch/i386/kernel/cpu/cpufreq/acpi.c
+81
-423
drivers/acpi/dispatcher/dsmthdat.c
drivers/acpi/dispatcher/dsmthdat.c
+3
-2
drivers/acpi/processor.c
drivers/acpi/processor.c
+376
-3
include/acpi/processor.h
include/acpi/processor.h
+12
-12
No files found.
arch/i386/kernel/cpu/cpufreq/acpi.c
View file @
0a8c7fbf
...
...
@@ -42,7 +42,6 @@
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor P-States Driver"
#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME
(
"acpi_processor_perf"
)
...
...
@@ -52,181 +51,13 @@ MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
MODULE_LICENSE
(
"GPL"
);
static
struct
acpi_processor_performance
*
performance
[
NR_CPUS
];
static
int
acpi_processor_get_performance_control
(
struct
acpi_processor_performance
*
perf
)
{
int
result
=
0
;
acpi_status
status
=
0
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
pct
=
NULL
;
union
acpi_object
obj
=
{
0
};
struct
acpi_pct_register
*
reg
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_performance_control"
);
status
=
acpi_evaluate_object
(
perf
->
pr
->
handle
,
"_PCT"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _PCT
\n
"
));
return_VALUE
(
-
ENODEV
);
}
pct
=
(
union
acpi_object
*
)
buffer
.
pointer
;
if
(
!
pct
||
(
pct
->
type
!=
ACPI_TYPE_PACKAGE
)
||
(
pct
->
package
.
count
!=
2
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PCT data
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
/*
* control_register
*/
obj
=
pct
->
package
.
elements
[
0
];
if
((
obj
.
type
!=
ACPI_TYPE_BUFFER
)
||
(
obj
.
buffer
.
length
<
sizeof
(
struct
acpi_pct_register
))
||
(
obj
.
buffer
.
pointer
==
NULL
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PCT data (control_register)
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
reg
=
(
struct
acpi_pct_register
*
)
(
obj
.
buffer
.
pointer
);
if
(
reg
->
space_id
!=
ACPI_ADR_SPACE_SYSTEM_IO
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unsupported address space [%d] (control_register)
\n
"
,
(
u32
)
reg
->
space_id
));
result
=
-
EFAULT
;
goto
end
;
}
perf
->
control_register
=
(
u16
)
reg
->
address
;
perf
->
control_register_bit_width
=
reg
->
bit_width
;
/*
* status_register
*/
obj
=
pct
->
package
.
elements
[
1
];
if
((
obj
.
type
!=
ACPI_TYPE_BUFFER
)
||
(
obj
.
buffer
.
length
<
sizeof
(
struct
acpi_pct_register
))
||
(
obj
.
buffer
.
pointer
==
NULL
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PCT data (status_register)
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
reg
=
(
struct
acpi_pct_register
*
)
(
obj
.
buffer
.
pointer
);
if
(
reg
->
space_id
!=
ACPI_ADR_SPACE_SYSTEM_IO
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unsupported address space [%d] (status_register)
\n
"
,
(
u32
)
reg
->
space_id
));
result
=
-
EFAULT
;
goto
end
;
}
perf
->
status_register
=
(
u16
)
reg
->
address
;
perf
->
status_register_bit_width
=
reg
->
bit_width
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"control_register[0x%04x] status_register[0x%04x]
\n
"
,
perf
->
control_register
,
perf
->
status_register
));
end:
acpi_os_free
(
buffer
.
pointer
);
return_VALUE
(
result
);
}
static
int
acpi_processor_get_performance_states
(
struct
acpi_processor_performance
*
perf
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
acpi_buffer
format
=
{
sizeof
(
"NNNNNN"
),
"NNNNNN"
};
struct
acpi_buffer
state
=
{
0
,
NULL
};
union
acpi_object
*
pss
=
NULL
;
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_performance_states"
);
status
=
acpi_evaluate_object
(
perf
->
pr
->
handle
,
"_PSS"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _PSS
\n
"
));
return_VALUE
(
-
ENODEV
);
}
pss
=
(
union
acpi_object
*
)
buffer
.
pointer
;
if
(
!
pss
||
(
pss
->
type
!=
ACPI_TYPE_PACKAGE
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PSS data
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found %d performance states
\n
"
,
pss
->
package
.
count
));
if
(
pss
->
package
.
count
>
ACPI_PROCESSOR_MAX_PERFORMANCE
)
{
perf
->
state_count
=
ACPI_PROCESSOR_MAX_PERFORMANCE
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Limiting number of states to max (%d)
\n
"
,
ACPI_PROCESSOR_MAX_PERFORMANCE
));
}
else
perf
->
state_count
=
pss
->
package
.
count
;
for
(
i
=
0
;
i
<
perf
->
state_count
;
i
++
)
{
struct
acpi_processor_px
*
px
=
&
(
perf
->
states
[
i
]);
state
.
length
=
sizeof
(
struct
acpi_processor_px
);
state
.
pointer
=
px
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Extracting state %d
\n
"
,
i
));
status
=
acpi_extract_package
(
&
(
pss
->
package
.
elements
[
i
]),
&
format
,
&
state
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PSS data
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]
\n
"
,
i
,
(
u32
)
px
->
core_frequency
,
(
u32
)
px
->
power
,
(
u32
)
px
->
transition_latency
,
(
u32
)
px
->
bus_master_latency
,
(
u32
)
px
->
control
,
(
u32
)
px
->
status
));
if
(
!
px
->
core_frequency
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"core_frequency is 0
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
}
struct
cpufreq_acpi_io
{
struct
acpi_processor_performance
acpi_data
;
struct
cpufreq_frequency_table
*
freq_table
;
};
end:
acpi_os_free
(
buffer
.
pointer
);
static
struct
cpufreq_acpi_io
*
acpi_io_data
[
NR_CPUS
];
return_VALUE
(
result
);
}
static
int
acpi_processor_write_port
(
...
...
@@ -267,7 +98,8 @@ acpi_processor_read_port(
static
int
acpi_processor_set_performance
(
struct
acpi_processor_performance
*
perf
,
struct
cpufreq_acpi_io
*
data
,
unsigned
int
cpu
,
int
state
)
{
u16
port
=
0
;
...
...
@@ -279,28 +111,19 @@ acpi_processor_set_performance (
ACPI_FUNCTION_TRACE
(
"acpi_processor_set_performance"
);
if
(
!
perf
||
!
perf
->
pr
)
return_VALUE
(
-
EINVAL
);
if
(
state
>=
perf
->
state_count
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Invalid target state (P%d)
\n
"
,
state
));
return_VALUE
(
-
ENODEV
);
}
if
(
state
==
perf
->
state
)
{
if
(
state
==
data
->
acpi_data
.
state
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Already at target state (P%d)
\n
"
,
state
));
return_VALUE
(
0
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Transitioning from P%d to P%d
\n
"
,
perf
->
state
,
state
));
data
->
acpi_data
.
state
,
state
));
/* cpufreq frequency struct */
cpufreq_freqs
.
cpu
=
perf
->
pr
->
id
;
cpufreq_freqs
.
old
=
perf
->
states
[
perf
->
state
].
core_frequency
*
1000
;
cpufreq_freqs
.
new
=
perf
->
states
[
state
].
core_frequency
*
1000
;
cpufreq_freqs
.
cpu
=
cpu
;
cpufreq_freqs
.
old
=
data
->
freq_table
[
data
->
acpi_data
.
state
].
frequency
;
cpufreq_freqs
.
new
=
data
->
freq_table
[
state
].
frequency
;
/* notify cpufreq */
cpufreq_notify_transition
(
&
cpufreq_freqs
,
CPUFREQ_PRECHANGE
);
...
...
@@ -310,9 +133,9 @@ acpi_processor_set_performance (
* control_register.
*/
port
=
perf
->
control_register
;
bit_width
=
perf
->
control_register_
bit_width
;
value
=
(
u32
)
perf
->
states
[
state
].
control
;
port
=
data
->
acpi_data
.
control_register
.
address
;
bit_width
=
data
->
acpi_data
.
control_register
.
bit_width
;
value
=
(
u32
)
data
->
acpi_data
.
states
[
state
].
control
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Writing 0x%08x to port 0x%04x
\n
"
,
value
,
port
));
...
...
@@ -331,12 +154,12 @@ acpi_processor_set_performance (
* giving up.
*/
port
=
perf
->
status_register
;
bit_width
=
perf
->
status_register_
bit_width
;
port
=
data
->
acpi_data
.
status_register
.
address
;
bit_width
=
data
->
acpi_data
.
status_register
.
bit_width
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Looking for 0x%08x from port 0x%04x
\n
"
,
(
u32
)
perf
->
states
[
state
].
status
,
port
));
(
u32
)
data
->
acpi_data
.
states
[
state
].
status
,
port
));
for
(
i
=
0
;
i
<
100
;
i
++
)
{
ret
=
acpi_processor_read_port
(
port
,
bit_width
,
&
value
);
...
...
@@ -345,7 +168,7 @@ acpi_processor_set_performance (
"Invalid port width 0x%04x
\n
"
,
bit_width
));
return_VALUE
(
ret
);
}
if
(
value
==
(
u32
)
perf
->
states
[
state
].
status
)
if
(
value
==
(
u32
)
data
->
acpi_data
.
states
[
state
].
status
)
break
;
udelay
(
10
);
}
...
...
@@ -353,7 +176,7 @@ acpi_processor_set_performance (
/* notify cpufreq */
cpufreq_notify_transition
(
&
cpufreq_freqs
,
CPUFREQ_POSTCHANGE
);
if
(
value
!=
(
u32
)
perf
->
states
[
state
].
status
)
{
if
(
value
!=
(
u32
)
data
->
acpi_data
.
states
[
state
].
status
)
{
unsigned
int
tmp
=
cpufreq_freqs
.
new
;
cpufreq_freqs
.
new
=
cpufreq_freqs
.
old
;
cpufreq_freqs
.
old
=
tmp
;
...
...
@@ -367,179 +190,33 @@ acpi_processor_set_performance (
"Transition successful after %d microseconds
\n
"
,
i
*
10
));
perf
->
state
=
state
;
data
->
acpi_data
.
state
=
state
;
return_VALUE
(
0
);
}
#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
/* /proc/acpi/processor/../performance interface (DEPRECATED) */
static
int
acpi_processor_perf_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
static
struct
file_operations
acpi_processor_perf_fops
=
{
.
open
=
acpi_processor_perf_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
int
acpi_processor_perf_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_processor
*
pr
=
(
struct
acpi_processor
*
)
seq
->
private
;
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_perf_seq_show"
);
if
(
!
pr
)
goto
end
;
if
(
!
pr
->
performance
)
{
seq_puts
(
seq
,
"<not supported>
\n
"
);
goto
end
;
}
seq_printf
(
seq
,
"state count: %d
\n
"
"active state: P%d
\n
"
,
pr
->
performance
->
state_count
,
pr
->
performance
->
state
);
seq_puts
(
seq
,
"states:
\n
"
);
for
(
i
=
0
;
i
<
pr
->
performance
->
state_count
;
i
++
)
seq_printf
(
seq
,
" %cP%d: %d MHz, %d mW, %d uS
\n
"
,
(
i
==
pr
->
performance
->
state
?
'*'
:
' '
),
i
,
(
u32
)
pr
->
performance
->
states
[
i
].
core_frequency
,
(
u32
)
pr
->
performance
->
states
[
i
].
power
,
(
u32
)
pr
->
performance
->
states
[
i
].
transition_latency
);
end:
return
0
;
}
static
int
acpi_processor_perf_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_processor_perf_seq_show
,
PDE
(
inode
)
->
data
);
}
static
int
acpi_processor_write_performance
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
)
{
int
result
=
0
;
struct
seq_file
*
m
=
(
struct
seq_file
*
)
file
->
private_data
;
struct
acpi_processor
*
pr
=
(
struct
acpi_processor
*
)
m
->
private
;
struct
acpi_processor_performance
*
perf
;
char
state_string
[
12
]
=
{
'\0'
};
unsigned
int
new_state
=
0
;
struct
cpufreq_policy
policy
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_write_performance"
);
if
(
!
pr
||
(
count
>
sizeof
(
state_string
)
-
1
))
return_VALUE
(
-
EINVAL
);
perf
=
pr
->
performance
;
if
(
!
perf
)
return_VALUE
(
-
EINVAL
);
if
(
copy_from_user
(
state_string
,
buffer
,
count
))
return_VALUE
(
-
EFAULT
);
state_string
[
count
]
=
'\0'
;
new_state
=
simple_strtoul
(
state_string
,
NULL
,
0
);
if
(
new_state
>=
perf
->
state_count
)
return_VALUE
(
-
EINVAL
);
cpufreq_get_policy
(
&
policy
,
pr
->
id
);
policy
.
cpu
=
pr
->
id
;
policy
.
min
=
perf
->
states
[
new_state
].
core_frequency
*
1000
;
policy
.
max
=
perf
->
states
[
new_state
].
core_frequency
*
1000
;
result
=
cpufreq_set_policy
(
&
policy
);
if
(
result
)
return_VALUE
(
result
);
return_VALUE
(
count
);
}
static
void
acpi_cpufreq_add_file
(
struct
acpi_processor
*
pr
)
{
struct
proc_dir_entry
*
entry
=
NULL
;
struct
acpi_device
*
device
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_addfile"
);
if
(
acpi_bus_get_device
(
pr
->
handle
,
&
device
))
return_VOID
;
/* add file 'performance' [R/W] */
entry
=
create_proc_entry
(
ACPI_PROCESSOR_FILE_PERFORMANCE
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
acpi_device_dir
(
device
));
if
(
!
entry
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unable to create '%s' fs entry
\n
"
,
ACPI_PROCESSOR_FILE_PERFORMANCE
));
else
{
entry
->
proc_fops
=
&
acpi_processor_perf_fops
;
entry
->
proc_fops
->
write
=
acpi_processor_write_performance
;
entry
->
data
=
acpi_driver_data
(
device
);
}
return_VOID
;
}
static
void
acpi_cpufreq_remove_file
(
struct
acpi_processor
*
pr
)
{
struct
acpi_device
*
device
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_addfile"
);
if
(
acpi_bus_get_device
(
pr
->
handle
,
&
device
))
return_VOID
;
/* remove file 'performance' */
remove_proc_entry
(
ACPI_PROCESSOR_FILE_PERFORMANCE
,
acpi_device_dir
(
device
));
return_VOID
;
}
#else
static
void
acpi_cpufreq_add_file
(
struct
acpi_processor
*
pr
)
{
return
;
}
static
void
acpi_cpufreq_remove_file
(
struct
acpi_processor
*
pr
)
{
return
;
}
#endif
/* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
static
int
acpi_cpufreq_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
)
{
struct
acpi_processor_performance
*
perf
=
performance
[
policy
->
cpu
];
struct
cpufreq_acpi_io
*
data
=
acpi_io_data
[
policy
->
cpu
];
unsigned
int
next_state
=
0
;
unsigned
int
result
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_setpolicy"
);
result
=
cpufreq_frequency_table_target
(
policy
,
perf
->
freq_table
,
result
=
cpufreq_frequency_table_target
(
policy
,
data
->
freq_table
,
target_freq
,
relation
,
&
next_state
);
if
(
result
)
return_VALUE
(
result
);
result
=
acpi_processor_set_performance
(
perf
,
next_state
);
result
=
acpi_processor_set_performance
(
data
,
policy
->
cpu
,
next_state
);
return_VALUE
(
result
);
}
...
...
@@ -550,89 +227,66 @@ acpi_cpufreq_verify (
struct
cpufreq_policy
*
policy
)
{
unsigned
int
result
=
0
;
struct
acpi_processor_performance
*
perf
=
performance
[
policy
->
cpu
];
struct
cpufreq_acpi_io
*
data
=
acpi_io_data
[
policy
->
cpu
];
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_verify"
);
result
=
cpufreq_frequency_table_verify
(
policy
,
perf
->
freq_table
);
cpufreq_verify_within_limits
(
policy
,
perf
->
states
[
perf
->
state_count
-
1
].
core_frequency
*
1000
,
perf
->
states
[
0
].
core_frequency
*
1000
);
data
->
freq_table
);
return_VALUE
(
result
);
}
static
int
acpi_processor_get_performance_info
(
struct
acpi_processor_performance
*
perf
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
acpi_handle
handle
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_performance_info"
);
if
(
!
perf
||
!
perf
->
pr
||
!
perf
->
pr
->
handle
)
return_VALUE
(
-
EINVAL
);
status
=
acpi_get_handle
(
perf
->
pr
->
handle
,
"_PCT"
,
&
handle
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"ACPI-based processor performance control unavailable
\n
"
));
return_VALUE
(
-
ENODEV
);
}
result
=
acpi_processor_get_performance_control
(
perf
);
if
(
result
)
return_VALUE
(
result
);
result
=
acpi_processor_get_performance_states
(
perf
);
if
(
result
)
return_VALUE
(
result
);
return_VALUE
(
0
);
}
static
int
acpi_cpufreq_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
unsigned
int
i
;
unsigned
int
cpu
=
policy
->
cpu
;
struct
acpi_processor_performance
*
perf
;
struct
cpufreq_acpi_io
*
data
;
unsigned
int
result
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_cpu_init"
);
perf
=
kmalloc
(
sizeof
(
struct
acpi_processor_performance
),
GFP_KERNEL
);
if
(
!
perf
)
data
=
kmalloc
(
sizeof
(
struct
cpufreq_acpi_io
),
GFP_KERNEL
);
if
(
!
data
)
return_VALUE
(
-
ENOMEM
);
memset
(
perf
,
0
,
sizeof
(
struct
acpi_processor_performance
));
memset
(
data
,
0
,
sizeof
(
struct
cpufreq_acpi_io
));
performance
[
cpu
]
=
perf
;
acpi_io_data
[
cpu
]
=
data
;
result
=
acpi_processor_register_performance
(
perf
,
cpu
);
result
=
acpi_processor_register_performance
(
&
data
->
acpi_data
,
cpu
);
if
(
result
)
goto
err_free
;
result
=
acpi_processor_get_performance_info
(
perf
);
if
(
result
)
/* capability check */
if
(
data
->
acpi_data
.
state_count
<=
1
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"No P-States
\n
"
));
result
=
-
ENODEV
;
goto
err_unreg
;
}
if
((
data
->
acpi_data
.
control_register
.
space_id
!=
ACPI_ADR_SPACE_SYSTEM_IO
)
||
(
data
->
acpi_data
.
status_register
.
space_id
!=
ACPI_ADR_SPACE_SYSTEM_IO
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unsupported address space [%d, %d]
\n
"
,
(
u32
)
(
data
->
acpi_data
.
control_register
.
space_id
),
(
u32
)
(
data
->
acpi_data
.
status_register
.
space_id
)));
result
=
-
ENODEV
;
goto
err_unreg
;
}
/* capability check */
if
(
perf
->
state_count
<=
1
)
/* alloc freq_table */
data
->
freq_table
=
kmalloc
(
sizeof
(
struct
cpufreq_frequency_table
)
*
(
data
->
acpi_data
.
state_count
+
1
),
GFP_KERNEL
);
if
(
!
data
->
freq_table
)
{
result
=
-
ENOMEM
;
goto
err_unreg
;
}
/* detect transition latency */
policy
->
cpuinfo
.
transition_latency
=
0
;
for
(
i
=
0
;
i
<
perf
->
state_count
;
i
++
)
{
if
((
perf
->
states
[
i
].
transition_latency
*
1000
)
>
policy
->
cpuinfo
.
transition_latency
)
policy
->
cpuinfo
.
transition_latency
=
perf
->
states
[
i
].
transition_latency
*
1000
;
for
(
i
=
0
;
i
<
data
->
acpi_data
.
state_count
;
i
++
)
{
if
((
data
->
acpi_data
.
states
[
i
].
transition_latency
*
1000
)
>
policy
->
cpuinfo
.
transition_latency
)
policy
->
cpuinfo
.
transition_latency
=
data
->
acpi_data
.
states
[
i
].
transition_latency
*
1000
;
}
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
...
...
@@ -640,38 +294,42 @@ acpi_cpufreq_cpu_init (
* The current speed is unknown and not detectable by ACPI... argh! Assume
* it's P0, it will be set to this value later during initialization.
*/
policy
->
cur
=
perf
->
states
[
0
].
core_frequency
*
1000
;
policy
->
cur
=
data
->
acpi_data
.
states
[
0
].
core_frequency
*
1000
;
/* table init */
for
(
i
=
0
;
i
<=
perf
->
state_count
;
i
++
)
for
(
i
=
0
;
i
<=
data
->
acpi_data
.
state_count
;
i
++
)
{
perf
->
freq_table
[
i
].
index
=
i
;
if
(
i
<
perf
->
state_count
)
perf
->
freq_table
[
i
].
frequency
=
perf
->
states
[
i
].
core_frequency
*
1000
;
data
->
freq_table
[
i
].
index
=
i
;
if
(
i
<
data
->
acpi_data
.
state_count
)
data
->
freq_table
[
i
].
frequency
=
data
->
acpi_data
.
states
[
i
].
core_frequency
*
1000
;
else
perf
->
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
data
->
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
}
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
&
perf
->
freq_table
[
0
]);
acpi_cpufreq_add_file
(
perf
->
pr
);
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
&
data
->
freq_table
[
0
]);
if
(
result
)
{
goto
err_freqfree
;
}
printk
(
KERN_INFO
"cpufreq: CPU%u - ACPI performance management activated.
\n
"
,
cpu
);
for
(
i
=
0
;
i
<
perf
->
state_count
;
i
++
)
for
(
i
=
0
;
i
<
data
->
acpi_data
.
state_count
;
i
++
)
printk
(
KERN_INFO
"cpufreq: %cP%d: %d MHz, %d mW, %d uS
\n
"
,
(
i
==
perf
->
state
?
'*'
:
' '
),
i
,
(
u32
)
perf
->
states
[
i
].
core_frequency
,
(
u32
)
perf
->
states
[
i
].
power
,
(
u32
)
perf
->
states
[
i
].
transition_latency
);
(
i
==
data
->
acpi_data
.
state
?
'*'
:
' '
),
i
,
(
u32
)
data
->
acpi_data
.
states
[
i
].
core_frequency
,
(
u32
)
data
->
acpi_data
.
states
[
i
].
power
,
(
u32
)
data
->
acpi_data
.
states
[
i
].
transition_latency
);
return_VALUE
(
result
);
err_freqfree:
kfree
(
data
->
freq_table
);
err_unreg:
acpi_processor_unregister_performance
(
perf
,
cpu
);
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
cpu
);
err_free:
kfree
(
perf
);
performance
[
cpu
]
=
NULL
;
kfree
(
data
);
acpi_io_data
[
cpu
]
=
NULL
;
return_VALUE
(
result
);
}
...
...
@@ -681,15 +339,15 @@ static int
acpi_cpufreq_cpu_exit
(
struct
cpufreq_policy
*
policy
)
{
struct
acpi_processor_performance
*
perf
=
performance
[
policy
->
cpu
];
struct
cpufreq_acpi_io
*
data
=
acpi_io_data
[
policy
->
cpu
];
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_cpu_exit"
);
if
(
perf
)
{
acpi_cpufreq_remove_file
(
perf
->
pr
);
performance
[
policy
->
cpu
]
=
NULL
;
acpi_processor_unregister_performance
(
perf
,
policy
->
cpu
);
kfree
(
perf
);
if
(
data
)
{
acpi_io_data
[
policy
->
cpu
]
=
NULL
;
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
policy
->
cpu
);
kfree
(
data
);
}
return_VALUE
(
0
);
...
...
drivers/acpi/dispatcher/dsmthdat.c
View file @
0a8c7fbf
...
...
@@ -203,9 +203,10 @@ acpi_ds_method_data_init_args (
while
((
index
<
ACPI_METHOD_NUM_ARGS
)
&&
(
index
<
max_param_count
)
&&
params
[
index
])
{
/*
* A valid parameter.
* Store the argument in the method/walk descriptor
* Store the argument in the method/walk descriptor.
* Do not copy the arg in order to implement call by reference
*/
status
=
acpi_ds_
store_object_to_local
(
AML_ARG_OP
,
index
,
params
[
index
],
status
=
acpi_ds_
method_data_set_value
(
AML_ARG_OP
,
index
,
params
[
index
],
walk_state
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
...
...
drivers/acpi/processor.c
View file @
0a8c7fbf
...
...
@@ -23,7 +23,7 @@
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* TBD:
* 1. Make # power
/performance
states dynamic.
* 1. Make # power states dynamic.
* 2. Support duty_cycle values that span bit 4.
* 3. Optimize by having scheduler determine business instead of
* having us try to calculate it here.
...
...
@@ -58,6 +58,7 @@
#define ACPI_PROCESSOR_FILE_POWER "power"
#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
#define ACPI_PROCESSOR_FILE_LIMIT "limit"
#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
...
...
@@ -855,6 +856,369 @@ static void acpi_processor_ppc_exit(void) {
acpi_processor_ppc_is_init
=
0
;
}
/*
* when registering a cpufreq driver with this ACPI processor driver, the
* _PCT and _PSS structures are read out and written into struct
* acpi_processor_performance.
*/
static
int
acpi_processor_set_pdc
(
struct
acpi_processor
*
pr
)
{
acpi_status
status
=
AE_OK
;
u32
arg0_buf
[
3
];
union
acpi_object
arg0
=
{
ACPI_TYPE_BUFFER
};
struct
acpi_object_list
no_object
=
{
1
,
&
arg0
};
struct
acpi_object_list
*
pdc
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_set_pdc"
);
arg0
.
buffer
.
length
=
12
;
arg0
.
buffer
.
pointer
=
(
u8
*
)
arg0_buf
;
arg0_buf
[
0
]
=
ACPI_PDC_REVISION_ID
;
arg0_buf
[
1
]
=
0
;
arg0_buf
[
2
]
=
0
;
pdc
=
(
pr
->
performance
->
pdc
)
?
pr
->
performance
->
pdc
:
&
no_object
;
status
=
acpi_evaluate_object
(
pr
->
handle
,
"_PDC"
,
pdc
,
NULL
);
if
((
ACPI_FAILURE
(
status
))
&&
(
pr
->
performance
->
pdc
))
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Error evaluating _PDC, using legacy perf. control...
\n
"
));
return_VALUE
(
status
);
}
static
int
acpi_processor_get_performance_control
(
struct
acpi_processor
*
pr
)
{
int
result
=
0
;
acpi_status
status
=
0
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
pct
=
NULL
;
union
acpi_object
obj
=
{
0
};
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_performance_control"
);
status
=
acpi_evaluate_object
(
pr
->
handle
,
"_PCT"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _PCT
\n
"
));
return_VALUE
(
-
ENODEV
);
}
pct
=
(
union
acpi_object
*
)
buffer
.
pointer
;
if
(
!
pct
||
(
pct
->
type
!=
ACPI_TYPE_PACKAGE
)
||
(
pct
->
package
.
count
!=
2
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PCT data
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
/*
* control_register
*/
obj
=
pct
->
package
.
elements
[
0
];
if
((
obj
.
type
!=
ACPI_TYPE_BUFFER
)
||
(
obj
.
buffer
.
length
<
sizeof
(
struct
acpi_pct_register
))
||
(
obj
.
buffer
.
pointer
==
NULL
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PCT data (control_register)
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
memcpy
(
&
pr
->
performance
->
control_register
,
obj
.
buffer
.
pointer
,
sizeof
(
struct
acpi_pct_register
));
/*
* status_register
*/
obj
=
pct
->
package
.
elements
[
1
];
if
((
obj
.
type
!=
ACPI_TYPE_BUFFER
)
||
(
obj
.
buffer
.
length
<
sizeof
(
struct
acpi_pct_register
))
||
(
obj
.
buffer
.
pointer
==
NULL
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PCT data (status_register)
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
memcpy
(
&
pr
->
performance
->
status_register
,
obj
.
buffer
.
pointer
,
sizeof
(
struct
acpi_pct_register
));
end:
acpi_os_free
(
buffer
.
pointer
);
return_VALUE
(
result
);
}
static
int
acpi_processor_get_performance_states
(
struct
acpi_processor
*
pr
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
acpi_buffer
format
=
{
sizeof
(
"NNNNNN"
),
"NNNNNN"
};
struct
acpi_buffer
state
=
{
0
,
NULL
};
union
acpi_object
*
pss
=
NULL
;
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_performance_states"
);
status
=
acpi_evaluate_object
(
pr
->
handle
,
"_PSS"
,
NULL
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _PSS
\n
"
));
return_VALUE
(
-
ENODEV
);
}
pss
=
(
union
acpi_object
*
)
buffer
.
pointer
;
if
(
!
pss
||
(
pss
->
type
!=
ACPI_TYPE_PACKAGE
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PSS data
\n
"
));
result
=
-
EFAULT
;
goto
end
;
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found %d performance states
\n
"
,
pss
->
package
.
count
));
pr
->
performance
->
state_count
=
pss
->
package
.
count
;
pr
->
performance
->
states
=
kmalloc
(
sizeof
(
struct
acpi_processor_px
)
*
pss
->
package
.
count
,
GFP_KERNEL
);
if
(
!
pr
->
performance
->
states
)
{
result
=
-
ENOMEM
;
goto
end
;
}
for
(
i
=
0
;
i
<
pr
->
performance
->
state_count
;
i
++
)
{
struct
acpi_processor_px
*
px
=
&
(
pr
->
performance
->
states
[
i
]);
state
.
length
=
sizeof
(
struct
acpi_processor_px
);
state
.
pointer
=
px
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Extracting state %d
\n
"
,
i
));
status
=
acpi_extract_package
(
&
(
pss
->
package
.
elements
[
i
]),
&
format
,
&
state
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PSS data
\n
"
));
result
=
-
EFAULT
;
kfree
(
pr
->
performance
->
states
);
goto
end
;
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]
\n
"
,
i
,
(
u32
)
px
->
core_frequency
,
(
u32
)
px
->
power
,
(
u32
)
px
->
transition_latency
,
(
u32
)
px
->
bus_master_latency
,
(
u32
)
px
->
control
,
(
u32
)
px
->
status
));
if
(
!
px
->
core_frequency
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"core_frequency is 0
\n
"
));
result
=
-
EFAULT
;
kfree
(
pr
->
performance
->
states
);
goto
end
;
}
}
end:
acpi_os_free
(
buffer
.
pointer
);
return_VALUE
(
result
);
}
static
int
acpi_processor_get_performance_info
(
struct
acpi_processor
*
pr
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
acpi_handle
handle
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_performance_info"
);
if
(
!
pr
||
!
pr
->
performance
||
!
pr
->
handle
)
return_VALUE
(
-
EINVAL
);
status
=
acpi_get_handle
(
pr
->
handle
,
"_PCT"
,
&
handle
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"ACPI-based processor performance control unavailable
\n
"
));
return_VALUE
(
-
ENODEV
);
}
acpi_processor_set_pdc
(
pr
);
result
=
acpi_processor_get_performance_control
(
pr
);
if
(
result
)
return_VALUE
(
result
);
result
=
acpi_processor_get_performance_states
(
pr
);
if
(
result
)
return_VALUE
(
result
);
result
=
acpi_processor_get_platform_limit
(
pr
);
if
(
result
)
return_VALUE
(
result
);
return_VALUE
(
0
);
}
#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
/* /proc/acpi/processor/../performance interface (DEPRECATED) */
static
int
acpi_processor_perf_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
static
struct
file_operations
acpi_processor_perf_fops
=
{
.
open
=
acpi_processor_perf_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
static
int
acpi_processor_perf_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_processor
*
pr
=
(
struct
acpi_processor
*
)
seq
->
private
;
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_perf_seq_show"
);
if
(
!
pr
)
goto
end
;
if
(
!
pr
->
performance
)
{
seq_puts
(
seq
,
"<not supported>
\n
"
);
goto
end
;
}
seq_printf
(
seq
,
"state count: %d
\n
"
"active state: P%d
\n
"
,
pr
->
performance
->
state_count
,
pr
->
performance
->
state
);
seq_puts
(
seq
,
"states:
\n
"
);
for
(
i
=
0
;
i
<
pr
->
performance
->
state_count
;
i
++
)
seq_printf
(
seq
,
" %cP%d: %d MHz, %d mW, %d uS
\n
"
,
(
i
==
pr
->
performance
->
state
?
'*'
:
' '
),
i
,
(
u32
)
pr
->
performance
->
states
[
i
].
core_frequency
,
(
u32
)
pr
->
performance
->
states
[
i
].
power
,
(
u32
)
pr
->
performance
->
states
[
i
].
transition_latency
);
end:
return
0
;
}
static
int
acpi_processor_perf_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_processor_perf_seq_show
,
PDE
(
inode
)
->
data
);
}
static
int
acpi_processor_write_performance
(
struct
file
*
file
,
const
char
__user
*
buffer
,
size_t
count
,
loff_t
*
data
)
{
int
result
=
0
;
struct
seq_file
*
m
=
(
struct
seq_file
*
)
file
->
private_data
;
struct
acpi_processor
*
pr
=
(
struct
acpi_processor
*
)
m
->
private
;
struct
acpi_processor_performance
*
perf
;
char
state_string
[
12
]
=
{
'\0'
};
unsigned
int
new_state
=
0
;
struct
cpufreq_policy
policy
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_write_performance"
);
if
(
!
pr
||
(
count
>
sizeof
(
state_string
)
-
1
))
return_VALUE
(
-
EINVAL
);
perf
=
pr
->
performance
;
if
(
!
perf
)
return_VALUE
(
-
EINVAL
);
if
(
copy_from_user
(
state_string
,
buffer
,
count
))
return_VALUE
(
-
EFAULT
);
state_string
[
count
]
=
'\0'
;
new_state
=
simple_strtoul
(
state_string
,
NULL
,
0
);
if
(
new_state
>=
perf
->
state_count
)
return_VALUE
(
-
EINVAL
);
cpufreq_get_policy
(
&
policy
,
pr
->
id
);
policy
.
cpu
=
pr
->
id
;
policy
.
min
=
perf
->
states
[
new_state
].
core_frequency
*
1000
;
policy
.
max
=
perf
->
states
[
new_state
].
core_frequency
*
1000
;
result
=
cpufreq_set_policy
(
&
policy
);
if
(
result
)
return_VALUE
(
result
);
return_VALUE
(
count
);
}
static
void
acpi_cpufreq_add_file
(
struct
acpi_processor
*
pr
)
{
struct
proc_dir_entry
*
entry
=
NULL
;
struct
acpi_device
*
device
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_addfile"
);
if
(
acpi_bus_get_device
(
pr
->
handle
,
&
device
))
return_VOID
;
/* add file 'performance' [R/W] */
entry
=
create_proc_entry
(
ACPI_PROCESSOR_FILE_PERFORMANCE
,
S_IFREG
|
S_IRUGO
|
S_IWUSR
,
acpi_device_dir
(
device
));
if
(
!
entry
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unable to create '%s' fs entry
\n
"
,
ACPI_PROCESSOR_FILE_PERFORMANCE
));
else
{
entry
->
proc_fops
=
&
acpi_processor_perf_fops
;
entry
->
proc_fops
->
write
=
acpi_processor_write_performance
;
entry
->
data
=
acpi_driver_data
(
device
);
}
return_VOID
;
}
static
void
acpi_cpufreq_remove_file
(
struct
acpi_processor
*
pr
)
{
struct
acpi_device
*
device
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_addfile"
);
if
(
acpi_bus_get_device
(
pr
->
handle
,
&
device
))
return_VOID
;
/* remove file 'performance' */
remove_proc_entry
(
ACPI_PROCESSOR_FILE_PERFORMANCE
,
acpi_device_dir
(
device
));
return_VOID
;
}
#else
static
void
acpi_cpufreq_add_file
(
struct
acpi_processor
*
pr
)
{
return
;
}
static
void
acpi_cpufreq_remove_file
(
struct
acpi_processor
*
pr
)
{
return
;
}
#endif
/* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
int
acpi_processor_register_performance
(
...
...
@@ -882,7 +1246,14 @@ acpi_processor_register_performance (
}
pr
->
performance
=
performance
;
performance
->
pr
=
pr
;
if
(
acpi_processor_get_performance_info
(
pr
))
{
pr
->
performance
=
NULL
;
up
(
&
performance_sem
);
return_VALUE
(
-
EIO
);
}
acpi_cpufreq_add_file
(
pr
);
up
(
&
performance_sem
);
return_VALUE
(
0
);
...
...
@@ -910,8 +1281,10 @@ acpi_processor_unregister_performance (
return_VOID
;
}
kfree
(
pr
->
performance
->
states
);
pr
->
performance
=
NULL
;
performance
->
pr
=
NULL
;
acpi_cpufreq_remove_file
(
pr
);
up
(
&
performance_sem
);
...
...
include/acpi/processor.h
View file @
0a8c7fbf
...
...
@@ -9,8 +9,6 @@
#define ACPI_PROCESSOR_MAX_C2_LATENCY 100
#define ACPI_PROCESSOR_MAX_C3_LATENCY 1000
#define ACPI_PROCESSOR_MAX_PERFORMANCE 8
#define ACPI_PROCESSOR_MAX_THROTTLING 16
#define ACPI_PROCESSOR_MAX_THROTTLE 250
/* 25% */
#define ACPI_PROCESSOR_MAX_DUTY_WIDTH 4
...
...
@@ -67,20 +65,22 @@ struct acpi_processor_px {
acpi_integer
status
;
/* success indicator */
};
#define ACPI_PDC_REVISION_ID 0x1
struct
acpi_processor_performance
{
int
state
;
int
platform_limit
;
u16
control_register
;
u16
status_register
;
u8
control_register_bit_width
;
u8
status_register_bit_width
;
int
state_count
;
struct
acpi_processor_px
states
[
ACPI_PROCESSOR_MAX_PERFORMANCE
];
struct
cpufreq_frequency_table
freq_table
[
ACPI_PROCESSOR_MAX_PERFORMANCE
];
struct
acpi_processor
*
pr
;
unsigned
int
state
;
unsigned
int
platform_limit
;
struct
acpi_pct_register
control_register
;
struct
acpi_pct_register
status_register
;
unsigned
int
state_count
;
struct
acpi_processor_px
*
states
;
/* the _PDC objects passed by the driver, if any */
struct
acpi_object_list
*
pdc
;
};
/* Throttling Control */
struct
acpi_processor_tx
{
...
...
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