diff options
Diffstat (limited to 'schulung_tools/drivers/modules/hellodriver/hello.c')
| -rw-r--r-- | schulung_tools/drivers/modules/hellodriver/hello.c | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/schulung_tools/drivers/modules/hellodriver/hello.c b/schulung_tools/drivers/modules/hellodriver/hello.c deleted file mode 100644 index 7f78d06..0000000 --- a/schulung_tools/drivers/modules/hellodriver/hello.c +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/init.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/uaccess.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/cdev.h> -#include <linux/of.h> - -struct hello_dev { - struct device *dev; - struct cdev cdev; - unsigned int minor; -}; - -#define HELLO_MAX_DEVICES 10 - -static struct class *hello_class; -static dev_t hello_devt; - -static int hello_open(struct inode *node, struct file *f) -{ - struct cdev *cd = node->i_cdev; - struct hello_dev *hello = container_of(cd, struct hello_dev, cdev); - dev_info(hello->dev, "%s\n", __func__); - f->private_data = hello; - return 0; -} - -static int hello_release(struct inode *node, struct file *f) -{ - struct hello_dev *hello = f->private_data; - dev_info(hello->dev, "%s\n", __func__); - f->private_data = NULL; - return 0; -} - -static ssize_t hello_read(struct file *f, char __user *u, size_t s, loff_t *l) -{ - struct hello_dev *hello = f->private_data; - char buf[10]; - size_t len; - - dev_info(hello->dev, "%s: size=%zu offset=%llu\n", __func__, s, *l); - - if (*l >= 40) - return 0; - - len = snprintf(buf, sizeof(buf), "hello:%d\n", hello->minor); - - if (s < len) - len = s; - - if (copy_to_user(u, buf, len) != 0) - return -EFAULT; - - *l += len; - - return len; -} - -static ssize_t hello_write(struct file *f, const char __user *u, size_t s, - loff_t *l) -{ - struct hello_dev *hello = f->private_data; - dev_info(hello->dev, "%s: size=%zu offset=%llu\n", __func__, s, *l); - return s; -} - -static const struct file_operations hello_fops = { - .owner = THIS_MODULE, - .open = hello_open, - .release = hello_release, - .read = hello_read, - .write = hello_write, -}; - -static int hello_probe(struct platform_device *pdev) -{ - struct hello_dev *hello; - struct device *dev; - dev_t devt; - int ret; - - hello = devm_kzalloc(&pdev->dev, sizeof(*hello), GFP_KERNEL); - if (!hello) { - dev_err(&pdev->dev, "devm_kzalloc failed\n"); - return -ENOMEM; - } - -#ifdef CONFIG_OF - ret = of_property_read_u32(pdev->dev.of_node, "index", &hello->minor); - if (ret < 0) { - dev_err(&pdev->dev, "no index specified\n"); - goto err_out; - } -#else - hello->minor = (unsigned)pdev->id; -#endif - - if (hello->minor >= HELLO_MAX_DEVICES) { - dev_err(&pdev->dev, "invalid index: %u\n", hello->minor); - ret = -EINVAL; - goto err_out; - } - - hello->dev = &pdev->dev; - platform_set_drvdata(pdev, hello); - - devt = MKDEV(MAJOR(hello_devt), hello->minor); - - cdev_init(&hello->cdev, &hello_fops); - hello->cdev.owner = THIS_MODULE; - ret = cdev_add(&hello->cdev, devt, 1); - if (ret != 0) { - dev_err(&pdev->dev, "cdev_add failed\n"); - goto err_drvdata; - } - - dev = device_create(hello_class, &pdev->dev, devt, hello, - "hello%d", hello->minor); - if (IS_ERR(dev)) { - dev_err(&pdev->dev, "device_create failed\n"); - ret = PTR_ERR(dev); - goto err_cdev; - } - - dev_info(&pdev->dev, "HELLO! I am hello device %d!\n", hello->minor); - - return 0; - -err_cdev: - cdev_del(&hello->cdev); -err_drvdata: - platform_set_drvdata(pdev, NULL); -err_out: - return ret; -} - -static int hello_remove(struct platform_device *pdev) -{ - struct hello_dev *hello = platform_get_drvdata(pdev); - - device_destroy(hello_class, MKDEV(MAJOR(hello_devt), hello->minor)); - cdev_del(&hello->cdev); - platform_set_drvdata(pdev, NULL); - - dev_info(&pdev->dev, "GOODBYE! I was hello device %d!\n", hello->minor); - - return 0; -} - -static const struct of_device_id hello_match[] = { - { .compatible = "virtual,hello", }, - { /* end of table */ } -}; - -static struct platform_driver hello_driver = { - .driver = { - .name = "hello", - .of_match_table = hello_match, - }, - .probe = hello_probe, - .remove = hello_remove, -}; - -#ifndef CONFIG_OF -static struct platform_device *pdevs[3]; -#endif - -static int __init hello_init(void) -{ - int ret; - - printk(KERN_INFO "%s\n", __func__); - - ret = alloc_chrdev_region(&hello_devt, 0, HELLO_MAX_DEVICES, "hello"); - if (ret < 0) - return ret; - - hello_class = class_create(THIS_MODULE, "hello"); - if (IS_ERR(hello_class)) { - printk(KERN_ERR "%s: failed to create class\n", __func__); - ret = PTR_ERR(hello_class); - goto err_region; - } - - ret = platform_driver_register(&hello_driver); - if (ret != 0) - goto err_class; - -#ifndef CONFIG_OF - pdevs[0] = platform_device_register_simple("hello", 1, NULL, 0); - pdevs[1] = platform_device_register_simple("hello", 3, NULL, 0); - pdevs[2] = platform_device_register_simple("hello", 5, NULL, 0); -#endif - - return 0; - -err_class: - class_destroy(hello_class); -err_region: - unregister_chrdev_region(hello_devt, HELLO_MAX_DEVICES); - return ret; -} - -static void __exit hello_exit(void) -{ - printk(KERN_INFO "%s\n", __func__); - -#ifndef CONFIG_OF - platform_device_unregister(pdevs[0]); - platform_device_unregister(pdevs[1]); - platform_device_unregister(pdevs[2]); -#endif - - platform_driver_unregister(&hello_driver); - class_destroy(hello_class); - unregister_chrdev_region(hello_devt, HELLO_MAX_DEVICES); -} - -module_init(hello_init); -module_exit(hello_exit); - -MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>"); -MODULE_DESCRIPTION("a great module for hello-ing!"); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION("20190101"); |
