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
nexedi
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
Show 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
,
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
]);
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
&
data
->
freq_table
[
0
]);
if
(
result
)
{
goto
err_freqfree
;
}
acpi_cpufreq_add_file
(
perf
->
pr
);
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