Commit 02426233 authored by Danilo Krummrich's avatar Danilo Krummrich
Browse files

rust: driver: let probe() return impl PinInit<Self, Error>



The driver model defines the lifetime of the private data stored in (and
owned by) a bus device to be valid from when the driver is bound to a
device (i.e. from successful probe()) until the driver is unbound from
the device.

This is already taken care of by the Rust implementation of the driver
model. However, we still ask drivers to return a Result<Pin<KBox<Self>>>
from probe().

Unlike in C, where we do not have the concept of initializers, but
rather deal with uninitialized memory, drivers can just return an
impl PinInit<Self, Error> instead.

This contributes to more clarity to the fact that a driver returns it's
device private data in probe() and the Rust driver model owns the data,
manages the lifetime and - considering the lifetime - provides (safe)
accessors for the driver.

Hence, let probe() functions return an impl PinInit<Self, Error> instead
of Result<Pin<KBox<Self>>>.

Reviewed-by: default avatarAlice Ryhl <aliceryhl@google.com>
Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
parent fc2b38de
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -207,9 +207,9 @@ impl platform::Driver for CPUFreqDTDriver {
    fn probe(
        pdev: &platform::Device<Core>,
        _id_info: Option<&Self::IdInfo>,
    ) -> Result<Pin<KBox<Self>>> {
    ) -> impl PinInit<Self, Error> {
        cpufreq::Registration::<CPUFreqDTDriver>::new_foreign_owned(pdev.as_ref())?;
        Ok(KBox::new(Self {}, GFP_KERNEL)?.into())
        Ok(Self {})
    }
}

+2 −2
Original line number Diff line number Diff line
@@ -45,13 +45,13 @@ impl auxiliary::Driver for NovaDriver {
    type IdInfo = ();
    const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;

    fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
    fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
        let data = try_pin_init!(NovaData { adev: adev.into() });

        let drm = drm::Device::<Self>::new(adev.as_ref(), data)?;
        drm::Registration::new_foreign_owned(&drm, adev.as_ref(), 0)?;

        Ok(KBox::new(Self { drm }, GFP_KERNEL)?.into())
        Ok(Self { drm })
    }
}

+2 −2
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ impl platform::Driver for TyrDriver {
    fn probe(
        pdev: &platform::Device<Core>,
        _info: Option<&Self::IdInfo>,
    ) -> Result<Pin<KBox<Self>>> {
    ) -> impl PinInit<Self, Error> {
        let core_clk = Clk::get(pdev.as_ref(), Some(c_str!("core")))?;
        let stacks_clk = OptionalClk::get(pdev.as_ref(), Some(c_str!("stacks")))?;
        let coregroup_clk = OptionalClk::get(pdev.as_ref(), Some(c_str!("coregroup")))?;
@@ -143,7 +143,7 @@ fn probe(
        let tdev: ARef<TyrDevice> = drm::Device::new(pdev.as_ref(), data)?;
        drm::driver::Registration::new_foreign_owned(&tdev, pdev.as_ref(), 0)?;

        let driver = KBox::pin_init(try_pin_init!(TyrDriver { device: tdev }), GFP_KERNEL)?;
        let driver = TyrDriver { device: tdev };

        // We need this to be dev_info!() because dev_dbg!() does not work at
        // all in Rust for now, and we need to see whether probe succeeded.
+13 −21
Original line number Diff line number Diff line
@@ -51,36 +51,28 @@ impl pci::Driver for NovaCore {
    type IdInfo = ();
    const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;

    fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
    fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> impl PinInit<Self, Error> {
        pin_init::pin_init_scope(move || {
            dev_dbg!(pdev.as_ref(), "Probe Nova Core GPU driver.\n");

            pdev.enable_device_mem()?;
            pdev.set_master();

        let devres_bar = Arc::pin_init(
            let bar = Arc::pin_init(
                pdev.iomap_region_sized::<BAR0_SIZE>(0, c_str!("nova-core/bar0")),
                GFP_KERNEL,
            )?;

        // Used to provided a `&Bar0` to `Gpu::new` without tying it to the lifetime of
        // `devres_bar`.
        let bar_clone = Arc::clone(&devres_bar);
        let bar = bar_clone.access(pdev.as_ref())?;

        let this = KBox::pin_init(
            try_pin_init!(Self {
                gpu <- Gpu::new(pdev, devres_bar, bar),
            Ok(try_pin_init!(Self {
                gpu <- Gpu::new(pdev, bar.clone(), bar.access(pdev.as_ref())?),
                _reg: auxiliary::Registration::new(
                    pdev.as_ref(),
                    c_str!("nova-drm"),
                    0, // TODO[XARR]: Once it lands, use XArray; for now we don't use the ID.
                    crate::MODULE_NAME
                )?,
            }),
            GFP_KERNEL,
        )?;

        Ok(this)
            }))
        })
    }

    fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
+3 −3
Original line number Diff line number Diff line
@@ -68,9 +68,9 @@ extern "C" fn probe_callback(
        let info = T::ID_TABLE.info(id.index());

        from_result(|| {
            let data = T::probe(adev, info)?;
            let data = T::probe(adev, info);

            adev.as_ref().set_drvdata(data);
            adev.as_ref().set_drvdata(data)?;
            Ok(0)
        })
    }
@@ -184,7 +184,7 @@ pub trait Driver {
    /// Auxiliary driver probe.
    ///
    /// Called when an auxiliary device is matches a corresponding driver.
    fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>;
    fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> impl PinInit<Self, Error>;
}

/// The auxiliary device representation.
Loading