/* * Copyright (c) 2024, Sönke Holz * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Kernel::DeviceTree { using DriverInitFunction = void (*)(); class Driver { AK_MAKE_NONCOPYABLE(Driver); AK_MAKE_NONMOVABLE(Driver); public: Driver(StringView name) : m_driver_name(name) { } virtual ~Driver() = default; virtual Span compatibles() const = 0; virtual ErrorOr probe(Device const&, StringView compatible_entry) const = 0; StringView name() const { return m_driver_name; } private: StringView const m_driver_name; }; #define DEVICETREE_DRIVER(driver_name, compatibles_array) \ class driver_name final : public Kernel::DeviceTree::Driver { \ public: \ driver_name() \ : Kernel::DeviceTree::Driver(#driver_name##sv) \ { \ } \ \ static void init(); \ Span compatibles() const override { return compatibles_array; } \ ErrorOr probe(Kernel::DeviceTree::Device const& device, StringView compatible_entry) const override; \ }; \ \ void driver_name::init() \ { \ auto driver = MUST(adopt_nonnull_own_or_enomem(new (nothrow) driver_name())); \ MUST(Kernel::DeviceTree::Management::register_driver(move(driver))); \ } \ \ static Kernel::DeviceTree::DriverInitFunction driver_init_function_ptr_##driver_name [[gnu::section(".driver_init"), gnu::used]] = &driver_name::init }