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
2900681b
Commit
2900681b
authored
Dec 16, 2009
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'osc' into release
parents
243e1ef8
3563ff96
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
181 additions
and
64 deletions
+181
-64
drivers/acpi/bus.c
drivers/acpi/bus.c
+148
-0
drivers/acpi/pci_root.c
drivers/acpi/pci_root.c
+14
-62
include/linux/acpi.h
include/linux/acpi.h
+19
-2
No files found.
drivers/acpi/bus.c
View file @
2900681b
...
...
@@ -344,6 +344,152 @@ bool acpi_bus_can_wakeup(acpi_handle handle)
EXPORT_SYMBOL
(
acpi_bus_can_wakeup
);
static
void
acpi_print_osc_error
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
,
char
*
error
)
{
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
};
int
i
;
if
(
ACPI_FAILURE
(
acpi_get_name
(
handle
,
ACPI_FULL_PATHNAME
,
&
buffer
)))
printk
(
KERN_DEBUG
"%s
\n
"
,
error
);
else
{
printk
(
KERN_DEBUG
"%s:%s
\n
"
,
(
char
*
)
buffer
.
pointer
,
error
);
kfree
(
buffer
.
pointer
);
}
printk
(
KERN_DEBUG
"_OSC request data:"
);
for
(
i
=
0
;
i
<
context
->
cap
.
length
;
i
+=
sizeof
(
u32
))
printk
(
"%x "
,
*
((
u32
*
)(
context
->
cap
.
pointer
+
i
)));
printk
(
"
\n
"
);
}
static
u8
hex_val
(
unsigned
char
c
)
{
return
isdigit
(
c
)
?
c
-
'0'
:
toupper
(
c
)
-
'A'
+
10
;
}
static
acpi_status
acpi_str_to_uuid
(
char
*
str
,
u8
*
uuid
)
{
int
i
;
static
int
opc_map_to_uuid
[
16
]
=
{
6
,
4
,
2
,
0
,
11
,
9
,
16
,
14
,
19
,
21
,
24
,
26
,
28
,
30
,
32
,
34
};
if
(
strlen
(
str
)
!=
36
)
return
AE_BAD_PARAMETER
;
for
(
i
=
0
;
i
<
36
;
i
++
)
{
if
(
i
==
8
||
i
==
13
||
i
==
18
||
i
==
23
)
{
if
(
str
[
i
]
!=
'-'
)
return
AE_BAD_PARAMETER
;
}
else
if
(
!
isxdigit
(
str
[
i
]))
return
AE_BAD_PARAMETER
;
}
for
(
i
=
0
;
i
<
16
;
i
++
)
{
uuid
[
i
]
=
hex_val
(
str
[
opc_map_to_uuid
[
i
]])
<<
4
;
uuid
[
i
]
|=
hex_val
(
str
[
opc_map_to_uuid
[
i
]
+
1
]);
}
return
AE_OK
;
}
acpi_status
acpi_run_osc
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
)
{
acpi_status
status
;
struct
acpi_object_list
input
;
union
acpi_object
in_params
[
4
];
union
acpi_object
*
out_obj
;
u8
uuid
[
16
];
u32
errors
;
if
(
!
context
)
return
AE_ERROR
;
if
(
ACPI_FAILURE
(
acpi_str_to_uuid
(
context
->
uuid_str
,
uuid
)))
return
AE_ERROR
;
context
->
ret
.
length
=
ACPI_ALLOCATE_BUFFER
;
context
->
ret
.
pointer
=
NULL
;
/* Setting up input parameters */
input
.
count
=
4
;
input
.
pointer
=
in_params
;
in_params
[
0
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
0
].
buffer
.
length
=
16
;
in_params
[
0
].
buffer
.
pointer
=
uuid
;
in_params
[
1
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
1
].
integer
.
value
=
context
->
rev
;
in_params
[
2
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
2
].
integer
.
value
=
context
->
cap
.
length
/
sizeof
(
u32
);
in_params
[
3
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
3
].
buffer
.
length
=
context
->
cap
.
length
;
in_params
[
3
].
buffer
.
pointer
=
context
->
cap
.
pointer
;
status
=
acpi_evaluate_object
(
handle
,
"_OSC"
,
&
input
,
&
context
->
ret
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
/* return buffer should have the same length as cap buffer */
if
(
context
->
ret
.
length
!=
context
->
cap
.
length
)
return
AE_NULL_OBJECT
;
out_obj
=
context
->
ret
.
pointer
;
if
(
out_obj
->
type
!=
ACPI_TYPE_BUFFER
)
{
acpi_print_osc_error
(
handle
,
context
,
"_OSC evaluation returned wrong type"
);
status
=
AE_TYPE
;
goto
out_kfree
;
}
/* Need to ignore the bit0 in result code */
errors
=
*
((
u32
*
)
out_obj
->
buffer
.
pointer
)
&
~
(
1
<<
0
);
if
(
errors
)
{
if
(
errors
&
OSC_REQUEST_ERROR
)
acpi_print_osc_error
(
handle
,
context
,
"_OSC request failed"
);
if
(
errors
&
OSC_INVALID_UUID_ERROR
)
acpi_print_osc_error
(
handle
,
context
,
"_OSC invalid UUID"
);
if
(
errors
&
OSC_INVALID_REVISION_ERROR
)
acpi_print_osc_error
(
handle
,
context
,
"_OSC invalid revision"
);
if
(
errors
&
OSC_CAPABILITIES_MASK_ERROR
)
{
if
(((
u32
*
)
context
->
cap
.
pointer
)[
OSC_QUERY_TYPE
]
&
OSC_QUERY_ENABLE
)
goto
out_success
;
status
=
AE_SUPPORT
;
goto
out_kfree
;
}
status
=
AE_ERROR
;
goto
out_kfree
;
}
out_success:
return
AE_OK
;
out_kfree:
kfree
(
context
->
ret
.
pointer
);
context
->
ret
.
pointer
=
NULL
;
return
status
;
}
EXPORT_SYMBOL
(
acpi_run_osc
);
static
u8
sb_uuid_str
[]
=
"0811B06E-4A27-44F9-8D60-3CBBC22E7B48"
;
static
void
acpi_bus_osc_support
(
void
)
{
u32
capbuf
[
2
];
struct
acpi_osc_context
context
=
{
.
uuid_str
=
sb_uuid_str
,
.
rev
=
1
,
.
cap
.
length
=
8
,
.
cap
.
pointer
=
capbuf
,
};
acpi_handle
handle
;
capbuf
[
OSC_QUERY_TYPE
]
=
OSC_QUERY_ENABLE
;
capbuf
[
OSC_SUPPORT_TYPE
]
=
OSC_SB_PR3_SUPPORT
;
/* _PR3 is in use */
#ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
capbuf
[
OSC_SUPPORT_TYPE
]
|=
OSC_SB_PAD_SUPPORT
;
#endif
if
(
ACPI_FAILURE
(
acpi_get_handle
(
NULL
,
"
\\
_SB"
,
&
handle
)))
return
;
if
(
ACPI_SUCCESS
(
acpi_run_osc
(
handle
,
&
context
)))
kfree
(
context
.
ret
.
pointer
);
/* do we need to check the returned cap? Sounds no */
}
/* --------------------------------------------------------------------------
Event Management
-------------------------------------------------------------------------- */
...
...
@@ -734,6 +880,8 @@ static int __init acpi_bus_init(void)
status
=
acpi_ec_ecdt_probe
();
/* Ignore result. Not having an ECDT is not fatal. */
acpi_bus_osc_support
();
status
=
acpi_initialize_objects
(
ACPI_FULL_INITIALIZATION
);
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_ERR
PREFIX
"Unable to initialize ACPI objects
\n
"
);
...
...
drivers/acpi/pci_root.c
View file @
2900681b
...
...
@@ -202,72 +202,24 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
}
}
static
u8
OSC_UUID
[
16
]
=
{
0x5B
,
0x4D
,
0xDB
,
0x33
,
0xF7
,
0x1F
,
0x1C
,
0x40
,
0x96
,
0x57
,
0x74
,
0x41
,
0xC0
,
0x3D
,
0xD7
,
0x66
};
static
u8
pci_osc_uuid_str
[]
=
"33DB4D5B-1FF7-401C-9657-7441C03DD766"
;
static
acpi_status
acpi_pci_run_osc
(
acpi_handle
handle
,
const
u32
*
capbuf
,
u32
*
retval
)
{
struct
acpi_osc_context
context
=
{
.
uuid_str
=
pci_osc_uuid_str
,
.
rev
=
1
,
.
cap
.
length
=
12
,
.
cap
.
pointer
=
(
void
*
)
capbuf
,
};
acpi_status
status
;
struct
acpi_object_list
input
;
union
acpi_object
in_params
[
4
];
struct
acpi_buffer
output
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
union
acpi_object
*
out_obj
;
u32
errors
;
/* Setting up input parameters */
input
.
count
=
4
;
input
.
pointer
=
in_params
;
in_params
[
0
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
0
].
buffer
.
length
=
16
;
in_params
[
0
].
buffer
.
pointer
=
OSC_UUID
;
in_params
[
1
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
1
].
integer
.
value
=
1
;
in_params
[
2
].
type
=
ACPI_TYPE_INTEGER
;
in_params
[
2
].
integer
.
value
=
3
;
in_params
[
3
].
type
=
ACPI_TYPE_BUFFER
;
in_params
[
3
].
buffer
.
length
=
12
;
in_params
[
3
].
buffer
.
pointer
=
(
u8
*
)
capbuf
;
status
=
acpi_evaluate_object
(
handle
,
"_OSC"
,
&
input
,
&
output
);
if
(
ACPI_FAILURE
(
status
))
return
status
;
if
(
!
output
.
length
)
return
AE_NULL_OBJECT
;
out_obj
=
output
.
pointer
;
if
(
out_obj
->
type
!=
ACPI_TYPE_BUFFER
)
{
printk
(
KERN_DEBUG
"_OSC evaluation returned wrong type
\n
"
);
status
=
AE_TYPE
;
goto
out_kfree
;
}
/* Need to ignore the bit0 in result code */
errors
=
*
((
u32
*
)
out_obj
->
buffer
.
pointer
)
&
~
(
1
<<
0
);
if
(
errors
)
{
if
(
errors
&
OSC_REQUEST_ERROR
)
printk
(
KERN_DEBUG
"_OSC request failed
\n
"
);
if
(
errors
&
OSC_INVALID_UUID_ERROR
)
printk
(
KERN_DEBUG
"_OSC invalid UUID
\n
"
);
if
(
errors
&
OSC_INVALID_REVISION_ERROR
)
printk
(
KERN_DEBUG
"_OSC invalid revision
\n
"
);
if
(
errors
&
OSC_CAPABILITIES_MASK_ERROR
)
{
if
(
capbuf
[
OSC_QUERY_TYPE
]
&
OSC_QUERY_ENABLE
)
goto
out_success
;
printk
(
KERN_DEBUG
"Firmware did not grant requested _OSC control
\n
"
);
status
=
AE_SUPPORT
;
goto
out_kfree
;
}
status
=
AE_ERROR
;
goto
out_kfree
;
status
=
acpi_run_osc
(
handle
,
&
context
);
if
(
ACPI_SUCCESS
(
status
))
{
*
retval
=
*
((
u32
*
)(
context
.
ret
.
pointer
+
8
));
kfree
(
context
.
ret
.
pointer
);
}
out_success:
*
retval
=
*
((
u32
*
)(
out_obj
->
buffer
.
pointer
+
8
));
status
=
AE_OK
;
out_kfree:
kfree
(
output
.
pointer
);
return
status
;
}
...
...
@@ -277,10 +229,10 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
u32
support_set
,
result
,
capbuf
[
3
];
/* do _OSC query for all possible controls */
support_set
=
root
->
osc_support_set
|
(
flags
&
OSC_SUPPORT_MASKS
);
support_set
=
root
->
osc_support_set
|
(
flags
&
OSC_
PCI_
SUPPORT_MASKS
);
capbuf
[
OSC_QUERY_TYPE
]
=
OSC_QUERY_ENABLE
;
capbuf
[
OSC_SUPPORT_TYPE
]
=
support_set
;
capbuf
[
OSC_CONTROL_TYPE
]
=
OSC_CONTROL_MASKS
;
capbuf
[
OSC_CONTROL_TYPE
]
=
OSC_
PCI_
CONTROL_MASKS
;
status
=
acpi_pci_run_osc
(
root
->
device
->
handle
,
capbuf
,
&
result
);
if
(
ACPI_SUCCESS
(
status
))
{
...
...
@@ -427,7 +379,7 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
if
(
ACPI_FAILURE
(
status
))
return
status
;
control_req
=
(
flags
&
OSC_CONTROL_MASKS
);
control_req
=
(
flags
&
OSC_
PCI_
CONTROL_MASKS
);
if
(
!
control_req
)
return
AE_TYPE
;
...
...
include/linux/acpi.h
View file @
2900681b
...
...
@@ -253,10 +253,16 @@ void __init acpi_old_suspend_ordering(void);
void
__init
acpi_s4_no_nvs
(
void
);
#endif
/* CONFIG_PM_SLEEP */
struct
acpi_osc_context
{
char
*
uuid_str
;
/* uuid string */
int
rev
;
struct
acpi_buffer
cap
;
/* arg2/arg3 */
struct
acpi_buffer
ret
;
/* free by caller if success */
};
#define OSC_QUERY_TYPE 0
#define OSC_SUPPORT_TYPE 1
#define OSC_CONTROL_TYPE 2
#define OSC_SUPPORT_MASKS 0x1f
/* _OSC DW0 Definition */
#define OSC_QUERY_ENABLE 1
...
...
@@ -265,12 +271,23 @@ void __init acpi_s4_no_nvs(void);
#define OSC_INVALID_REVISION_ERROR 8
#define OSC_CAPABILITIES_MASK_ERROR 16
acpi_status
acpi_run_osc
(
acpi_handle
handle
,
struct
acpi_osc_context
*
context
);
/* platform-wide _OSC bits */
#define OSC_SB_PAD_SUPPORT 1
#define OSC_SB_PPC_OST_SUPPORT 2
#define OSC_SB_PR3_SUPPORT 4
#define OSC_SB_CPUHP_OST_SUPPORT 8
#define OSC_SB_APEI_SUPPORT 16
/* PCI defined _OSC bits */
/* _OSC DW1 Definition (OS Support Fields) */
#define OSC_EXT_PCI_CONFIG_SUPPORT 1
#define OSC_ACTIVE_STATE_PWR_SUPPORT 2
#define OSC_CLOCK_PWR_CAPABILITY_SUPPORT 4
#define OSC_PCI_SEGMENT_GROUPS_SUPPORT 8
#define OSC_MSI_SUPPORT 16
#define OSC_PCI_SUPPORT_MASKS 0x1f
/* _OSC DW1 Definition (OS Control Fields) */
#define OSC_PCI_EXPRESS_NATIVE_HP_CONTROL 1
...
...
@@ -279,7 +296,7 @@ void __init acpi_s4_no_nvs(void);
#define OSC_PCI_EXPRESS_AER_CONTROL 8
#define OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL 16
#define OSC_CONTROL_MASKS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
#define OSC_
PCI_
CONTROL_MASKS (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | \
OSC_SHPC_NATIVE_HP_CONTROL | \
OSC_PCI_EXPRESS_PME_CONTROL | \
OSC_PCI_EXPRESS_AER_CONTROL | \
...
...
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