diff --git a/drivers/gpu/drm/panthor-rs/Makefile b/drivers/gpu/drm/panthor-rs/Makefile
index 29f3096194fd33c9ab0e946cfb5c6786d18c015e..d64b0b7292897eea231c7d6c78f77fd6e7281123 100644
--- a/drivers/gpu/drm/panthor-rs/Makefile
+++ b/drivers/gpu/drm/panthor-rs/Makefile
@@ -1,6 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0 or MIT
 
 panthor_rs-y := \
+	panthor_devfreq.o \
+	panthor_device.o \
+	panthor_drv.o \
+	panthor_fw.o \
+	panthor_gem.o \
+	panthor_gpu.o \
+	panthor_heap.o \
+	panthor_mmu.o \
+	panthor_sched.o \
 	panthor.o
 
 obj-$(CONFIG_DRM_PANTHOR_RS) += panthor_rs.o
diff --git a/drivers/gpu/drm/panthor-rs/file.rs b/drivers/gpu/drm/panthor-rs/file.rs
index 2f2486f86e160d4a3d0d60f9a2de793a4398aeac..e25d47b9a380b69ad1a2bed9ea136858541b6180 100644
--- a/drivers/gpu/drm/panthor-rs/file.rs
+++ b/drivers/gpu/drm/panthor-rs/file.rs
@@ -19,6 +19,7 @@ use kernel::{
     drm::file::GenericFile,
     uapi,
     error::to_result,
+    bindings,
 };
 use core;
 use core::ptr;
@@ -27,6 +28,34 @@ use core::ffi;
 /// Convenience type alias for our DRM `File` type.
 pub(crate) type DrmFile = drm::file::File<File>;
 
+extern "C" {
+    fn _panthor_ioctl_dev_query(ptdev: *mut bindings::panthor_device, args: *mut uapi::drm_panthor_dev_query) -> ffi::c_int;
+    fn _panthor_ioctl_vm_create(ptdev: *mut bindings::panthor_device, data: *mut uapi::drm_panthor_vm_create, file: *const bindings::drm_file) -> ffi::c_int;
+    fn panthor_ioctl_vm_bind_async(args: *mut uapi::drm_panthor_vm_bind, file: *mut bindings::drm_file) -> ffi::c_int;
+    fn panthor_ioctl_vm_bind_sync(args: *mut uapi::drm_panthor_vm_bind, file: *mut bindings::drm_file) -> ffi::c_int;
+    fn panthor_group_submit(
+        ddev: *mut bindings::drm_device,
+        args: *mut uapi::drm_panthor_group_submit,
+        file: *mut bindings::drm_file,
+    ) -> core::ffi::c_int;
+    fn panthor_tiler_heap_create(
+        pfile: *mut bindings::panthor_file,
+        args: *mut uapi::drm_panthor_tiler_heap_create,
+    ) -> core::ffi::c_int;
+    fn panthor_tiler_heap_destroy(
+        pfile: *mut bindings::panthor_file,
+        args: *const uapi::drm_panthor_tiler_heap_destroy,
+    ) -> core::ffi::c_int;
+    fn _panthor_group_create(
+        args: *mut uapi::drm_panthor_group_create,
+        pfile: *mut bindings::panthor_file,
+    ) -> core::ffi::c_int;
+    fn panthor_group_get_state(
+        pfile: *mut bindings::panthor_file,
+        get_state: *mut uapi::drm_panthor_group_get_state,
+    ) -> core::ffi::c_int;
+}
+
 /// State associated with a client.
 #[repr(C)]
 pub(crate) struct File {
@@ -59,6 +88,11 @@ impl File {
         data: &mut uapi::drm_panthor_dev_query,
         _file: &DrmFile,
     ) -> Result<u32> {
+        let devdata = device.data();
+
+        to_result(unsafe {
+            _panthor_ioctl_dev_query(devdata.ptdev, data)
+        })?;
         Ok(0)
     }
 
@@ -68,6 +102,11 @@ impl File {
         data: &mut uapi::drm_panthor_vm_create,
         file: &DrmFile,
     ) -> Result<u32> {
+        let devdata = device.data();
+
+        to_result(unsafe {
+            _panthor_ioctl_vm_create(devdata.ptdev, data, file.raw())
+        })?;
         Ok(0)
     }
 
@@ -77,6 +116,14 @@ impl File {
         data: &mut uapi::drm_panthor_vm_destroy,
         file: &DrmFile,
     ) -> Result<u32> {
+        if data.pad != 0 {
+            return Err(EINVAL);
+        }
+
+        to_result(unsafe {
+            let pfile: *mut bindings::panthor_file = (*file.raw()).driver_priv as *mut _;
+            bindings::panthor_vm_pool_destroy_vm((*pfile).vms, data.id)
+        })?;
         Ok(0)
     }
 
@@ -86,6 +133,13 @@ impl File {
         data: &mut uapi::drm_panthor_vm_bind,
         file: &DrmFile,
     ) -> Result<u32> {
+        //TODO: drm_dev_enter(device., &cookie))
+
+        if data.flags == uapi::drm_panthor_vm_bind_flags_DRM_PANTHOR_VM_BIND_ASYNC {
+            to_result(unsafe {panthor_ioctl_vm_bind_async(data, file.raw() as *mut _)})?;
+        } else {
+            to_result(unsafe {panthor_ioctl_vm_bind_sync(data, file.raw() as *mut _)})?;
+        }
         Ok(0)
     }
 
@@ -95,6 +149,20 @@ impl File {
         data: &mut uapi::drm_panthor_vm_get_state,
         file: &DrmFile,
     ) -> Result<u32> {
+        let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+        let vm = unsafe { bindings::panthor_vm_pool_get_vm((*pfile).vms, data.vm_id) };
+
+        if vm.is_null() {
+            return Err(EINVAL);
+        }
+
+        if unsafe {bindings::panthor_vm_is_unusable(vm)} {
+            data.state = uapi::drm_panthor_vm_state_DRM_PANTHOR_VM_STATE_UNUSABLE;
+        } else {
+            data.state = uapi::drm_panthor_vm_state_DRM_PANTHOR_VM_STATE_USABLE;
+        }
+
+        unsafe {bindings::panthor_vm_put(vm)};
         Ok(0)
     }
 
@@ -104,6 +172,32 @@ impl File {
         data: &mut uapi::drm_panthor_bo_create,
         file: &DrmFile,
     ) -> Result<u32> {
+        //TODO if (!drm_dev_enter(ddev, &cookie))
+        //    return -ENODEV;
+
+    if data.size == 0 || data.pad != 0 ||
+       (data.flags & !uapi::drm_panthor_bo_flags_DRM_PANTHOR_BO_NO_MMAP != 0) {
+            return Err(EINVAL);
+        }
+
+        let mut vm = ptr::null_mut();
+        if data.exclusive_vm_id != 0 {
+            let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+            vm = unsafe { bindings::panthor_vm_pool_get_vm((*pfile).vms, data.exclusive_vm_id) };
+
+            if vm.is_null() {
+                return Err(EINVAL);
+            }
+        }
+
+        let ret = unsafe {
+            let ptdev = device.data().ptdev;
+            bindings::panthor_gem_create_with_handle(file.raw() as *mut _, (*ptdev).base,
+                vm, &mut data.size as *mut _, data.flags, &mut data.handle as *mut _)
+        };
+        unsafe {bindings::panthor_vm_put(vm)};
+
+        to_result(ret)?;
         Ok(0)
     }
 
@@ -122,6 +216,9 @@ impl File {
         data: &mut uapi::drm_panthor_group_create,
         file: &DrmFile,
     ) -> Result<u32> {
+        let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+
+        to_result(unsafe {_panthor_group_create(data, pfile)})?;
         Ok(0)
     }
 
@@ -131,6 +228,13 @@ impl File {
         data: &mut uapi::drm_panthor_group_destroy,
         file: &DrmFile,
     ) -> Result<u32> {
+        if data.pad != 0 {
+            return Err(EINVAL)
+        }
+
+        let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+
+        to_result(unsafe {bindings::panthor_group_destroy(pfile, data.group_handle)})?;
         Ok(0)
     }
 
@@ -140,6 +244,9 @@ impl File {
         data: &mut uapi::drm_panthor_group_get_state,
         file: &DrmFile,
     ) -> Result<u32> {
+        let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+
+        to_result(unsafe {panthor_group_get_state(pfile, data)})?;
         Ok(0)
     }
 
@@ -149,6 +256,9 @@ impl File {
         data: &mut uapi::drm_panthor_tiler_heap_create,
         file: &DrmFile,
     ) -> Result<u32> {
+        let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+
+        to_result(unsafe {panthor_tiler_heap_create(pfile, data)})?;
         Ok(0)
     }
 
@@ -158,6 +268,9 @@ impl File {
         data: &mut uapi::drm_panthor_tiler_heap_destroy,
         file: &DrmFile,
     ) -> Result<u32> {
+        let pfile: *mut bindings::panthor_file = unsafe {(*file.raw()).driver_priv as *mut _};
+
+        to_result(unsafe {panthor_tiler_heap_destroy(pfile, data)})?;
         Ok(0)
     }
 
@@ -167,6 +280,10 @@ impl File {
         data: &mut uapi::drm_panthor_group_submit,
         file: &DrmFile,
     ) -> Result<u32> {
+        to_result(unsafe {
+            let ptdev = device.data().ptdev;
+            panthor_group_submit((*ptdev).base, data, file.raw() as *mut _)
+        })?;
         Ok(0)
     }
 }
diff --git a/drivers/gpu/drm/panthor-rs/panthor_drv.c b/drivers/gpu/drm/panthor-rs/panthor_drv.c
index 47ebc714288ac05bf23b2cc6a45d5d567d079d6e..fd7fcb2c14bcecbc20eb40f85ee151d8ddc09faf 100644
--- a/drivers/gpu/drm/panthor-rs/panthor_drv.c
+++ b/drivers/gpu/drm/panthor-rs/panthor_drv.c
@@ -746,11 +746,8 @@ static void panthor_submit_ctx_cleanup(struct panthor_submit_ctx *ctx,
 	kvfree(ctx->jobs);
 }
 
-static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct drm_file *file)
+int _panthor_ioctl_dev_query(struct panthor_device *ptdev, struct drm_panthor_dev_query *args)
 {
-	struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base);
-	struct drm_panthor_dev_query *args = data;
-
 	if (!args->pointer) {
 		switch (args->type) {
 		case DRM_PANTHOR_DEV_QUERY_GPU_INFO:
@@ -780,15 +777,13 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d
 
 #define PANTHOR_VM_CREATE_FLAGS			0
 
-static int panthor_ioctl_vm_create(struct drm_device *ddev, void *data,
-				   struct drm_file *file)
+int _panthor_ioctl_vm_create(struct panthor_device *ptdev, struct drm_panthor_vm_create *args,
+			    const struct drm_file *file)
 {
-	struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base);
 	struct panthor_file *pfile = file->driver_priv;
-	struct drm_panthor_vm_create *args = data;
 	int cookie, ret;
 
-	if (!drm_dev_enter(ddev, &cookie))
+	if (!drm_dev_enter(ptdev->base, &cookie))
 		return -ENODEV;
 
 	ret = panthor_vm_pool_create_vm(ptdev, pfile->vms,  args);
@@ -875,11 +870,10 @@ static int panthor_ioctl_bo_mmap_offset(struct drm_device *ddev, void *data,
 	return ret;
 }
 
-static int panthor_ioctl_group_submit(struct drm_device *ddev, void *data,
-				      struct drm_file *file)
+int panthor_group_submit(struct drm_device *ddev, struct drm_panthor_group_submit *args,
+			 struct drm_file *file)
 {
 	struct panthor_file *pfile = file->driver_priv;
-	struct drm_panthor_group_submit *args = data;
 	struct drm_panthor_queue_submit *jobs_args;
 	struct panthor_submit_ctx ctx;
 	int ret = 0, cookie;
@@ -992,11 +986,9 @@ static int panthor_ioctl_group_destroy(struct drm_device *ddev, void *data,
 	return panthor_group_destroy(pfile, args->group_handle);
 }
 
-static int panthor_ioctl_group_create(struct drm_device *ddev, void *data,
-				      struct drm_file *file)
+int _panthor_group_create(struct drm_panthor_group_create *args,
+			  struct panthor_file *pfile)
 {
-	struct panthor_file *pfile = file->driver_priv;
-	struct drm_panthor_group_create *args = data;
 	struct drm_panthor_queue_create *queue_args;
 	int ret;
 
@@ -1026,11 +1018,9 @@ static int panthor_ioctl_group_get_state(struct drm_device *ddev, void *data,
 	return panthor_group_get_state(pfile, args);
 }
 
-static int panthor_ioctl_tiler_heap_create(struct drm_device *ddev, void *data,
-					   struct drm_file *file)
+int panthor_tiler_heap_create(struct panthor_file *pfile,
+			      struct drm_panthor_tiler_heap_create *args)
 {
-	struct panthor_file *pfile = file->driver_priv;
-	struct drm_panthor_tiler_heap_create *args = data;
 	struct panthor_heap_pool *pool;
 	struct panthor_vm *vm;
 	int ret;
@@ -1069,11 +1059,9 @@ static int panthor_ioctl_tiler_heap_create(struct drm_device *ddev, void *data,
 	return ret;
 }
 
-static int panthor_ioctl_tiler_heap_destroy(struct drm_device *ddev, void *data,
-					    struct drm_file *file)
+int panthor_tiler_heap_destroy(struct panthor_file *pfile,
+			       const struct drm_panthor_tiler_heap_destroy *args)
 {
-	struct panthor_file *pfile = file->driver_priv;
-	struct drm_panthor_tiler_heap_destroy *args = data;
 	struct panthor_heap_pool *pool;
 	struct panthor_vm *vm;
 	int ret;
@@ -1099,8 +1087,7 @@ static int panthor_ioctl_tiler_heap_destroy(struct drm_device *ddev, void *data,
 	return ret;
 }
 
-static int panthor_ioctl_vm_bind_async(struct drm_device *ddev,
-				       struct drm_panthor_vm_bind *args,
+int panthor_ioctl_vm_bind_async(struct drm_panthor_vm_bind *args,
 				       struct drm_file *file)
 {
 	struct panthor_file *pfile = file->driver_priv;
@@ -1168,8 +1155,7 @@ static int panthor_ioctl_vm_bind_async(struct drm_device *ddev,
 	return ret;
 }
 
-static int panthor_ioctl_vm_bind_sync(struct drm_device *ddev,
-				      struct drm_panthor_vm_bind *args,
+int panthor_ioctl_vm_bind_sync(struct drm_panthor_vm_bind *args,
 				      struct drm_file *file)
 {
 	struct panthor_file *pfile = file->driver_priv;
@@ -1203,24 +1189,6 @@ static int panthor_ioctl_vm_bind_sync(struct drm_device *ddev,
 
 #define PANTHOR_VM_BIND_FLAGS DRM_PANTHOR_VM_BIND_ASYNC
 
-static int panthor_ioctl_vm_bind(struct drm_device *ddev, void *data,
-				 struct drm_file *file)
-{
-	struct drm_panthor_vm_bind *args = data;
-	int cookie, ret;
-
-	if (!drm_dev_enter(ddev, &cookie))
-		return -ENODEV;
-
-	if (args->flags & DRM_PANTHOR_VM_BIND_ASYNC)
-		ret = panthor_ioctl_vm_bind_async(ddev, args, file);
-	else
-		ret = panthor_ioctl_vm_bind_sync(ddev, args, file);
-
-	drm_dev_exit(cookie);
-	return ret;
-}
-
 static int panthor_ioctl_vm_get_state(struct drm_device *ddev, void *data,
 				      struct drm_file *file)
 {
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 818612f0024a53248d6c7e10c241c7e3f5fcdadf..3c0d8e399ce2cefae12615c52e9d5274efa21b6d 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -28,6 +28,9 @@
 #include <linux/workqueue.h>
 
 #include <../drivers/gpu/drm/panthor-rs/panthor_device.h>
+#include <../drivers/gpu/drm/panthor-rs/panthor_gem.h>
+#include <../drivers/gpu/drm/panthor-rs/panthor_mmu.h>
+#include <../drivers/gpu/drm/panthor-rs/panthor_sched.h>
 
 /* `bindgen` gets confused at certain things. */
 const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;