diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index c6f549e2d..a245ad9eb 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -256,9 +256,7 @@ static void nvgpu_init_mm_vars(struct gk20a *g) } int nvgpu_probe(struct gk20a *g, - const char *debugfs_symlink, - const char *interface_name, - struct class *device_class) + const char *debugfs_symlink) { struct device *dev = dev_from_gk20a(g); struct gk20a_platform *platform = dev_get_drvdata(dev); @@ -290,7 +288,7 @@ int nvgpu_probe(struct gk20a *g, nvgpu_init_mm_vars(g); /* platform probe can defer do user init only if probe succeeds */ - err = gk20a_user_init(dev, interface_name, device_class); + err = gk20a_user_init(dev); if (err) return err; diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.h b/drivers/gpu/nvgpu/os/linux/driver_common.h index 5d23e2d1a..026ab206a 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.h +++ b/drivers/gpu/nvgpu/os/linux/driver_common.h @@ -18,12 +18,9 @@ #define NVGPU_LINUX_DRIVER_COMMON struct gk20a; -struct class; int nvgpu_probe(struct gk20a *g, - const char *debugfs_symlink, - const char *interface_name, - struct class *device_class); + const char *debugfs_symlink); void nvgpu_init_gk20a(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl.c b/drivers/gpu/nvgpu/os/linux/ioctl.c index 33aa8c5d9..22e4ad55c 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl.c @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -32,7 +33,7 @@ #include "fecs_trace_linux.h" #include "platform_gk20a.h" -#define GK20A_NUM_CDEVS 7 +#define GK20A_NUM_CDEVS 10 const struct file_operations gk20a_channel_ops = { .owner = THIS_MODULE, @@ -149,9 +150,35 @@ static const struct file_operations gk20a_sched_ops = { .read = gk20a_sched_dev_read, }; +static char *nvgpu_devnode(const char *cdev_name) +{ + /* Special case to maintain legacy names */ + if (strcmp(cdev_name, "channel") == 0) { + return kasprintf(GFP_KERNEL, "nvhost-gpu"); + } + + return kasprintf(GFP_KERNEL, "nvhost-%s-gpu", cdev_name); +} + +static char *nvgpu_pci_devnode(struct device *dev, umode_t *mode) +{ + if (mode) { + *mode = S_IRUSR | S_IWUSR; + } + + /* Special case to maintain legacy names */ + if (strcmp(dev_name(dev), "channel") == 0) { + return kasprintf(GFP_KERNEL, "nvgpu-pci/card-%s", + dev_name(dev->parent)); + } + + return kasprintf(GFP_KERNEL, "nvgpu-pci/card-%s-%s", + dev_name(dev->parent), dev_name(dev)); +} + static int gk20a_create_device( struct device *dev, int devno, - const char *interface_name, const char *cdev_name, + const char *cdev_name, struct cdev *cdev, struct device **out, const struct file_operations *ops, struct class *class) @@ -159,6 +186,7 @@ static int gk20a_create_device( struct device *subdev; int err; struct gk20a *g = gk20a_from_dev(dev); + const char *device_name = NULL; nvgpu_log_fn(g, " "); @@ -171,9 +199,12 @@ static int gk20a_create_device( return err; } - subdev = device_create(class, NULL, devno, NULL, - interface_name, cdev_name); + if (class->devnode == NULL) { + device_name = nvgpu_devnode(cdev_name); + } + subdev = device_create(class, dev, devno, NULL, + device_name ? device_name : cdev_name); if (IS_ERR(subdev)) { err = PTR_ERR(dev); cdev_del(cdev); @@ -182,14 +213,23 @@ static int gk20a_create_device( return err; } + if (device_name != NULL) { + kfree(device_name); + } + *out = subdev; return 0; } -void gk20a_user_deinit(struct device *dev, struct class *class) +void gk20a_user_deinit(struct device *dev) { struct gk20a *g = gk20a_from_dev(dev); struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct class *class = l->devnode_class; + + if (class == NULL) { + return; + } if (l->channel.node) { device_destroy(class, l->channel.cdev.dev); @@ -243,15 +283,34 @@ void gk20a_user_deinit(struct device *dev, struct class *class) if (l->cdev_region) unregister_chrdev_region(l->cdev_region, GK20A_NUM_CDEVS); + + class_destroy(class); + l->devnode_class = NULL; } -int gk20a_user_init(struct device *dev, const char *interface_name, - struct class *class) +int gk20a_user_init(struct device *dev) { int err; dev_t devno; struct gk20a *g = gk20a_from_dev(dev); struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct class *class; + + if (g->pci_class != 0U) { + class = class_create(THIS_MODULE, "nvidia-pci-gpu"); + if (IS_ERR(class)) { + dev_err(dev, "failed to create class"); + return PTR_ERR(class); + } + class->devnode = nvgpu_pci_devnode; + } else { + class = class_create(THIS_MODULE, "nvidia-gpu"); + if (IS_ERR(class)) { + dev_err(dev, "failed to create class"); + return PTR_ERR(class); + } + class->devnode = NULL; + } err = alloc_chrdev_region(&devno, 0, GK20A_NUM_CDEVS, dev_name(dev)); if (err) { @@ -260,56 +319,56 @@ int gk20a_user_init(struct device *dev, const char *interface_name, } l->cdev_region = devno; - err = gk20a_create_device(dev, devno++, interface_name, "", + err = gk20a_create_device(dev, devno++, "channel", &l->channel.cdev, &l->channel.node, &gk20a_channel_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-as", + err = gk20a_create_device(dev, devno++, "as", &l->as_dev.cdev, &l->as_dev.node, &gk20a_as_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-ctrl", + err = gk20a_create_device(dev, devno++, "ctrl", &l->ctrl.cdev, &l->ctrl.node, &gk20a_ctrl_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-dbg", + err = gk20a_create_device(dev, devno++, "dbg", &l->dbg.cdev, &l->dbg.node, &gk20a_dbg_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-prof", + err = gk20a_create_device(dev, devno++, "prof", &l->prof.cdev, &l->prof.node, &gk20a_prof_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-prof-dev", + err = gk20a_create_device(dev, devno++, "prof-dev", &l->prof_dev.cdev, &l->prof_dev.node, &gk20a_prof_dev_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-prof-ctx", + err = gk20a_create_device(dev, devno++, "prof-ctx", &l->prof_ctx.cdev, &l->prof_ctx.node, &gk20a_prof_ctx_ops, class); if (err) goto fail; - err = gk20a_create_device(dev, devno++, interface_name, "-tsg", + err = gk20a_create_device(dev, devno++, "tsg", &l->tsg.cdev, &l->tsg.node, &gk20a_tsg_ops, class); @@ -317,7 +376,7 @@ int gk20a_user_init(struct device *dev, const char *interface_name, goto fail; #if defined(CONFIG_NVGPU_FECS_TRACE) - err = gk20a_create_device(dev, devno++, interface_name, "-ctxsw", + err = gk20a_create_device(dev, devno++, "ctxsw", &l->ctxsw.cdev, &l->ctxsw.node, &gk20a_ctxsw_ops, class); @@ -325,15 +384,16 @@ int gk20a_user_init(struct device *dev, const char *interface_name, goto fail; #endif - err = gk20a_create_device(dev, devno++, interface_name, "-sched", + err = gk20a_create_device(dev, devno++, "sched", &l->sched.cdev, &l->sched.node, &gk20a_sched_ops, class); if (err) goto fail; + l->devnode_class = class; return 0; fail: - gk20a_user_deinit(dev, &nvgpu_class); + gk20a_user_deinit(dev); return err; } diff --git a/drivers/gpu/nvgpu/os/linux/ioctl.h b/drivers/gpu/nvgpu/os/linux/ioctl.h index 7bf167119..96fb73d3c 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl.h +++ b/drivers/gpu/nvgpu/os/linux/ioctl.h @@ -14,10 +14,8 @@ #define __NVGPU_IOCTL_H__ struct device; -struct class; -int gk20a_user_init(struct device *dev, const char *interface_name, - struct class *class); -void gk20a_user_deinit(struct device *dev, struct class *class); +int gk20a_user_init(struct device *dev); +void gk20a_user_deinit(struct device *dev); #endif diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index e22b0e38c..d621f16a7 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -90,9 +90,6 @@ #include "nvgpu_next_gpuid.h" #endif -#define CLASS_NAME "nvidia-gpu" -/* TODO: Change to e.g. "nvidia-gpu%s" once we have symlinks in place. */ - #define GK20A_WAIT_FOR_IDLE_MS 2000 #define CREATE_TRACE_POINTS @@ -1709,7 +1706,7 @@ static int gk20a_probe(struct platform_device *dev) platform->reset_control = NULL; #endif - err = nvgpu_probe(gk20a, "gpu.0", INTERFACE_NAME, &nvgpu_class); + err = nvgpu_probe(gk20a, "gpu.0"); if (err) goto return_err; @@ -1742,7 +1739,7 @@ return_err: return err; } -int nvgpu_remove(struct device *dev, struct class *class) +int nvgpu_remove(struct device *dev) { struct gk20a *g = get_gk20a(dev); #ifdef CONFIG_NVGPU_SUPPORT_CDE @@ -1775,7 +1772,7 @@ int nvgpu_remove(struct device *dev, struct class *class) nvgpu_clk_arb_cleanup_arbiter(g); - gk20a_user_deinit(dev, class); + gk20a_user_deinit(dev); gk20a_debug_deinit(g); @@ -1805,7 +1802,7 @@ static int __exit gk20a_remove(struct platform_device *pdev) if (gk20a_gpu_is_virtual(dev)) return vgpu_remove(pdev); - err = nvgpu_remove(dev, &nvgpu_class); + err = nvgpu_remove(dev); gk20a_dma_buf_priv_list_clear(l); nvgpu_mutex_destroy(&l->dmabuf_priv_list_lock); @@ -1839,20 +1836,11 @@ static struct platform_driver gk20a_driver = { } }; -struct class nvgpu_class = { - .owner = THIS_MODULE, - .name = CLASS_NAME, -}; - static int __init gk20a_init(void) { int ret; - ret = class_register(&nvgpu_class); - if (ret) - return ret; - ret = nvgpu_pci_init(); if (ret) return ret; @@ -1864,7 +1852,6 @@ static void __exit gk20a_exit(void) { nvgpu_pci_exit(); platform_driver_unregister(&gk20a_driver); - class_unregister(&nvgpu_class); } MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/nvgpu/os/linux/module.h b/drivers/gpu/nvgpu/os/linux/module.h index 79cc6292a..b822989ab 100644 --- a/drivers/gpu/nvgpu/os/linux/module.h +++ b/drivers/gpu/nvgpu/os/linux/module.h @@ -17,14 +17,13 @@ struct gk20a; struct device; struct platform_device; struct nvgpu_os_linux; -struct class; int gk20a_pm_finalize_poweron(struct device *dev); int nvgpu_finalize_poweron_linux(struct nvgpu_os_linux *l); void gk20a_remove_support(struct gk20a *g); void gk20a_driver_start_unload(struct gk20a *g); int nvgpu_quiesce(struct gk20a *g); -int nvgpu_remove(struct device *dev, struct class *class); +int nvgpu_remove(struct device *dev); int nvgpu_wait_for_gpu_idle(struct gk20a *g); void nvgpu_free_irq(struct gk20a *g); struct device_node *nvgpu_get_node(struct gk20a *g); diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index effed9e04..12f211a60 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -29,6 +29,8 @@ #include "cde.h" #include "sched.h" +struct class; + struct nvgpu_os_linux_ops { struct { void (*get_program_numbers)(struct gk20a *g, @@ -76,6 +78,8 @@ struct nvgpu_os_linux { struct device *dev; struct dgpu_thermal_alert thermal_alert; struct nvgpu_interrupts interrupts; + struct class *devnode_class; + struct { struct cdev cdev; struct device *node; @@ -202,8 +206,6 @@ static inline struct device *dev_from_gk20a(struct gk20a *g) return nvgpu_os_linux_from_gk20a(g)->dev; } -#define INTERFACE_NAME "nvhost%s-gpu" - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) #define totalram_size_in_mb (totalram_pages() >> (10 - (PAGE_SHIFT - 10))) #else diff --git a/drivers/gpu/nvgpu/os/linux/pci.c b/drivers/gpu/nvgpu/os/linux/pci.c index 264717b7f..1e80cb080 100644 --- a/drivers/gpu/nvgpu/os/linux/pci.c +++ b/drivers/gpu/nvgpu/os/linux/pci.c @@ -46,7 +46,6 @@ #include "dmabuf_priv.h" #define BOOT_GPC2CLK_MHZ 2581U -#define PCI_INTERFACE_NAME "card-%s%%s" static int nvgpu_pci_tegra_probe(struct device *dev) { @@ -395,19 +394,6 @@ static int nvgpu_pci_init_support(struct pci_dev *pdev) return err; } -static char *nvgpu_pci_devnode(struct device *dev, umode_t *mode) -{ - if (mode) - *mode = S_IRUGO | S_IWUGO; - return kasprintf(GFP_KERNEL, "nvgpu-pci/%s", dev_name(dev)); -} - -static struct class nvgpu_pci_class = { - .owner = THIS_MODULE, - .name = "nvidia-pci-gpu", - .devnode = nvgpu_pci_devnode, -}; - #ifdef CONFIG_PM static int nvgpu_pci_pm_runtime_resume(struct device *dev) { @@ -506,7 +492,6 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, struct nvgpu_os_linux *l; struct gk20a *g; int err; - char nodefmt[64]; struct device_node *np; u32 device_index = PCI_DEVICE_INDEX(pent->driver_data); u32 device_flags = PCI_DEVICE_FLAGS(pent->driver_data); @@ -636,10 +621,7 @@ static int nvgpu_pci_probe(struct pci_dev *pdev, goto err_free_irq; } - (void) snprintf(nodefmt, sizeof(nodefmt), - PCI_INTERFACE_NAME, dev_name(&pdev->dev)); - - err = nvgpu_probe(g, "gpu_pci", nodefmt, &nvgpu_pci_class); + err = nvgpu_probe(g, "gpu_pci"); if (err) goto err_free_irq; @@ -756,7 +738,7 @@ static void nvgpu_pci_remove(struct pci_dev *pdev) nvgpu_free_irq(g); - nvgpu_remove(dev, &nvgpu_pci_class); + nvgpu_remove(dev); #if defined(CONFIG_PCI_MSI) if (g->msi_enabled) @@ -830,13 +812,9 @@ int __init nvgpu_pci_init(void) { int ret; - ret = class_register(&nvgpu_pci_class); - if (ret) - return ret; - ret = pci_register_driver(&nvgpu_pci_driver); if (ret) - goto driver_fail; + return ret; ret = nvgpu_pci_power_init(&nvgpu_pci_driver); if (ret) @@ -846,8 +824,6 @@ int __init nvgpu_pci_init(void) power_init_fail: pci_unregister_driver(&nvgpu_pci_driver); -driver_fail: - class_unregister(&nvgpu_pci_class); return ret; } @@ -855,6 +831,5 @@ void __exit nvgpu_pci_exit(void) { nvgpu_pci_power_exit(&nvgpu_pci_driver); pci_unregister_driver(&nvgpu_pci_driver); - class_unregister(&nvgpu_pci_class); nvgpu_pci_power_cleanup(); } diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c index 589bc426b..9873fea57 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c @@ -365,7 +365,7 @@ int vgpu_probe(struct platform_device *pdev) platform->g = gk20a; platform->vgpu_priv = priv; - err = gk20a_user_init(dev, INTERFACE_NAME, &nvgpu_class); + err = gk20a_user_init(dev); if (err) return err; @@ -491,7 +491,7 @@ int vgpu_remove(struct platform_device *pdev) vgpu_comm_deinit(); gk20a_sched_ctrl_cleanup(g); - gk20a_user_deinit(dev, &nvgpu_class); + gk20a_user_deinit(dev); vgpu_remove_sysfs(dev); gk20a_get_platform(dev)->g = NULL; nvgpu_put(g);