mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: expose device creation
Allow gk20a_create_device() to happen outside the main ioctl logic and rename it to have the modern nvgpu_ prefix. Add a separate function to do cdev allocation and refactor the existing two callers slightly to avoid repetition on the cdev struct initialization. As a side effect, this modification fixes the error path that used to not return an error if adding a device fails and also leaked the allocated cdev memory. Jira NVGPU-6788 Change-Id: Ia1f018b88d78fafdfcf4e95f6aa66e2368e58974 Signed-off-by: Konsta Hölttä <kholtta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2674426 Reviewed-by: Alex Waterman <alexw@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
82df5b0219
commit
f11ca4c300
@@ -251,11 +251,10 @@ static char *nvgpu_mig_fgpu_devnode(struct device *dev, umode_t *mode)
|
||||
priv_data->minor_instance_id, dev_name(dev));
|
||||
}
|
||||
|
||||
static int gk20a_create_device(
|
||||
int nvgpu_create_device(
|
||||
struct device *dev, int devno,
|
||||
const char *cdev_name,
|
||||
struct cdev *cdev, struct device **out,
|
||||
const struct file_operations *ops,
|
||||
struct nvgpu_class *class)
|
||||
{
|
||||
struct device *subdev;
|
||||
@@ -265,9 +264,6 @@ static int gk20a_create_device(
|
||||
|
||||
nvgpu_log_fn(g, " ");
|
||||
|
||||
cdev_init(cdev, ops);
|
||||
cdev->owner = THIS_MODULE;
|
||||
|
||||
err = cdev_add(cdev, devno, 1);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to add %s cdev\n", cdev_name);
|
||||
@@ -297,6 +293,45 @@ static int gk20a_create_device(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nvgpu_alloc_and_create_device(
|
||||
struct device *dev, int devno,
|
||||
const char *cdev_name,
|
||||
const struct file_operations *ops,
|
||||
struct nvgpu_class *class)
|
||||
{
|
||||
struct gk20a *g = gk20a_from_dev(dev);
|
||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
||||
struct nvgpu_cdev *cdev;
|
||||
int err;
|
||||
|
||||
cdev = nvgpu_kzalloc(g, sizeof(*cdev));
|
||||
if (cdev == NULL) {
|
||||
dev_err(dev, "failed to allocate cdev\n");
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cdev_init(&cdev->cdev, ops);
|
||||
cdev->cdev.owner = THIS_MODULE;
|
||||
|
||||
err = nvgpu_create_device(dev, devno, cdev_name,
|
||||
&cdev->cdev, &cdev->node, class);
|
||||
if (err) {
|
||||
goto free_cdev;
|
||||
}
|
||||
|
||||
cdev->class = class;
|
||||
nvgpu_init_list_node(&cdev->list_entry);
|
||||
nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head);
|
||||
|
||||
return 0;
|
||||
|
||||
free_cdev:
|
||||
nvgpu_kfree(g, cdev);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
void gk20a_remove_devices_and_classes(struct gk20a *g, bool power_node)
|
||||
{
|
||||
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
|
||||
@@ -568,7 +603,6 @@ int gk20a_power_node_init(struct device *dev)
|
||||
struct nvgpu_class *class;
|
||||
u32 total_cdevs;
|
||||
u32 num_classes;
|
||||
struct nvgpu_cdev *cdev;
|
||||
|
||||
if (!l->cdev_list_init_done) {
|
||||
nvgpu_init_list_node(&l->cdev_list_head);
|
||||
@@ -591,28 +625,17 @@ int gk20a_power_node_init(struct device *dev)
|
||||
|
||||
l->power_cdev_region = devno;
|
||||
nvgpu_list_for_each_entry(class, &l->class_list_head, nvgpu_class, list_entry) {
|
||||
cdev = nvgpu_kzalloc(g, sizeof(*cdev));
|
||||
if (cdev == NULL) {
|
||||
dev_err(dev, "failed to allocate cdev\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* dev_node_list[0] is the power node to issue
|
||||
* power-on to the GPU.
|
||||
*/
|
||||
err = gk20a_create_device(dev, devno++,
|
||||
err = nvgpu_alloc_and_create_device(dev, devno++,
|
||||
dev_node_list[0].name,
|
||||
&cdev->cdev, &cdev->node,
|
||||
dev_node_list[0].fops,
|
||||
class);
|
||||
if (err) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cdev->class = class;
|
||||
nvgpu_init_list_node(&cdev->list_entry);
|
||||
nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head);
|
||||
}
|
||||
|
||||
l->power_cdevs = total_cdevs;
|
||||
@@ -632,7 +655,6 @@ int gk20a_user_nodes_init(struct device *dev)
|
||||
struct nvgpu_class *class;
|
||||
u32 num_cdevs, total_cdevs;
|
||||
u32 num_classes;
|
||||
struct nvgpu_cdev *cdev;
|
||||
u32 cdev_index;
|
||||
|
||||
if (!l->cdev_list_init_done) {
|
||||
@@ -683,24 +705,13 @@ int gk20a_user_nodes_init(struct device *dev)
|
||||
continue;
|
||||
}
|
||||
|
||||
cdev = nvgpu_kzalloc(g, sizeof(*cdev));
|
||||
if (cdev == NULL) {
|
||||
dev_err(dev, "failed to allocate cdev\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = gk20a_create_device(dev, devno++,
|
||||
err = nvgpu_alloc_and_create_device(dev, devno++,
|
||||
dev_node_list[cdev_index].name,
|
||||
&cdev->cdev, &cdev->node,
|
||||
dev_node_list[cdev_index].fops,
|
||||
class);
|
||||
if (err) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cdev->class = class;
|
||||
nvgpu_init_list_node(&cdev->list_entry);
|
||||
nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user