diff options
author | Myron Stowe <myron.stowe@hp.com> | 2010-10-21 16:24:04 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-10-24 23:27:09 -0400 |
commit | d362edaf5386acedad4319a6721bb1540b74dcf7 (patch) | |
tree | 501cdcf9c8788ff7f3d9d23404c8796801baa4f4 /drivers/acpi/osl.c | |
parent | 29718521237a1b1607ea05b49243100ea2044337 (diff) |
ACPI: Pre-map 'system event' related register blocks
During ACPI initialization, pre-map fixed hardware registers that are
accessed during ACPI's 'system event' related IRQ handing.
ACPI's 'system event' handing accesses specific fixed hardware
registers; namely PM1a event, PM1b event, GPE0, and GPE1 register
blocks which are declared within the FADT. If these registers are
backed by MMIO, as opposed to I/O port space, accessing them within
interrupt context will cause a panic as acpi_os_read_memory()
depends on ioremap() in such cases - BZ 18012.
By utilizing the functionality provided in the previous two patches -
ACPI: Maintain a list of ACPI memory mapped I/O remappings, and, ACPI:
Add interfaces for ioremapping/iounmapping ACPI registers - accesses
to ACPI MMIO areas will now be safe from within interrupt contexts (IRQ
and/or NMI) provided the area was pre-mapped. This solves BZ 18012.
ACPI "System Event" reference(s):
ACPI Specification, Revision 4.0, Section 3 "ACPI Overview",
3.8 "System Events", 5.6 "ACPI Event Programming Model".
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=18012
Reported-by: <bjorn.helgaas@hp.com>
Signed-off-by: Myron Stowe <myron.stowe@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index fc6c5d21c3eb..c63d4cb37dab 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -199,36 +199,6 @@ static int __init acpi_reserve_resources(void) | |||
199 | } | 199 | } |
200 | device_initcall(acpi_reserve_resources); | 200 | device_initcall(acpi_reserve_resources); |
201 | 201 | ||
202 | acpi_status __init acpi_os_initialize(void) | ||
203 | { | ||
204 | return AE_OK; | ||
205 | } | ||
206 | |||
207 | acpi_status acpi_os_initialize1(void) | ||
208 | { | ||
209 | kacpid_wq = create_workqueue("kacpid"); | ||
210 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | ||
211 | kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); | ||
212 | BUG_ON(!kacpid_wq); | ||
213 | BUG_ON(!kacpi_notify_wq); | ||
214 | BUG_ON(!kacpi_hotplug_wq); | ||
215 | return AE_OK; | ||
216 | } | ||
217 | |||
218 | acpi_status acpi_os_terminate(void) | ||
219 | { | ||
220 | if (acpi_irq_handler) { | ||
221 | acpi_os_remove_interrupt_handler(acpi_irq_irq, | ||
222 | acpi_irq_handler); | ||
223 | } | ||
224 | |||
225 | destroy_workqueue(kacpid_wq); | ||
226 | destroy_workqueue(kacpi_notify_wq); | ||
227 | destroy_workqueue(kacpi_hotplug_wq); | ||
228 | |||
229 | return AE_OK; | ||
230 | } | ||
231 | |||
232 | void acpi_os_printf(const char *fmt, ...) | 202 | void acpi_os_printf(const char *fmt, ...) |
233 | { | 203 | { |
234 | va_list args; | 204 | va_list args; |
@@ -1598,5 +1568,44 @@ acpi_os_validate_address ( | |||
1598 | } | 1568 | } |
1599 | return AE_OK; | 1569 | return AE_OK; |
1600 | } | 1570 | } |
1601 | |||
1602 | #endif | 1571 | #endif |
1572 | |||
1573 | acpi_status __init acpi_os_initialize(void) | ||
1574 | { | ||
1575 | acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block); | ||
1576 | acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block); | ||
1577 | acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block); | ||
1578 | acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block); | ||
1579 | |||
1580 | return AE_OK; | ||
1581 | } | ||
1582 | |||
1583 | acpi_status acpi_os_initialize1(void) | ||
1584 | { | ||
1585 | kacpid_wq = create_workqueue("kacpid"); | ||
1586 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | ||
1587 | kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); | ||
1588 | BUG_ON(!kacpid_wq); | ||
1589 | BUG_ON(!kacpi_notify_wq); | ||
1590 | BUG_ON(!kacpi_hotplug_wq); | ||
1591 | return AE_OK; | ||
1592 | } | ||
1593 | |||
1594 | acpi_status acpi_os_terminate(void) | ||
1595 | { | ||
1596 | if (acpi_irq_handler) { | ||
1597 | acpi_os_remove_interrupt_handler(acpi_irq_irq, | ||
1598 | acpi_irq_handler); | ||
1599 | } | ||
1600 | |||
1601 | acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block); | ||
1602 | acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block); | ||
1603 | acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block); | ||
1604 | acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block); | ||
1605 | |||
1606 | destroy_workqueue(kacpid_wq); | ||
1607 | destroy_workqueue(kacpi_notify_wq); | ||
1608 | destroy_workqueue(kacpi_hotplug_wq); | ||
1609 | |||
1610 | return AE_OK; | ||
1611 | } | ||