Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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