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
fdfec545
Commit
fdfec545
authored
Feb 06, 2004
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge intel.com:/home/lenb/bk/linux-2.6.3
into intel.com:/home/lenb/src/linux-acpi-test-2.6.3
parents
f4d86110
f817979f
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1396 additions
and
1019 deletions
+1396
-1019
CREDITS
CREDITS
+5
-0
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/boot.c
+11
-9
arch/i386/kernel/cpu/cpufreq/acpi.c
arch/i386/kernel/cpu/cpufreq/acpi.c
+102
-536
arch/ia64/kernel/acpi.c
arch/ia64/kernel/acpi.c
+7
-15
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/iosapic.c
+1
-1
arch/x86_64/kernel/acpi/boot.c
arch/x86_64/kernel/acpi/boot.c
+11
-9
drivers/acpi/asus_acpi.c
drivers/acpi/asus_acpi.c
+464
-289
drivers/acpi/numa.c
drivers/acpi/numa.c
+16
-12
drivers/acpi/pci_irq.c
drivers/acpi/pci_irq.c
+7
-5
drivers/acpi/processor.c
drivers/acpi/processor.c
+679
-90
drivers/acpi/tables.c
drivers/acpi/tables.c
+17
-11
drivers/acpi/toshiba_acpi.c
drivers/acpi/toshiba_acpi.c
+56
-25
include/acpi/processor.h
include/acpi/processor.h
+15
-15
include/asm-ia64/iosapic.h
include/asm-ia64/iosapic.h
+3
-0
include/linux/acpi.h
include/linux/acpi.h
+2
-2
No files found.
CREDITS
View file @
fdfec545
...
...
@@ -818,6 +818,11 @@ S: 1382 Bordeaux Drive
S: Sunnyvale, CA 94087
S: USA
N: Bruno Ducrot
E: ducrot@poupinou.org
D: CPUFreq and ACPI bugfixes.
S: Mougin, France
N: Don Dugger
E: n0ano@valinux.com
D: Linux/IA-64
...
...
arch/i386/kernel/acpi/boot.c
View file @
fdfec545
...
...
@@ -32,6 +32,7 @@
#include <asm/io_apic.h>
#include <asm/apic.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mpspec.h>
#if defined (CONFIG_X86_LOCAL_APIC)
...
...
@@ -45,8 +46,8 @@
int
acpi_noirq
__initdata
=
0
;
/* skip ACPI IRQ initialization */
int
acpi_ht
__initdata
=
1
;
/* enable HT */
int
acpi_lapic
=
0
;
int
acpi_ioapic
=
0
;
int
acpi_lapic
;
int
acpi_ioapic
;
/* --------------------------------------------------------------------------
Boot-time Configuration
...
...
@@ -471,7 +472,7 @@ acpi_boot_init (void)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
*/
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_ADDR_OVR
,
acpi_parse_lapic_addr_ovr
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_ADDR_OVR
,
acpi_parse_lapic_addr_ovr
,
0
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing LAPIC address override entry
\n
"
);
return
result
;
...
...
@@ -479,7 +480,8 @@ acpi_boot_init (void)
mp_register_lapic_address
(
acpi_lapic_addr
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC
,
acpi_parse_lapic
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC
,
acpi_parse_lapic
,
MAX_APICS
);
if
(
!
result
)
{
printk
(
KERN_ERR
PREFIX
"No LAPIC entries present
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
...
...
@@ -491,7 +493,7 @@ acpi_boot_init (void)
return
result
;
}
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_NMI
,
acpi_parse_lapic_nmi
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_NMI
,
acpi_parse_lapic_nmi
,
0
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing LAPIC NMI entry
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
...
...
@@ -528,8 +530,8 @@ acpi_boot_init (void)
return
1
;
}
result
=
acpi_table_parse_madt
(
ACPI_MADT_IOAPIC
,
acpi_parse_ioapic
);
if
(
!
result
)
{
result
=
acpi_table_parse_madt
(
ACPI_MADT_IOAPIC
,
acpi_parse_ioapic
,
MAX_IO_APICS
);
if
(
!
result
)
{
printk
(
KERN_ERR
PREFIX
"No IOAPIC entries present
\n
"
);
return
-
ENODEV
;
}
...
...
@@ -541,14 +543,14 @@ acpi_boot_init (void)
/* Build a default routing table for legacy (ISA) interrupts. */
mp_config_acpi_legacy_irqs
();
result
=
acpi_table_parse_madt
(
ACPI_MADT_INT_SRC_OVR
,
acpi_parse_int_src_ovr
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_INT_SRC_OVR
,
acpi_parse_int_src_ovr
,
NR_IRQ_VECTORS
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing interrupt source overrides entry
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
return
result
;
}
result
=
acpi_table_parse_madt
(
ACPI_MADT_NMI_SRC
,
acpi_parse_nmi_src
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_NMI_SRC
,
acpi_parse_nmi_src
,
NR_IRQ_VECTORS
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing NMI SRC entry
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
...
...
arch/i386/kernel/cpu/cpufreq/acpi.c
View file @
fdfec545
/*
* acpi
_processor_perf
.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
* acpi
-cpufreq-io
.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
* Copyright (C) 2002
, 2003
Dominik Brodowski <linux@brodo.de>
* Copyright (C) 2002
- 2004
Dominik Brodowski <linux@brodo.de>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
...
...
@@ -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,184 +51,13 @@ MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME);
MODULE_LICENSE
(
"GPL"
);
static
struct
acpi_processor_performance
*
performance
;
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
;
if
(
perf
->
state_count
>
1
)
perf
->
pr
->
flags
.
performance
=
1
;
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
;
}
if
(
!
px
->
core_frequency
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid _PSS data: freq is zero
\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
));
}
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
(
...
...
@@ -270,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
;
...
...
@@ -282,38 +111,19 @@ acpi_processor_set_performance (
ACPI_FUNCTION_TRACE
(
"acpi_processor_set_performance"
);
if
(
!
perf
||
!
perf
->
pr
)
return_VALUE
(
-
EINVAL
);
if
(
!
perf
->
pr
->
flags
.
performance
)
return_VALUE
(
-
ENODEV
);
if
(
state
>=
perf
->
state_count
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Invalid target state (P%d)
\n
"
,
state
));
return_VALUE
(
-
ENODEV
);
}
if
(
state
<
perf
->
pr
->
performance_platform_limit
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Platform limit (P%d) overrides target state (P%d)
\n
"
,
perf
->
pr
->
performance_platform_limit
,
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
;
cpufreq_freqs
.
new
=
perf
->
states
[
state
].
core_
frequency
;
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
);
...
...
@@ -323,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
));
...
...
@@ -344,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
);
...
...
@@ -358,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
);
}
...
...
@@ -366,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
;
...
...
@@ -380,169 +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
->
flags
.
performance
||
!
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
acpi_processor
*
pr
=
(
struct
acpi_processor
*
)
data
;
char
state_string
[
12
]
=
{
'\0'
};
unsigned
int
new_state
=
0
;
struct
cpufreq_policy
policy
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_write_performance"
);
if
(
!
pr
||
!
pr
->
performance
||
(
count
>
sizeof
(
state_string
)
-
1
))
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
);
cpufreq_get_policy
(
&
policy
,
pr
->
id
);
policy
.
cpu
=
pr
->
id
;
policy
.
max
=
pr
->
performance
->
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
[
perf
->
pr
->
limit
.
state
.
px
]
,
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
);
}
...
...
@@ -553,119 +227,110 @@ 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
[
perf
->
pr
->
limit
.
state
.
px
]);
cpufreq_verify_within_limits
(
policy
,
perf
->
states
[
perf
->
state_count
-
1
].
core_frequency
*
1000
,
perf
->
states
[
perf
->
pr
->
limit
.
state
.
px
].
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
);
result
=
acpi_processor_get_platform_limit
(
perf
->
pr
);
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
*
pr
=
NULL
;
struct
acpi_processor_performance
*
perf
=
&
performance
[
policy
->
cpu
];
struct
acpi_device
*
device
;
struct
cpufreq_acpi_io
*
data
;
unsigned
int
result
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_cpu_init"
);
acpi_processor_register_performance
(
perf
,
&
pr
,
cpu
);
data
=
kmalloc
(
sizeof
(
struct
cpufreq_acpi_io
),
GFP_KERNEL
);
if
(
!
data
)
return_VALUE
(
-
ENOMEM
);
memset
(
data
,
0
,
sizeof
(
struct
cpufreq_acpi_io
));
pr
=
performance
[
cpu
].
pr
;
if
(
!
pr
)
return_VALUE
(
-
ENODEV
);
acpi_io_data
[
cpu
]
=
data
;
result
=
acpi_processor_
get_performance_info
(
perf
);
result
=
acpi_processor_
register_performance
(
&
data
->
acpi_data
,
cpu
);
if
(
result
)
return_VALUE
(
-
ENODEV
)
;
goto
err_free
;
/* capability check */
if
(
!
pr
->
flags
.
performance
)
return_VALUE
(
-
ENODEV
);
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
;
}
/* 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
;
policy
->
cur
=
perf
->
states
[
pr
->
limit
.
state
.
px
].
core_frequency
*
1000
;
/*
* 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
=
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
(
pr
);
if
(
acpi_bus_get_device
(
pr
->
handle
,
&
device
))
device
=
NULL
;
result
=
cpufreq_frequency_table_cpuinfo
(
policy
,
&
data
->
freq_table
[
0
]);
if
(
result
)
{
goto
err_freqfree
;
}
printk
(
KERN_INFO
"cpufreq: %s - ACPI performance management activated.
\n
"
,
device
?
acpi_device_bid
(
device
)
:
"CPU??"
);
for
(
i
=
0
;
i
<
pr
->
performance
->
state_count
;
i
++
)
printk
(
KERN_INFO
"cpufreq: CPU%u - ACPI performance management activated.
\n
"
,
cpu
);
for
(
i
=
0
;
i
<
data
->
acpi_data
.
state_count
;
i
++
)
printk
(
KERN_INFO
"cpufreq: %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
);
(
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
(
&
data
->
acpi_data
,
cpu
);
err_free:
kfree
(
data
);
acpi_io_data
[
cpu
]
=
NULL
;
return_VALUE
(
result
);
}
...
...
@@ -674,11 +339,16 @@ static int
acpi_cpufreq_cpu_exit
(
struct
cpufreq_policy
*
policy
)
{
struct
acpi_processor
*
pr
=
performance
[
policy
->
cpu
].
pr
;
struct
cpufreq_acpi_io
*
data
=
acpi_io_data
[
policy
->
cpu
];
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_cpu_exit"
);
acpi_cpufreq_remove_file
(
pr
);
if
(
data
)
{
acpi_io_data
[
policy
->
cpu
]
=
NULL
;
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
policy
->
cpu
);
kfree
(
data
);
}
return_VALUE
(
0
);
}
...
...
@@ -698,97 +368,11 @@ static int __init
acpi_cpufreq_init
(
void
)
{
int
result
=
0
;
int
current_state
=
0
;
int
i
=
0
;
struct
acpi_processor
*
pr
=
NULL
;
struct
acpi_processor_performance
*
perf
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_init"
);
/* alloc memory */
if
(
performance
)
return_VALUE
(
-
EBUSY
);
performance
=
kmalloc
(
NR_CPUS
*
sizeof
(
struct
acpi_processor_performance
),
GFP_KERNEL
);
if
(
!
performance
)
return_VALUE
(
-
ENOMEM
);
memset
(
performance
,
0
,
NR_CPUS
*
sizeof
(
struct
acpi_processor_performance
));
/* register struct acpi_processor_performance performance */
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
cpu_online
(
i
))
acpi_processor_register_performance
(
&
performance
[
i
],
&
pr
,
i
);
}
/* initialize */
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
cpu_online
(
i
)
&&
performance
[
i
].
pr
)
result
=
acpi_processor_get_performance_info
(
&
performance
[
i
]);
}
/* test it on one CPU */
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
!
cpu_online
(
i
))
continue
;
pr
=
performance
[
i
].
pr
;
if
(
pr
&&
pr
->
flags
.
performance
)
goto
found_capable_cpu
;
}
result
=
-
ENODEV
;
goto
err0
;
found_capable_cpu:
result
=
cpufreq_register_driver
(
&
acpi_cpufreq_driver
);
if
(
result
)
goto
err0
;
perf
=
pr
->
performance
;
current_state
=
perf
->
state
;
if
(
current_state
==
pr
->
limit
.
state
.
px
)
{
result
=
acpi_processor_set_performance
(
perf
,
(
perf
->
state_count
-
1
));
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Disabled P-States due to failure while switching.
\n
"
));
result
=
-
ENODEV
;
goto
err1
;
}
}
result
=
acpi_processor_set_performance
(
perf
,
pr
->
limit
.
state
.
px
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Disabled P-States due to failure while switching.
\n
"
));
result
=
-
ENODEV
;
goto
err1
;
}
if
(
current_state
!=
0
)
{
result
=
acpi_processor_set_performance
(
perf
,
current_state
);
if
(
result
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Disabled P-States due to failure while switching.
\n
"
));
result
=
-
ENODEV
;
goto
err1
;
}
}
return_VALUE
(
0
);
/* error handling */
err1:
cpufreq_unregister_driver
(
&
acpi_cpufreq_driver
);
err0:
/* unregister struct acpi_processor_performance performance */
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
performance
[
i
].
pr
)
{
performance
[
i
].
pr
->
flags
.
performance
=
0
;
performance
[
i
].
pr
->
performance
=
NULL
;
performance
[
i
].
pr
=
NULL
;
}
}
kfree
(
performance
);
printk
(
KERN_INFO
"cpufreq: No CPUs supporting ACPI performance management found.
\n
"
);
return_VALUE
(
result
);
}
...
...
@@ -796,27 +380,9 @@ acpi_cpufreq_init (void)
static
void
__exit
acpi_cpufreq_exit
(
void
)
{
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_cpufreq_exit"
);
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
performance
[
i
].
pr
)
performance
[
i
].
pr
->
flags
.
performance
=
0
;
}
cpufreq_unregister_driver
(
&
acpi_cpufreq_driver
);
/* unregister struct acpi_processor_performance performance */
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
{
if
(
performance
[
i
].
pr
)
{
performance
[
i
].
pr
->
flags
.
performance
=
0
;
performance
[
i
].
pr
->
performance
=
NULL
;
performance
[
i
].
pr
=
NULL
;
}
}
kfree
(
performance
);
cpufreq_unregister_driver
(
&
acpi_cpufreq_driver
);
return_VOID
;
}
...
...
arch/ia64/kernel/acpi.c
View file @
fdfec545
...
...
@@ -191,8 +191,6 @@ acpi_parse_lsapic (acpi_table_entry_header *header)
if
(
!
lsapic
->
flags
.
enabled
)
printk
(
" disabled"
);
else
if
(
available_cpus
>=
NR_CPUS
)
printk
(
" ignored (increase NR_CPUS)"
);
else
{
printk
(
" enabled"
);
#ifdef CONFIG_SMP
...
...
@@ -395,12 +393,6 @@ acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
size
=
ma
->
length_hi
;
size
=
(
size
<<
32
)
|
ma
->
length_lo
;
if
(
num_memblks
>=
NR_MEMBLKS
)
{
printk
(
KERN_ERR
"Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx
\n
"
,
size
/
(
1024
*
1024
),
paddr
);
return
;
}
/* Ignore disabled entries */
if
(
!
ma
->
flags
.
enabled
)
return
;
...
...
@@ -552,29 +544,29 @@ acpi_boot_init (void)
/* Local APIC */
if
(
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_ADDR_OVR
,
acpi_parse_lapic_addr_ovr
)
<
0
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_ADDR_OVR
,
acpi_parse_lapic_addr_ovr
,
0
)
<
0
)
printk
(
KERN_ERR
PREFIX
"Error parsing LAPIC address override entry
\n
"
);
if
(
acpi_table_parse_madt
(
ACPI_MADT_LSAPIC
,
acpi_parse_lsapic
)
<
1
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_LSAPIC
,
acpi_parse_lsapic
,
NR_CPUS
)
<
1
)
printk
(
KERN_ERR
PREFIX
"Error parsing MADT - no LAPIC entries
\n
"
);
if
(
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_NMI
,
acpi_parse_lapic_nmi
)
<
0
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_NMI
,
acpi_parse_lapic_nmi
,
0
)
<
0
)
printk
(
KERN_ERR
PREFIX
"Error parsing LAPIC NMI entry
\n
"
);
/* I/O APIC */
if
(
acpi_table_parse_madt
(
ACPI_MADT_IOSAPIC
,
acpi_parse_iosapic
)
<
1
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_IOSAPIC
,
acpi_parse_iosapic
,
NR_IOSAPICS
)
<
1
)
printk
(
KERN_ERR
PREFIX
"Error parsing MADT - no IOSAPIC entries
\n
"
);
/* System-Level Interrupt Routing */
if
(
acpi_table_parse_madt
(
ACPI_MADT_PLAT_INT_SRC
,
acpi_parse_plat_int_src
)
<
0
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_PLAT_INT_SRC
,
acpi_parse_plat_int_src
,
ACPI_MAX_PLATFORM_INTERRUPTS
)
<
0
)
printk
(
KERN_ERR
PREFIX
"Error parsing platform interrupt source entry
\n
"
);
if
(
acpi_table_parse_madt
(
ACPI_MADT_INT_SRC_OVR
,
acpi_parse_int_src_ovr
)
<
0
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_INT_SRC_OVR
,
acpi_parse_int_src_ovr
,
0
)
<
0
)
printk
(
KERN_ERR
PREFIX
"Error parsing interrupt source overrides entry
\n
"
);
if
(
acpi_table_parse_madt
(
ACPI_MADT_NMI_SRC
,
acpi_parse_nmi_src
)
<
0
)
if
(
acpi_table_parse_madt
(
ACPI_MADT_NMI_SRC
,
acpi_parse_nmi_src
,
0
)
<
0
)
printk
(
KERN_ERR
PREFIX
"Error parsing NMI SRC entry
\n
"
);
skip_madt:
...
...
arch/ia64/kernel/iosapic.c
View file @
fdfec545
...
...
@@ -114,7 +114,7 @@ static struct iosapic {
char
*
addr
;
/* base address of IOSAPIC */
unsigned
int
gsi_base
;
/* first GSI assigned to this IOSAPIC */
unsigned
short
num_rte
;
/* number of RTE in this IOSAPIC */
}
iosapic_lists
[
256
];
}
iosapic_lists
[
NR_IOSAPICS
];
static
int
num_iosapic
;
...
...
arch/x86_64/kernel/acpi/boot.c
View file @
fdfec545
...
...
@@ -51,8 +51,8 @@
int
acpi_noirq
__initdata
=
0
;
/* skip ACPI IRQ initialization */
int
acpi_ht
__initdata
=
1
;
/* enable HT */
int
acpi_lapic
=
0
;
int
acpi_ioapic
=
0
;
int
acpi_lapic
;
int
acpi_ioapic
;
/* --------------------------------------------------------------------------
Boot-time Configuration
...
...
@@ -439,7 +439,7 @@ acpi_boot_init (void)
* and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
*/
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_ADDR_OVR
,
acpi_parse_lapic_addr_ovr
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_ADDR_OVR
,
acpi_parse_lapic_addr_ovr
,
0
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing LAPIC address override entry
\n
"
);
return
result
;
...
...
@@ -447,7 +447,8 @@ acpi_boot_init (void)
mp_register_lapic_address
(
acpi_lapic_addr
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC
,
acpi_parse_lapic
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC
,
acpi_parse_lapic
,
MAX_APICS
);
if
(
!
result
)
{
printk
(
KERN_ERR
PREFIX
"No LAPIC entries present
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
...
...
@@ -459,7 +460,7 @@ acpi_boot_init (void)
return
result
;
}
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_NMI
,
acpi_parse_lapic_nmi
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_LAPIC_NMI
,
acpi_parse_lapic_nmi
,
0
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing LAPIC NMI entry
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
...
...
@@ -496,8 +497,8 @@ acpi_boot_init (void)
return
1
;
}
result
=
acpi_table_parse_madt
(
ACPI_MADT_IOAPIC
,
acpi_parse_ioapic
);
if
(
!
result
)
{
result
=
acpi_table_parse_madt
(
ACPI_MADT_IOAPIC
,
acpi_parse_ioapic
,
MAX_IO_APICS
);
if
(
!
result
)
{
printk
(
KERN_ERR
PREFIX
"No IOAPIC entries present
\n
"
);
return
-
ENODEV
;
}
...
...
@@ -509,14 +510,15 @@ acpi_boot_init (void)
/* Build a default routing table for legacy (ISA) interrupts. */
mp_config_acpi_legacy_irqs
();
result
=
acpi_table_parse_madt
(
ACPI_MADT_INT_SRC_OVR
,
acpi_parse_int_src_ovr
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_INT_SRC_OVR
,
acpi_parse_int_src_ovr
,
NR_IRQ_VECTORS
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing interrupt source overrides entry
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
return
result
;
}
result
=
acpi_table_parse_madt
(
ACPI_MADT_NMI_SRC
,
acpi_parse_nmi_src
);
result
=
acpi_table_parse_madt
(
ACPI_MADT_NMI_SRC
,
acpi_parse_nmi_src
,
NR_IRQ_VECTORS
);
if
(
result
<
0
)
{
printk
(
KERN_ERR
PREFIX
"Error parsing NMI SRC entry
\n
"
);
/* TBD: Cleanup to allow fallback to MPS */
...
...
drivers/acpi/asus_acpi.c
View file @
fdfec545
...
...
@@ -2,7 +2,7 @@
* asus_acpi.c - Asus Laptop ACPI Extras
*
*
* Copyright (C) 2002, 2003 Julien Lerouge, Karol Kozimor
* Copyright (C) 2002, 2003
, 2004
Julien Lerouge, Karol Kozimor
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -23,16 +23,16 @@
* http://sourceforge.net/projects/acpi4asus/
*
* Credits:
* Pontus Fuchs - Helper functions, cleanup
* Johann Wiesner - Small compile fixes
* John Belmonte - ACPI code for Toshiba laptop was a good starting point.
*
* TODO:
* add Fn key status
* Add mode selection on module loading (parameter) -> still necessary?
* Complete display switching -- may require dirty hacks?
* Complete display switching -- may require dirty hacks
or calling _DOS
?
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
...
...
@@ -41,12 +41,13 @@
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#define ASUS_ACPI_VERSION "0.2
6
"
#define ASUS_ACPI_VERSION "0.2
7
"
#define PROC_ASUS "asus" //the directory
#define PROC_MLED "mled"
#define PROC_WLED "wled"
#define PROC_INFOS "info"
#define PROC_TLED "tled"
#define PROC_INFO "info"
#define PROC_LCD "lcd"
#define PROC_BRN "brn"
#define PROC_DISP "disp"
...
...
@@ -67,6 +68,7 @@
*/
#define MLED_ON 0x01 //is MLED ON ?
#define WLED_ON 0x02
#define TLED_ON 0x04
MODULE_AUTHOR
(
"Julien Lerouge, Karol Kozimor"
);
MODULE_DESCRIPTION
(
ACPI_HOTK_NAME
);
...
...
@@ -81,22 +83,25 @@ MODULE_PARM(asus_gid, "i");
MODULE_PARM_DESC
(
gid
,
"GID for entries in /proc/acpi/asus.
\n
"
);
/* For each model, all features implemented */
/* For each model, all features implemented,
* those marked with R are relative to HOTK, A for absolute */
struct
model_data
{
char
*
name
;
//name of the laptop
char
*
mt_mled
;
//method to handle mled
char
*
mled_status
;
//node to handle mled reading
char
*
mt_wled
;
//method to handle wled
char
*
wled_status
;
//node to handle wled reading
char
*
mt_lcd_switch
;
//method to turn LCD ON/OFF
char
*
lcd_status
;
//node to read LCD panel state
char
*
brightness_up
;
//method to set brightness up
char
*
brightness_down
;
//guess what ?
char
*
brightness_set
;
//method to set absolute brightness
char
*
brightness_get
;
//method to get absolute brightness
char
*
brightness_status
;
//node to get brightness
char
*
display_set
;
//method to set video output
char
*
display_get
;
//method to get video output
char
*
name
;
//name of the laptop________________A
char
*
mt_mled
;
//method to handle mled_____________R
char
*
mled_status
;
//node to handle mled reading_______A
char
*
mt_wled
;
//method to handle wled_____________R
char
*
wled_status
;
//node to handle wled reading_______A
char
*
mt_tled
;
//method to handle tled_____________R
char
*
tled_status
;
//node to handle tled reading_______A
char
*
mt_lcd_switch
;
//method to turn LCD ON/OFF_________A
char
*
lcd_status
;
//node to read LCD panel state______A
char
*
brightness_up
;
//method to set brightness up_______A
char
*
brightness_down
;
//guess what ?______________________A
char
*
brightness_set
;
//method to set absolute brightness_R
char
*
brightness_get
;
//method to get absolute brightness_R
char
*
brightness_status
;
//node to get brightness____________A
char
*
display_set
;
//method to set video output________R
char
*
display_get
;
//method to get video output________R
};
/*
...
...
@@ -104,91 +109,239 @@ struct model_data {
* about the hotk device
*/
struct
asus_hotk
{
struct
acpi_device
*
device
;
//the device we are in
acpi_handle
handle
;
//the handle of the hotk device
char
status
;
//status of the hotk, for LEDs, ...
struct
model_data
*
methods
;
//methods available on the laptop
u8
brightness
;
//brigh
ness level
struct
acpi_device
*
device
;
//the device we are in
acpi_handle
handle
;
//the handle of the hotk device
char
status
;
//status of the hotk, for LEDs, ...
struct
model_data
*
methods
;
//methods available on the laptop
u8
brightness
;
//bright
ness level
enum
{
A1X
=
0
,
//A1340D, A1300F
A2X
,
//A2500H
D1X
,
//D1
L1X
,
//L1400B
L2X
,
//L2000D -> TODO check Q11 (Fn+F8)
// Calling this method simply hangs the
// computer, ISMI method hangs the laptop.
L3D
,
//L3400D
L3X
,
//L3C
L5X
,
//L5C TODO this model seems to have one more
// LED, add support
M2X
,
//M2400E
M3N
,
//M3700N, but also S1300N -> TODO WLED
S1X
,
//S1300A -> TODO special keys do not work ?
S2X
,
//S200 (J1 reported), Victor MP-XP7210
//TODO A1370D does not seem to have an ATK device
// L8400 model doesn't have ATK
A1x
=
0
,
//A1340D, A1300F
A2x
,
//A2500H
D1x
,
//D1
L2D
,
//L2000D
L3C
,
//L3800C
L3D
,
//L3400D
L3H
,
//L3H, but also L2000E
L5x
,
//L5800C
L8L
,
//L8400L
M1A
,
//M1300A
M2E
,
//M2400E
S1x
,
//S1300A, but also L1400B and M2400A (L84F)
S2x
,
//S200 (J1 reported), Victor MP-XP7210
//TODO A1370D does not seem to have an ATK device
// L8400 model doesn't have ATK
xxN
,
//M2400N, M3700N, S1300N (Centrino)
END_MODEL
}
model
;
//Models currently supported
u16
event_count
[
128
];
//count for each event TODO make this better
}
model
;
//Models currently supported
u16
event_count
[
128
];
//count for each event TODO make this better
};
/* Here we go */
#define
L3X_PREFIX "\\_SB.PCI0.PX40.ECD
0."
#define
S1X_PREFIX "\\_SB.PCI0.PX4
0."
#define
L1X_PREFIX S1X_PREFIX
#define
A1X_PREFIX "\\_SB.PCI0.ISA.EC
0."
#define S2
X_PREFIX A1X
_PREFIX
#define
M3
N_PREFIX "\\_SB.PCI0.SBRG.EC0."
#define
A1x_PREFIX "\\_SB.PCI0.ISA.EC
0."
#define
L3C_PREFIX "\\_SB.PCI0.PX40.ECD
0."
#define
M1A_PREFIX "\\_SB.PCI0.PX40.EC0."
#define
S1x_PREFIX "\\_SB.PCI0.PX4
0."
#define S2
x_PREFIX A1x
_PREFIX
#define
xx
N_PREFIX "\\_SB.PCI0.SBRG.EC0."
static
struct
model_data
model_conf
[
END_MODEL
]
=
{
/*
* name| mled |mled read| wled |wled read| lcd sw |lcd read |
* br up|br down | br set | br read | br status|set disp | get disp
*
* br set and read shall be in hotk device !
* same for set disp
* Those pathnames are relative to the HOTK / ATKD device :
* - mt_mled
* - mt_wled
* - brightness_set
* - brightness_get
* - display_set
* - display_get
*
* TODO I have seen a SWBX and AIBX method on some models, like L1400B,
* it seems to be a kind of switch, but what for ?
*
*/
{
"A1X"
,
"MLED"
,
"
\\
MAIL"
,
NULL
,
NULL
,
A1X_PREFIX
"_Q10"
,
"
\\
BKLI"
,
A1X_PREFIX
"_Q0E"
,
A1X_PREFIX
"_Q0F"
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
},
{
"A2X"
,
"MLED"
,
NULL
,
"WLED"
,
"
\\
SG66"
,
"
\\
Q10"
,
"
\\
BAOF"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
"SPLV"
,
"GPLV"
,
"
\\
CMOD"
,
"SDSP"
,
"
\\
INFB"
},
{
"D1X"
,
"MLED"
,
NULL
,
NULL
,
NULL
,
"
\\
Q0D"
,
"
\\
GP11"
,
"
\\
Q0C"
,
"
\\
Q0B"
,
NULL
,
NULL
,
"
\\
BLVL"
,
"SDSP"
,
"
\\
INFB"
},
{
"L1X"
,
"MLED"
,
NULL
,
"WLED"
,
NULL
,
L1X_PREFIX
"Q10"
,
"
\\
PNOF"
,
L1X_PREFIX
"Q0F"
,
L1X_PREFIX
"Q0E"
,
"SPLV"
,
"GPLV"
,
"
\\
BRIT"
,
NULL
,
NULL
},
{
"L2X"
,
"MLED"
,
"
\\
SGP6"
,
"WLED"
,
"
\\
RCP3"
,
"
\\
Q10"
,
"
\\
SGP0"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
NULL
,
NULL
,
NULL
,
"SDSP"
,
"
\\
INFB"
},
{
"L3D"
,
"MLED"
,
"
\\
MALD"
,
"WLED"
,
NULL
,
"
\\
Q10"
,
"
\\
BKLG"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
"SPLV"
,
"GPLV"
,
"
\\
BLVL"
,
"SDSP"
,
"
\\
INFB"
},
{
"L3X"
,
"MLED"
,
NULL
,
"WLED"
,
NULL
,
L3X_PREFIX
"_Q10"
,
"
\\
GL32"
,
L3X_PREFIX
"_Q0F"
,
L3X_PREFIX
"_Q0E"
,
"SPLV"
,
"GPLV"
,
"
\\
BLVL"
,
"SDSP"
,
"
\\
_SB.PCI0.PCI1.VGAC.NMAP"
},
{
"L5X"
,
"MLED"
,
NULL
,
"WLED"
,
"WRED"
,
"
\\
Q0D"
,
"
\\
BAOF"
,
"
\\
Q0C"
,
"
\\
Q0B"
,
"SPLV"
,
"GPLV"
,
NULL
,
"SDSP"
,
"
\\
INFB"
},
{
"M2X"
,
"MLED"
,
NULL
,
"WLED"
,
NULL
,
"
\\
Q10"
,
"
\\
GP06"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
"SPLV"
,
"GPLV"
,
NULL
,
"SDSP"
,
"
\\
INFB"
},
{
"M3N"
,
"MLED"
,
NULL
,
"WLED"
,
"
\\
PO33"
,
M3N_PREFIX
"_Q10"
,
"
\\
BKLT"
,
M3N_PREFIX
"_Q0F"
,
M3N_PREFIX
"_Q0E"
,
"SPLV"
,
"GPLV"
,
"
\\
LBTN"
,
"SDSP"
,
"
\\
ADVG"
},
{
"S1X"
,
"MLED"
,
"
\\
EMLE"
,
"WLED"
,
NULL
,
S1X_PREFIX
"Q10"
,
"
\\
PNOF"
,
S1X_PREFIX
"Q0F"
,
S1X_PREFIX
"Q0E"
,
"SPLV"
,
"GPLV"
,
"
\\
BRIT"
,
NULL
,
NULL
},
{
"S2X"
,
"MLED"
,
"
\\
MAIL"
,
NULL
,
NULL
,
S2X_PREFIX
"_Q10"
,
"
\\
BKLI"
,
S2X_PREFIX
"_Q0B"
,
S2X_PREFIX
"_Q0A"
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
}
{
.
name
=
"A1x"
,
.
mt_mled
=
"MLED"
,
.
mled_status
=
"
\\
MAIL"
,
.
mt_lcd_switch
=
A1x_PREFIX
"_Q10"
,
.
lcd_status
=
"
\\
BKLI"
,
.
brightness_up
=
A1x_PREFIX
"_Q0E"
,
.
brightness_down
=
A1x_PREFIX
"_Q0F"
,
},
{
.
name
=
"A2x"
,
.
mt_mled
=
"MLED"
,
.
mt_wled
=
"WLED"
,
.
wled_status
=
"
\\
SG66"
,
.
mt_lcd_switch
=
"
\\
Q10"
,
.
lcd_status
=
"
\\
BAOF"
,
.
brightness_up
=
"
\\
Q0E"
,
.
brightness_down
=
"
\\
Q0F"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
brightness_status
=
"
\\
CMOD"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"D1x"
,
.
mt_mled
=
"MLED"
,
.
mt_lcd_switch
=
"
\\
Q0D"
,
.
lcd_status
=
"
\\
GP11"
,
.
brightness_up
=
"
\\
Q0C"
,
.
brightness_down
=
"
\\
Q0B"
,
.
brightness_status
=
"
\\
BLVL"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"L2D"
,
.
mt_mled
=
"MLED"
,
.
mled_status
=
"
\\
SGP6"
,
.
mt_wled
=
"WLED"
,
.
wled_status
=
"
\\
RCP3"
,
.
mt_lcd_switch
=
"
\\
Q10"
,
.
lcd_status
=
"
\\
SGP0"
,
.
brightness_up
=
"
\\
Q0E"
,
.
brightness_down
=
"
\\
Q0F"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"L3C"
,
.
mt_mled
=
"MLED"
,
.
mt_wled
=
"WLED"
,
.
mt_lcd_switch
=
L3C_PREFIX
"_Q10"
,
.
lcd_status
=
"
\\
GL32"
,
.
brightness_up
=
L3C_PREFIX
"_Q0F"
,
.
brightness_down
=
L3C_PREFIX
"_Q0E"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
brightness_status
=
"
\\
BLVL"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
_SB.PCI0.PCI1.VGAC.NMAP"
},
{
.
name
=
"L3D"
,
.
mt_mled
=
"MLED"
,
.
mled_status
=
"
\\
MALD"
,
.
mt_wled
=
"WLED"
,
.
mt_lcd_switch
=
"
\\
Q10"
,
.
lcd_status
=
"
\\
BKLG"
,
.
brightness_up
=
"
\\
Q0E"
,
.
brightness_down
=
"
\\
Q0F"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
brightness_status
=
"
\\
BLVL"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"L3H"
,
.
mt_mled
=
"MLED"
,
.
mt_wled
=
"WLED"
,
.
mt_lcd_switch
=
"EHK"
,
.
lcd_status
=
"
\\
_SB.PCI0.PM.PBC"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"L5x"
,
.
mt_mled
=
"MLED"
,
// .mt_wled = "WLED",
// .wled_status = "\\WRED",
/* Present, but not controlled by ACPI */
.
mt_tled
=
"TLED"
,
.
mt_lcd_switch
=
"
\\
Q0D"
,
.
lcd_status
=
"
\\
BAOF"
,
.
brightness_up
=
"
\\
Q0C"
,
.
brightness_down
=
"
\\
Q0B"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"L8L"
/* No features, but at least support the hotkeys */
},
{
.
name
=
"M1A"
,
.
mt_mled
=
"MLED"
,
.
mt_lcd_switch
=
M1A_PREFIX
"Q10"
,
.
lcd_status
=
"
\\
PNOF"
,
.
brightness_up
=
M1A_PREFIX
"Q0E"
,
.
brightness_down
=
M1A_PREFIX
"Q0F"
,
.
brightness_status
=
"
\\
BRIT"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"M2E"
,
.
mt_mled
=
"MLED"
,
.
mt_wled
=
"WLED"
,
.
mt_lcd_switch
=
"
\\
Q10"
,
.
lcd_status
=
"
\\
GP06"
,
.
brightness_up
=
"
\\
Q0E"
,
.
brightness_down
=
"
\\
Q0F"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
INFB"
},
{
.
name
=
"S1x"
,
.
mt_mled
=
"MLED"
,
.
mled_status
=
"
\\
EMLE"
,
.
mt_wled
=
"WLED"
,
.
mt_lcd_switch
=
S1x_PREFIX
"Q10"
,
.
lcd_status
=
"
\\
PNOF"
,
.
brightness_up
=
S1x_PREFIX
"Q0F"
,
.
brightness_down
=
S1x_PREFIX
"Q0E"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
brightness_status
=
"
\\
BRIT"
,
},
{
.
name
=
"S2x"
,
.
mt_mled
=
"MLED"
,
.
mled_status
=
"
\\
MAIL"
,
.
mt_lcd_switch
=
S2x_PREFIX
"_Q10"
,
.
lcd_status
=
"
\\
BKLI"
,
.
brightness_up
=
S2x_PREFIX
"_Q0B"
,
.
brightness_down
=
S2x_PREFIX
"_Q0A"
,
},
{
.
name
=
"xxN"
,
.
mt_mled
=
"MLED"
,
// .mt_wled = "WLED",
// .wled_status = "\\PO33",
/* Present, but not controlled by ACPI */
.
mt_lcd_switch
=
xxN_PREFIX
"_Q10"
,
.
lcd_status
=
"
\\
BKLT"
,
.
brightness_up
=
xxN_PREFIX
"_Q0F"
,
.
brightness_down
=
xxN_PREFIX
"_Q0E"
,
.
brightness_set
=
"SPLV"
,
.
brightness_get
=
"GPLV"
,
.
brightness_status
=
"
\\
LBTN"
,
.
display_set
=
"SDSP"
,
.
display_get
=
"
\\
ADVG"
}
};
/* procdir we use */
...
...
@@ -264,7 +417,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
void
*
data
)
{
int
len
=
0
;
int
sfun
;
int
temp
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
char
buf
[
16
];
//enough for all info
/*
...
...
@@ -275,8 +428,23 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
len
+=
sprintf
(
page
,
ACPI_HOTK_NAME
" "
ASUS_ACPI_VERSION
"
\n
"
);
len
+=
sprintf
(
page
+
len
,
"Model reference : %s
\n
"
,
hotk
->
methods
->
name
);
if
(
read_acpi_int
(
hotk
->
handle
,
"SFUN"
,
&
sfun
))
len
+=
sprintf
(
page
+
len
,
"SFUN value : 0x%04x
\n
"
,
sfun
);
/*
* The SFUN method probably allows the original driver to get the list
* of features supported by a given model. For now, 0x0100 or 0x0800
* bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
* The significance of others is yet to be found.
*/
if
(
read_acpi_int
(
hotk
->
handle
,
"SFUN"
,
&
temp
))
len
+=
sprintf
(
page
+
len
,
"SFUN value : 0x%04x
\n
"
,
temp
);
/*
* Another value for userspace: the ASYM method returns 0x02 for
* battery low and 0x04 for battery critical, it's readings tend to be
* more accurate than those provided by _BST.
* Note: since not all the laptops provide this method, errors are
* silently ignored.
*/
if
(
read_acpi_int
(
hotk
->
handle
,
"ASYM"
,
&
temp
))
len
+=
sprintf
(
page
+
len
,
"ASYM value : 0x%04x
\n
"
,
temp
);
if
(
asus_info
)
{
snprintf
(
buf
,
16
,
"%d"
,
asus_info
->
length
);
len
+=
sprintf
(
page
+
len
,
"DSDT length : %s
\n
"
,
buf
);
...
...
@@ -300,128 +468,179 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof,
}
/*
* proc file handlers
/*
* /proc handlers
* We write our info in page, we begin at offset off and cannot write more
* than count bytes. We set eof to 1 if we handle those 2 values. We return the
* number of bytes written in page
*/
/* Generic LED functions */
static
int
proc_read_mled
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
read_led
(
struct
asus_hotk
*
hotk
,
const
char
*
ledname
,
int
ledmask
)
{
int
len
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
int
led_status
=
0
;
/*
* We use the easy way, we don't care of off and count, so we don't set eof
* to 1
*/
if
(
hotk
->
methods
->
mled_status
)
{
if
(
read_acpi_int
(
NULL
,
hotk
->
methods
->
mled_status
,
&
led_status
))
len
=
sprintf
(
page
,
"%d
\n
"
,
led_status
);
if
(
ledname
)
{
int
led_status
;
if
(
read_acpi_int
(
NULL
,
ledname
,
&
led_status
))
return
led_status
;
else
printk
(
KERN_WARNING
"Asus ACPI: Error reading
M
LED "
printk
(
KERN_WARNING
"Asus ACPI: Error reading LED "
"status
\n
"
);
}
else
{
len
=
sprintf
(
page
,
"%d
\n
"
,
(
hotk
->
status
&
MLED_ON
)
?
1
:
0
);
}
return
len
;
return
(
hotk
->
status
&
ledmask
)
?
1
:
0
;
}
/* FIXME: kill extraneous args so it can be called independently */
static
int
proc_write_mled
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
write_led
(
const
char
*
buffer
,
unsigned
long
count
,
struct
asus_hotk
*
hotk
,
char
*
ledname
,
int
ledmask
,
int
invert
)
{
int
value
;
int
led_out
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
/* scan expression. Multiple expressions may be delimited with ; */
if
(
sscanf
(
buffer
,
"%i"
,
&
value
)
==
1
)
led_out
=
~
value
&
1
;
led_out
=
value
?
1
:
0
;
hotk
->
status
=
(
value
)
?
(
hotk
->
status
|
MLED_ON
)
:
(
hotk
->
status
&
~
MLED_ON
);
/* We don't have to check mt_mled exists if we are here :) */
if
(
!
write_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
mt_mled
,
led_out
,
NULL
))
printk
(
KERN_WARNING
"Asus ACPI: MLED write failed
\n
"
);
(
led_out
)
?
(
hotk
->
status
|
ledmask
)
:
(
hotk
->
status
&
~
ledmask
);
if
(
invert
)
/* invert target value */
led_out
=
!
led_out
&
0x1
;
if
(
!
write_acpi_int
(
hotk
->
handle
,
ledname
,
led_out
,
NULL
))
printk
(
KERN_WARNING
"Asus ACPI: LED (%s) write failed
\n
"
,
ledname
);
return
count
;
}
/*
* We write our info in page, we begin at offset off and cannot write more
* than count bytes. We set eof to 1 if we handle those 2 values. We return the
* number of bytes written in page
* Proc handlers for MLED
*/
static
int
proc_read_
w
led
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
proc_read_
m
led
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
int
len
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
int
led_status
;
return
sprintf
(
page
,
"%d
\n
"
,
read_led
(
hotk
,
hotk
->
methods
->
mled_status
,
MLED_ON
));
}
if
(
hotk
->
methods
->
wled_status
)
{
if
(
read_acpi_int
(
NULL
,
hotk
->
methods
->
wled_status
,
&
led_status
))
len
=
sprintf
(
page
,
"%d
\n
"
,
led_status
);
else
printk
(
KERN_WARNING
"Asus ACPI: Error reading WLED "
"status
\n
"
);
}
else
{
len
=
sprintf
(
page
,
"%d
\n
"
,
(
hotk
->
status
&
WLED_ON
)
?
1
:
0
);
}
return
len
;
static
int
proc_write_mled
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
return
write_led
(
buffer
,
count
,
hotk
,
hotk
->
methods
->
mt_mled
,
MLED_ON
,
1
);
}
/*
* Proc handlers for WLED
*/
static
int
proc_read_wled
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
return
sprintf
(
page
,
"%d
\n
"
,
read_led
(
hotk
,
hotk
->
methods
->
wled_status
,
WLED_ON
));
}
static
int
proc_write_wled
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
int
value
;
int
led_out
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
return
write_led
(
buffer
,
count
,
hotk
,
hotk
->
methods
->
mt_wled
,
WLED_ON
,
0
);
}
/* scan expression. Multiple expressions may be delimited with ; */
if
(
sscanf
(
buffer
,
"%i"
,
&
value
)
==
1
)
led_out
=
value
&
1
;
hotk
->
status
=
(
value
)
?
(
hotk
->
status
|
WLED_ON
)
:
(
hotk
->
status
&
~
WLED_ON
);
/* We don't have to check if mt_wled exists if we are here :) */
if
(
!
write_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
mt_wled
,
led_out
,
NULL
))
printk
(
KERN_WARNING
"Asus ACPI: WLED write failed
\n
"
);
/*
* Proc handlers for TLED
*/
static
int
proc_read_tled
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
return
sprintf
(
page
,
"%d
\n
"
,
read_led
(
hotk
,
hotk
->
methods
->
tled_status
,
TLED_ON
));
}
return
count
;
static
int
proc_write_tled
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
return
write_led
(
buffer
,
count
,
hotk
,
hotk
->
methods
->
mt_tled
,
TLED_ON
,
0
);
}
static
int
get_lcd_state
(
struct
asus_hotk
*
hotk
)
{
int
lcd
=
0
;
/* We don't have to check anything, if we are here */
if
(
!
read_acpi_int
(
NULL
,
hotk
->
methods
->
lcd_status
,
&
lcd
))
printk
(
KERN_WARNING
"Asus ACPI: Error reading LCD status
\n
"
);
if
(
hotk
->
model
!=
L3H
)
{
/* We don't have to check anything if we are here */
if
(
!
read_acpi_int
(
NULL
,
hotk
->
methods
->
lcd_status
,
&
lcd
))
printk
(
KERN_WARNING
"Asus ACPI: Error reading LCD status
\n
"
);
if
(
hotk
->
model
==
L2X
)
lcd
=
~
lcd
;
if
(
hotk
->
model
==
L2D
)
lcd
=
~
lcd
;
}
else
{
/* L3H and the like have to be handled differently */
acpi_status
status
=
0
;
struct
acpi_object_list
input
;
union
acpi_object
mt_params
[
2
];
struct
acpi_buffer
output
;
union
acpi_object
out_obj
;
input
.
count
=
2
;
input
.
pointer
=
mt_params
;
/* Note: the following values are partly guessed up, but
otherwise they seem to work */
mt_params
[
0
].
type
=
ACPI_TYPE_INTEGER
;
mt_params
[
0
].
integer
.
value
=
0x02
;
mt_params
[
1
].
type
=
ACPI_TYPE_INTEGER
;
mt_params
[
1
].
integer
.
value
=
0x02
;
output
.
length
=
sizeof
(
out_obj
);
output
.
pointer
=
&
out_obj
;
status
=
acpi_evaluate_object
(
NULL
,
hotk
->
methods
->
lcd_status
,
&
input
,
&
output
);
if
(
status
!=
AE_OK
)
return
-
1
;
if
(
out_obj
.
type
==
ACPI_TYPE_INTEGER
)
/* That's what the AML code does */
lcd
=
out_obj
.
integer
.
value
>>
8
;
}
return
(
lcd
&
1
);
}
static
int
set_lcd_state
(
struct
asus_hotk
*
hotk
,
int
value
)
{
int
lcd
=
0
;
acpi_status
status
=
0
;
lcd
=
value
?
1
:
0
;
if
(
lcd
!=
get_lcd_state
(
hotk
))
{
/* switch */
if
(
hotk
->
model
!=
L3H
)
{
status
=
acpi_evaluate_object
(
NULL
,
hotk
->
methods
->
mt_lcd_switch
,
NULL
,
NULL
);
}
else
{
/* L3H and the like have to be handled differently */
if
(
!
write_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
mt_lcd_switch
,
0x07
,
NULL
))
status
=
AE_ERROR
;
/* L3H's AML executes EHK (0x07) upon Fn+F7 keypress,
the exact behaviour is simulated here */
}
if
(
ACPI_FAILURE
(
status
))
printk
(
KERN_WARNING
"Asus ACPI: Error switching LCD
\n
"
);
}
return
0
;
}
static
int
proc_read_lcd
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
...
...
@@ -436,26 +655,10 @@ proc_write_lcd(struct file *file, const char *buffer,
unsigned
long
count
,
void
*
data
)
{
int
value
;
int
lcd
=
0
;
acpi_status
status
=
0
;
int
lcd_status
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
/* scan expression. Multiple expressions may be delimited with ; */
if
(
sscanf
(
buffer
,
"%i"
,
&
value
)
==
1
)
lcd
=
value
&
1
;
lcd_status
=
get_lcd_state
(
hotk
);
if
(
lcd_status
!=
lcd
)
{
/* switch */
status
=
acpi_evaluate_object
(
NULL
,
hotk
->
methods
->
mt_lcd_switch
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
printk
(
KERN_WARNING
"Asus ACPI: Error switching LCD
\n
"
);
}
set_lcd_state
(
hotk
,
value
);
return
count
;
}
...
...
@@ -521,7 +724,6 @@ proc_write_brn(struct file *file, const char *buffer,
int
value
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
/* scan expression. Multiple expressions may be delimited with ; */
if
(
sscanf
(
buffer
,
"%d"
,
&
value
)
==
1
)
{
value
=
(
0
<
value
)
?
((
15
<
value
)
?
15
:
value
)
:
0
;
/* 0 <= value <= 15 */
...
...
@@ -546,7 +748,6 @@ static void set_display(int value, struct asus_hotk *hotk)
* Now, *this* one could be more user-friendly, but so far, no-one has
* complained. The significance of bits is the same as in proc_write_disp()
*/
static
int
proc_read_disp
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
...
...
@@ -560,12 +761,11 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof,
}
/*
* Experimental support for display switching. As of now:
0x0
1 should activate
* the LCD output,
0x02 should do for CRT, and 0x0
4 for TV-Out. Any combination
* Experimental support for display switching. As of now: 1 should activate
* the LCD output,
2 should do for CRT, and
4 for TV-Out. Any combination
* (bitwise) of these will suffice. I never actually tested 3 displays hooked up
* simultaneously, so be warned.
* simultaneously, so be warned.
See the acpi4asus README for more info.
*/
static
int
proc_write_disp
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
...
...
@@ -573,7 +773,6 @@ proc_write_disp(struct file *file, const char *buffer,
int
value
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
/* scan expression. Multiple expressions may be delimited with ; */
if
(
sscanf
(
buffer
,
"%d"
,
&
value
)
==
1
)
set_display
(
value
,
hotk
);
else
{
...
...
@@ -583,6 +782,31 @@ proc_write_disp(struct file *file, const char *buffer,
return
count
;
}
typedef
int
(
proc_readfunc
)(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
);
typedef
int
(
proc_writefunc
)(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
);
static
int
__init
asus_proc_add
(
char
*
name
,
proc_writefunc
*
writefunc
,
proc_readfunc
*
readfunc
,
mode_t
mode
,
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
proc
=
create_proc_entry
(
name
,
mode
,
acpi_device_dir
(
device
));
if
(
!
proc
)
{
printk
(
KERN_WARNING
" Unable to create %s fs entry
\n
"
,
name
);
return
-
1
;
}
proc
->
write_proc
=
writefunc
;
proc
->
read_proc
=
readfunc
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;
return
0
;
}
static
int
__init
asus_hotk_add_fs
(
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
proc
;
...
...
@@ -605,46 +829,28 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
if
(
!
acpi_device_dir
(
device
))
return
(
-
ENODEV
);
proc
=
create_proc_entry
(
PROC_INFO
S
,
mode
,
acpi_device_dir
(
device
));
proc
=
create_proc_entry
(
PROC_INFO
,
mode
,
acpi_device_dir
(
device
));
if
(
proc
)
{
proc
->
read_proc
=
proc_read_info
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;
;
proc
->
gid
=
asus_gid
;
}
else
{
printk
(
KERN_WARNING
" Unable to create "
PROC_INFO
S
printk
(
KERN_WARNING
" Unable to create "
PROC_INFO
" fs entry
\n
"
);
}
if
(
hotk
->
methods
->
mt_wled
)
{
proc
=
create_proc_entry
(
PROC_WLED
,
mode
,
acpi_device_dir
(
device
));
if
(
proc
)
{
proc
->
write_proc
=
proc_write_wled
;
proc
->
read_proc
=
proc_read_wled
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;;
}
else
{
printk
(
KERN_WARNING
" Unable to create "
PROC_WLED
" fs entry
\n
"
);
}
asus_proc_add
(
PROC_WLED
,
&
proc_write_wled
,
&
proc_read_wled
,
mode
,
device
);
}
if
(
hotk
->
methods
->
mt_mled
)
{
proc
=
create_proc_entry
(
PROC_MLED
,
mode
,
acpi_device_dir
(
device
));
if
(
proc
)
{
proc
->
write_proc
=
proc_write_mled
;
proc
->
read_proc
=
proc_read_mled
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;;
}
else
{
printk
(
KERN_WARNING
" Unable to create "
PROC_MLED
" fs entry
\n
"
);
}
asus_proc_add
(
PROC_MLED
,
&
proc_write_mled
,
&
proc_read_mled
,
mode
,
device
);
}
if
(
hotk
->
methods
->
mt_tled
)
{
asus_proc_add
(
PROC_TLED
,
&
proc_write_tled
,
&
proc_read_tled
,
mode
,
device
);
}
/*
...
...
@@ -652,49 +858,17 @@ static int __init asus_hotk_add_fs(struct acpi_device *device)
* from keyboard
*/
if
(
hotk
->
methods
->
mt_lcd_switch
&&
hotk
->
methods
->
lcd_status
)
{
proc
=
create_proc_entry
(
PROC_LCD
,
mode
,
acpi_device_dir
(
device
));
if
(
proc
)
{
proc
->
write_proc
=
proc_write_lcd
;
proc
->
read_proc
=
proc_read_lcd
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;;
}
else
{
printk
(
KERN_WARNING
" Unable to create "
PROC_LCD
" fs entry
\n
"
);
}
asus_proc_add
(
PROC_LCD
,
&
proc_write_lcd
,
&
proc_read_lcd
,
mode
,
device
);
}
if
((
hotk
->
methods
->
brightness_up
&&
hotk
->
methods
->
brightness_down
)
||
(
hotk
->
methods
->
brightness_get
&&
hotk
->
methods
->
brightness_get
))
{
proc
=
create_proc_entry
(
PROC_BRN
,
mode
,
acpi_device_dir
(
device
));
if
(
proc
)
{
proc
->
write_proc
=
proc_write_brn
;
proc
->
read_proc
=
proc_read_brn
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;;
}
else
{
printk
(
KERN_WARNING
" Unable to create "
PROC_BRN
" fs entry
\n
"
);
}
asus_proc_add
(
PROC_BRN
,
&
proc_write_brn
,
&
proc_read_brn
,
mode
,
device
);
}
if
(
hotk
->
methods
->
display_set
)
{
proc
=
create_proc_entry
(
PROC_DISP
,
mode
,
acpi_device_dir
(
device
));
if
(
proc
)
{
proc
->
write_proc
=
proc_write_disp
;
proc
->
read_proc
=
proc_read_disp
;
proc
->
data
=
acpi_driver_data
(
device
);
proc
->
owner
=
THIS_MODULE
;
proc
->
uid
=
asus_uid
;
proc
->
gid
=
asus_gid
;;
}
else
{
printk
(
KERN_WARNING
" Unable to create "
PROC_DISP
" fs entry
\n
"
);
}
asus_proc_add
(
PROC_DISP
,
&
proc_write_disp
,
&
proc_read_disp
,
mode
,
device
);
}
return
0
;
...
...
@@ -761,11 +935,6 @@ static int __init asus_hotk_get_info(struct asus_hotk *hotk)
else
if
(
bsts_result
)
printk
(
KERN_NOTICE
" BSTS called, 0x%02x returned
\n
"
,
bsts_result
);
/*
* Here, we also use asus_info to make decision. For example, on INIT
* method, S1X and L1X models both reports to be L84F, but they don't
* have the same methods (L1X has WLED, S1X don't)
*/
model
=
(
union
acpi_object
*
)
buffer
.
pointer
;
if
(
model
->
type
==
ACPI_TYPE_STRING
)
{
printk
(
KERN_NOTICE
" %s model detected, "
,
model
->
string
.
pointer
);
...
...
@@ -774,52 +943,63 @@ static int __init asus_hotk_get_info(struct asus_hotk *hotk)
hotk
->
model
=
END_MODEL
;
if
(
strncmp
(
model
->
string
.
pointer
,
"L3D"
,
3
)
==
0
)
hotk
->
model
=
L3D
;
/*
* L2B has same settings that L3X, except for GL32, but as
* there is no node to get the LCD status, and as GL32 is never
* used anywhere else, I assume it's safe, even if lcd get is
* broken for this model (TODO fix it ?)
*/
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L3H"
,
3
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"L2E"
,
3
)
==
0
)
hotk
->
model
=
L3H
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L3"
,
2
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"L2B"
,
3
)
==
0
)
hotk
->
model
=
L3X
;
hotk
->
model
=
L3C
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L8L"
,
3
)
==
0
)
hotk
->
model
=
L8L
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"M2N"
,
3
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"M3N"
,
3
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"S1N"
,
3
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"S5N"
,
3
)
==
0
)
hotk
->
model
=
xxN
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"M1"
,
2
)
==
0
)
hotk
->
model
=
M1A
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"M2"
,
2
)
==
0
)
hotk
->
model
=
M2X
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"M3N"
,
3
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"S1N"
,
3
)
==
0
)
hotk
->
model
=
M3N
;
/* S1300N is similar enough */
hotk
->
model
=
M2E
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L2"
,
2
)
==
0
)
hotk
->
model
=
L2X
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L8"
,
2
)
==
0
)
{
/* S1300A reports L84F, but L1400B too */
if
(
asus_info
)
{
if
(
strncmp
(
asus_info
->
oem_table_id
,
"L1"
,
2
)
==
0
)
hotk
->
model
=
L1X
;
}
else
hotk
->
model
=
S1X
;
}
hotk
->
model
=
L2D
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L8"
,
2
)
==
0
)
hotk
->
model
=
S1x
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"D1"
,
2
)
==
0
)
hotk
->
model
=
D1
X
;
hotk
->
model
=
D1
x
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"A1"
,
2
)
==
0
)
hotk
->
model
=
A1
X
;
hotk
->
model
=
A1
x
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"A2"
,
2
)
==
0
)
hotk
->
model
=
A2
X
;
hotk
->
model
=
A2
x
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"J1"
,
2
)
==
0
)
hotk
->
model
=
S2
X
;
hotk
->
model
=
S2
x
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"L5"
,
2
)
==
0
)
hotk
->
model
=
L5
X
;
hotk
->
model
=
L5
x
;
if
(
hotk
->
model
==
END_MODEL
)
{
/* By default use the same values, as I don't know others */
printk
(
"unsupported, trying default values, supply the "
"developers with your DSDT
\n
"
);
hotk
->
model
=
L2X
;
hotk
->
model
=
M2E
;
}
else
{
printk
(
"supported
\n
"
);
}
hotk
->
methods
=
&
model_conf
[
hotk
->
model
];
/* Sort of per-model blacklist */
if
(
strncmp
(
model
->
string
.
pointer
,
"L2B"
,
3
)
==
0
)
hotk
->
methods
->
lcd_status
=
NULL
;
/* L2B is similar enough to L3C to use its settings, with this only
exception */
else
if
(
strncmp
(
model
->
string
.
pointer
,
"S5N"
,
3
)
==
0
)
hotk
->
methods
->
mt_mled
=
NULL
;
/* S5N has no MLED */
else
if
(
asus_info
)
{
if
(
strncmp
(
asus_info
->
oem_table_id
,
"L1"
,
2
)
==
0
)
hotk
->
methods
->
mled_status
=
NULL
;
/* S1300A reports L84F, but L1400B too, account for that */
}
acpi_os_free
(
model
);
return
AE_OK
;
...
...
@@ -917,8 +1097,6 @@ static int __init asus_hotk_add(struct acpi_device *device)
}
static
int
asus_hotk_remove
(
struct
acpi_device
*
device
,
int
type
)
{
acpi_status
status
=
0
;
...
...
@@ -940,15 +1118,13 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
}
static
int
__init
asus_acpi_init
(
void
)
{
int
result
;
asus_proc_dir
=
proc_mkdir
(
PROC_ASUS
,
acpi_root_dir
);
if
(
!
asus_proc_dir
)
{
printk
(
KERN_ERR
"Asus ACPI: Unable to create /proc entry"
);
printk
(
KERN_ERR
"Asus ACPI: Unable to create /proc entry
\n
"
);
return
(
-
ENODEV
);
}
asus_proc_dir
->
owner
=
THIS_MODULE
;
...
...
@@ -963,7 +1139,6 @@ static int __init asus_acpi_init(void)
}
static
void
__exit
asus_acpi_exit
(
void
)
{
acpi_bus_unregister_driver
(
&
asus_hotk_driver
);
...
...
drivers/acpi/numa.c
View file @
fdfec545
...
...
@@ -30,8 +30,9 @@
#include <linux/errno.h>
#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
#include <acpi/acmacros.h>
extern
int
__init
acpi_table_parse_madt_family
(
enum
acpi_table_id
id
,
unsigned
long
madt_size
,
int
entry_id
,
acpi_madt_entry_handler
handler
);
extern
int
__init
acpi_table_parse_madt_family
(
enum
acpi_table_id
id
,
unsigned
long
madt_size
,
int
entry_id
,
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
);
void
__init
acpi_table_print_srat_entry
(
...
...
@@ -46,9 +47,9 @@ acpi_table_print_srat_entry (
{
struct
acpi_table_processor_affinity
*
p
=
(
struct
acpi_table_processor_affinity
*
)
header
;
printk
(
KERN_INFO
PREFIX
"SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s
\n
"
,
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
"SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s
\n
"
,
p
->
apic_id
,
p
->
lsapic_eid
,
p
->
proximity_domain
,
p
->
flags
.
enabled
?
"enabled"
:
"disabled"
);
p
->
flags
.
enabled
?
"enabled"
:
"disabled"
)
)
;
}
break
;
...
...
@@ -56,11 +57,11 @@ acpi_table_print_srat_entry (
{
struct
acpi_table_memory_affinity
*
p
=
(
struct
acpi_table_memory_affinity
*
)
header
;
printk
(
KERN_INFO
PREFIX
"SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s
\n
"
,
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
"SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s
\n
"
,
p
->
base_addr_hi
,
p
->
base_addr_lo
,
p
->
length_hi
,
p
->
length_lo
,
p
->
memory_type
,
p
->
proximity_domain
,
p
->
flags
.
enabled
?
"enabled"
:
"disabled"
,
p
->
flags
.
hot_pluggable
?
" hot-pluggable"
:
""
);
p
->
flags
.
hot_pluggable
?
" hot-pluggable"
:
""
)
)
;
}
break
;
...
...
@@ -97,7 +98,7 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size)
static
int
__init
acpi_parse_processor_affinity
(
acpi_table_entry_header
*
header
)
{
struct
acpi_table_processor_affinity
*
processor_affinity
=
NULL
;
struct
acpi_table_processor_affinity
*
processor_affinity
;
processor_affinity
=
(
struct
acpi_table_processor_affinity
*
)
header
;
if
(
!
processor_affinity
)
...
...
@@ -115,7 +116,7 @@ acpi_parse_processor_affinity (acpi_table_entry_header *header)
static
int
__init
acpi_parse_memory_affinity
(
acpi_table_entry_header
*
header
)
{
struct
acpi_table_memory_affinity
*
memory_affinity
=
NULL
;
struct
acpi_table_memory_affinity
*
memory_affinity
;
memory_affinity
=
(
struct
acpi_table_memory_affinity
*
)
header
;
if
(
!
memory_affinity
)
...
...
@@ -133,7 +134,7 @@ acpi_parse_memory_affinity (acpi_table_entry_header *header)
static
int
__init
acpi_parse_srat
(
unsigned
long
phys_addr
,
unsigned
long
size
)
{
struct
acpi_table_srat
*
srat
=
NULL
;
struct
acpi_table_srat
*
srat
;
if
(
!
phys_addr
||
!
size
)
return
-
EINVAL
;
...
...
@@ -149,10 +150,11 @@ acpi_parse_srat (unsigned long phys_addr, unsigned long size)
int
__init
acpi_table_parse_srat
(
enum
acpi_srat_entry_id
id
,
acpi_madt_entry_handler
handler
)
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
)
{
return
acpi_table_parse_madt_family
(
ACPI_SRAT
,
sizeof
(
struct
acpi_table_srat
),
id
,
handler
);
id
,
handler
,
max_entries
);
}
...
...
@@ -166,9 +168,11 @@ acpi_numa_init()
if
(
result
>
0
)
{
result
=
acpi_table_parse_srat
(
ACPI_SRAT_PROCESSOR_AFFINITY
,
acpi_parse_processor_affinity
);
acpi_parse_processor_affinity
,
NR_CPUS
);
result
=
acpi_table_parse_srat
(
ACPI_SRAT_MEMORY_AFFINITY
,
acpi_parse_memory_affinity
);
acpi_parse_memory_affinity
,
NR_MEMBLKS
);
}
else
{
/* FIXME */
printk
(
"Warning: acpi_table_parse(ACPI_SRAT) returned %d!
\n
"
,
result
);
...
...
drivers/acpi/pci_irq.c
View file @
fdfec545
...
...
@@ -315,7 +315,6 @@ acpi_pci_irq_enable (
{
int
irq
=
0
;
u8
pin
=
0
;
static
u16
irq_mask
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_irq_enable"
);
...
...
@@ -372,10 +371,13 @@ acpi_pci_irq_enable (
* Make sure all (legacy) PCI IRQs are set as level-triggered.
*/
#ifdef CONFIG_X86
if
((
dev
->
irq
<
16
)
&&
!
((
1
<<
dev
->
irq
)
&
irq_mask
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Setting IRQ %d as level-triggered
\n
"
,
dev
->
irq
));
irq_mask
|=
(
1
<<
dev
->
irq
);
eisa_set_level_irq
(
dev
->
irq
);
{
static
u16
irq_mask
;
if
((
dev
->
irq
<
16
)
&&
!
((
1
<<
dev
->
irq
)
&
irq_mask
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Setting IRQ %d as level-triggered
\n
"
,
dev
->
irq
));
irq_mask
|=
(
1
<<
dev
->
irq
);
eisa_set_level_irq
(
dev
->
irq
);
}
}
#endif
#ifdef CONFIG_IOSAPIC
...
...
drivers/acpi/processor.c
View file @
fdfec545
...
...
@@ -3,6 +3,7 @@
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
* Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
...
...
@@ -22,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.
...
...
@@ -55,9 +56,9 @@
#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
#define ACPI_PROCESSOR_FILE_INFO "info"
#define ACPI_PROCESSOR_FILE_POWER "power"
#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
#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
...
...
@@ -746,7 +747,62 @@ acpi_processor_get_power_info (
/* --------------------------------------------------------------------------
Performance Management
-------------------------------------------------------------------------- */
int
#ifdef CONFIG_CPU_FREQ
static
DECLARE_MUTEX
(
performance_sem
);
/*
* _PPC support is implemented as a CPUfreq policy notifier:
* This means each time a CPUfreq driver registered also with
* the ACPI core is asked to change the speed policy, the maximum
* value is adjusted so that it is within the platform limit.
*
* Also, when a new platform limit value is detected, the CPUfreq
* policy is adjusted accordingly.
*/
static
int
acpi_processor_ppc_is_init
=
0
;
static
int
acpi_processor_ppc_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
data
)
{
struct
cpufreq_policy
*
policy
=
data
;
struct
acpi_processor
*
pr
;
unsigned
int
ppc
=
0
;
down
(
&
performance_sem
);
if
(
event
!=
CPUFREQ_INCOMPATIBLE
)
goto
out
;
pr
=
processors
[
policy
->
cpu
];
if
(
!
pr
||
!
pr
->
performance
)
goto
out
;
ppc
=
(
unsigned
int
)
pr
->
performance_platform_limit
;
if
(
!
ppc
)
goto
out
;
if
(
ppc
>
pr
->
performance
->
state_count
)
goto
out
;
cpufreq_verify_within_limits
(
policy
,
0
,
pr
->
performance
->
states
[
ppc
].
core_frequency
*
1000
);
out:
up
(
&
performance_sem
);
return
0
;
}
static
struct
notifier_block
acpi_ppc_notifier_block
=
{
.
notifier_call
=
acpi_processor_ppc_notifier
,
};
static
int
acpi_processor_get_platform_limit
(
struct
acpi_processor
*
pr
)
{
...
...
@@ -770,35 +826,491 @@ acpi_processor_get_platform_limit (
pr
->
performance_platform_limit
=
(
int
)
ppc
;
acpi_processor_get_limit_info
(
pr
);
return_VALUE
(
0
);
}
static
int
acpi_processor_ppc_has_changed
(
struct
acpi_processor
*
pr
)
{
int
ret
=
acpi_processor_get_platform_limit
(
pr
);
if
(
ret
<
0
)
return
(
ret
);
else
return
cpufreq_update_policy
(
pr
->
id
);
}
static
void
acpi_processor_ppc_init
(
void
)
{
if
(
!
cpufreq_register_notifier
(
&
acpi_ppc_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
))
acpi_processor_ppc_is_init
=
1
;
else
printk
(
KERN_DEBUG
"Warning: Processor Platform Limit not supported.
\n
"
);
}
static
void
acpi_processor_ppc_exit
(
void
)
{
if
(
acpi_processor_ppc_is_init
)
cpufreq_unregister_notifier
(
&
acpi_ppc_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
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
);
}
EXPORT_SYMBOL
(
acpi_processor_get_platform_limit
);
#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
(
struct
acpi_processor_performance
*
performance
,
struct
acpi_processor
**
pr
,
unsigned
int
cpu
)
{
struct
acpi_processor
*
pr
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_register_performance"
);
*
pr
=
processors
[
cpu
];
if
(
!*
pr
)
if
(
!
acpi_processor_ppc_is_init
)
return_VALUE
(
-
EINVAL
);
down
(
&
performance_sem
);
pr
=
processors
[
cpu
];
if
(
!
pr
)
{
up
(
&
performance_sem
);
return_VALUE
(
-
ENODEV
);
}
if
((
*
pr
)
->
performance
)
if
(
pr
->
performance
)
{
up
(
&
performance_sem
);
return_VALUE
(
-
EBUSY
);
}
(
*
pr
)
->
performance
=
performance
;
performance
->
pr
=
*
pr
;
return
0
;
pr
->
performance
=
performance
;
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
);
}
EXPORT_SYMBOL
(
acpi_processor_register_performance
);
/* for the rest of it, check cpufreq/acpi.c */
void
acpi_processor_unregister_performance
(
struct
acpi_processor_performance
*
performance
,
unsigned
int
cpu
)
{
struct
acpi_processor
*
pr
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_unregister_performance"
);
if
(
!
acpi_processor_ppc_is_init
)
return_VOID
;
down
(
&
performance_sem
);
pr
=
processors
[
cpu
];
if
(
!
pr
)
{
up
(
&
performance_sem
);
return_VOID
;
}
kfree
(
pr
->
performance
->
states
);
pr
->
performance
=
NULL
;
acpi_cpufreq_remove_file
(
pr
);
up
(
&
performance_sem
);
return_VOID
;
}
EXPORT_SYMBOL
(
acpi_processor_unregister_performance
);
/* for the rest of it, check arch/i386/kernel/cpu/cpufreq/acpi.c */
#else
/* !CONFIG_CPU_FREQ */
static
void
acpi_processor_ppc_init
(
void
)
{
return
;
}
static
void
acpi_processor_ppc_exit
(
void
)
{
return
;
}
static
int
acpi_processor_ppc_has_changed
(
struct
acpi_processor
*
pr
)
{
static
unsigned
int
printout
=
1
;
if
(
printout
)
{
printk
(
KERN_WARNING
"Warning: Processor Platform Limit event detected, but not handled.
\n
"
);
printk
(
KERN_WARNING
"Consider compiling CPUfreq support into your kernel.
\n
"
);
printout
=
0
;
}
return
0
;
}
#endif
/* CONFIG_CPU_FREQ */
/* --------------------------------------------------------------------------
Throttling Control
...
...
@@ -1043,27 +1555,6 @@ acpi_processor_apply_limit (
if
(
!
pr
->
flags
.
limit
)
return_VALUE
(
-
ENODEV
);
#ifdef CONFIG_CPU_FREQ
if
(
pr
->
flags
.
performance
)
{
px
=
pr
->
performance_platform_limit
;
if
(
pr
->
limit
.
user
.
px
>
px
)
px
=
pr
->
limit
.
user
.
px
;
if
(
pr
->
limit
.
thermal
.
px
>
px
)
px
=
pr
->
limit
.
thermal
.
px
;
{
struct
cpufreq_policy
policy
;
policy
.
cpu
=
pr
->
id
;
cpufreq_get_policy
(
&
policy
,
pr
->
id
);
policy
.
max
=
pr
->
performance
->
states
[
px
].
core_frequency
*
1000
;
/* racy */
result
=
cpufreq_set_policy
(
&
policy
);
}
if
(
result
)
goto
end
;
}
else
if
(
pr
->
performance_platform_limit
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Platform limit event detected. Consider using ACPI P-States CPUfreq driver
\n
"
));
}
#endif
if
(
pr
->
flags
.
throttling
)
{
if
(
pr
->
limit
.
user
.
tx
>
tx
)
tx
=
pr
->
limit
.
user
.
tx
;
...
...
@@ -1091,6 +1582,113 @@ acpi_processor_apply_limit (
}
#ifdef CONFIG_CPU_FREQ
/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
* offers (in most cases) voltage scaling in addition to frequency scaling, and
* thus a cubic (instead of linear) reduction of energy. Also, we allow for
* _any_ cpufreq driver and not only the acpi-cpufreq driver.
*/
static
unsigned
int
cpufreq_thermal_reduction_pctg
[
NR_CPUS
];
static
unsigned
int
acpi_thermal_cpufreq_is_init
=
0
;
static
int
cpu_has_cpufreq
(
unsigned
int
cpu
)
{
struct
cpufreq_policy
policy
;
if
(
!
acpi_thermal_cpufreq_is_init
)
return
-
ENODEV
;
if
(
!
cpufreq_get_policy
(
&
policy
,
cpu
))
return
-
ENODEV
;
return
0
;
}
static
int
acpi_thermal_cpufreq_increase
(
unsigned
int
cpu
)
{
if
(
!
cpu_has_cpufreq
)
return
-
ENODEV
;
if
(
cpufreq_thermal_reduction_pctg
[
cpu
]
<
60
)
{
cpufreq_thermal_reduction_pctg
[
cpu
]
+=
20
;
cpufreq_update_policy
(
cpu
);
return
0
;
}
return
-
ERANGE
;
}
static
int
acpi_thermal_cpufreq_decrease
(
unsigned
int
cpu
)
{
if
(
!
cpu_has_cpufreq
)
return
-
ENODEV
;
if
(
cpufreq_thermal_reduction_pctg
[
cpu
]
>=
20
)
{
cpufreq_thermal_reduction_pctg
[
cpu
]
-=
20
;
cpufreq_update_policy
(
cpu
);
return
0
;
}
return
-
ERANGE
;
}
static
int
acpi_thermal_cpufreq_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
data
)
{
struct
cpufreq_policy
*
policy
=
data
;
unsigned
long
max_freq
=
0
;
if
(
event
!=
CPUFREQ_ADJUST
)
goto
out
;
max_freq
=
(
policy
->
cpuinfo
.
max_freq
*
(
100
-
cpufreq_thermal_reduction_pctg
[
policy
->
cpu
]))
/
100
;
cpufreq_verify_within_limits
(
policy
,
0
,
max_freq
);
out:
return
0
;
}
static
struct
notifier_block
acpi_thermal_cpufreq_notifier_block
=
{
.
notifier_call
=
acpi_thermal_cpufreq_notifier
,
};
static
void
acpi_thermal_cpufreq_init
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
cpufreq_thermal_reduction_pctg
[
i
]
=
0
;
i
=
cpufreq_register_notifier
(
&
acpi_thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
if
(
!
i
)
acpi_thermal_cpufreq_is_init
=
1
;
}
static
void
acpi_thermal_cpufreq_exit
(
void
)
{
if
(
acpi_thermal_cpufreq_is_init
)
cpufreq_unregister_notifier
(
&
acpi_thermal_cpufreq_notifier_block
,
CPUFREQ_POLICY_NOTIFIER
);
acpi_thermal_cpufreq_is_init
=
0
;
}
#else
/* ! CONFIG_CPU_FREQ */
static
void
acpi_thermal_cpufreq_init
(
void
)
{
return
;
}
static
void
acpi_thermal_cpufreq_exit
(
void
)
{
return
;
}
static
int
acpi_thermal_cpufreq_increase
(
unsigned
int
cpu
)
{
return
-
ENODEV
;
}
static
int
acpi_thermal_cpufreq_decrease
(
unsigned
int
cpu
)
{
return
-
ENODEV
;
}
#endif
int
acpi_processor_set_thermal_limit
(
acpi_handle
handle
,
...
...
@@ -1099,7 +1697,6 @@ acpi_processor_set_thermal_limit (
int
result
=
0
;
struct
acpi_processor
*
pr
=
NULL
;
struct
acpi_device
*
device
=
NULL
;
int
px
=
0
;
int
tx
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_set_thermal_limit"
);
...
...
@@ -1116,12 +1713,7 @@ acpi_processor_set_thermal_limit (
if
(
!
pr
)
return_VALUE
(
-
ENODEV
);
if
(
!
pr
->
flags
.
limit
)
return_VALUE
(
-
ENODEV
);
/* Thermal limits are always relative to the current Px/Tx state. */
if
(
pr
->
flags
.
performance
)
pr
->
limit
.
thermal
.
px
=
pr
->
performance
->
state
;
if
(
pr
->
flags
.
throttling
)
pr
->
limit
.
thermal
.
tx
=
pr
->
throttling
.
state
;
...
...
@@ -1130,26 +1722,27 @@ acpi_processor_set_thermal_limit (
* performance state.
*/
px
=
pr
->
limit
.
thermal
.
px
;
tx
=
pr
->
limit
.
thermal
.
tx
;
switch
(
type
)
{
case
ACPI_PROCESSOR_LIMIT_NONE
:
px
=
0
;
do
{
result
=
acpi_thermal_cpufreq_decrease
(
pr
->
id
);
}
while
(
!
result
);
tx
=
0
;
break
;
case
ACPI_PROCESSOR_LIMIT_INCREMENT
:
if
(
pr
->
flags
.
performance
)
{
if
(
px
==
(
pr
->
performance
->
state_count
-
1
))
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
/* if going up: P-states first, T-states later */
result
=
acpi_thermal_cpufreq_increase
(
pr
->
id
);
if
(
!
result
)
goto
end
;
else
if
(
result
==
-
ERANGE
)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"At maximum performance state
\n
"
));
else
{
px
++
;
goto
end
;
}
}
if
(
pr
->
flags
.
throttling
)
{
if
(
tx
==
(
pr
->
throttling
.
state_count
-
1
))
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
...
...
@@ -1160,37 +1753,41 @@ acpi_processor_set_thermal_limit (
break
;
case
ACPI_PROCESSOR_LIMIT_DECREMENT
:
if
(
pr
->
flags
.
performance
)
{
if
(
px
==
pr
->
performance_platform_limit
)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"At minimum performance state
\n
"
));
else
{
px
--
;
goto
end
;
}
}
/* if going down: T-states first, P-states later */
if
(
pr
->
flags
.
throttling
)
{
if
(
tx
==
0
)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"At minimum throttling state
\n
"
));
else
else
{
tx
--
;
goto
end
;
}
}
result
=
acpi_thermal_cpufreq_decrease
(
pr
->
id
);
if
(
result
==
-
ERANGE
)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"At minimum performance state
\n
"
));
break
;
}
end:
pr
->
limit
.
thermal
.
px
=
px
;
pr
->
limit
.
thermal
.
tx
=
tx
;
if
(
pr
->
flags
.
throttling
)
{
pr
->
limit
.
thermal
.
px
=
0
;
pr
->
limit
.
thermal
.
tx
=
tx
;
result
=
acpi_processor_apply_limit
(
pr
);
if
(
result
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unable to set thermal limit
\n
"
));
result
=
acpi_processor_apply_limit
(
pr
);
if
(
result
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unable to set thermal limit
\n
"
));
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Thermal limit now (P%d:T%d)
\n
"
,
pr
->
limit
.
thermal
.
px
,
pr
->
limit
.
thermal
.
tx
));
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Thermal limit now (P%d:T%d)
\n
"
,
pr
->
limit
.
thermal
.
px
,
pr
->
limit
.
thermal
.
tx
));
}
else
result
=
0
;
return_VALUE
(
result
);
}
...
...
@@ -1205,7 +1802,7 @@ acpi_processor_get_limit_info (
if
(
!
pr
)
return_VALUE
(
-
EINVAL
);
if
(
pr
->
flags
.
performance
||
pr
->
flags
.
throttling
)
if
(
pr
->
flags
.
throttling
)
pr
->
flags
.
limit
=
1
;
return_VALUE
(
0
);
...
...
@@ -1232,14 +1829,12 @@ static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
"bus mastering control: %s
\n
"
"power management: %s
\n
"
"throttling control: %s
\n
"
"performance management: %s
\n
"
"limit interface: %s
\n
"
,
pr
->
id
,
pr
->
acpi_id
,
pr
->
flags
.
bm_control
?
"yes"
:
"no"
,
pr
->
flags
.
power
?
"yes"
:
"no"
,
pr
->
flags
.
throttling
?
"yes"
:
"no"
,
pr
->
flags
.
performance
?
"yes"
:
"no"
,
pr
->
flags
.
limit
?
"yes"
:
"no"
);
end:
...
...
@@ -1396,11 +1991,9 @@ static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
}
seq_printf
(
seq
,
"active limit: P%d:T%d
\n
"
"platform limit: P%d:T0
\n
"
"user limit: P%d:T%d
\n
"
"thermal limit: P%d:T%d
\n
"
,
pr
->
limit
.
state
.
px
,
pr
->
limit
.
state
.
tx
,
pr
->
flags
.
performance
?
pr
->
performance_platform_limit
:
0
,
pr
->
limit
.
user
.
px
,
pr
->
limit
.
user
.
tx
,
pr
->
limit
.
thermal
.
px
,
pr
->
limit
.
thermal
.
tx
);
...
...
@@ -1447,15 +2040,6 @@ acpi_processor_write_limit (
return_VALUE
(
-
EINVAL
);
}
if
(
pr
->
flags
.
performance
)
{
if
((
px
<
pr
->
performance_platform_limit
)
||
(
px
>
(
pr
->
performance
->
state_count
-
1
)))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid px
\n
"
));
return_VALUE
(
-
EINVAL
);
}
pr
->
limit
.
user
.
px
=
px
;
}
if
(
pr
->
flags
.
throttling
)
{
if
((
tx
<
0
)
||
(
tx
>
(
pr
->
throttling
.
state_count
-
1
)))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid tx
\n
"
));
...
...
@@ -1635,9 +2219,9 @@ acpi_processor_get_info (
}
acpi_processor_get_power_info
(
pr
);
pr
->
flags
.
performance
=
0
;
pr
->
performance_platform_limit
=
0
;
acpi_processor_get_platform_limit
(
pr
);
#ifdef CONFIG_CPU_FREQ
acpi_processor_ppc_has_changed
(
pr
)
;
#endif
acpi_processor_get_throttling_info
(
pr
);
acpi_processor_get_limit_info
(
pr
);
...
...
@@ -1651,7 +2235,6 @@ acpi_processor_notify (
u32
event
,
void
*
data
)
{
int
result
=
0
;
struct
acpi_processor
*
pr
=
(
struct
acpi_processor
*
)
data
;
struct
acpi_device
*
device
=
NULL
;
...
...
@@ -1665,9 +2248,7 @@ acpi_processor_notify (
switch
(
event
)
{
case
ACPI_PROCESSOR_NOTIFY_PERFORMANCE
:
result
=
acpi_processor_get_platform_limit
(
pr
);
if
(
!
result
)
acpi_processor_apply_limit
(
pr
);
acpi_processor_ppc_has_changed
(
pr
);
acpi_bus_generate_event
(
device
,
event
,
pr
->
performance_platform_limit
);
break
;
...
...
@@ -1813,6 +2394,10 @@ acpi_processor_init (void)
return_VALUE
(
-
ENODEV
);
}
acpi_thermal_cpufreq_init
();
acpi_processor_ppc_init
();
return_VALUE
(
0
);
}
...
...
@@ -1822,6 +2407,10 @@ acpi_processor_exit (void)
{
ACPI_FUNCTION_TRACE
(
"acpi_processor_exit"
);
acpi_processor_ppc_exit
();
acpi_thermal_cpufreq_exit
();
acpi_bus_unregister_driver
(
&
acpi_processor_driver
);
remove_proc_entry
(
ACPI_PROCESSOR_CLASS
,
acpi_root_dir
);
...
...
drivers/acpi/tables.c
View file @
fdfec545
...
...
@@ -302,13 +302,14 @@ acpi_table_parse_madt_family (
enum
acpi_table_id
id
,
unsigned
long
madt_size
,
int
entry_id
,
acpi_madt_entry_handler
handler
)
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
)
{
void
*
madt
=
NULL
;
acpi_table_entry_header
*
entry
=
NULL
;
unsigned
long
count
=
0
;
unsigned
long
madt_end
=
0
;
unsigned
int
i
=
0
;
acpi_table_entry_header
*
entry
;
unsigned
int
count
=
0
;
unsigned
long
madt_end
;
unsigned
int
i
;
if
(
!
handler
)
return
-
EINVAL
;
...
...
@@ -342,13 +343,18 @@ acpi_table_parse_madt_family (
((
unsigned
long
)
madt
+
madt_size
);
while
(((
unsigned
long
)
entry
)
<
madt_end
)
{
if
(
entry
->
type
==
entry_id
)
{
count
++
;
if
(
entry
->
type
==
entry_id
&&
(
!
max_entries
||
count
++
<
max_entries
))
handler
(
entry
);
}
entry
=
(
acpi_table_entry_header
*
)
((
unsigned
long
)
entry
+
entry
->
length
);
}
if
(
max_entries
&&
count
>
max_entries
)
{
printk
(
KERN_WARNING
PREFIX
"[%s:0x%02x] ignored %i entries of "
"%i found
\n
"
,
acpi_table_signatures
[
id
],
entry_id
,
count
-
max_entries
,
count
);
}
return
count
;
}
...
...
@@ -357,10 +363,11 @@ acpi_table_parse_madt_family (
int
__init
acpi_table_parse_madt
(
enum
acpi_madt_entry_id
id
,
acpi_madt_entry_handler
handler
)
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
)
{
return
acpi_table_parse_madt_family
(
ACPI_APIC
,
sizeof
(
struct
acpi_table_madt
),
id
,
handler
);
id
,
handler
,
max_entries
);
}
...
...
@@ -585,4 +592,3 @@ acpi_table_init (void)
return
0
;
}
drivers/acpi/toshiba_acpi.c
View file @
fdfec545
...
...
@@ -2,7 +2,7 @@
* toshiba_acpi.c - Toshiba Laptop ACPI Extras
*
*
* Copyright (C) 2002-200
3
John Belmonte
* Copyright (C) 2002-200
4
John Belmonte
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -33,7 +33,7 @@
*
*/
#define TOSHIBA_ACPI_VERSION "0.1
6
"
#define TOSHIBA_ACPI_VERSION "0.1
7
"
#define PROC_INTERFACE_VERSION 1
#include <linux/kernel.h>
...
...
@@ -48,9 +48,15 @@ MODULE_AUTHOR("John Belmonte");
MODULE_DESCRIPTION
(
"Toshiba Laptop ACPI Extras Driver"
);
MODULE_LICENSE
(
"GPL"
);
#define MY_LOGPREFIX "toshiba_acpi: "
#define MY_ERR KERN_ERR MY_LOGPREFIX
#define MY_NOTICE KERN_NOTICE MY_LOGPREFIX
#define MY_INFO KERN_INFO MY_LOGPREFIX
/* Toshiba ACPI method paths */
#define METHOD_LCD_BRIGHTNESS "\\_SB_.PCI0.VGA_.LCD_._BCM"
#define METHOD_HCI "\\_SB_.VALD.GHCI"
#define METHOD_HCI_1 "\\_SB_.VALD.GHCI"
#define METHOD_HCI_2 "\\_SB_.VALZ.GHCI"
#define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX"
/* Toshiba HCI interface definitions
...
...
@@ -120,6 +126,16 @@ snscanf(const char* str, int n, const char* format, ...)
/* acpi interface wrappers
*/
static
int
is_valid_acpi_path
(
const
char
*
methodName
)
{
acpi_handle
handle
;
acpi_status
status
;
status
=
acpi_get_handle
(
0
,
(
char
*
)
methodName
,
&
handle
);
return
!
ACPI_FAILURE
(
status
);
}
static
int
write_acpi_int
(
const
char
*
methodName
,
int
val
)
{
...
...
@@ -154,6 +170,8 @@ read_acpi_int(const char* methodName, int* pVal)
}
#endif
static
const
char
*
method_hci
/*= 0*/
;
/* Perform a raw HCI call. Here we don't care about input or output buffer
* format.
*/
...
...
@@ -177,7 +195,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
results
.
length
=
sizeof
(
out_objs
);
results
.
pointer
=
out_objs
;
status
=
acpi_evaluate_object
(
0
,
METHOD_HCI
,
&
params
,
status
=
acpi_evaluate_object
(
0
,
(
char
*
)
method_hci
,
&
params
,
&
results
);
if
((
status
==
AE_OK
)
&&
(
out_objs
->
package
.
count
<=
HCI_WORDS
))
{
for
(
i
=
0
;
i
<
out_objs
->
package
.
count
;
++
i
)
{
...
...
@@ -215,7 +233,7 @@ hci_read1(u32 reg, u32* out1, u32* result)
return
status
;
}
static
struct
proc_dir_entry
*
toshiba_proc_dir
;
static
struct
proc_dir_entry
*
toshiba_proc_dir
/*= 0*/
;
static
int
force_fan
;
static
int
last_key_event
;
static
int
key_event_valid
;
...
...
@@ -270,7 +288,7 @@ read_lcd(char* p)
p
+=
sprintf
(
p
,
"brightness_levels: %d
\n
"
,
HCI_LCD_BRIGHTNESS_LEVELS
);
}
else
{
p
+=
sprintf
(
p
,
"ERROR
\n
"
);
p
rintk
(
MY_ERR
"Error reading LCD brightness
\n
"
);
}
return
p
;
...
...
@@ -310,7 +328,7 @@ read_video(char* p)
p
+=
sprintf
(
p
,
"crt_out: %d
\n
"
,
is_crt
);
p
+=
sprintf
(
p
,
"tv_out: %d
\n
"
,
is_tv
);
}
else
{
p
+=
sprintf
(
p
,
"ERROR
\n
"
);
p
rintk
(
MY_ERR
"Error reading video out status
\n
"
);
}
return
p
;
...
...
@@ -320,25 +338,31 @@ static unsigned long
write_video
(
const
char
*
buffer
,
unsigned
long
count
)
{
int
value
;
const
char
*
buffer_end
=
buffer
+
count
;
int
remain
=
count
;
int
lcd_out
=
-
1
;
int
crt_out
=
-
1
;
int
tv_out
=
-
1
;
u32
hci_result
;
int
video_out
;
/* scan expression. Multiple expressions may be delimited with ; */
do
{
if
(
snscanf
(
buffer
,
count
,
" lcd_out : %i"
,
&
value
)
==
1
)
/* scan expression. Multiple expressions may be delimited with ;
*
* NOTE: to keep scanning simple, invalid fields are ignored
*/
while
(
remain
)
{
if
(
snscanf
(
buffer
,
remain
,
" lcd_out : %i"
,
&
value
)
==
1
)
lcd_out
=
value
&
1
;
else
if
(
snscanf
(
buffer
,
count
,
" crt_out : %i"
,
&
value
)
==
1
)
else
if
(
snscanf
(
buffer
,
remain
,
" crt_out : %i"
,
&
value
)
==
1
)
crt_out
=
value
&
1
;
else
if
(
snscanf
(
buffer
,
count
,
" tv_out : %i"
,
&
value
)
==
1
)
else
if
(
snscanf
(
buffer
,
remain
,
" tv_out : %i"
,
&
value
)
==
1
)
tv_out
=
value
&
1
;
/* advance to one character past the next ; */
do
++
buffer
;
while
((
buffer
<
buffer_end
)
&&
(
*
(
buffer
-
1
)
!=
';'
));
}
while
(
buffer
<
buffer_end
);
do
{
++
buffer
;
--
remain
;
}
while
(
remain
&&
*
(
buffer
-
1
)
!=
';'
);
}
hci_read1
(
HCI_VIDEO_OUT
,
&
video_out
,
&
hci_result
);
if
(
hci_result
==
HCI_SUCCESS
)
{
...
...
@@ -353,6 +377,8 @@ write_video(const char* buffer, unsigned long count)
* video setting if something changed. */
if
(
new_video_out
!=
video_out
)
write_acpi_int
(
METHOD_VIDEO_OUT
,
new_video_out
);
}
else
{
return
-
EFAULT
;
}
return
count
;
...
...
@@ -369,7 +395,7 @@ read_fan(char* p)
p
+=
sprintf
(
p
,
"running: %d
\n
"
,
(
value
>
0
));
p
+=
sprintf
(
p
,
"force_on: %d
\n
"
,
force_fan
);
}
else
{
p
+=
sprintf
(
p
,
"ERROR
\n
"
);
p
rintk
(
MY_ERR
"Error reading fan status
\n
"
);
}
return
p
;
...
...
@@ -413,8 +439,9 @@ read_keys(char* p)
* some machines where system events sporadically
* become disabled. */
hci_write1
(
HCI_SYSTEM_EVENT
,
1
,
&
hci_result
);
printk
(
MY_NOTICE
"Re-enabled hotkeys
\n
"
);
}
else
{
p
+=
sprintf
(
p
,
"ERROR
\n
"
);
p
rintk
(
MY_ERR
"Error reading hotkey status
\n
"
);
goto
end
;
}
}
...
...
@@ -465,7 +492,7 @@ ProcItem proc_items[] =
{
0
,
0
,
0
},
};
static
acpi_status
static
acpi_status
__init
add_device
(
void
)
{
struct
proc_dir_entry
*
proc
;
...
...
@@ -483,7 +510,7 @@ add_device(void)
return
(
AE_OK
);
}
static
acpi_status
static
acpi_status
__exit
remove_device
(
void
)
{
ProcItem
*
item
;
...
...
@@ -497,15 +524,19 @@ static int __init
toshiba_acpi_init
(
void
)
{
acpi_status
status
=
AE_OK
;
int
value
;
u32
hci_result
;
/* simple device detection: try reading an HCI register */
hci_read1
(
HCI_LCD_BRIGHTNESS
,
&
value
,
&
hci_result
);
if
(
hci_result
!=
HCI_SUCCESS
)
/* simple device detection: look for HCI method */
if
(
is_valid_acpi_path
(
METHOD_HCI_1
))
method_hci
=
METHOD_HCI_1
;
else
if
(
is_valid_acpi_path
(
METHOD_HCI_2
))
method_hci
=
METHOD_HCI_2
;
else
return
-
ENODEV
;
printk
(
"Toshiba Laptop ACPI Extras version %s
\n
"
,
TOSHIBA_ACPI_VERSION
);
printk
(
MY_INFO
"Toshiba Laptop ACPI Extras version %s
\n
"
,
TOSHIBA_ACPI_VERSION
);
printk
(
MY_INFO
" HCI method: %s
\n
"
,
method_hci
);
force_fan
=
0
;
key_event_valid
=
0
;
...
...
include/acpi/processor.h
View file @
fdfec545
...
...
@@ -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
{
...
...
@@ -133,11 +133,11 @@ struct acpi_processor {
struct
acpi_processor_limit
limit
;
};
extern
int
acpi_processor_get_platform_limit
(
struct
acpi_processor
*
pr
);
extern
int
acpi_processor_register_performance
(
struct
acpi_processor_performance
*
performance
,
struct
acpi_processor
**
pr
,
unsigned
int
cpu
);
extern
void
acpi_processor_unregister_performance
(
struct
acpi_processor_performance
*
performance
,
unsigned
int
cpu
);
#endif
include/asm-ia64/iosapic.h
View file @
fdfec545
...
...
@@ -52,6 +52,9 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_IOSAPIC
#define NR_IOSAPICS 256
extern
void
__init
iosapic_system_init
(
int
pcat_compat
);
extern
void
__init
iosapic_init
(
unsigned
long
address
,
unsigned
int
gsi_base
);
...
...
include/linux/acpi.h
View file @
fdfec545
...
...
@@ -355,8 +355,8 @@ int acpi_numa_init (void);
int
acpi_table_init
(
void
);
int
acpi_table_parse
(
enum
acpi_table_id
id
,
acpi_table_handler
handler
);
int
acpi_get_table_header_early
(
enum
acpi_table_id
id
,
struct
acpi_table_header
**
header
);
int
acpi_table_parse_madt
(
enum
acpi_madt_entry_id
id
,
acpi_madt_entry_handler
handler
);
int
acpi_table_parse_srat
(
enum
acpi_srat_entry_id
id
,
acpi_madt_entry_handler
handler
);
int
acpi_table_parse_madt
(
enum
acpi_madt_entry_id
id
,
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
);
int
acpi_table_parse_srat
(
enum
acpi_srat_entry_id
id
,
acpi_madt_entry_handler
handler
,
unsigned
int
max_entries
);
void
acpi_table_print
(
struct
acpi_table_header
*
header
,
unsigned
long
phys_addr
);
void
acpi_table_print_madt_entry
(
acpi_table_entry_header
*
madt
);
void
acpi_table_print_srat_entry
(
acpi_table_entry_header
*
srat
);
...
...
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