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
d7374b3f
Commit
d7374b3f
authored
Jun 19, 2003
by
Andy Grover
Browse files
Options
Browse Files
Download
Plain Diff
Merge groveronline.com:/root/bk/linux-2.5
into groveronline.com:/root/bk/linux-acpi
parents
189ea5d0
42af0cb8
Changes
30
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
1997 additions
and
172 deletions
+1997
-172
arch/i386/kernel/acpi/Makefile
arch/i386/kernel/acpi/Makefile
+1
-0
arch/i386/kernel/acpi/acpitable.c
arch/i386/kernel/acpi/acpitable.c
+553
-0
arch/i386/kernel/acpi/acpitable.h
arch/i386/kernel/acpi/acpitable.h
+260
-0
arch/i386/kernel/setup.c
arch/i386/kernel/setup.c
+10
-1
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+28
-3
drivers/acpi/Makefile
drivers/acpi/Makefile
+1
-0
drivers/acpi/asus_acpi.c
drivers/acpi/asus_acpi.c
+951
-0
drivers/acpi/dispatcher/dsmthdat.c
drivers/acpi/dispatcher/dsmthdat.c
+6
-19
drivers/acpi/events/evgpe.c
drivers/acpi/events/evgpe.c
+5
-3
drivers/acpi/events/evgpeblk.c
drivers/acpi/events/evgpeblk.c
+17
-12
drivers/acpi/executer/exoparg1.c
drivers/acpi/executer/exoparg1.c
+43
-34
drivers/acpi/executer/exstore.c
drivers/acpi/executer/exstore.c
+2
-2
drivers/acpi/executer/exsystem.c
drivers/acpi/executer/exsystem.c
+2
-2
drivers/acpi/executer/exutils.c
drivers/acpi/executer/exutils.c
+4
-1
drivers/acpi/hardware/hwregs.c
drivers/acpi/hardware/hwregs.c
+32
-15
drivers/acpi/hardware/hwsleep.c
drivers/acpi/hardware/hwsleep.c
+2
-2
drivers/acpi/tables/tbconvrt.c
drivers/acpi/tables/tbconvrt.c
+17
-9
drivers/acpi/utilities/utmisc.c
drivers/acpi/utilities/utmisc.c
+2
-0
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp.h
+6
-10
drivers/pci/hotplug/acpiphp_core.c
drivers/pci/hotplug/acpiphp_core.c
+6
-9
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/acpiphp_glue.c
+24
-26
drivers/pci/hotplug/acpiphp_pci.c
drivers/pci/hotplug/acpiphp_pci.c
+2
-2
drivers/pci/hotplug/acpiphp_res.c
drivers/pci/hotplug/acpiphp_res.c
+2
-2
include/acpi/acconfig.h
include/acpi/acconfig.h
+1
-1
include/acpi/acglobal.h
include/acpi/acglobal.h
+1
-0
include/acpi/achware.h
include/acpi/achware.h
+1
-1
include/acpi/acpiosxf.h
include/acpi/acpiosxf.h
+4
-4
include/acpi/actypes.h
include/acpi/actypes.h
+7
-12
include/asm-i386/acpi.h
include/asm-i386/acpi.h
+5
-0
include/linux/acpi.h
include/linux/acpi.h
+2
-2
No files found.
arch/i386/kernel/acpi/Makefile
View file @
d7374b3f
obj-$(CONFIG_ACPI_HT_ONLY)
:=
acpitable.o
obj-$(CONFIG_ACPI_BOOT)
:=
boot.o
obj-$(CONFIG_ACPI_SLEEP)
+=
sleep.o wakeup.o
arch/i386/kernel/acpi/acpitable.c
0 → 100644
View file @
d7374b3f
/*
* acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
*
* Copyright (C) 1999 Andrew Henroid
* Copyright (C) 2001 Richard Schaal
* Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
* Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* $Id: acpitable.c,v 1.7 2001/11/04 12:21:18 fenrus Exp $
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <asm/mpspec.h>
#include <asm/io.h>
#include <asm/apic.h>
#include <asm/apicdef.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include "acpitable.h"
static
acpi_table_handler
acpi_boot_ops
[
ACPI_TABLE_COUNT
];
int
acpi_lapic
;
static
unsigned
char
__init
acpi_checksum
(
void
*
buffer
,
int
length
)
{
int
i
;
unsigned
char
*
bytebuffer
;
unsigned
char
sum
=
0
;
if
(
!
buffer
||
length
<=
0
)
return
0
;
bytebuffer
=
(
unsigned
char
*
)
buffer
;
for
(
i
=
0
;
i
<
length
;
i
++
)
sum
+=
*
(
bytebuffer
++
);
return
sum
;
}
static
void
__init
acpi_print_table_header
(
acpi_table_header
*
header
)
{
if
(
!
header
)
return
;
printk
(
KERN_INFO
"ACPI table found: %.4s v%d [%.6s %.8s %d.%d]
\n
"
,
header
->
signature
,
header
->
revision
,
header
->
oem_id
,
header
->
oem_table_id
,
header
->
oem_revision
>>
16
,
header
->
oem_revision
&
0xffff
);
return
;
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_scan_memory_for_rsdp
*
* PARAMETERS: address - Starting pointer for search
* length - Maximum length to search
*
* RETURN: Pointer to the RSDP if found and valid, otherwise NULL.
*
* DESCRIPTION: Search a block of memory for the RSDP signature
*
******************************************************************************/
static
void
*
__init
acpi_tb_scan_memory_for_rsdp
(
void
*
address
,
int
length
)
{
u32
offset
;
if
(
length
<=
0
)
return
NULL
;
/* Search from given start addr for the requested length */
offset
=
0
;
while
(
offset
<
length
)
{
/* The signature must match and the checksum must be correct */
if
(
strncmp
(
address
,
RSDP_SIG
,
sizeof
(
RSDP_SIG
)
-
1
)
==
0
&&
acpi_checksum
(
address
,
RSDP_CHECKSUM_LENGTH
)
==
0
)
{
/* If so, we have found the RSDP */
printk
(
KERN_INFO
"ACPI: RSDP located at physical address %p
\n
"
,
address
);
return
address
;
}
offset
+=
RSDP_SCAN_STEP
;
address
+=
RSDP_SCAN_STEP
;
}
/* Searched entire block, no RSDP was found */
printk
(
KERN_INFO
"ACPI: Searched entire block, no RSDP was found.
\n
"
);
return
NULL
;
}
/*******************************************************************************
*
* FUNCTION: acpi_find_root_pointer
*
* PARAMETERS: none
*
* RETURN: physical address of the RSDP
*
* DESCRIPTION: Search lower 1_mbyte of memory for the root system descriptor
* pointer structure. If it is found, set *RSDP to point to it.
*
* NOTE: The RSDP must be either in the first 1_k of the Extended
* BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
* 5.2.2; assertion #421).
*
******************************************************************************/
static
struct
acpi_table_rsdp
*
__init
acpi_find_root_pointer
(
void
)
{
struct
acpi_table_rsdp
*
rsdp
;
/*
* Physical address is given
*/
/*
* Region 1) Search EBDA (low memory) paragraphs
*/
rsdp
=
acpi_tb_scan_memory_for_rsdp
(
__va
(
LO_RSDP_WINDOW_BASE
),
LO_RSDP_WINDOW_SIZE
);
if
(
rsdp
)
return
rsdp
;
/*
* Region 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
*/
rsdp
=
acpi_tb_scan_memory_for_rsdp
(
__va
(
HI_RSDP_WINDOW_BASE
),
HI_RSDP_WINDOW_SIZE
);
if
(
rsdp
)
return
rsdp
;
printk
(
KERN_ERR
"ACPI: System description tables not found
\n
"
);
return
NULL
;
}
/*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
* provides a single page, and it is possible that the page is not
* sufficient.
* By using this area, we can map up to MAX_IO_APICS pages temporarily,
* i.e. until the next __va_range() call.
*
* Important Safety Note: The fixed I/O APIC page numbers are *subtracted*
* from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and
* count idx down while incrementing the phys address.
*/
static
__init
char
*
__va_range
(
unsigned
long
phys
,
unsigned
long
size
)
{
unsigned
long
base
,
offset
,
mapped_size
;
int
idx
;
offset
=
phys
&
(
PAGE_SIZE
-
1
);
mapped_size
=
PAGE_SIZE
-
offset
;
set_fixmap
(
FIX_IO_APIC_BASE_END
,
phys
);
base
=
fix_to_virt
(
FIX_IO_APIC_BASE_END
);
dprintk
(
"__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx
\n
"
,
phys
,
size
,
FIX_IO_APIC_BASE_END
,
base
);
/*
* Most cases can be covered by the below.
*/
idx
=
FIX_IO_APIC_BASE_END
;
while
(
mapped_size
<
size
)
{
if
(
--
idx
<
FIX_IO_APIC_BASE_0
)
return
0
;
/* cannot handle this */
phys
+=
PAGE_SIZE
;
set_fixmap
(
idx
,
phys
);
mapped_size
+=
PAGE_SIZE
;
}
return
((
unsigned
char
*
)
base
+
offset
);
}
static
int
__init
acpi_tables_init
(
void
)
{
int
result
=
-
ENODEV
;
acpi_table_header
*
header
=
NULL
;
struct
acpi_table_rsdp
*
rsdp
=
NULL
;
struct
acpi_table_rsdt
*
rsdt
=
NULL
;
struct
acpi_table_rsdt
saved_rsdt
;
int
tables
=
0
;
int
type
=
0
;
int
i
=
0
;
rsdp
=
(
struct
acpi_table_rsdp
*
)
acpi_find_root_pointer
();
if
(
!
rsdp
)
return
-
ENODEV
;
printk
(
KERN_INFO
"%.8s v%d [%.6s]
\n
"
,
rsdp
->
signature
,
rsdp
->
revision
,
rsdp
->
oem_id
);
if
(
strncmp
(
rsdp
->
signature
,
RSDP_SIG
,
strlen
(
RSDP_SIG
)))
{
printk
(
KERN_WARNING
"RSDP table signature incorrect
\n
"
);
return
-
EINVAL
;
}
rsdt
=
(
struct
acpi_table_rsdt
*
)
__va_range
(
rsdp
->
rsdt_address
,
sizeof
(
struct
acpi_table_rsdt
));
if
(
!
rsdt
)
{
printk
(
KERN_WARNING
"ACPI: Invalid root system description tables (RSDT)
\n
"
);
return
-
ENODEV
;
}
header
=
&
rsdt
->
header
;
acpi_print_table_header
(
header
);
if
(
strncmp
(
header
->
signature
,
RSDT_SIG
,
strlen
(
RSDT_SIG
)))
{
printk
(
KERN_WARNING
"ACPI: RSDT signature incorrect
\n
"
);
return
-
ENODEV
;
}
/*
* The number of tables is computed by taking the
* size of all entries (header size minus total
* size of RSDT) divided by the size of each entry
* (4-byte table pointers).
*/
tables
=
(
header
->
length
-
sizeof
(
acpi_table_header
))
/
4
;
memcpy
(
&
saved_rsdt
,
rsdt
,
sizeof
(
saved_rsdt
));
if
(
saved_rsdt
.
header
.
length
>
sizeof
(
saved_rsdt
))
{
printk
(
KERN_WARNING
"ACPI: Too big length in RSDT: %d
\n
"
,
saved_rsdt
.
header
.
length
);
return
-
ENODEV
;
}
for
(
i
=
0
;
i
<
tables
;
i
++
)
{
/* Map in header, then map in full table length. */
header
=
(
acpi_table_header
*
)
__va_range
(
saved_rsdt
.
entry
[
i
],
sizeof
(
acpi_table_header
));
if
(
!
header
)
break
;
header
=
(
acpi_table_header
*
)
__va_range
(
saved_rsdt
.
entry
[
i
],
header
->
length
);
if
(
!
header
)
break
;
acpi_print_table_header
(
header
);
if
(
acpi_checksum
(
header
,
header
->
length
))
{
printk
(
KERN_WARNING
"ACPI %s has invalid checksum
\n
"
,
acpi_table_signatures
[
i
]);
continue
;
}
for
(
type
=
0
;
type
<
ACPI_TABLE_COUNT
;
type
++
)
if
(
!
strncmp
((
char
*
)
&
header
->
signature
,
acpi_table_signatures
[
type
],
strlen
(
acpi_table_signatures
[
type
])))
break
;
if
(
type
>=
ACPI_TABLE_COUNT
)
{
printk
(
KERN_WARNING
"ACPI: Unsupported table %.4s
\n
"
,
header
->
signature
);
continue
;
}
if
(
!
acpi_boot_ops
[
type
])
continue
;
result
=
acpi_boot_ops
[
type
]
(
header
,
(
unsigned
long
)
saved_rsdt
.
entry
[
i
]);
}
return
result
;
}
static
int
total_cpus
__initdata
=
0
;
int
have_acpi_tables
;
extern
void
__init
MP_processor_info
(
struct
mpc_config_processor
*
);
static
void
__init
acpi_parse_lapic
(
struct
acpi_table_lapic
*
local_apic
)
{
struct
mpc_config_processor
proc_entry
;
int
ix
=
0
;
if
(
!
local_apic
)
return
;
printk
(
KERN_INFO
"LAPIC (acpi_id[0x%04x] id[0x%x] enabled[%d])
\n
"
,
local_apic
->
acpi_id
,
local_apic
->
id
,
local_apic
->
flags
.
enabled
);
printk
(
KERN_INFO
"CPU %d (0x%02x00)"
,
total_cpus
,
local_apic
->
id
);
if
(
local_apic
->
flags
.
enabled
)
{
printk
(
" enabled"
);
ix
=
local_apic
->
id
;
if
(
ix
>=
MAX_APICS
)
{
printk
(
KERN_WARNING
"Processor #%d INVALID - (Max ID: %d).
\n
"
,
ix
,
MAX_APICS
);
return
;
}
/*
* Fill in the info we want to save. Not concerned about
* the processor ID. Processor features aren't present in
* the table.
*/
proc_entry
.
mpc_type
=
MP_PROCESSOR
;
proc_entry
.
mpc_apicid
=
local_apic
->
id
;
proc_entry
.
mpc_cpuflag
=
CPU_ENABLED
;
if
(
proc_entry
.
mpc_apicid
==
boot_cpu_physical_apicid
)
{
printk
(
" (BSP)"
);
proc_entry
.
mpc_cpuflag
|=
CPU_BOOTPROCESSOR
;
}
proc_entry
.
mpc_cpufeature
=
(
boot_cpu_data
.
x86
<<
8
)
|
(
boot_cpu_data
.
x86_model
<<
4
)
|
boot_cpu_data
.
x86_mask
;
proc_entry
.
mpc_featureflag
=
boot_cpu_data
.
x86_capability
[
0
];
proc_entry
.
mpc_reserved
[
0
]
=
0
;
proc_entry
.
mpc_reserved
[
1
]
=
0
;
proc_entry
.
mpc_apicver
=
0x10
;
/* integrated APIC */
MP_processor_info
(
&
proc_entry
);
}
else
{
printk
(
" disabled"
);
}
printk
(
"
\n
"
);
total_cpus
++
;
return
;
}
static
void
__init
acpi_parse_ioapic
(
struct
acpi_table_ioapic
*
ioapic
)
{
if
(
!
ioapic
)
return
;
printk
(
KERN_INFO
"IOAPIC (id[0x%x] address[0x%x] global_irq_base[0x%x])
\n
"
,
ioapic
->
id
,
ioapic
->
address
,
ioapic
->
global_irq_base
);
if
(
nr_ioapics
>=
MAX_IO_APICS
)
{
printk
(
KERN_WARNING
"Max # of I/O APICs (%d) exceeded (found %d).
\n
"
,
MAX_IO_APICS
,
nr_ioapics
);
/* panic("Recompile kernel with bigger MAX_IO_APICS!\n"); */
}
}
/* Interrupt source overrides inform the machine about exceptions
to the normal "PIC" mode interrupt routing */
static
void
__init
acpi_parse_int_src_ovr
(
struct
acpi_table_int_src_ovr
*
intsrc
)
{
if
(
!
intsrc
)
return
;
printk
(
KERN_INFO
"INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])
\n
"
,
intsrc
->
bus
,
intsrc
->
bus_irq
,
intsrc
->
global_irq
,
intsrc
->
flags
.
polarity
,
intsrc
->
flags
.
trigger
);
}
/*
* At this point, we look at the interrupt assignment entries in the MPS
* table.
*/
static
void
__init
acpi_parse_nmi_src
(
struct
acpi_table_nmi_src
*
nmisrc
)
{
if
(
!
nmisrc
)
return
;
printk
(
KERN_INFO
"NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])
\n
"
,
nmisrc
->
flags
.
polarity
,
nmisrc
->
flags
.
trigger
,
nmisrc
->
global_irq
);
}
static
void
__init
acpi_parse_lapic_nmi
(
struct
acpi_table_lapic_nmi
*
localnmi
)
{
if
(
!
localnmi
)
return
;
printk
(
KERN_INFO
"LAPIC_NMI (acpi_id[0x%04x] polarity[0x%x] trigger[0x%x] lint[0x%x])
\n
"
,
localnmi
->
acpi_id
,
localnmi
->
flags
.
polarity
,
localnmi
->
flags
.
trigger
,
localnmi
->
lint
);
}
static
void
__init
acpi_parse_lapic_addr_ovr
(
struct
acpi_table_lapic_addr_ovr
*
lapic_addr_ovr
)
{
if
(
!
lapic_addr_ovr
)
return
;
printk
(
KERN_INFO
"LAPIC_ADDR_OVR (address[0x%lx])
\n
"
,
(
unsigned
long
)
lapic_addr_ovr
->
address
);
}
static
void
__init
acpi_parse_plat_int_src
(
struct
acpi_table_plat_int_src
*
plintsrc
)
{
if
(
!
plintsrc
)
return
;
printk
(
KERN_INFO
"PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]
\n
"
,
plintsrc
->
flags
.
polarity
,
plintsrc
->
flags
.
trigger
,
plintsrc
->
type
,
plintsrc
->
id
,
plintsrc
->
eid
,
plintsrc
->
iosapic_vector
,
plintsrc
->
global_irq
);
}
static
int
__init
acpi_parse_madt
(
acpi_table_header
*
header
,
unsigned
long
phys
)
{
struct
acpi_table_madt
*
madt
;
acpi_madt_entry_header
*
entry_header
;
int
table_size
;
madt
=
(
struct
acpi_table_madt
*
)
__va_range
(
phys
,
header
->
length
);
if
(
!
madt
)
return
-
EINVAL
;
table_size
=
(
int
)
(
header
->
length
-
sizeof
(
*
madt
));
entry_header
=
(
acpi_madt_entry_header
*
)
((
void
*
)
madt
+
sizeof
(
*
madt
));
while
(
entry_header
&&
(
table_size
>
0
))
{
switch
(
entry_header
->
type
)
{
case
ACPI_MADT_LAPIC
:
acpi_parse_lapic
((
struct
acpi_table_lapic
*
)
entry_header
);
break
;
case
ACPI_MADT_IOAPIC
:
acpi_parse_ioapic
((
struct
acpi_table_ioapic
*
)
entry_header
);
break
;
case
ACPI_MADT_INT_SRC_OVR
:
acpi_parse_int_src_ovr
((
struct
acpi_table_int_src_ovr
*
)
entry_header
);
break
;
case
ACPI_MADT_NMI_SRC
:
acpi_parse_nmi_src
((
struct
acpi_table_nmi_src
*
)
entry_header
);
break
;
case
ACPI_MADT_LAPIC_NMI
:
acpi_parse_lapic_nmi
((
struct
acpi_table_lapic_nmi
*
)
entry_header
);
break
;
case
ACPI_MADT_LAPIC_ADDR_OVR
:
acpi_parse_lapic_addr_ovr
((
struct
acpi_table_lapic_addr_ovr
*
)
entry_header
);
break
;
case
ACPI_MADT_PLAT_INT_SRC
:
acpi_parse_plat_int_src
((
struct
acpi_table_plat_int_src
*
)
entry_header
);
break
;
default:
printk
(
KERN_WARNING
"Unsupported MADT entry type 0x%x
\n
"
,
entry_header
->
type
);
break
;
}
table_size
-=
entry_header
->
length
;
entry_header
=
(
acpi_madt_entry_header
*
)
((
void
*
)
entry_header
+
entry_header
->
length
);
}
if
(
!
total_cpus
)
{
printk
(
"ACPI: No Processors found in the APCI table.
\n
"
);
return
-
EINVAL
;
}
printk
(
KERN_INFO
"%d CPUs total
\n
"
,
total_cpus
);
if
(
madt
->
lapic_address
)
mp_lapic_addr
=
madt
->
lapic_address
;
else
mp_lapic_addr
=
APIC_DEFAULT_PHYS_BASE
;
printk
(
KERN_INFO
"Local APIC address %x
\n
"
,
madt
->
lapic_address
);
return
0
;
}
/*
* Configure the processor info using MADT in the ACPI tables. If we fail to
* configure that, then we use the MPS tables.
*/
void
__init
acpi_boot_init
(
void
)
{
memset
(
&
acpi_boot_ops
,
0
,
sizeof
(
acpi_boot_ops
));
acpi_boot_ops
[
ACPI_APIC
]
=
acpi_parse_madt
;
/*
* Only do this when requested, either because of CPU/Bios type or from the command line
*/
if
(
!
acpi_tables_init
())
acpi_lapic
=
1
;
}
arch/i386/kernel/acpi/acpitable.h
0 → 100644
View file @
d7374b3f
/*
* acpitable.c - IA32-specific ACPI boot-time initialization (Revision: 1)
*
* Copyright (C) 1999 Andrew Henroid
* Copyright (C) 2001 Richard Schaal
* Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
* Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
* Copyright (C) 2001 Arjan van de Ven <arjanv@redhat.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* $Id: acpitable.h,v 1.3 2001/11/03 22:41:34 fenrus Exp $
*/
/*
* The following codes are cut&pasted from drivers/acpi. Part of the code
* there can be not updated or delivered yet.
* To avoid conflicts when CONFIG_ACPI is defined, the following codes are
* modified so that they are self-contained in this file.
* -- jun
*/
#ifndef _HEADER_ACPITABLE_H_
#define _HEADER_ACPITABLE_H_
#define dprintk printk
typedef
unsigned
int
ACPI_TBLPTR
;
typedef
struct
{
/* ACPI common table header */
char
signature
[
4
];
/* identifies type of table */
u32
length
;
/* length of table,
in bytes, * including header */
u8
revision
;
/* specification minor version # */
u8
checksum
;
/* to make sum of entire table == 0 */
char
oem_id
[
6
];
/* OEM identification */
char
oem_table_id
[
8
];
/* OEM table identification */
u32
oem_revision
;
/* OEM revision number */
char
asl_compiler_id
[
4
];
/* ASL compiler vendor ID */
u32
asl_compiler_revision
;
/* ASL compiler revision number */
}
acpi_table_header
__attribute__
((
packed
));;
enum
{
ACPI_APIC
=
0
,
ACPI_BOOT
,
ACPI_DBGP
,
ACPI_DSDT
,
ACPI_ECDT
,
ACPI_ETDT
,
ACPI_FACP
,
ACPI_FACS
,
ACPI_OEMX
,
ACPI_PSDT
,
ACPI_SBST
,
ACPI_SLIT
,
ACPI_SPCR
,
ACPI_SRAT
,
ACPI_SSDT
,
ACPI_SPMI
,
ACPI_XSDT
,
ACPI_TABLE_COUNT
};
static
char
*
acpi_table_signatures
[
ACPI_TABLE_COUNT
]
=
{
"APIC"
,
"BOOT"
,
"DBGP"
,
"DSDT"
,
"ECDT"
,
"ETDT"
,
"FACP"
,
"FACS"
,
"OEM"
,
"PSDT"
,
"SBST"
,
"SLIT"
,
"SPCR"
,
"SRAT"
,
"SSDT"
,
"SPMI"
,
"XSDT"
};
struct
acpi_table_madt
{
acpi_table_header
header
;
u32
lapic_address
;
struct
{
u32
pcat_compat
:
1
;
u32
reserved
:
31
;
}
flags
__attribute__
((
packed
));
}
__attribute__
((
packed
));;
enum
{
ACPI_MADT_LAPIC
=
0
,
ACPI_MADT_IOAPIC
,
ACPI_MADT_INT_SRC_OVR
,
ACPI_MADT_NMI_SRC
,
ACPI_MADT_LAPIC_NMI
,
ACPI_MADT_LAPIC_ADDR_OVR
,
ACPI_MADT_IOSAPIC
,
ACPI_MADT_LSAPIC
,
ACPI_MADT_PLAT_INT_SRC
,
ACPI_MADT_ENTRY_COUNT
};
#define RSDP_SIG "RSD PTR "
#define RSDT_SIG "RSDT"
#define ACPI_DEBUG_PRINT(pl)
#define ACPI_MEMORY_MODE 0x01
#define ACPI_LOGICAL_ADDRESSING 0x00
#define ACPI_PHYSICAL_ADDRESSING 0x01
#define LO_RSDP_WINDOW_BASE 0
/* Physical Address */
#define HI_RSDP_WINDOW_BASE 0xE0000
/* Physical Address */
#define LO_RSDP_WINDOW_SIZE 0x400
#define HI_RSDP_WINDOW_SIZE 0x20000
#define RSDP_SCAN_STEP 16
#define RSDP_CHECKSUM_LENGTH 20
typedef
int
(
*
acpi_table_handler
)
(
acpi_table_header
*
header
,
unsigned
long
);
struct
acpi_table_rsdp
{
char
signature
[
8
];
u8
checksum
;
char
oem_id
[
6
];
u8
revision
;
u32
rsdt_address
;
}
__attribute__
((
packed
));
struct
acpi_table_rsdt
{
acpi_table_header
header
;
u32
entry
[
ACPI_TABLE_COUNT
];
}
__attribute__
((
packed
));
typedef
struct
{
u8
type
;
u8
length
;
}
acpi_madt_entry_header
__attribute__
((
packed
));
typedef
struct
{
u16
polarity
:
2
;
u16
trigger
:
2
;
u16
reserved
:
12
;
}
acpi_madt_int_flags
__attribute__
((
packed
));
struct
acpi_table_lapic
{
acpi_madt_entry_header
header
;
u8
acpi_id
;
u8
id
;
struct
{
u32
enabled
:
1
;
u32
reserved
:
31
;
}
flags
__attribute__
((
packed
));
}
__attribute__
((
packed
));
struct
acpi_table_ioapic
{
acpi_madt_entry_header
header
;
u8
id
;
u8
reserved
;
u32
address
;
u32
global_irq_base
;
}
__attribute__
((
packed
));
struct
acpi_table_int_src_ovr
{
acpi_madt_entry_header
header
;
u8
bus
;
u8
bus_irq
;
u32
global_irq
;
acpi_madt_int_flags
flags
;
}
__attribute__
((
packed
));
struct
acpi_table_nmi_src
{
acpi_madt_entry_header
header
;
acpi_madt_int_flags
flags
;
u32
global_irq
;
}
__attribute__
((
packed
));
struct
acpi_table_lapic_nmi
{
acpi_madt_entry_header
header
;
u8
acpi_id
;
acpi_madt_int_flags
flags
;
u8
lint
;
}
__attribute__
((
packed
));
struct
acpi_table_lapic_addr_ovr
{
acpi_madt_entry_header
header
;
u8
reserved
[
2
];
u64
address
;
}
__attribute__
((
packed
));
struct
acpi_table_iosapic
{
acpi_madt_entry_header
header
;
u8
id
;
u8
reserved
;
u32
global_irq_base
;
u64
address
;
}
__attribute__
((
packed
));
struct
acpi_table_lsapic
{
acpi_madt_entry_header
header
;
u8
acpi_id
;
u8
id
;
u8
eid
;
u8
reserved
[
3
];
struct
{
u32
enabled
:
1
;
u32
reserved
:
31
;
}
flags
;
}
__attribute__
((
packed
));
struct
acpi_table_plat_int_src
{
acpi_madt_entry_header
header
;
acpi_madt_int_flags
flags
;
u8
type
;
u8
id
;
u8
eid
;
u8
iosapic_vector
;
u32
global_irq
;
u32
reserved
;
}
__attribute__
((
packed
));
/*
* ACPI Table Descriptor. One per ACPI table
*/
typedef
struct
acpi_table_desc
{
struct
acpi_table_desc
*
prev
;
struct
acpi_table_desc
*
next
;
struct
acpi_table_desc
*
installed_desc
;
acpi_table_header
*
pointer
;
void
*
base_pointer
;
u8
*
aml_pointer
;
u64
physical_address
;
u32
aml_length
;
u32
length
;
u32
count
;
u16
table_id
;
u8
type
;
u8
allocation
;
u8
loaded_into_namespace
;
}
acpi_table_desc
__attribute__
((
packed
));;
#endif
arch/i386/kernel/setup.c
View file @
d7374b3f
...
...
@@ -61,7 +61,12 @@ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
unsigned
long
mmu_cr4_features
;
EXPORT_SYMBOL_GPL
(
mmu_cr4_features
);
int
acpi_disabled
__initdata
=
0
;
#ifdef CONFIG_ACPI_HT_ONLY
int
acpi_disabled
=
1
;
#else
int
acpi_disabled
=
0
;
#endif
EXPORT_SYMBOL
(
acpi_disabled
);
int
MCA_bus
;
/* for MCA, but anyone else can use it if they want */
...
...
@@ -514,6 +519,10 @@ static void __init parse_cmdline_early (char ** cmdline_p)
if
(
c
==
' '
&&
!
memcmp
(
from
,
"acpi=off"
,
8
))
acpi_disabled
=
1
;
/* "acpismp=force" turns on ACPI again */
else
if
(
!
memcmp
(
from
,
"acpismp=force"
,
14
))
acpi_disabled
=
0
;
/*
* highmem=size forces highmem to be exactly 'size' bytes.
* This works even on boxes that have no highmem otherwise.
...
...
drivers/acpi/Kconfig
View file @
d7374b3f
...
...
@@ -49,12 +49,12 @@ config ACPI_HT_ONLY
Full ACPI support (CONFIG_ACPI) is preferred. Use this option
only if you wish to limit ACPI's role to processor enumeration.
There is no command-line option to disable this, but the kernel
will fall back to the MPS table if the MADT is not present
.
In this configuration, ACPI defaults to off. It must be enabled
on the command-line with the "acpismp=force" option
.
config ACPI_BOOT
bool
depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) || X86 && ACPI && !ACPI_HT_ONLY
|| X86 && ACPI
depends on IA64 && (!IA64_HP_SIM || IA64_SGI_SN) || X86 && ACPI && !ACPI_HT_ONLY
default y
config ACPI_SLEEP
...
...
@@ -135,6 +135,31 @@ config ACPI_NUMA
bool "NUMA support" if NUMA && (IA64 && !IA64_HP_SIM || X86 && ACPI && !ACPI_HT_ONLY && !X86_64)
default y if IA64 && IA64_SGI_SN
config ACPI_ASUS
tristate "ASUS/Medion Laptop Extras"
depends on X86 && ACPI && !ACPI_HT_ONLY
---help---
This driver provides support for extra features of ACPI-compatible
ASUS laptops. As some of Medion laptops are made by ASUS, it may also
support some Medion laptops (such as 9675 for example). It makes all
the extra buttons generate standard ACPI events that go through
/proc/acpi/events, and (on some models) adds support for changing the
display brightness and output, switching the LCD backlight on and off,
and most importantly, allows you to blink those fancy LEDs intended
for reporting mail and wireless status.
All settings are changed via /proc/acpi/asus directory entries. Owner
and group for these entries can be set with asus_uid and asus_gid
parameters.
More information and a userspace daemon for handling the extra buttons
at <http://sourceforge.net/projects/acpi4asus/>.
If you have an ACPI-compatible ASUS laptop, say Y or M here. This
driver is still under development, so if your laptop is unsupported or
something works not quite as expected, please use the mailing list
available on the above page (acpi4asus-user@lists.sourceforge.net)
config ACPI_TOSHIBA
tristate "Toshiba Laptop Extras"
depends on X86 && ACPI && !ACPI_HT_ONLY
...
...
drivers/acpi/Makefile
View file @
d7374b3f
...
...
@@ -44,5 +44,6 @@ obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-$(CONFIG_ACPI_SYSTEM)
+=
system.o event.o
obj-$(CONFIG_ACPI_DEBUG)
+=
debug.o
obj-$(CONFIG_ACPI_NUMA)
+=
numa.o
obj-$(CONFIG_ACPI_ASUS)
+=
asus_acpi.o
obj-$(CONFIG_ACPI_TOSHIBA)
+=
toshiba_acpi.o
obj-$(CONFIG_ACPI_BUS)
+=
scan.o
drivers/acpi/asus_acpi.c
0 → 100644
View file @
d7374b3f
/*
* asus_acpi.c - Asus Laptop ACPI Extras
*
*
* Copyright (C) 2002, 2003 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* The development page for this driver is located at
* http://sourceforge.net/projects/acpi4asus/
*
* Credits:
* 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?
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
#define ASUS_ACPI_VERSION "0.24a"
#define PROC_ASUS "asus" //the directory
#define PROC_MLED "mled"
#define PROC_WLED "wled"
#define PROC_INFOS "info"
#define PROC_LCD "lcd"
#define PROC_BRN "brn"
#define PROC_DISP "disp"
#define ACPI_HOTK_NAME "Asus Laptop ACPI Extras Driver"
#define ACPI_HOTK_CLASS "hotkey"
#define ACPI_HOTK_DEVICE_NAME "Hotkey"
#define ACPI_HOTK_HID "ATK0100"
/*
* Some events we use, same for all Asus
*/
#define BR_UP 0x10
#define BR_DOWN 0x20
/*
* Flags for hotk status
*/
#define MLED_ON 0x01 //is MLED ON ?
#define WLED_ON 0x02
MODULE_AUTHOR
(
"Julien Lerouge, Karol Kozimor"
);
MODULE_DESCRIPTION
(
ACPI_HOTK_NAME
);
MODULE_LICENSE
(
"GPL"
);
static
uid_t
asus_uid
=
0
;
static
gid_t
asus_gid
=
0
;
MODULE_PARM
(
asus_uid
,
"i"
);
MODULE_PARM_DESC
(
uid
,
"UID for entries in /proc/acpi/asus.
\n
"
);
MODULE_PARM
(
asus_gid
,
"i"
);
MODULE_PARM_DESC
(
gid
,
"GID for entries in /proc/acpi/asus.
\n
"
);
/* For each model, all features implemented */
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
};
/*
* This is the main structure, we can use it to store anything interesting
* 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
;
//brighness level
enum
{
L2X
=
0
,
//L200D -> TODO check Q11 (Fn+F8)
// Calling this method simply hang the
// computer, ISMI method hangs the laptop.
L3X
,
//L3C
L3D
,
//L3400D
M2X
,
//M2400E
S1X
,
//S1300A -> TODO special keys do not work ?
D1X
,
//D1
L1X
,
//L1400B
A1X
,
//A1340D, A1300F
J1X
,
//S200 (J1)
//TODO A1370D does not seems to have a ATK device
// L8400 model doesn't have ATK
END_MODEL
,
}
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.ECD0."
#define S1X_PREFIX "\\_SB.PCI0.PX40."
#define L1X_PREFIX S1X_PREFIX
#define A1X_PREFIX "\\_SB.PCI0.ISA.EC0."
#define J1X_PREFIX A1X_PREFIX
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
*
* 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 ?
*
*/
{
"L2X"
,
"MLED"
,
"
\\
SGP6"
,
"WLED"
,
"
\\
RCP3"
,
"
\\
Q10"
,
"
\\
SGP0"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
NULL
,
NULL
,
NULL
,
"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"
},
{
"L3D"
,
"MLED"
,
"
\\
MALD"
,
"WLED"
,
NULL
,
"
\\
Q10"
,
"
\\
BKLG"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
"SPLV"
,
"GPLV"
,
"
\\
BLVL"
,
"SDSP"
,
"
\\
INFB"
},
{
"M2X"
,
"MLED"
,
NULL
,
"WLED"
,
NULL
,
"
\\
Q10"
,
"
\\
GP06"
,
"
\\
Q0E"
,
"
\\
Q0F"
,
"SPLV"
,
"GPLV"
,
NULL
,
"SDSP"
,
"
\\
INFB"
},
{
"S1X"
,
"MLED"
,
"
\\
EMLE"
,
"WLED"
,
NULL
,
S1X_PREFIX
"Q10"
,
"
\\
PNOF"
,
S1X_PREFIX
"Q0F"
,
S1X_PREFIX
"Q0E"
,
"SPLV"
,
"GPLV"
,
"
\\
BRIT"
,
NULL
,
NULL
},
{
"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
},
{
"A1X"
,
"MLED"
,
"
\\
MAIL"
,
NULL
,
NULL
,
A1X_PREFIX
"_Q10"
,
"
\\
BKLI"
,
A1X_PREFIX
"_Q0E"
,
A1X_PREFIX
"_Q0F"
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
},
{
"J1X"
,
"MLED"
,
"
\\
MAIL"
,
NULL
,
NULL
,
J1X_PREFIX
"_Q10"
,
"
\\
BKLI"
,
J1X_PREFIX
"_Q0B"
,
J1X_PREFIX
"_Q0A"
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
}
};
/* procdir we use */
static
struct
proc_dir_entry
*
asus_proc_dir
=
NULL
;
/*
* This header is made available to allow proper configuration given model,
* revision number , ... this info cannot go in struct asus_hotk because it is
* available before the hotk
*/
static
struct
acpi_table_header
*
asus_info
=
NULL
;
/*
* The hotkey driver declaration
*/
static
int
asus_hotk_add
(
struct
acpi_device
*
device
);
static
int
asus_hotk_remove
(
struct
acpi_device
*
device
,
int
type
);
static
struct
acpi_driver
asus_hotk_driver
=
{
.
name
=
ACPI_HOTK_NAME
,
.
class
=
ACPI_HOTK_CLASS
,
.
ids
=
ACPI_HOTK_HID
,
.
ops
=
{
.
add
=
asus_hotk_add
,
.
remove
=
asus_hotk_remove
,
},
};
/*
* This function evaluates an ACPI method, given an int as parameter, the
* method is searched within the scope of the handle, can be NULL. The output
* of the method is written is output, which can also be NULL
*
* returns 1 if write is successful, 0 else.
*/
static
int
write_acpi_int
(
acpi_handle
handle
,
const
char
*
method
,
int
val
,
struct
acpi_buffer
*
output
)
{
struct
acpi_object_list
params
;
//list of input parameters (an int here)
union
acpi_object
in_obj
;
//the only param we use
acpi_status
status
;
params
.
count
=
1
;
params
.
pointer
=
&
in_obj
;
in_obj
.
type
=
ACPI_TYPE_INTEGER
;
in_obj
.
integer
.
value
=
val
;
status
=
acpi_evaluate_object
(
handle
,
(
char
*
)
method
,
&
params
,
output
);
return
(
status
==
AE_OK
);
}
static
int
read_acpi_int
(
acpi_handle
handle
,
const
char
*
method
,
int
*
val
)
{
struct
acpi_buffer
output
;
union
acpi_object
out_obj
;
acpi_status
status
;
output
.
length
=
sizeof
(
out_obj
);
output
.
pointer
=
&
out_obj
;
status
=
acpi_evaluate_object
(
handle
,
(
char
*
)
method
,
NULL
,
&
output
);
*
val
=
out_obj
.
integer
.
value
;
return
(
status
==
AE_OK
)
&&
(
out_obj
.
type
==
ACPI_TYPE_INTEGER
);
}
/*
* 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
*/
static
int
proc_read_info
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
int
len
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
char
buf
[
16
];
//enough for all info
/*
* We use the easy way, we don't care of off and count, so we don't set eof
* to 1
*/
len
+=
sprintf
(
page
,
ACPI_HOTK_NAME
" "
ASUS_ACPI_VERSION
"
\n
"
);
len
+=
sprintf
(
page
+
len
,
"Model reference : %s
\n
"
,
hotk
->
methods
->
name
);
if
(
asus_info
)
{
snprintf
(
buf
,
5
,
"%s"
,
asus_info
->
signature
);
len
+=
sprintf
(
page
+
len
,
"ACPI signature : %s
\n
"
,
buf
);
snprintf
(
buf
,
16
,
"%d"
,
asus_info
->
length
);
len
+=
sprintf
(
page
+
len
,
"Table length : %s
\n
"
,
buf
);
snprintf
(
buf
,
16
,
"%d"
,
asus_info
->
revision
);
len
+=
sprintf
(
page
+
len
,
"ACPI minor version : %s
\n
"
,
buf
);
snprintf
(
buf
,
16
,
"%d"
,
asus_info
->
checksum
);
len
+=
sprintf
(
page
+
len
,
"Checksum : %s
\n
"
,
buf
);
snprintf
(
buf
,
7
,
"%s"
,
asus_info
->
oem_id
);
len
+=
sprintf
(
page
+
len
,
"OEM identification : %s
\n
"
,
buf
);
snprintf
(
buf
,
9
,
"%s"
,
asus_info
->
oem_table_id
);
len
+=
sprintf
(
page
+
len
,
"OEM table id : %s
\n
"
,
buf
);
snprintf
(
buf
,
16
,
"%x"
,
asus_info
->
oem_revision
);
len
+=
sprintf
(
page
+
len
,
"OEM rev number : 0x%s
\n
"
,
buf
);
snprintf
(
buf
,
5
,
"%s"
,
asus_info
->
asl_compiler_id
);
len
+=
sprintf
(
page
+
len
,
"ASL comp vendor ID : %s
\n
"
,
buf
);
snprintf
(
buf
,
16
,
"%x"
,
asus_info
->
asl_compiler_revision
);
len
+=
sprintf
(
page
+
len
,
"ASL comp rev number: 0x%s
\n
"
,
buf
);
}
return
len
;
}
/*
* proc file handlers
*/
static
int
proc_read_mled
(
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
=
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
);
else
printk
(
KERN_NOTICE
"Asus ACPI: Error reading MLED "
"status
\n
"
);
}
else
{
len
=
sprintf
(
page
,
"%d
\n
"
,
(
hotk
->
status
&
MLED_ON
)
?
1
:
0
);
}
return
len
;
}
static
int
proc_write_mled
(
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
;
/* scan expression. Multiple expressions may be delimited with ; */
if
(
sscanf
(
buffer
,
"%i"
,
&
value
)
==
1
)
led_out
=
~
value
&
1
;
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_NOTICE
"Asus ACPI: MLED write failed
\n
"
);
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
*/
static
int
proc_read_wled
(
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
;
if
(
hotk
->
methods
->
wled_status
)
{
if
(
read_acpi_int
(
NULL
,
hotk
->
methods
->
mled_status
,
&
led_status
))
len
=
sprintf
(
page
,
"%d
\n
"
,
led_status
);
else
printk
(
KERN_NOTICE
"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_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
;
/* 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_NOTICE
"Asus ACPI: WLED write failed
\n
"
);
return
count
;
}
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_NOTICE
"Asus ACPI: Error reading LCD status
\n
"
);
if
(
hotk
->
model
==
L2X
)
lcd
=
~
lcd
;
return
(
lcd
&
1
);
}
static
int
proc_read_lcd
(
char
*
page
,
char
**
start
,
off_t
off
,
int
count
,
int
*
eof
,
void
*
data
)
{
return
sprintf
(
page
,
"%d
\n
"
,
get_lcd_state
((
struct
asus_hotk
*
)
data
));
}
static
int
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_NOTICE
"Asus ACPI: Error switching LCD
\n
"
);
}
return
count
;
}
/*
* Change the brightness level
*/
static
void
set_brightness
(
int
value
,
struct
asus_hotk
*
hotk
)
{
acpi_status
status
=
0
;
/* ATKD laptop */
if
(
hotk
->
methods
->
brightness_set
)
{
if
(
!
write_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
brightness_set
,
value
,
NULL
))
printk
(
KERN_NOTICE
"Asus ACPI: Error changing brightness
\n
"
);
return
;
}
/* HOTK laptop if we are here, act as appropriate */
value
-=
hotk
->
brightness
;
while
(
value
!=
0
)
{
status
=
acpi_evaluate_object
(
NULL
,
(
value
>
0
)
?
hotk
->
methods
->
brightness_up
:
hotk
->
methods
->
brightness_down
,
NULL
,
NULL
);
(
value
>
0
)
?
value
--
:
value
++
;
if
(
ACPI_FAILURE
(
status
))
printk
(
KERN_NOTICE
"Asus ACPI: Error changing brightness
\n
"
);
}
return
;
}
static
int
read_brightness
(
struct
asus_hotk
*
hotk
)
{
int
value
;
if
(
hotk
->
methods
->
brightness_get
)
{
/* ATKD laptop */
if
(
!
read_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
brightness_get
,
&
value
))
printk
(
KERN_NOTICE
"Asus ACPI: Error reading brightness
\n
"
);
}
else
if
(
hotk
->
methods
->
brightness_status
)
{
/* For D1 for example */
if
(
!
read_acpi_int
(
NULL
,
hotk
->
methods
->
brightness_status
,
&
value
))
printk
(
KERN_NOTICE
"Asus ACPI: Error reading brightness
\n
"
);
}
else
/* HOTK laptop */
value
=
hotk
->
brightness
;
return
value
;
}
static
int
proc_read_brn
(
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_brightness
(
hotk
));
}
static
int
proc_write_brn
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
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 */
set_brightness
(
value
,
hotk
);
}
else
{
printk
(
KERN_NOTICE
"Asus ACPI: Error reading user input
\n
"
);
}
return
count
;
}
static
void
set_display
(
int
value
,
struct
asus_hotk
*
hotk
)
{
/* no sanity check needed for now */
if
(
!
write_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
display_set
,
value
,
NULL
))
printk
(
KERN_NOTICE
"Asus ACPI: Error setting display
\n
"
);
return
;
}
/*
* 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
)
{
int
value
=
0
;
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
if
(
!
read_acpi_int
(
hotk
->
handle
,
hotk
->
methods
->
display_get
,
&
value
))
printk
(
KERN_NOTICE
"Asus ACPI: Error reading display status
\n
"
);
return
sprintf
(
page
,
"%d
\n
"
,
value
);
}
/*
* Preliminary support for display switching. As of now: 0x01 should activate
* the LCD output, 0x02 should do for CRT, and 0x04 for TV-Out. Any combination
* (bitwise) of these will suffice. I never actually tested 3 displays hooked up
* simultaneously, so be warned.
*/
static
int
proc_write_disp
(
struct
file
*
file
,
const
char
*
buffer
,
unsigned
long
count
,
void
*
data
)
{
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
{
printk
(
KERN_NOTICE
"Asus ACPI: Error reading user input
\n
"
);
}
return
count
;
}
static
int
asus_hotk_add_fs
(
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
proc
;
struct
asus_hotk
*
hotk
=
acpi_driver_data
(
device
);
mode_t
mode
;
/*
* If parameter uid or gid is not changed, keep the default setting for
* our proc entries (-rw-rw-rw-) else, it means we care about security,
* and then set to -rw-rw----
*/
if
((
asus_uid
==
0
)
&&
(
asus_gid
==
0
)){
mode
=
S_IFREG
|
S_IRUGO
|
S_IWUGO
;
}
else
{
mode
=
S_IFREG
|
S_IRUSR
|
S_IRGRP
|
S_IWUSR
|
S_IWGRP
;
}
acpi_device_dir
(
device
)
=
asus_proc_dir
;
if
(
!
acpi_device_dir
(
device
))
return
(
-
ENODEV
);
proc
=
create_proc_entry
(
PROC_INFOS
,
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
;;
}
else
{
printk
(
KERN_NOTICE
" Unable to create "
PROC_INFOS
" 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_NOTICE
" Unable to create "
PROC_WLED
" fs entry
\n
"
);
}
}
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_NOTICE
" Unable to create "
PROC_MLED
" fs entry
\n
"
);
}
}
/*
* We need both read node and write method as LCD switch is also accessible
* 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_NOTICE
" Unable to create "
PROC_LCD
" fs entry
\n
"
);
}
}
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_NOTICE
" Unable to create "
PROC_BRN
" fs entry
\n
"
);
}
}
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_NOTICE
" Unable to create "
PROC_DISP
" fs entry
\n
"
);
}
}
return
(
AE_OK
);
}
static
void
asus_hotk_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
/* TODO Find a better way to handle events count. Here, in data, we receive
* the hotk, so we can make anything !!
*/
struct
asus_hotk
*
hotk
=
(
struct
asus_hotk
*
)
data
;
if
(
!
hotk
)
return
;
if
((
event
&
~
((
u32
)
BR_UP
))
<
16
)
{
hotk
->
brightness
=
(
event
&
~
((
u32
)
BR_UP
));
}
else
if
((
event
&
~
((
u32
)
BR_DOWN
))
<
16
)
{
hotk
->
brightness
=
(
event
&
~
((
u32
)
BR_DOWN
));
}
acpi_bus_generate_event
(
hotk
->
device
,
event
,
hotk
->
event_count
[
event
%
128
]
++
);
return
;
}
/*
* This function is used to initialize the hotk with right values. In this
* method, we can make all the detection we want, and modify the hotk struct
*/
static
int
asus_hotk_get_info
(
struct
asus_hotk
*
hotk
)
{
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
model
=
NULL
;
/*
* We have to write 0 on init this far for all ASUS models
*/
if
(
!
write_acpi_int
(
hotk
->
handle
,
"INIT"
,
0
,
&
buffer
))
{
printk
(
KERN_NOTICE
" Hotkey initialization failed
\n
"
);
return
-
ENODEV
;
}
/*
* 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
);
}
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
,
"L3"
,
2
)
==
0
||
strncmp
(
model
->
string
.
pointer
,
"L2B"
,
3
)
==
0
)
hotk
->
model
=
L3X
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"M2"
,
2
)
==
0
)
hotk
->
model
=
M2X
;
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
(
strncmp
(
asus_info
->
oem_table_id
,
"L1"
,
2
)
==
0
)
hotk
->
model
=
L1X
;
else
hotk
->
model
=
S1X
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"D1"
,
2
)
==
0
)
hotk
->
model
=
D1X
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"A1"
,
2
)
==
0
)
hotk
->
model
=
A1X
;
else
if
(
strncmp
(
model
->
string
.
pointer
,
"J1"
,
2
)
==
0
)
hotk
->
model
=
J1X
;
if
(
hotk
->
model
==
END_MODEL
)
{
/* By default use the same values, as I don't know others */
printk
(
"unsupported, trying default values, contact the "
"developers
\n
"
);
hotk
->
model
=
L2X
;
}
else
{
printk
(
"supported
\n
"
);
}
hotk
->
methods
=
&
model_conf
[
hotk
->
model
];
acpi_os_free
(
model
);
return
AE_OK
;
}
static
int
asus_hotk_check
(
struct
asus_hotk
*
hotk
)
{
int
result
=
0
;
if
(
!
hotk
)
return
(
-
EINVAL
);
result
=
acpi_bus_get_status
(
hotk
->
device
);
if
(
result
)
return
(
result
);
if
(
hotk
->
device
->
status
.
present
)
{
result
=
asus_hotk_get_info
(
hotk
);
}
else
{
printk
(
KERN_NOTICE
" Hotkey device not present, aborting
\n
"
);
return
(
-
EINVAL
);
}
return
(
result
);
}
static
int
asus_hotk_add
(
struct
acpi_device
*
device
)
{
struct
asus_hotk
*
hotk
=
NULL
;
acpi_status
status
=
AE_OK
;
int
result
;
if
(
!
device
)
return
(
-
EINVAL
);
hotk
=
(
struct
asus_hotk
*
)
kmalloc
(
sizeof
(
struct
asus_hotk
),
GFP_KERNEL
);
if
(
!
hotk
)
return
(
-
ENOMEM
);
memset
(
hotk
,
0
,
sizeof
(
struct
asus_hotk
));
hotk
->
handle
=
device
->
handle
;
sprintf
(
acpi_device_name
(
device
),
"%s"
,
ACPI_HOTK_DEVICE_NAME
);
sprintf
(
acpi_device_class
(
device
),
"%s"
,
ACPI_HOTK_CLASS
);
acpi_driver_data
(
device
)
=
hotk
;
hotk
->
device
=
device
;
result
=
asus_hotk_check
(
hotk
);
if
(
result
)
goto
end
;
result
=
asus_hotk_add_fs
(
device
);
if
(
result
)
goto
end
;
/*
* We install the handler, it will receive the hotk in parameter, so, we
* could add other data to the hotk struct
*/
status
=
acpi_install_notify_handler
(
hotk
->
handle
,
ACPI_SYSTEM_NOTIFY
,
asus_hotk_notify
,
hotk
);
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_NOTICE
" Error installing notify handler
\n
"
);
}
else
{
printk
(
KERN_DEBUG
" Notify Handler installed successfully
\n
"
);
}
/* For HOTK laptops: init the hotk->brightness value */
if
((
!
hotk
->
methods
->
brightness_get
)
&&
(
!
hotk
->
methods
->
brightness_status
)
&&
(
hotk
->
methods
->
brightness_up
&&
hotk
->
methods
->
brightness_down
))
{
status
=
acpi_evaluate_object
(
NULL
,
hotk
->
methods
->
brightness_down
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
printk
(
KERN_NOTICE
" Error changing brightness
\n
"
);
status
=
acpi_evaluate_object
(
NULL
,
hotk
->
methods
->
brightness_up
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
printk
(
KERN_NOTICE
" Error changing brightness
\n
"
);
}
end:
if
(
result
)
{
kfree
(
hotk
);
}
return
(
result
);
}
static
int
asus_hotk_remove
(
struct
acpi_device
*
device
,
int
type
)
{
acpi_status
status
=
0
;
struct
asus_hotk
*
hotk
=
NULL
;
if
(
!
device
||
!
acpi_driver_data
(
device
))
return
(
-
EINVAL
);
hotk
=
(
struct
asus_hotk
*
)
acpi_driver_data
(
device
);
status
=
acpi_remove_notify_handler
(
hotk
->
handle
,
ACPI_SYSTEM_NOTIFY
,
asus_hotk_notify
);
if
(
ACPI_FAILURE
(
status
))
printk
(
KERN_NOTICE
"Error removing notify handler
\n
"
);
kfree
(
hotk
);
return
(
0
);
}
static
int
__init
asus_acpi_init
(
void
)
{
int
result
=
0
;
acpi_status
status
=
0
;
struct
acpi_buffer
dsdt
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
printk
(
KERN_NOTICE
"Asus Laptop ACPI Extras version %s
\n
"
,
ASUS_ACPI_VERSION
);
/*
* Here is the code to know the model we are running on. We need to
* know this before calling the acpi_bus_register_driver function, in
* case the HID for the laptop we are running on is different from
* ACPI_HOTK_HID, which I have never seen yet :)
*
* This information is then available in the global var asus_info
*/
status
=
acpi_get_table
(
ACPI_TABLE_DSDT
,
1
,
&
dsdt
);
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_NOTICE
" Couldn't get the DSDT table header
\n
"
);
}
else
{
asus_info
=
(
struct
acpi_table_header
*
)
dsdt
.
pointer
;
}
asus_proc_dir
=
proc_mkdir
(
PROC_ASUS
,
acpi_root_dir
);
if
(
!
asus_proc_dir
)
return
(
-
ENODEV
);
asus_proc_dir
->
owner
=
THIS_MODULE
;
result
=
acpi_bus_register_driver
(
&
asus_hotk_driver
);
if
(
result
<
0
)
{
printk
(
KERN_NOTICE
" Error registering "
ACPI_HOTK_NAME
"
\n
"
);
remove_proc_entry
(
PROC_ASUS
,
acpi_root_dir
);
return
(
-
ENODEV
);
}
return
(
0
);
}
static
void
__exit
asus_acpi_exit
(
void
)
{
acpi_bus_unregister_driver
(
&
asus_hotk_driver
);
remove_proc_entry
(
PROC_ASUS
,
acpi_root_dir
);
acpi_os_free
(
asus_info
);
return
;
}
module_init
(
asus_acpi_init
);
module_exit
(
asus_acpi_exit
);
drivers/acpi/dispatcher/dsmthdat.c
View file @
d7374b3f
...
...
@@ -306,7 +306,6 @@ acpi_ds_method_data_set_value (
{
acpi_status
status
;
struct
acpi_namespace_node
*
node
;
union
acpi_operand_object
*
new_desc
=
object
;
ACPI_FUNCTION_TRACE
(
"ds_method_data_set_value"
);
...
...
@@ -325,28 +324,16 @@ acpi_ds_method_data_set_value (
}
/*
* If the object has just been created and is not attached to anything,
* (the reference count is 1), then we can just store it directly into
* the arg/local. Otherwise, we must copy it.
* Increment ref count so object can't be deleted while installed.
* NOTE: We do not copy the object in order to preserve the call by
* reference semantics of ACPI Control Method invocation.
* (See ACPI specification 2.0_c)
*/
if
(
object
->
common
.
reference_count
>
1
)
{
status
=
acpi_ut_copy_iobject_to_iobject
(
object
,
&
new_desc
,
walk_state
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_EXEC
,
"Object Copied %p, new %p
\n
"
,
object
,
new_desc
));
}
else
{
/* Increment ref count so object can't be deleted while installed */
acpi_ut_add_reference
(
new_desc
);
}
acpi_ut_add_reference
(
object
);
/* Install the object */
node
->
object
=
new_desc
;
node
->
object
=
object
;
return_ACPI_STATUS
(
status
);
}
...
...
drivers/acpi/events/evgpe.c
View file @
d7374b3f
...
...
@@ -186,11 +186,13 @@ acpi_ev_gpe_detect (
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INTERRUPTS
,
"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X
\n
"
,
"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X
\n
"
,
ACPI_HIDWORD
(
gpe_register_info
->
status_address
.
address
),
ACPI_LODWORD
(
gpe_register_info
->
status_address
.
address
),
gpe_register_info
->
status
,
ACPI_HIDWORD
(
gpe_register_info
->
enable_address
.
address
),
ACPI_LODWORD
(
gpe_register_info
->
enable_address
.
address
),
gpe_register_info
->
enable
,
gpe_register_info
->
status
));
gpe_register_info
->
enable
));
/* First check if there is anything active at all in this register */
...
...
drivers/acpi/events/evgpeblk.c
View file @
d7374b3f
...
...
@@ -76,9 +76,14 @@ acpi_ev_valid_gpe_event (
/* No need for spin lock since we are not changing any list elements */
/* Walk the GPE interrupt levels */
gpe_xrupt_block
=
acpi_gbl_gpe_xrupt_list_head
;
while
(
gpe_xrupt_block
)
{
gpe_block
=
gpe_xrupt_block
->
gpe_block_list_head
;
/* Walk the GPE blocks on this interrupt level */
while
(
gpe_block
)
{
if
((
&
gpe_block
->
event_info
[
0
]
<=
gpe_event_info
)
&&
(
&
gpe_block
->
event_info
[((
acpi_size
)
gpe_block
->
register_count
)
*
8
]
>
gpe_event_info
))
{
...
...
@@ -155,7 +160,7 @@ acpi_ev_walk_gpe_list (
*
* PARAMETERS: Callback from walk_namespace
*
* RETURN:
None
* RETURN:
Status
*
* DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
* control method under the _GPE portion of the namespace.
...
...
@@ -164,10 +169,10 @@ acpi_ev_walk_gpe_list (
*
* The name of each GPE control method is of the form:
* "_Lnn" or "_Enn"
* Where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* nn - is the GPE number [in HEX]
*
Where:
*
L - means that the GPE is level triggered
*
E - means that the GPE is edge triggered
*
nn - is the GPE number [in HEX]
*
******************************************************************************/
...
...
@@ -196,7 +201,8 @@ acpi_ev_save_method_info (
name
[
ACPI_NAME_SIZE
]
=
0
;
/*
* Edge/Level determination is based on the 2nd character of the method name
* Edge/Level determination is based on the 2nd character
* of the method name
*/
switch
(
name
[
1
])
{
case
'L'
:
...
...
@@ -249,15 +255,14 @@ acpi_ev_save_method_info (
gpe_event_info
->
flags
=
type
;
gpe_event_info
->
method_node
=
(
struct
acpi_namespace_node
*
)
obj_handle
;
/*
* Enable the GPE (SCIs should be disabled at this point)
*/
/* Enable the GPE (SCIs should be disabled at this point) */
status
=
acpi_hw_enable_gpe
(
gpe_event_info
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_
ERROR
,
ACPI_DEBUG_PRINT
((
ACPI_DB_
LOAD
,
"Registered GPE method %s as GPE number 0x%.2X
\n
"
,
name
,
gpe_number
));
return_ACPI_STATUS
(
AE_OK
);
...
...
@@ -867,8 +872,8 @@ acpi_ev_gpe_initialize (void)
}
/*
* GPE0 and GPE1 do not have to be contiguous in the GPE number
space,
*
But, GPE0 always starts at
zero.
* GPE0 and GPE1 do not have to be contiguous in the GPE number
*
space. However, GPE0 always starts at GPE number
zero.
*/
gpe_number_max
=
acpi_gbl_FADT
->
gpe1_base
+
((
register_count1
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
);
...
...
drivers/acpi/executer/exoparg1.c
View file @
d7374b3f
...
...
@@ -222,7 +222,7 @@ acpi_ex_opcode_1A_1T_1R (
union
acpi_operand_object
*
return_desc2
=
NULL
;
u32
temp32
;
u32
i
;
u32
j
;
u32
power_of_ten
;
acpi_integer
digit
;
...
...
@@ -291,61 +291,70 @@ acpi_ex_opcode_1A_1T_1R (
case
AML_FROM_BCD_OP
:
/* from_bcd (BCDValue, Result) */
/*
* The 64-bit ACPI integer can hold 16 4-bit BCD integers
* The 64-bit ACPI integer can hold 16 4-bit BCD characters
* (if table is 32-bit, integer can hold 8 BCD characters)
* Convert each 4-bit BCD value
*/
power_of_ten
=
1
;
return_desc
->
integer
.
value
=
0
;
for
(
i
=
0
;
i
<
ACPI_MAX_BCD_DIGITS
;
i
++
)
{
/* Get one BCD digit */
digit
=
operand
[
0
]
->
integer
.
value
;
digit
=
(
acpi_integer
)
((
operand
[
0
]
->
integer
.
value
>>
(
i
*
4
))
&
0xF
);
/* Convert each BCD digit (each is one nybble wide) */
for
(
i
=
0
;
(
i
<
acpi_gbl_integer_nybble_width
)
&&
(
digit
>
0
);
i
++
)
{
/* Get the least significant 4-bit BCD digit */
temp32
=
((
u32
)
digit
)
&
0xF
;
/* Check the range of the digit */
if
(
digit
>
9
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"BCD digit too large: %d
\n
"
,
(
u32
)
digit
));
if
(
temp32
>
9
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"BCD digit too large (not decimal): 0x%X
\n
"
,
temp32
));
status
=
AE_AML_NUMERIC_OVERFLOW
;
goto
cleanup
;
}
if
(
digit
>
0
)
{
/* Sum into the result with the appropriate power of 10 */
/* Sum the digit into the result with the current power of 10 */
for
(
j
=
0
;
j
<
i
;
j
++
)
{
digit
*=
10
;
}
return_desc
->
integer
.
value
+=
(((
acpi_integer
)
temp32
)
*
power_of_ten
);
return_desc
->
integer
.
value
+=
digit
;
}
/* Shift to next BCD digit */
digit
>>=
4
;
/* Next power of 10 */
power_of_ten
*=
10
;
}
break
;
case
AML_TO_BCD_OP
:
/* to_bcd (Operand, Result) */
if
(
operand
[
0
]
->
integer
.
value
>
ACPI_MAX_BCD_VALUE
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"BCD overflow: %8.8X%8.8X
\n
"
,
ACPI_HIDWORD
(
operand
[
0
]
->
integer
.
value
),
ACPI_LODWORD
(
operand
[
0
]
->
integer
.
value
)));
status
=
AE_AML_NUMERIC_OVERFLOW
;
goto
cleanup
;
}
return_desc
->
integer
.
value
=
0
;
for
(
i
=
0
;
i
<
ACPI_MAX_BCD_DIGITS
;
i
++
)
{
/* Divide by nth factor of 10 */
digit
=
operand
[
0
]
->
integer
.
value
;
temp32
=
0
;
digit
=
operand
[
0
]
->
integer
.
value
;
for
(
j
=
0
;
j
<
i
;
j
++
)
{
(
void
)
acpi_ut_short_divide
(
&
digit
,
10
,
&
digit
,
&
temp32
);
}
/* Each BCD digit is one nybble wide */
/* Create the BCD digit from the remainder above */
for
(
i
=
0
;
(
i
<
acpi_gbl_integer_nybble_width
)
&&
(
digit
>
0
);
i
++
)
{
(
void
)
acpi_ut_short_divide
(
&
digit
,
10
,
&
digit
,
&
temp32
);
if
(
digit
>
0
)
{
return_desc
->
integer
.
value
+=
((
acpi_integer
)
temp32
<<
(
i
*
4
));
}
/* Insert the BCD digit that resides in the remainder from above */
return_desc
->
integer
.
value
|=
(((
acpi_integer
)
temp32
)
<<
(
i
*
4
));
}
/* Overflow if there is any data left in Digit */
if
(
digit
>
0
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Integer too large to convert to BCD: %8.8X%8.8X
\n
"
,
ACPI_HIDWORD
(
operand
[
0
]
->
integer
.
value
),
ACPI_LODWORD
(
operand
[
0
]
->
integer
.
value
)));
status
=
AE_AML_NUMERIC_OVERFLOW
;
goto
cleanup
;
}
break
;
...
...
drivers/acpi/executer/exstore.c
View file @
d7374b3f
...
...
@@ -190,8 +190,8 @@ acpi_ex_store (
case
ACPI_TYPE_INTEGER
:
ACPI_DEBUG_PRINT_RAW
((
ACPI_DB_DEBUG_OBJECT
,
"%8.8X%8.8X
\n
"
,
ACPI_HIWORD
(
source_desc
->
integer
.
value
),
ACPI_LOWORD
(
source_desc
->
integer
.
value
)));
ACPI_HI
D
WORD
(
source_desc
->
integer
.
value
),
ACPI_LO
D
WORD
(
source_desc
->
integer
.
value
)));
break
;
...
...
drivers/acpi/executer/exsystem.c
View file @
d7374b3f
...
...
@@ -134,7 +134,7 @@ acpi_ex_system_do_stall (
acpi_ex_exit_interpreter
();
acpi_os_s
tall
(
how_long
);
acpi_os_s
leep
(
0
,
(
how_long
/
1000
)
+
1
);
/* And now we must get the interpreter again */
...
...
@@ -142,7 +142,7 @@ acpi_ex_system_do_stall (
}
else
{
acpi_os_s
leep
(
0
,
(
how_long
/
1000
)
+
1
);
acpi_os_s
tall
(
how_long
);
}
return
(
status
);
...
...
drivers/acpi/executer/exutils.c
View file @
d7374b3f
...
...
@@ -289,7 +289,10 @@ acpi_ex_digits_needed (
/*
* acpi_integer is unsigned, so we don't worry about a '-'
*/
current_value
=
value
;
if
((
current_value
=
value
)
==
0
)
{
return_VALUE
(
1
);
}
num_digits
=
0
;
while
(
current_value
)
{
...
...
drivers/acpi/hardware/hwregs.c
View file @
d7374b3f
...
...
@@ -56,7 +56,7 @@
*
* FUNCTION: acpi_hw_clear_acpi_status
*
* PARAMETERS:
none
* PARAMETERS:
Flags - Lock the hardware or not
*
* RETURN: none
*
...
...
@@ -65,7 +65,8 @@
******************************************************************************/
acpi_status
acpi_hw_clear_acpi_status
(
void
)
acpi_hw_clear_acpi_status
(
u32
flags
)
{
acpi_status
status
;
...
...
@@ -77,10 +78,11 @@ acpi_hw_clear_acpi_status (void)
ACPI_BITMASK_ALL_FIXED_STATUS
,
(
u16
)
acpi_gbl_FADT
->
xpm1a_evt_blk
.
address
));
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_HARDWARE
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
if
(
flags
&
ACPI_MTX_LOCK
)
{
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_HARDWARE
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
}
status
=
acpi_hw_register_write
(
ACPI_MTX_DO_NOT_LOCK
,
ACPI_REGISTER_PM1_STATUS
,
...
...
@@ -104,7 +106,9 @@ acpi_hw_clear_acpi_status (void)
status
=
acpi_ev_walk_gpe_list
(
acpi_hw_clear_gpe_block
);
unlock_and_exit:
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_HARDWARE
);
if
(
flags
&
ACPI_MTX_LOCK
)
{
(
void
)
acpi_ut_release_mutex
(
ACPI_MTX_HARDWARE
);
}
return_ACPI_STATUS
(
status
);
}
...
...
@@ -237,8 +241,9 @@ acpi_hw_get_bit_register_info (
*
* FUNCTION: acpi_get_register
*
* PARAMETERS: register_id - Index of ACPI Register to access
* use_lock - Lock the hardware
* PARAMETERS: register_id - ID of ACPI bit_register to access
* return_value - Value that was read from the register
* Flags - Lock the hardware or not
*
* RETURN: Value is read from specified Register. Value returned is
* normalized to bit0 (is shifted all the way right)
...
...
@@ -290,7 +295,8 @@ acpi_get_register (
*
return_value
=
register_value
;
ACPI_DEBUG_PRINT
((
ACPI_DB_IO
,
"Read value %X
\n
"
,
register_value
));
ACPI_DEBUG_PRINT
((
ACPI_DB_IO
,
"Read value %8.8X register %X
\n
"
,
register_value
,
bit_reg_info
->
parent_register
));
}
return_ACPI_STATUS
(
status
);
...
...
@@ -443,7 +449,8 @@ acpi_set_register (
ACPI_DEBUG_EXEC
(
register_value
=
((
register_value
&
bit_reg_info
->
access_bit_mask
)
>>
bit_reg_info
->
bit_position
));
ACPI_DEBUG_PRINT
((
ACPI_DB_IO
,
"ACPI Register Write actual %X
\n
"
,
register_value
));
ACPI_DEBUG_PRINT
((
ACPI_DB_IO
,
"Set bits: %8.8X actual %8.8X register %X
\n
"
,
value
,
register_value
,
bit_reg_info
->
parent_register
));
return_ACPI_STATUS
(
status
);
}
...
...
@@ -751,10 +758,15 @@ acpi_hw_low_level_read (
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unsupported address space: %X
\n
"
,
reg
->
address_space_id
));
status
=
AE_BAD_PARAMETER
;
break
;
return
(
AE_BAD_PARAMETER
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_IO
,
"Read: %8.8X width %2d from %8.8X%8.8X (%s)
\n
"
,
*
value
,
width
,
ACPI_HIDWORD
(
reg
->
address
),
ACPI_LODWORD
(
reg
->
address
),
acpi_ut_get_region_name
(
reg
->
address_space_id
)));
return
(
status
);
}
...
...
@@ -832,9 +844,14 @@ acpi_hw_low_level_write (
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unsupported address space: %X
\n
"
,
reg
->
address_space_id
));
status
=
AE_BAD_PARAMETER
;
break
;
return
(
AE_BAD_PARAMETER
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_IO
,
"Wrote: %8.8X width %2d to %8.8X%8.8X (%s)
\n
"
,
value
,
width
,
ACPI_HIDWORD
(
reg
->
address
),
ACPI_LODWORD
(
reg
->
address
),
acpi_ut_get_region_name
(
reg
->
address_space_id
)));
return
(
status
);
}
drivers/acpi/hardware/hwsleep.c
View file @
d7374b3f
...
...
@@ -231,7 +231,7 @@ acpi_enter_sleep_state (
return_ACPI_STATUS
(
status
);
}
status
=
acpi_hw_clear_acpi_status
();
status
=
acpi_hw_clear_acpi_status
(
ACPI_MTX_DO_NOT_LOCK
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -355,7 +355,7 @@ acpi_enter_sleep_state_s4bios (
ACPI_FUNCTION_TRACE
(
"acpi_enter_sleep_state_s4bios"
);
acpi_set_register
(
ACPI_BITREG_WAKE_STATUS
,
1
,
ACPI_MTX_DO_NOT_LOCK
);
acpi_hw_clear_acpi_status
();
acpi_hw_clear_acpi_status
(
ACPI_MTX_DO_NOT_LOCK
);
acpi_hw_disable_non_wakeup_gpes
();
...
...
drivers/acpi/tables/tbconvrt.c
View file @
d7374b3f
...
...
@@ -287,10 +287,14 @@ acpi_tb_convert_fadt1 (
(
acpi_physical_address
)
(
local_fadt
->
xpm1a_evt_blk
.
address
+
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
)));
acpi_tb_init_generic_address
(
&
acpi_gbl_xpm1b_enable
,
(
u8
)
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
),
(
acpi_physical_address
)
(
local_fadt
->
xpm1b_evt_blk
.
address
+
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
)));
/* PM1B is optional; leave null if not present */
if
(
local_fadt
->
xpm1b_evt_blk
.
address
)
{
acpi_tb_init_generic_address
(
&
acpi_gbl_xpm1b_enable
,
(
u8
)
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
),
(
acpi_physical_address
)
(
local_fadt
->
xpm1b_evt_blk
.
address
+
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
)));
}
}
...
...
@@ -379,11 +383,15 @@ acpi_tb_convert_fadt2 (
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
)));
acpi_gbl_xpm1a_enable
.
address_space_id
=
local_fadt
->
xpm1a_evt_blk
.
address_space_id
;
acpi_tb_init_generic_address
(
&
acpi_gbl_xpm1b_enable
,
(
u8
)
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
),
(
acpi_physical_address
)
(
local_fadt
->
xpm1b_evt_blk
.
address
+
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
)));
acpi_gbl_xpm1b_enable
.
address_space_id
=
local_fadt
->
xpm1b_evt_blk
.
address_space_id
;
/* PM1B is optional; leave null if not present */
if
(
local_fadt
->
xpm1b_evt_blk
.
address
)
{
acpi_tb_init_generic_address
(
&
acpi_gbl_xpm1b_enable
,
(
u8
)
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
),
(
acpi_physical_address
)
(
local_fadt
->
xpm1b_evt_blk
.
address
+
ACPI_DIV_2
(
acpi_gbl_FADT
->
pm1_evt_len
)));
acpi_gbl_xpm1b_enable
.
address_space_id
=
local_fadt
->
xpm1b_evt_blk
.
address_space_id
;
}
}
...
...
drivers/acpi/utilities/utmisc.c
View file @
d7374b3f
...
...
@@ -203,10 +203,12 @@ acpi_ut_set_integer_width (
if
(
revision
<=
1
)
{
acpi_gbl_integer_bit_width
=
32
;
acpi_gbl_integer_nybble_width
=
8
;
acpi_gbl_integer_byte_width
=
4
;
}
else
{
acpi_gbl_integer_bit_width
=
64
;
acpi_gbl_integer_nybble_width
=
16
;
acpi_gbl_integer_byte_width
=
8
;
}
}
...
...
drivers/pci/hotplug/acpiphp.h
View file @
d7374b3f
...
...
@@ -5,8 +5,8 @@
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002
Takayoshi Kochi (t-kouchi@c
q.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
* Copyright (c) 2002
,2003 Takayoshi Kochi (t-kochi@b
q.jp.nec.com)
* Copyright (c) 2002
,2003
NEC Corporation
*
* All rights reserved.
*
...
...
@@ -26,8 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <gregkh@us.ibm.com>,
* <h-aono@ap.jp.nec.com>,
* <t-kouchi@cq.jp.nec.com>
* <t-kochi@bq.jp.nec.com>
*
*/
...
...
@@ -35,6 +34,7 @@
#define _ACPIPHP_H
#include <linux/acpi.h>
#include <linux/kobject.h>
/* for KOBJ_NAME_LEN */
#include "pci_hotplug.h"
#define dbg(format, arg...) \
...
...
@@ -49,7 +49,7 @@
#define SLOT_MAGIC 0x67267322
/* name size which is used for entries in pcihpfs */
#define SLOT_NAME_SIZE
32
/* ACPI{_SUN}-{BUS}:{DEV
} */
#define SLOT_NAME_SIZE
KOBJ_NAME_LEN
/* {_SUN
} */
struct
acpiphp_bridge
;
struct
acpiphp_slot
;
...
...
@@ -212,11 +212,7 @@ struct acpiphp_func {
#define FUNC_HAS_PS2 (0x00000040)
#define FUNC_HAS_PS3 (0x00000080)
/* not yet */
#define SLOT_SUPPORT_66MHZ (0x00010000)
#define SLOT_SUPPORT_100MHZ (0x00020000)
#define SLOT_SUPPORT_133MHZ (0x00040000)
#define SLOT_SUPPORT_PCIX (0x00080000)
#define FUNC_EXISTS (0x10000000)
/* to make sure we call _EJ0 only for existing funcs */
/* function prototypes */
...
...
drivers/pci/hotplug/acpiphp_core.c
View file @
d7374b3f
...
...
@@ -5,8 +5,8 @@
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002
Takayoshi Kochi (t-kouchi@c
q.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
* Copyright (c) 2002
,2003 Takayoshi Kochi (t-kochi@b
q.jp.nec.com)
* Copyright (c) 2002
,2003
NEC Corporation
*
* All rights reserved.
*
...
...
@@ -26,8 +26,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <gregkh@us.ibm.com>,
* <h-aono@ap.jp.nec.com>,
* <t-kouchi@cq.jp.nec.com>
* <t-kochi@bq.jp.nec.com>
*
*/
...
...
@@ -57,7 +56,7 @@ int acpiphp_debug;
static
int
num_slots
;
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-ko
uchi@c
q.jp.nec.com>"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-ko
chi@b
q.jp.nec.com>"
#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver"
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
...
...
@@ -376,10 +375,8 @@ static int init_acpi (void)
*/
static
void
make_slot_name
(
struct
slot
*
slot
)
{
snprintf
(
slot
->
hotplug_slot
->
name
,
SLOT_NAME_SIZE
,
"ACPI%d-%02x:%02x"
,
slot
->
acpi_slot
->
sun
,
slot
->
acpi_slot
->
bridge
->
bus
,
slot
->
acpi_slot
->
device
);
snprintf
(
slot
->
hotplug_slot
->
name
,
SLOT_NAME_SIZE
,
"%u"
,
slot
->
acpi_slot
->
sun
);
}
/**
...
...
drivers/pci/hotplug/acpiphp_glue.c
View file @
d7374b3f
/*
* ACPI PCI HotPlug glue functions to ACPI CA subsystem
*
* Copyright (c) 2002
Takayoshi Kochi (t-kouchi@c
q.jp.nec.com)
* Copyright (c) 2002
,2003 Takayoshi Kochi (t-kochi@b
q.jp.nec.com)
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
* Copyright (c) 2002
,2003
NEC Corporation
*
* All rights reserved.
*
...
...
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <t-ko
uchi@c
q.jp.nec.com>
* Send feedback to <t-ko
chi@b
q.jp.nec.com>
*
*/
...
...
@@ -204,7 +204,6 @@ register_slot (acpi_handle handle, u32 lvl, void *context, void **rv)
if
(
ACPI_FAILURE
(
status
))
{
err
(
"failed to register interrupt notify handler
\n
"
);
kfree
(
newfunc
);
return
status
;
}
...
...
@@ -617,9 +616,8 @@ find_p2p_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
/* find hot-pluggable slots, and then find P2P bridge */
static
int
add_bridge
s
(
struct
acpi_device
*
devic
e
)
static
int
add_bridge
(
acpi_handle
handl
e
)
{
acpi_handle
*
handle
=
device
->
handle
;
acpi_status
status
;
unsigned
long
tmp
;
int
seg
,
bus
;
...
...
@@ -673,6 +671,12 @@ static int add_bridges(struct acpi_device *device)
}
static
void
remove_bridge
(
acpi_handle
handle
)
{
/* No-op for now .. */
}
static
int
power_on_slot
(
struct
acpiphp_slot
*
slot
)
{
acpi_status
status
;
...
...
@@ -725,9 +729,7 @@ static int power_off_slot (struct acpiphp_slot *slot)
list_for_each
(
l
,
&
slot
->
funcs
)
{
func
=
list_entry
(
l
,
struct
acpiphp_func
,
sibling
);
if
(
func
->
flags
&
FUNC_HAS_PS3
)
{
dbg
(
"%s: executing _PS3 on %s
\n
"
,
__FUNCTION__
,
func
->
pci_dev
->
slot_name
);
if
(
func
->
flags
&
(
FUNC_HAS_PS3
|
FUNC_EXISTS
))
{
status
=
acpi_evaluate_object
(
func
->
handle
,
"_PS3"
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
warn
(
"%s: _PS3 failed
\n
"
,
__FUNCTION__
);
...
...
@@ -740,10 +742,8 @@ static int power_off_slot (struct acpiphp_slot *slot)
list_for_each
(
l
,
&
slot
->
funcs
)
{
func
=
list_entry
(
l
,
struct
acpiphp_func
,
sibling
);
if
(
func
->
flags
&
FUNC_HAS_EJ0
)
{
dbg
(
"%s: executing _EJ0 on %s
\n
"
,
__FUNCTION__
,
func
->
pci_dev
->
slot_name
);
/* We don't want to call _EJ0 on non-existing functions. */
if
(
func
->
flags
&
(
FUNC_HAS_EJ0
|
FUNC_EXISTS
))
{
/* _EJ0 method take one argument */
arg_list
.
count
=
1
;
arg_list
.
pointer
=
&
arg
;
...
...
@@ -756,6 +756,7 @@ static int power_off_slot (struct acpiphp_slot *slot)
retval
=
-
1
;
goto
err_exit
;
}
func
->
flags
&=
(
~
FUNC_EXISTS
);
}
}
...
...
@@ -835,6 +836,8 @@ static int enable_device (struct acpiphp_slot *slot)
retval
=
acpiphp_configure_function
(
func
);
if
(
retval
)
goto
err_exit
;
func
->
flags
|=
FUNC_EXISTS
;
}
slot
->
flags
|=
SLOT_ENABLED
;
...
...
@@ -1029,13 +1032,10 @@ static void handle_hotplug_event_func (acpi_handle handle, u32 type, void *conte
}
}
static
struct
acpi_driver
acpi_pci_hp_driver
=
{
.
name
=
"pci_hp"
,
.
class
=
""
,
.
ids
=
ACPI_PCI_HOST_HID
,
.
ops
=
{
.
add
=
add_bridges
,
}
static
struct
acpi_pci_driver
acpi_pci_hp_driver
=
{
.
add
=
add_bridge
,
.
remove
=
remove_bridge
,
};
/**
...
...
@@ -1044,17 +1044,15 @@ static struct acpi_driver acpi_pci_hp_driver = {
*/
int
acpiphp_glue_init
(
void
)
{
acpi_status
status
;
int
num
;
if
(
list_empty
(
&
pci_root_buses
))
return
-
1
;
status
=
acpi_bus
_register_driver
(
&
acpi_pci_hp_driver
);
num
=
acpi_pci
_register_driver
(
&
acpi_pci_hp_driver
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"%s: acpi_walk_namespace() failed
\n
"
,
__FUNCTION__
);
if
(
num
<=
0
)
return
-
1
;
}
return
0
;
}
...
...
@@ -1296,7 +1294,7 @@ u8 acpiphp_get_power_status (struct acpiphp_slot *slot)
/*
* attention LED ON: 1
*
OFF: 0
*
OFF: 0
*
* TBD
* no direct attention led status information via ACPI
...
...
drivers/pci/hotplug/acpiphp_pci.c
View file @
d7374b3f
...
...
@@ -4,7 +4,7 @@
* Copyright (c) 1995,2001 Compaq Computer Corporation
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001,2002 IBM Corp.
* Copyright (c) 2002 Takayoshi Kochi (t-ko
uchi@c
q.jp.nec.com)
* Copyright (c) 2002 Takayoshi Kochi (t-ko
chi@b
q.jp.nec.com)
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
*
...
...
@@ -25,7 +25,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <t-ko
uchi@c
q.jp.nec.com>
* Send feedback to <t-ko
chi@b
q.jp.nec.com>
*
*/
...
...
drivers/pci/hotplug/acpiphp_res.c
View file @
d7374b3f
...
...
@@ -5,7 +5,7 @@
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002 Takayoshi Kochi (t-ko
uchi@c
q.jp.nec.com)
* Copyright (c) 2002 Takayoshi Kochi (t-ko
chi@b
q.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
*
* All rights reserved.
...
...
@@ -25,7 +25,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <gregkh@us.ibm.com>,
<h-aono@ap
.jp.nec.com>
* Send feedback to <gregkh@us.ibm.com>,
<t-kochi@bq
.jp.nec.com>
*
*/
...
...
include/acpi/acconfig.h
View file @
d7374b3f
...
...
@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20030
522
#define ACPI_CA_VERSION 0x20030
619
/* Maximum objects in the various object caches */
...
...
include/acpi/acglobal.h
View file @
d7374b3f
...
...
@@ -105,6 +105,7 @@ ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS;
*/
ACPI_EXTERN
u8
acpi_gbl_integer_bit_width
;
ACPI_EXTERN
u8
acpi_gbl_integer_byte_width
;
ACPI_EXTERN
u8
acpi_gbl_integer_nybble_width
;
ACPI_EXTERN
struct
acpi_generic_address
acpi_gbl_xpm1a_enable
;
ACPI_EXTERN
struct
acpi_generic_address
acpi_gbl_xpm1b_enable
;
...
...
include/acpi/achware.h
View file @
d7374b3f
...
...
@@ -108,7 +108,7 @@ acpi_hw_low_level_write (
acpi_status
acpi_hw_clear_acpi_status
(
void
);
u32
flags
);
/* GPE support */
...
...
include/acpi/acpiosxf.h
View file @
d7374b3f
...
...
@@ -287,15 +287,15 @@ acpi_os_derive_pci_id(
* Miscellaneous
*/
BOOLEAN
u8
acpi_os_readable
(
void
*
pointer
,
u32
length
);
acpi_size
length
);
BOOLEAN
u8
acpi_os_writable
(
void
*
pointer
,
u32
length
);
acpi_size
length
);
u32
acpi_os_get_timer
(
...
...
include/acpi/actypes.h
View file @
d7374b3f
...
...
@@ -50,11 +50,14 @@
/*
* Data type ranges
* Note: These macros are designed to be compiler independent as well as
* working around problems that some 32-bit compilers have with 64-bit
* constants.
*/
#define ACPI_UINT8_MAX (
~((UINT8) 0))
#define ACPI_UINT16_MAX (
~((UINT16) 0))
#define ACPI_UINT32_MAX (
~((UINT32) 0))
#define ACPI_UINT64_MAX (
~((UINT64) 0))
#define ACPI_UINT8_MAX (
UINT8) (~((UINT8) 0))
/* 0xFF */
#define ACPI_UINT16_MAX (
UINT16)(~((UINT16) 0))
/* 0xFFFF */
#define ACPI_UINT32_MAX (
UINT32)(~((UINT32) 0))
/* 0xFFFFFFFF */
#define ACPI_UINT64_MAX (
UINT64)(~((UINT64) 0))
/* 0xFFFFFFFFFFFFFFFF */
#define ACPI_ASCII_MAX 0x7F
...
...
@@ -299,8 +302,6 @@ struct uint32_struct
typedef
u32
acpi_integer
;
#define ACPI_INTEGER_MAX ACPI_UINT32_MAX
#define ACPI_INTEGER_BIT_SIZE 32
#define ACPI_MAX_BCD_VALUE 99999999
#define ACPI_MAX_BCD_DIGITS 8
#define ACPI_MAX_DECIMAL_DIGITS 10
#define ACPI_USE_NATIVE_DIVIDE
/* Use compiler native 32-bit divide */
...
...
@@ -313,12 +314,6 @@ typedef u32 acpi_integer;
typedef
u64
acpi_integer
;
#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
#define ACPI_INTEGER_BIT_SIZE 64
#if ACPI_MACHINE_WIDTH == 64
#define ACPI_MAX_BCD_VALUE 9999999999999999UL
#else
#define ACPI_MAX_BCD_VALUE 9999999999999999ULL
#endif
#define ACPI_MAX_BCD_DIGITS 16
#define ACPI_MAX_DECIMAL_DIGITS 19
#if ACPI_MACHINE_WIDTH == 64
...
...
include/asm-i386/acpi.h
View file @
d7374b3f
...
...
@@ -106,6 +106,10 @@
:"0"(n_hi), "1"(n_lo))
#ifdef CONFIG_ACPI_HT_ONLY
extern
int
acpi_lapic
;
#define acpi_ioapic 0
#else
#ifndef CONFIG_ACPI_BOOT
#define acpi_lapic 0
#define acpi_ioapic 0
...
...
@@ -120,6 +124,7 @@ extern int acpi_ioapic;
#else
#define acpi_ioapic 0
#endif
#endif
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
...
...
include/linux/acpi.h
View file @
d7374b3f
...
...
@@ -403,8 +403,8 @@ int acpi_pci_irq_init (void);
struct
acpi_pci_driver
{
struct
acpi_pci_driver
*
next
;
int
(
*
add
)(
acpi_handle
*
handle
);
void
(
*
remove
)(
acpi_handle
*
handle
);
int
(
*
add
)(
acpi_handle
handle
);
void
(
*
remove
)(
acpi_handle
handle
);
};
int
acpi_pci_register_driver
(
struct
acpi_pci_driver
*
driver
);
...
...
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