From 0f991be9e78427c2685112d953528b4bc2b1c70e Mon Sep 17 00:00:00 2001 From: Mainak Sen Date: Mon, 17 Mar 2025 10:43:25 +0000 Subject: [PATCH] nvdla: Replace deprecated nvhost_client* APIs Replace deprecated nvhost client device functions with their direct implementations to maintain compatibility with newer host1x drivers: 1. Replace nvhost_client_device_get_resources with direct implementation: - Get host1x data from parent device - Map device resources directly 2. Replace nvhost_client_device_init with nvdla_client_device_init: - Allocate character device region - Create device node using nvdla_client_device_create 3. Replace nvhost_client_device_release with nvdla_client_device_release: - Clean up device node - Unregister character device region This change ensures the NVDLA driver continues to work correctly with the host1x driver while removing dependencies on deprecated functions.The device node "nvhost-ctrl-dla" is still created with the same functionality as before. Bug 4921461 Jira HOSTX-5963 Change-Id: Ib27000fa47fdd72f80ca4030232d31e100c01ea4 Signed-off-by: Mainak Sen Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3320695 Reviewed-by: svcacv GVS: buildbot_gerritrpt Reviewed-by: Arvind M Reviewed-by: Mitch Harwell --- .../nvdla/port/device/nvdla_device_host1x.c | 143 ++++++++++++++++-- 1 file changed, 127 insertions(+), 16 deletions(-) diff --git a/drivers/video/tegra/host/nvdla/port/device/nvdla_device_host1x.c b/drivers/video/tegra/host/nvdla/port/device/nvdla_device_host1x.c index b06ba09b..c7f9d88a 100644 --- a/drivers/video/tegra/host/nvdla/port/device/nvdla_device_host1x.c +++ b/drivers/video/tegra/host/nvdla/port/device/nvdla_device_host1x.c @@ -4,63 +4,174 @@ * NVDLA device implementation as Host1x client. */ +#include + #include "../nvdla_device.h" #include "../../dla_queue.h" #include "../../nvdla_debug.h" -#include #include +#include +#include +#include #include #include #include +#include uint32_t nvdla_device_register_read(struct platform_device *pdev, uint32_t reg) { - return host1x_readl(pdev, reg); + struct nvhost_device_data *pdata = platform_get_drvdata(pdev); + void __iomem *addr = pdata->aperture[0] + reg; + + return readl(addr); } void nvdla_device_register_write(struct platform_device *pdev, uint32_t reg, uint32_t value) { - host1x_writel(pdev, reg, value); + struct nvhost_device_data *pdata = platform_get_drvdata(pdev); + void __iomem *addr = pdata->aperture[0] + reg; + + writel(value, addr); +} + +static struct device *nvdla_client_device_create(struct platform_device *pdev, + struct cdev *cdev, + const char *cdev_name, + dev_t devno, + const struct file_operations *ops) +{ + struct nvhost_device_data *pdata = platform_get_drvdata(pdev); + struct device *dev; + int err; + +#if defined(NV_CLASS_CREATE_HAS_NO_OWNER_ARG) /* Linux v6.4 */ + pdata->nvhost_class = class_create(pdev->dev.of_node->name); +#else + pdata->nvhost_class = class_create(THIS_MODULE, pdev->dev.of_node->name); +#endif + + if (IS_ERR(pdata->nvhost_class)) { + dev_err(&pdev->dev, "failed to create class\n"); + return ERR_CAST(pdata->nvhost_class); + } + + cdev_init(cdev, ops); + cdev->owner = THIS_MODULE; + + err = cdev_add(cdev, devno, 1); + if (err < 0) { + dev_err(&pdev->dev, "failed to add cdev\n"); + class_destroy(pdata->nvhost_class); + return ERR_PTR(err); + } + + dev = device_create(pdata->nvhost_class, &pdev->dev, devno, NULL, + (pdev->id <= 0) ? "nvhost-%s%s" : "nvhost-%s%s.%d", + cdev_name, pdev->dev.of_node->name, pdev->id); + + if (IS_ERR(dev)) { + dev_err(&pdev->dev, "failed to create %s device\n", cdev_name); + class_destroy(pdata->nvhost_class); + cdev_del(cdev); + } + + return dev; +} + +static int nvdla_client_device_init(struct platform_device *pdev) +{ + struct nvhost_device_data *pdata = platform_get_drvdata(pdev); + dev_t devno; + int err; + + err = alloc_chrdev_region(&devno, 0, 1, "nvhost"); + if (err < 0) { + dev_err(&pdev->dev, "failed to reserve chrdev region\n"); + return err; + } + + pdata->ctrl_node = nvdla_client_device_create(pdev, &pdata->ctrl_cdev, + "ctrl-", devno, + pdata->ctrl_ops); + if (IS_ERR(pdata->ctrl_node)) { + unregister_chrdev_region(devno, 1); + return PTR_ERR(pdata->ctrl_node); + } + + pdata->cdev_region = devno; + + return 0; +} + +static void nvdla_client_device_release(struct platform_device *pdev) +{ + struct nvhost_device_data *pdata = platform_get_drvdata(pdev); + + if (!IS_ERR_OR_NULL(pdata->ctrl_node)) { + device_destroy(pdata->nvhost_class, pdata->ctrl_cdev.dev); + cdev_del(&pdata->ctrl_cdev); + class_destroy(pdata->nvhost_class); + } + + unregister_chrdev_region(pdata->cdev_region, 1); } int32_t nvdla_module_init(struct platform_device *pdev) { int32_t err; + struct nvhost_device_data *pdata = platform_get_drvdata(pdev); + int i; - err = nvhost_client_device_get_resources(pdev); - if (err) { - nvdla_dbg_err(pdev, "Failed to get resource (err: %x)", err); - goto fail; + pdata->host1x = dev_get_drvdata(pdev->dev.parent); + if (!pdata->host1x) { + dev_warn(&pdev->dev, "No platform data for host1x!\n"); + return -ENODEV; + } + + /* Map device resources */ + for (i = 0; i < pdev->num_resources; i++) { + void __iomem *regs = NULL; + struct resource *r; + + r = platform_get_resource(pdev, IORESOURCE_MEM, i); + /* We've run out of mem resources */ + if (!r) + break; + + regs = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(regs)) { + err = PTR_ERR(regs); + dev_err(&pdev->dev, "failed to get register memory\n"); + return err; + } + + pdata->aperture[i] = regs; } err = nvhost_module_init(pdev); if (err) { nvdla_dbg_err(pdev, "Failed to init module (err: %x)", err); - goto fail; + return err; } - err = nvhost_client_device_init(pdev); + err = nvdla_client_device_init(pdev); if (err) { nvdla_dbg_err(pdev, "Failed to client device (err: %x)", err); - goto deinit_module; + nvhost_module_deinit(pdev); + return err; } return 0; - -deinit_module: - nvhost_module_deinit(pdev); -fail: - return err; } void nvdla_module_deinit(struct platform_device *pdev) { - nvhost_client_device_release(pdev); + nvdla_client_device_release(pdev); nvhost_module_deinit(pdev); }