platform_drv: add "leave_operational" attribute

If a device should not be reset, powered off, and its clocks
shall stay untouched when it gets released, the leave_operational
attribute can be set to true in the device node of the related
device inside the devices ROM delivered to the platform driver.
This is useful for drivers, which only enable and initialize
their device, and can be closed afterwards.

Ref genodelabs/genode#4654
This commit is contained in:
Stefan Kalkowski 2022-10-27 14:37:42 +02:00 committed by Christian Helmuth
parent f0315b2715
commit 01e1e4e5b9
3 changed files with 28 additions and 20 deletions

View File

@ -92,25 +92,27 @@ void Driver::Device::release(Session_component & sc)
if (!(_owner == sc))
return;
pci_disable(_env, *this);
if (!_leave_operational) {
pci_disable(_env, *this);
_reset_domain_list.for_each([&] (Reset_domain & r)
{
_model.resets().apply(r.name, [&] (Driver::Reset &reset) {
reset.assert(); });
});
_reset_domain_list.for_each([&] (Reset_domain & r)
{
_model.resets().apply(r.name, [&] (Driver::Reset &reset) {
reset.assert(); });
});
_power_domain_list.for_each([&] (Power_domain & p)
{
_model.powers().apply(p.name, [&] (Driver::Power &power) {
power.off(); });
});
_power_domain_list.for_each([&] (Power_domain & p)
{
_model.powers().apply(p.name, [&] (Driver::Power &power) {
power.off(); });
});
_clock_list.for_each([&] (Clock & c)
{
_model.clocks().apply(c.name, [&] (Driver::Clock &clock) {
clock.disable(); });
});
_clock_list.for_each([&] (Clock & c)
{
_model.clocks().apply(c.name, [&] (Driver::Clock &clock) {
clock.disable(); });
});
}
_owner = Owner();
sc.update_devices_rom();
@ -181,8 +183,11 @@ void Driver::Device::generate(Xml_generator & xml, bool info) const
}
Driver::Device::Device(Env & env, Device_model & model, Name name, Type type)
: _env(env), _model(model), _name(name), _type(type) { }
Driver::Device::Device(Env & env, Device_model & model, Name name, Type type,
bool leave_operational)
:
_env(env), _model(model), _name(name), _type(type),
_leave_operational(leave_operational) { }
Driver::Device::~Device()

View File

@ -210,7 +210,8 @@ class Driver::Device : private List_model<Device>::Element
Reserved_memory(Range range) : range(range) {}
};
Device(Env & env, Device_model & model, Name name, Type type);
Device(Env & env, Device_model & model, Name name, Type type,
bool leave_operational);
virtual ~Device();
Name name() const;
@ -279,6 +280,7 @@ class Driver::Device : private List_model<Device>::Element
Device_model & _model;
Name const _name;
Type const _type;
bool const _leave_operational;
Owner _owner {};
List_model<Io_mem> _io_mem_list {};
List_model<Irq> _irq_list {};

View File

@ -71,7 +71,8 @@ Device & Device_model::create_element(Genode::Xml_node node)
{
Device::Name name = node.attribute_value("name", Device::Name());
Device::Type type = node.attribute_value("type", Device::Type());
return *(new (_heap) Device(_env, *this, name, type));
bool leave_operational = node.attribute_value("leave_operational", false);
return *(new (_heap) Device(_env, *this, name, type, leave_operational));
}