On 6/6/25 1:28 AM, Tomeu Vizoso wrote:
This initial version supports the NPU as shipped in the RK3588 SoC and described in the first part of its TRM, in Chapter 36.
This NPU contains 3 independent cores that the driver can submit jobs to.
This commit adds just hardware initialization and power management.
v2:
- Split cores and IOMMUs as independent devices (Sebastian Reichel)
- Add some documentation (Jeffrey Hugo)
- Be more explicit in the Kconfig documentation (Jeffrey Hugo)
- Remove resets, as these haven't been found useful so far (Zenghui Yu)
- Repack structs (Jeffrey Hugo)
- Use DEFINE_DRM_ACCEL_FOPS (Jeffrey Hugo)
- Use devm_drm_dev_alloc (Jeffrey Hugo)
- Use probe log helper (Jeffrey Hugo)
- Introduce UABI header in a later patch (Jeffrey Hugo)
v3:
- Adapt to a split of the register block in the DT bindings (Nicolas Frattaroli)
- Move registers header to its own commit (Thomas Zimmermann)
- Misc. cleanups (Thomas Zimmermann and Jeff Hugo)
- Make use of GPL-2.0-only for the copyright notice (Jeff Hugo)
- PM improvements (Nicolas Frattaroli)
v4:
- Use bulk clk API (Krzysztof Kozlowski)
v6:
- Remove mention to NVDLA, as the hardware is only incidentally related (Kever Yang)
- Use calloc instead of GFP_ZERO (Jeff Hugo)
- Explicitly include linux/container_of.h (Jeff Hugo)
- pclk and npu clocks are now needed by all cores (Rob Herring)
v7:
- Assign its own IOMMU domain to each client, for isolation (Daniel Stone and Robin Murphy)
Signed-off-by: Tomeu Vizoso tomeu@tomeuvizoso.net
Documentation/accel/index.rst | 1 + Documentation/accel/rocket/index.rst | 19 +++ MAINTAINERS | 10 ++ drivers/accel/Kconfig | 1 + drivers/accel/Makefile | 1 + drivers/accel/rocket/Kconfig | 25 ++++ drivers/accel/rocket/Makefile | 8 + drivers/accel/rocket/rocket_core.c | 70 +++++++++ drivers/accel/rocket/rocket_core.h | 45 ++++++ drivers/accel/rocket/rocket_device.c | 25 ++++ drivers/accel/rocket/rocket_device.h | 26 ++++ drivers/accel/rocket/rocket_drv.c | 279 +++++++++++++++++++++++++++++++++++ drivers/accel/rocket/rocket_drv.h | 15 ++ 13 files changed, 525 insertions(+)
diff --git a/Documentation/accel/index.rst b/Documentation/accel/index.rst index bc85f26533d88891dde482f91e26c99991b22869..d8fa332d60a890dbb617454d2a26d9b6f9b196aa 100644 --- a/Documentation/accel/index.rst +++ b/Documentation/accel/index.rst @@ -10,6 +10,7 @@ Compute Accelerators introduction amdxdna/index qaic/index
- rocket/index
.. only:: subproject and html diff --git a/Documentation/accel/rocket/index.rst b/Documentation/accel/rocket/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..300eb3aeab1d8c6514c65af4d216b2d5a1669131 --- /dev/null +++ b/Documentation/accel/rocket/index.rst @@ -0,0 +1,19 @@ +.. SPDX-License-Identifier: GPL-2.0-only
+=====================================
- accel/rocket Rockchip NPU driver
+=====================================
+The accel/rocket driver supports the Neural Processing Units (NPUs) inside some +Rockchip SoCs such as the RK3588. Rockchip calls it RKNN and sometimes RKNPU.
+The hardware is described in chapter 36 in the RK3588 TRM.
+This driver just powers the hardware on and off, allocates and maps buffers to +the device and submits jobs to the frontend unit. Everything else is done in +userspace, as a Gallium driver (also called rocket) that is part of the Mesa3D +project.
+Hardware currently supported:
+* RK3588 \ No newline at end of file diff --git a/MAINTAINERS b/MAINTAINERS index 96b82704950184bd71623ff41fc4df31e4c7fe87..2d8833bf1f2db06ca624d703f19066adab2f9fde 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7263,6 +7263,16 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/accel/ivpu/ F: include/uapi/drm/ivpu_accel.h +DRM ACCEL DRIVER FOR ROCKCHIP NPU +M: Tomeu Vizoso tomeu@tomeuvizoso.net +L: dri-devel@lists.freedesktop.org +S: Supported +T: git https://gitlab.freedesktop.org/drm/misc/kernel.git +F: Documentation/accel/rocket/ +F: Documentation/devicetree/bindings/npu/rockchip,rknn-core.yaml +F: drivers/accel/rocket/ +F: include/uapi/drm/rocket_accel.h
- DRM COMPUTE ACCELERATORS DRIVERS AND FRAMEWORK M: Oded Gabbay ogabbay@kernel.org L: dri-devel@lists.freedesktop.org
diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig index 5b9490367a39fd12d35a8d9021768aa186c09308..bb01cebc42bf16ebf02e938040f339ff94869e33 100644 --- a/drivers/accel/Kconfig +++ b/drivers/accel/Kconfig @@ -28,5 +28,6 @@ source "drivers/accel/amdxdna/Kconfig" source "drivers/accel/habanalabs/Kconfig" source "drivers/accel/ivpu/Kconfig" source "drivers/accel/qaic/Kconfig" +source "drivers/accel/rocket/Kconfig" endif diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile index a301fb6089d4c515430175c5e2ba9190f6dc9158..ffc3fa58866616d933184a7659573cd4d4780a8d 100644 --- a/drivers/accel/Makefile +++ b/drivers/accel/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_ACCEL_AMDXDNA) += amdxdna/ obj-$(CONFIG_DRM_ACCEL_HABANALABS) += habanalabs/ obj-$(CONFIG_DRM_ACCEL_IVPU) += ivpu/ obj-$(CONFIG_DRM_ACCEL_QAIC) += qaic/ +obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/ \ No newline at end of file
Couple of these no newline warnings
diff --git a/drivers/accel/rocket/Kconfig b/drivers/accel/rocket/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..9a59c6c61bf4d6460d8008b16331f001c97de67d --- /dev/null +++ b/drivers/accel/rocket/Kconfig @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-only
+config DRM_ACCEL_ROCKET
tristate "Rocket (support for Rockchip NPUs)"
depends on DRM
depends on ARM64 || COMPILE_TEST
Should this be more specific for now ARCH_ROCKCHIP?
depends on MMU
select DRM_SCHED
select IOMMU_SUPPORT
select IOMMU_IO_PGTABLE_LPAE
select DRM_GEM_SHMEM_HELPER
help
Choose this option if you have a Rockchip SoC that contains a
compatible Neural Processing Unit (NPU), such as the RK3588. Called by
Rockchip either RKNN or RKNPU, it accelerates inference of neural
networks.
The interface exposed to userspace is described in
include/uapi/drm/rocket_accel.h and is used by the Rocket userspace
driver in Mesa3D.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called rocket.
diff --git a/drivers/accel/rocket/Makefile b/drivers/accel/rocket/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..abdd75f2492eaecf8bf5e78a2ac150ea19ac3e96 --- /dev/null +++ b/drivers/accel/rocket/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_DRM_ACCEL_ROCKET) := rocket.o
+rocket-y := \
- rocket_core.o \
- rocket_device.o \
- rocket_drv.o
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c new file mode 100644 index 0000000000000000000000000000000000000000..3a6f25f2b4103075102739588bcdad96510e2a4e --- /dev/null +++ b/drivers/accel/rocket/rocket_core.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright 2024-2025 Tomeu Vizoso tomeu@tomeuvizoso.net */
+#include <linux/clk.h> +#include <linux/dev_printk.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h>
+#include "rocket_core.h"
+int rocket_core_init(struct rocket_core *core) +{
- struct device *dev = core->dev;
- struct platform_device *pdev = to_platform_device(dev);
- u32 version;
- int err = 0;
- err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
- if (err)
return dev_err_probe(dev, err, "failed to get clocks for core %d\n", core->index);
- core->pc_iomem = devm_platform_ioremap_resource_byname(pdev, "pc");
- if (IS_ERR(core->pc_iomem)) {
dev_err(dev, "couldn't find PC registers %ld\n", PTR_ERR(core->pc_iomem));
return PTR_ERR(core->pc_iomem);
- }
- core->cna_iomem = devm_platform_ioremap_resource_byname(pdev, "cna");
- if (IS_ERR(core->cna_iomem)) {
dev_err(dev, "couldn't find CNA registers %ld\n", PTR_ERR(core->cna_iomem));
return PTR_ERR(core->cna_iomem);
- }
- core->core_iomem = devm_platform_ioremap_resource_byname(pdev, "core");
- if (IS_ERR(core->core_iomem)) {
dev_err(dev, "couldn't find CORE registers %ld\n", PTR_ERR(core->core_iomem));
return PTR_ERR(core->core_iomem);
- }
- pm_runtime_use_autosuspend(dev);
- /*
* As this NPU will be most often used as part of a media pipeline that
* ends presenting in a display, choose 50 ms (~3 frames at 60Hz) as an
* autosuspend delay as that will keep the device powered up while the
* pipeline is running.
*/
- pm_runtime_set_autosuspend_delay(dev, 50);
- pm_runtime_enable(dev);
devm_pm_runtime_enable(dev) here would take care of both functions in rocket_core_fini() so you wouldn't need that and can cleanup some return paths here.
Andrew
- err = pm_runtime_get_sync(dev);
- version = rocket_pc_readl(core, VERSION);
- version += rocket_pc_readl(core, VERSION_NUM) & 0xffff;
- pm_runtime_mark_last_busy(dev);
- pm_runtime_put_autosuspend(dev);
- dev_info(dev, "Rockchip NPU core %d version: %d\n", core->index, version);
- return 0;
+}
+void rocket_core_fini(struct rocket_core *core) +{
- pm_runtime_dont_use_autosuspend(core->dev);
- pm_runtime_disable(core->dev);
+} diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h new file mode 100644 index 0000000000000000000000000000000000000000..1b1beb9798f03ec2ca325496a4d894674d0b798d --- /dev/null +++ b/drivers/accel/rocket/rocket_core.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright 2024-2025 Tomeu Vizoso tomeu@tomeuvizoso.net */
+#ifndef __ROCKET_CORE_H__ +#define __ROCKET_CORE_H__
+#include <drm/gpu_scheduler.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/mutex_types.h>
+#include "rocket_registers.h"
+#define rocket_pc_readl(core, reg) \
- readl((core)->pc_iomem + (REG_PC_##reg))
+#define rocket_pc_writel(core, reg, value) \
- writel(value, (core)->pc_iomem + (REG_PC_##reg))
+#define rocket_cna_readl(core, reg) \
- readl((core)->cna_iomem + (REG_CNA_##reg) - REG_CNA_S_STATUS)
+#define rocket_cna_writel(core, reg, value) \
- writel(value, (core)->cna_iomem + (REG_CNA_##reg) - REG_CNA_S_STATUS)
+#define rocket_core_readl(core, reg) \
- readl((core)->core_iomem + (REG_CORE_##reg) - REG_CORE_S_STATUS)
+#define rocket_core_writel(core, reg, value) \
- writel(value, (core)->core_iomem + (REG_CORE_##reg) - REG_CORE_S_STATUS)
+struct rocket_core {
- struct device *dev;
- struct rocket_device *rdev;
- struct device_link *link;
- unsigned int index;
- int irq;
- void __iomem *pc_iomem;
- void __iomem *cna_iomem;
- void __iomem *core_iomem;
- struct clk_bulk_data clks[4];
+};
+int rocket_core_init(struct rocket_core *core); +void rocket_core_fini(struct rocket_core *core);
+#endif diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c new file mode 100644 index 0000000000000000000000000000000000000000..a05c103e117e3eaa6439884b7acb6e3483296edb --- /dev/null +++ b/drivers/accel/rocket/rocket_device.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright 2024-2025 Tomeu Vizoso tomeu@tomeuvizoso.net */
+#include <linux/array_size.h> +#include <linux/clk.h> +#include <linux/dev_printk.h>
+#include "rocket_device.h"
+int rocket_device_init(struct rocket_device *rdev) +{
- int err;
- /* Initialize core 0 (top) */
- err = rocket_core_init(&rdev->cores[0]);
- if (err)
return err;
- return 0;
+}
+void rocket_device_fini(struct rocket_device *rdev) +{
- rocket_core_fini(&rdev->cores[0]);
+} diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/rocket_device.h new file mode 100644 index 0000000000000000000000000000000000000000..b5d5f1479d56e2fde59bbcad9de2b58cef9a9a4d --- /dev/null +++ b/drivers/accel/rocket/rocket_device.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright 2024-2025 Tomeu Vizoso tomeu@tomeuvizoso.net */
+#ifndef __ROCKET_DEVICE_H__ +#define __ROCKET_DEVICE_H__
+#include <drm/drm_device.h> +#include <linux/clk.h> +#include <linux/container_of.h>
+#include "rocket_core.h"
+struct rocket_device {
- struct drm_device ddev;
- struct rocket_core *cores;
- unsigned int num_cores;
+};
+int rocket_device_init(struct rocket_device *rdev); +void rocket_device_fini(struct rocket_device *rdev);
+#define to_rocket_device(drm_dev) \
- ((struct rocket_device *)container_of(drm_dev, struct rocket_device, ddev))
+#endif diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c new file mode 100644 index 0000000000000000000000000000000000000000..b38a5c6264cb4e74d5e381adaeba1426e576fa56 --- /dev/null +++ b/drivers/accel/rocket/rocket_drv.c @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright 2024-2025 Tomeu Vizoso tomeu@tomeuvizoso.net */
+#include <drm/drm_accel.h> +#include <drm/drm_drv.h> +#include <drm/drm_gem.h> +#include <drm/drm_ioctl.h> +#include <drm/drm_of.h> +#include <linux/array_size.h> +#include <linux/clk.h> +#include <linux/component.h> +#include <linux/dma-mapping.h> +#include <linux/iommu.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h>
+#include "rocket_drv.h"
+static int +rocket_open(struct drm_device *dev, struct drm_file *file) +{
- struct rocket_device *rdev = to_rocket_device(dev);
- struct rocket_file_priv *rocket_priv;
- rocket_priv = kzalloc(sizeof(*rocket_priv), GFP_KERNEL);
- if (!rocket_priv)
return -ENOMEM;
- rocket_priv->rdev = rdev;
- rocket_priv->domain = iommu_paging_domain_alloc(dev->dev);
- file->driver_priv = rocket_priv;
- return 0;
+}
+static void +rocket_postclose(struct drm_device *dev, struct drm_file *file) +{
- struct rocket_file_priv *rocket_priv = file->driver_priv;
- iommu_domain_free(rocket_priv->domain);
- kfree(rocket_priv);
+}
+static const struct drm_ioctl_desc rocket_drm_driver_ioctls[] = { +#define ROCKET_IOCTL(n, func) \
- DRM_IOCTL_DEF_DRV(ROCKET_##n, rocket_ioctl_##func, 0)
+};
+DEFINE_DRM_ACCEL_FOPS(rocket_accel_driver_fops);
+/*
- Rocket driver version:
- 1.0 - initial interface
- */
+static const struct drm_driver rocket_drm_driver = {
- .driver_features = DRIVER_COMPUTE_ACCEL,
- .open = rocket_open,
- .postclose = rocket_postclose,
- .ioctls = rocket_drm_driver_ioctls,
- .num_ioctls = ARRAY_SIZE(rocket_drm_driver_ioctls),
- .fops = &rocket_accel_driver_fops,
- .name = "rocket",
- .desc = "rocket DRM",
+};
+static int rocket_drm_bind(struct device *dev) +{
- struct device_node *core_node;
- struct rocket_device *rdev;
- struct drm_device *ddev;
- unsigned int num_cores = 1;
- int err;
- rdev = devm_drm_dev_alloc(dev, &rocket_drm_driver, struct rocket_device, ddev);
- if (IS_ERR(rdev))
return PTR_ERR(rdev);
- ddev = &rdev->ddev;
- dev_set_drvdata(dev, rdev);
- for_each_compatible_node(core_node, NULL, "rockchip,rk3588-rknn-core")
if (of_device_is_available(core_node))
num_cores++;
- rdev->cores = devm_kcalloc(dev, num_cores, sizeof(*rdev->cores), GFP_KERNEL);
- if (IS_ERR(rdev->cores))
return PTR_ERR(rdev->cores);
- /* Add core 0, any other cores will be added later when they are bound */
- rdev->cores[0].rdev = rdev;
- rdev->cores[0].dev = dev;
- rdev->cores[0].index = 0;
- rdev->num_cores = 1;
- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
- if (err)
return err;
- err = rocket_device_init(rdev);
- if (err) {
dev_err_probe(dev, err, "Fatal error during NPU init\n");
goto err_device_fini;
- }
- err = component_bind_all(dev, rdev);
- if (err)
goto err_device_fini;
- err = drm_dev_register(ddev, 0);
- if (err < 0)
goto err_unbind;
- return 0;
+err_unbind:
- component_unbind_all(dev, rdev);
+err_device_fini:
- rocket_device_fini(rdev);
- return err;
+}
+static void rocket_drm_unbind(struct device *dev) +{
- struct rocket_device *rdev = dev_get_drvdata(dev);
- struct drm_device *ddev = &rdev->ddev;
- drm_dev_unregister(ddev);
- component_unbind_all(dev, rdev);
- rocket_device_fini(rdev);
+}
+const struct component_master_ops rocket_drm_ops = {
- .bind = rocket_drm_bind,
- .unbind = rocket_drm_unbind,
+};
+static int rocket_core_bind(struct device *dev, struct device *master, void *data) +{
- struct rocket_device *rdev = data;
- unsigned int core = rdev->num_cores;
- int err;
- dev_set_drvdata(dev, rdev);
- rdev->cores[core].rdev = rdev;
- rdev->cores[core].dev = dev;
- rdev->cores[core].index = core;
- rdev->cores[core].link = device_link_add(dev, rdev->cores[0].dev,
DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
- rdev->num_cores++;
- err = rocket_core_init(&rdev->cores[core]);
- if (err) {
rocket_device_fini(rdev);
return err;
- }
- return 0;
+}
+static void rocket_core_unbind(struct device *dev, struct device *master, void *data) +{
- struct rocket_device *rdev = data;
- for (unsigned int core = 1; core < rdev->num_cores; core++) {
if (rdev->cores[core].dev == dev) {
rocket_core_fini(&rdev->cores[core]);
device_link_del(rdev->cores[core].link);
break;
}
- }
+}
+const struct component_ops rocket_core_ops = {
- .bind = rocket_core_bind,
- .unbind = rocket_core_unbind,
+};
+static int rocket_probe(struct platform_device *pdev) +{
- struct component_match *match = NULL;
- struct device_node *core_node;
- if (fwnode_device_is_compatible(pdev->dev.fwnode, "rockchip,rk3588-rknn-core"))
return component_add(&pdev->dev, &rocket_core_ops);
- for_each_compatible_node(core_node, NULL, "rockchip,rk3588-rknn-core") {
if (!of_device_is_available(core_node))
continue;
drm_of_component_match_add(&pdev->dev, &match,
component_compare_of, core_node);
- }
- return component_master_add_with_match(&pdev->dev, &rocket_drm_ops, match);
+}
+static void rocket_remove(struct platform_device *pdev) +{
- if (fwnode_device_is_compatible(pdev->dev.fwnode, "rockchip,rk3588-rknn-core-top"))
component_master_del(&pdev->dev, &rocket_drm_ops);
- else if (fwnode_device_is_compatible(pdev->dev.fwnode, "rockchip,rk3588-rknn-core"))
component_del(&pdev->dev, &rocket_core_ops);
+}
+static const struct of_device_id dt_match[] = {
- { .compatible = "rockchip,rk3588-rknn-core-top" },
- { .compatible = "rockchip,rk3588-rknn-core" },
- {}
+}; +MODULE_DEVICE_TABLE(of, dt_match);
+static int find_core_for_dev(struct device *dev) +{
- struct rocket_device *rdev = dev_get_drvdata(dev);
- for (unsigned int core = 0; core < rdev->num_cores; core++) {
if (dev == rdev->cores[core].dev)
return core;
- }
- return -1;
+}
+static int rocket_device_runtime_resume(struct device *dev) +{
- struct rocket_device *rdev = dev_get_drvdata(dev);
- int core = find_core_for_dev(dev);
- int err = 0;
- if (core < 0)
return -ENODEV;
- err = clk_bulk_prepare_enable(ARRAY_SIZE(rdev->cores[core].clks), rdev->cores[core].clks);
- if (err) {
dev_err(dev, "failed to enable (%d) clocks for core %d\n", err, core);
return err;
- }
- return 0;
+}
+static int rocket_device_runtime_suspend(struct device *dev) +{
- struct rocket_device *rdev = dev_get_drvdata(dev);
- int core = find_core_for_dev(dev);
- if (core < 0)
return -ENODEV;
- clk_bulk_disable_unprepare(ARRAY_SIZE(rdev->cores[core].clks), rdev->cores[core].clks);
- return 0;
+}
+EXPORT_GPL_DEV_PM_OPS(rocket_pm_ops) = {
- RUNTIME_PM_OPS(rocket_device_runtime_suspend, rocket_device_runtime_resume, NULL)
- SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
+};
+static struct platform_driver rocket_driver = {
- .probe = rocket_probe,
- .remove = rocket_remove,
- .driver = {
.name = "rocket",
.pm = pm_ptr(&rocket_pm_ops),
.of_match_table = dt_match,
- },
+}; +module_platform_driver(rocket_driver);
+MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("DRM driver for the Rockchip NPU IP"); +MODULE_AUTHOR("Tomeu Vizoso"); diff --git a/drivers/accel/rocket/rocket_drv.h b/drivers/accel/rocket/rocket_drv.h new file mode 100644 index 0000000000000000000000000000000000000000..3219621afb72acdfa915c110e2ec3aacb66bd940 --- /dev/null +++ b/drivers/accel/rocket/rocket_drv.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright 2024-2025 Tomeu Vizoso tomeu@tomeuvizoso.net */
+#ifndef __ROCKET_DRV_H__ +#define __ROCKET_DRV_H__
+#include "rocket_device.h"
+struct rocket_file_priv {
- struct rocket_device *rdev;
- struct iommu_domain *domain;
+};
+#endif
linaro-mm-sig@lists.linaro.org