diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 45fbff25..af311644 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -14,3 +14,4 @@ ifneq ($(CONFIG_TEGRA_GPIO_LEGACY_DISABLE),y) obj-m += bluedroid_pm.o endif obj-m += nvscic2c-pcie/ +obj-m += ioctl_example.o diff --git a/drivers/misc/ioctl_example.c b/drivers/misc/ioctl_example.c new file mode 100644 index 00000000..74ce3d6f --- /dev/null +++ b/drivers/misc/ioctl_example.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#include +#include +#include +#include +#include +#include + +/* Define IOCTL commands */ +#define IOCTL_SET_VALUE _IOW('k', 1, int) +#define IOCTL_GET_VALUE _IOR('k', 2, int) + +static int value; +static dev_t dev_num; +static struct cdev cdev; +static struct class *dev_class; + +static int device_open(struct inode *inode, struct file *file) +{ + pr_info("ioctl_example: Device opened\n"); + return 0; +} + +static int device_release(struct inode *inode, struct file *file) +{ + pr_info("ioctl_example: Device closed\n"); + return 0; +} + +static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + switch (cmd) { + case IOCTL_SET_VALUE: + if (copy_from_user(&value, (int *)arg, sizeof(int))) + ret = -EFAULT; + break; + + case IOCTL_GET_VALUE: + if (copy_to_user((int *)arg, &value, sizeof(int))) + ret = -EFAULT; + break; + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +static struct file_operations fops = { + .owner = THIS_MODULE, + .open = device_open, + .release = device_release, + .unlocked_ioctl = device_ioctl, +}; + +static int __init ioctl_example_init(void) +{ + /* Allocate major and minor numbers */ + alloc_chrdev_region(&dev_num, 0, 1, "ioctl_example"); + + /* Initialize the character device structure */ + cdev_init(&cdev, &fops); + cdev_add(&cdev, dev_num, 1); + + /* Create a device class */ + dev_class = class_create(THIS_MODULE, "ioctl_example"); + device_create(dev_class, NULL, dev_num, NULL, "ioctl_example"); + + pr_info("ioctl_example: Module loaded\n"); + return 0; +} + +static void __exit ioctl_example_exit(void) +{ + device_destroy(dev_class, dev_num); + class_destroy(dev_class); + cdev_del(&cdev); + unregister_chrdev_region(dev_num, 1); + pr_info("ioctl_example: Module unloaded\n"); +} + +module_init(ioctl_example_init); +module_exit(ioctl_example_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Simple IOCTL Example"); +