blob: 03edc42dd4f473b0fe8d4e4e82681d98b4ca05e4 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/devices/bus/drivers/platform/platform-interrupt.h"
#include <fidl/fuchsia.hardware.interrupt/cpp/markers.h>
#include <iterator>
#include <bind/fuchsia/cpp/bind.h>
#include "src/devices/bus/drivers/platform/platform-bus.h"
#include "src/devices/bus/drivers/platform/platform-device.h"
namespace platform_bus {
void PlatformInterruptFragment::Get(GetCompleter::Sync& completer) {
zx::result irq = pdev_->GetInterrupt(index_, 0);
if (irq.is_error()) {
completer.ReplyError(irq.status_value());
} else {
completer.ReplySuccess(std::move(irq.value()));
}
}
zx::result<> PlatformInterruptFragment::Add(std::string_view name, PlatformDevice* pdev,
fuchsia_hardware_platform_bus::Irq& irq) {
fuchsia_hardware_interrupt::Service::InstanceHandler handler(
{.provider = bindings_.CreateHandler(this, dispatcher_, fidl::kIgnoreBindingClosure)});
zx::result result = pdev->bus()->outgoing()->AddService<fuchsia_hardware_interrupt::Service>(
std::move(handler), name);
if (result.is_error()) {
return result.take_error();
}
std::array offers = {
fdf::MakeOffer2<fuchsia_hardware_interrupt::Service>(name),
};
std::vector<fuchsia_driver_framework::NodeProperty2> props;
if (const auto& irq_props = irq.properties(); irq_props.has_value()) {
std::copy(irq_props->cbegin(), irq_props->cend(), std::back_inserter(props));
} else {
props = {
fdf::MakeProperty2(bind_fuchsia::PLATFORM_DEV_VID, pdev->vid()),
fdf::MakeProperty2(bind_fuchsia::PLATFORM_DEV_DID, pdev->did()),
fdf::MakeProperty2(bind_fuchsia::PLATFORM_DEV_PID, pdev->pid()),
fdf::MakeProperty2(bind_fuchsia::PLATFORM_DEV_INSTANCE_ID, pdev->instance_id()),
// Because "x == 0" is true if "x" is unset, start at 1.
fdf::MakeProperty2(bind_fuchsia::PLATFORM_DEV_INTERRUPT_ID, index_ + 1),
};
}
zx::result child =
fdf::AddChild(pdev->bus()->platform_node(), pdev->bus()->logger(), name, props, offers);
if (child.is_error()) {
return child.take_error();
}
node_ = std::move(child.value());
return zx::ok();
}
} // namespace platform_bus