mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 18:06:50 +00:00
acpica: execute suspend&resume ACPI methods
on 'system' ROM state changes. Issue #4669
This commit is contained in:
parent
58ff53ec52
commit
dee178aae5
@ -46,7 +46,7 @@ Excerpt of important parts of the acpica configuration
|
|||||||
!<start name="acpica">
|
!<start name="acpica">
|
||||||
! <!-- <binary name="debug-acpica"/> -->
|
! <!-- <binary name="debug-acpica"/> -->
|
||||||
! ...
|
! ...
|
||||||
! <config reset="no" poweroff="no" report="yes" report_period_ms="2000"/>
|
! <config reset="no" sleep="no" poweroff="no" report="yes" report_period_ms="2000"/>
|
||||||
! <route>
|
! <route>
|
||||||
! <service name="ROM" label="system"> <child name="..."/> </service>
|
! <service name="ROM" label="system"> <child name="..."/> </service>
|
||||||
! <service name="Report"> <child name="..."/> </service>
|
! <service name="Report"> <child name="..."/> </service>
|
||||||
|
@ -55,18 +55,70 @@ struct Acpica::Statechange
|
|||||||
Attached_rom_dataspace _system_state;
|
Attached_rom_dataspace _system_state;
|
||||||
bool _enable_reset;
|
bool _enable_reset;
|
||||||
bool _enable_poweroff;
|
bool _enable_poweroff;
|
||||||
|
bool _enable_sleep;
|
||||||
|
|
||||||
Statechange(Env &env, bool reset, bool poweroff)
|
Statechange(Env &env, bool reset, bool poweroff, bool sleep)
|
||||||
:
|
:
|
||||||
_dispatcher(env.ep(), *this, &Statechange::state_changed),
|
_dispatcher(env.ep(), *this, &Statechange::state_changed),
|
||||||
_system_state(env, "system"),
|
_system_state(env, "system"),
|
||||||
_enable_reset(reset), _enable_poweroff(poweroff)
|
_enable_reset(reset), _enable_poweroff(poweroff), _enable_sleep(sleep)
|
||||||
{
|
{
|
||||||
_system_state.sigh(_dispatcher);
|
_system_state.sigh(_dispatcher);
|
||||||
|
|
||||||
state_changed();
|
state_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void suspend_prepare_check(T const &state)
|
||||||
|
{
|
||||||
|
if (!_enable_sleep)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UINT8 sleep_state = 0;
|
||||||
|
|
||||||
|
if (state == "s0_prepare") { sleep_state = 0; } else
|
||||||
|
if (state == "s1_prepare") { sleep_state = 1; } else
|
||||||
|
if (state == "s2_prepare") { sleep_state = 2; } else
|
||||||
|
if (state == "s3_prepare") { sleep_state = 3; } else
|
||||||
|
if (state == "s4_prepare") { sleep_state = 4; } else
|
||||||
|
if (state == "s5_prepare") { sleep_state = 5; } else
|
||||||
|
return;
|
||||||
|
|
||||||
|
Genode::log("prepare suspend S", sleep_state);
|
||||||
|
|
||||||
|
ACPI_STATUS res = AcpiEnterSleepStatePrep(sleep_state);
|
||||||
|
if (ACPI_FAILURE(res))
|
||||||
|
Genode::error("AcpiEnterSleepStatePrep failed ",
|
||||||
|
res, " ", AcpiFormatException(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void resume_check(T const &state)
|
||||||
|
{
|
||||||
|
if (!_enable_sleep)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UINT8 sleep_state = 0;
|
||||||
|
|
||||||
|
if (state == "s0_resume") { sleep_state = 0; } else
|
||||||
|
if (state == "s1_resume") { sleep_state = 1; } else
|
||||||
|
if (state == "s2_resume") { sleep_state = 2; } else
|
||||||
|
if (state == "s3_resume") { sleep_state = 3; } else
|
||||||
|
if (state == "s4_resume") { sleep_state = 4; } else
|
||||||
|
if (state == "s5_resume") { sleep_state = 5; } else
|
||||||
|
return;
|
||||||
|
|
||||||
|
ACPI_STATUS res = AcpiLeaveSleepStatePrep(sleep_state);
|
||||||
|
if (ACPI_FAILURE(res))
|
||||||
|
Genode::error("AcpiLeaveSleepStatePrep failed ",
|
||||||
|
res, " ", AcpiFormatException(res));
|
||||||
|
|
||||||
|
res = AcpiLeaveSleepState(sleep_state);
|
||||||
|
if (ACPI_FAILURE(res))
|
||||||
|
Genode::error("AcpiLeaveSleepState failed ",
|
||||||
|
res, " ", AcpiFormatException(res));
|
||||||
|
}
|
||||||
|
|
||||||
void state_changed() {
|
void state_changed() {
|
||||||
|
|
||||||
_system_state.update();
|
_system_state.update();
|
||||||
@ -98,6 +150,11 @@ struct Acpica::Statechange
|
|||||||
" spaceid=", Hex(AcpiGbl_FADT.ResetRegister.SpaceId),
|
" spaceid=", Hex(AcpiGbl_FADT.ResetRegister.SpaceId),
|
||||||
" addr=", Hex(space_addr));
|
" addr=", Hex(space_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend_prepare_check(state);
|
||||||
|
|
||||||
|
resume_check(state);
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -139,6 +196,7 @@ struct Acpica::Main
|
|||||||
sci_irq(env.ep(), *this, &Main::acpi_irq),
|
sci_irq(env.ep(), *this, &Main::acpi_irq),
|
||||||
unchanged_state_max(config.xml().attribute_value("update_unchanged", 10U))
|
unchanged_state_max(config.xml().attribute_value("update_unchanged", 10U))
|
||||||
{
|
{
|
||||||
|
bool const enable_sleep = config.xml().attribute_value("sleep", false);
|
||||||
bool const enable_reset = config.xml().attribute_value("reset", false);
|
bool const enable_reset = config.xml().attribute_value("reset", false);
|
||||||
bool const enable_poweroff = config.xml().attribute_value("poweroff", false);
|
bool const enable_poweroff = config.xml().attribute_value("poweroff", false);
|
||||||
bool const enable_report = config.xml().attribute_value("report", false);
|
bool const enable_report = config.xml().attribute_value("report", false);
|
||||||
@ -152,8 +210,9 @@ struct Acpica::Main
|
|||||||
if (enable_report)
|
if (enable_report)
|
||||||
report->enable();
|
report->enable();
|
||||||
|
|
||||||
if (enable_reset || enable_poweroff)
|
if (enable_reset || enable_poweroff || enable_sleep)
|
||||||
new (heap) Acpica::Statechange(env, enable_reset, enable_poweroff);
|
new (heap) Acpica::Statechange(env, enable_reset, enable_poweroff,
|
||||||
|
enable_sleep);
|
||||||
|
|
||||||
/* setup IRQ */
|
/* setup IRQ */
|
||||||
if (!irq_handler.handler) {
|
if (!irq_handler.handler) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user