summaryrefslogtreecommitdiff
path: root/schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2019-02-15 13:10:21 +0106
committerJohn Ogness <john.ogness@linutronix.de>2019-02-15 13:10:21 +0106
commitaed79d1121a9c65dead95fb6ea8c2d8541d01143 (patch)
tree6917e9570dfd2d60f357759e096cb013bc0c001c /schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch
parent2d2484928560dd0ffec90069166b0161cdc84a54 (diff)
schulung_tools: hellodriver: add patches for use with leds
These patches are based heavily on the work by Manu to make the driver lessons more interesting. Rather than create a new driver, I took his work and created a series of patches that do interesting modifications to the hello driver. These patches can be used together with the "leds" program to do live blinking demonstrations. Signed-off-by: John Ogness <john.ogness@linutronix.de>
Diffstat (limited to 'schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch')
-rw-r--r--schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch338
1 files changed, 338 insertions, 0 deletions
diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch b/schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch
new file mode 100644
index 0000000..3274ccd
--- /dev/null
+++ b/schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch
@@ -0,0 +1,338 @@
+From 5f05842b160249563a7e4965aaa01998e562f487 Mon Sep 17 00:00:00 2001
+From: John Ogness <john.ogness@linutronix.de>
+Date: Fri, 15 Feb 2019 11:33:24 +0100
+Subject: [PATCH 7/7] hello: remove chardev, use only leds subsystem
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+---
+ hello-led.c | 38 -------------
+ hello.c | 181 +-----------------------------------------------------------
+ hello.h | 7 ---
+ 3 files changed, 3 insertions(+), 223 deletions(-)
+ delete mode 100644 hello-led.c
+ delete mode 100644 hello.h
+
+diff --git a/hello-led.c b/hello-led.c
+deleted file mode 100644
+index 43230cd..0000000
+--- a/hello-led.c
++++ /dev/null
+@@ -1,38 +0,0 @@
+-#include <stdio.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <fcntl.h>
+-#include <unistd.h>
+-#include <sys/ioctl.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include "hello.h"
+-
+-int main(int argc, char *argv[])
+-{
+- int fd;
+-
+- if (argc != 3) {
+- fprintf(stderr, "usage: %s <device> <led>\n", argv[0]);
+- return 1;
+- }
+-
+- fd = open(argv[1], O_RDWR);
+- if (fd < 0) {
+- fprintf(stderr, "open() failed: %s\n", strerror(errno));
+- return 1;
+- }
+-
+- if (strcmp(argv[2], "heartbeat") == 0)
+- ioctl(fd, HELLO_IOCTL_TOGGLE_LED, 0);
+- else if (strcmp(argv[2], "net") == 0)
+- ioctl(fd, HELLO_IOCTL_TOGGLE_LED, 1);
+- else if (strcmp(argv[2], "disk") == 0)
+- ioctl(fd, HELLO_IOCTL_TOGGLE_LED, 2);
+- else
+- fprintf(stderr, "unknown led\n");
+-
+- close(fd);
+-
+- return 0;
+-}
+diff --git a/hello.c b/hello.c
+index f9809f3..52df6d7 100644
+--- a/hello.c
++++ b/hello.c
+@@ -1,19 +1,12 @@
+ // 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/pci.h>
+-#include <linux/cdev.h>
+ #include <linux/leds.h>
+-#include "hello.h"
+
+ struct hello_dev {
+ struct device *dev;
+- struct cdev cdev;
+- unsigned int minor;
+ void __iomem *mem;
+
+ struct led_classdev led_heartbeat;
+@@ -21,115 +14,6 @@ struct hello_dev {
+ struct led_classdev led_disk;
+ };
+
+-#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 void toggle_led(struct hello_dev *hello, int offset)
+-{
+- if (readb(hello->mem + offset))
+- writeb(0, hello->mem + offset);
+- else
+- writeb(0xff, hello->mem + offset);
+-}
+-
+-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;
+- size_t sz = s;
+- char buf[32];
+-
+- if (sz >= sizeof(buf))
+- sz = sizeof(buf) - 1;
+- if (copy_from_user(buf, u, sz) != 0)
+- return -EFAULT;
+- buf[sz] = 0;
+-
+- dev_info(hello->dev, "%s: size=%zu offset=%llu buf=%s\n", __func__,
+- s, *l, buf);
+-
+- if (strstarts(buf, "heartbeat"))
+- toggle_led(hello, 0);
+- else if (strstarts(buf, "net"))
+- toggle_led(hello, 1);
+- else if (strstarts(buf, "disk"))
+- toggle_led(hello, 2);
+-
+- return s;
+-}
+-
+-static long hello_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+-{
+- struct hello_dev *hello = f->private_data;
+- u32 val;
+-
+- dev_info(hello->dev, "%s: cmd=%u arg=%lu\n", __func__, cmd, arg);
+-
+- switch (cmd) {
+- case HELLO_IOCTL_TOGGLE_LED:
+- val = arg;
+- if (val >= 0 && val <= 2)
+- toggle_led(hello, val);
+- break;
+- default:
+- return -EINVAL;
+- }
+-
+- return 0;
+-}
+-
+-static const struct file_operations hello_fops = {
+- .owner = THIS_MODULE,
+- .open = hello_open,
+- .release = hello_release,
+- .read = hello_read,
+- .write = hello_write,
+- .unlocked_ioctl = hello_ioctl,
+-};
+-
+ static void set_brightness(struct hello_dev *hello, int offset,
+ enum led_brightness b)
+ {
+@@ -194,8 +78,6 @@ static enum led_brightness hello_led_disk_get(struct led_classdev *ldev)
+ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ struct hello_dev *hello;
+- struct device *dev;
+- dev_t devt;
+ int ret;
+
+ hello = devm_kzalloc(&pdev->dev, sizeof(*hello), GFP_KERNEL);
+@@ -204,14 +86,6 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ return -ENOMEM;
+ }
+
+- hello->minor = 1;
+-
+- 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;
+ pci_set_drvdata(pdev, hello);
+
+@@ -241,24 +115,6 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ goto err_regions;
+ }
+
+- 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_iomap;
+- }
+-
+- 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;
+- }
+-
+ hello->led_heartbeat.name = "heartbeat";
+ hello->led_heartbeat.brightness = get_brightness(hello, 0);
+ hello->led_heartbeat.max_brightness = 1;
+@@ -280,14 +136,10 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ hello->led_disk.brightness_get = hello_led_disk_get;
+ led_classdev_register(&pdev->dev, &hello->led_disk);
+
+- dev_info(&pdev->dev, "HELLO! I am hello device %d!\n", hello->minor);
++ dev_info(&pdev->dev, "HELLO! I am hello device!\n");
+
+ return 0;
+
+-err_cdev:
+- cdev_del(&hello->cdev);
+-err_iomap:
+- pci_iounmap(pdev, hello->mem);
+ err_regions:
+ pci_release_regions(pdev);
+ err_enable:
+@@ -304,14 +156,12 @@ static void hello_remove(struct pci_dev *pdev)
+ led_classdev_unregister(&hello->led_disk);
+ led_classdev_unregister(&hello->led_net);
+ led_classdev_unregister(&hello->led_heartbeat);
+- device_destroy(hello_class, MKDEV(MAJOR(hello_devt), hello->minor));
+- cdev_del(&hello->cdev);
+ pci_iounmap(pdev, hello->mem);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+
+- dev_info(&pdev->dev, "GOODBYE! I was hello device %d!\n", hello->minor);
++ dev_info(&pdev->dev, "GOODBYE! I was hello device!\n");
+ }
+
+ static const struct pci_device_id hello_id_table[] = {
+@@ -329,32 +179,9 @@ static struct pci_driver hello_driver = {
+
+ 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 = pci_register_driver(&hello_driver);
+- if (ret != 0)
+- goto err_class;
+-
+- return 0;
+-
+-err_class:
+- class_destroy(hello_class);
+-err_region:
+- unregister_chrdev_region(hello_devt, HELLO_MAX_DEVICES);
+- return ret;
++ return pci_register_driver(&hello_driver);
+ }
+
+ static void __exit hello_exit(void)
+@@ -362,8 +189,6 @@ static void __exit hello_exit(void)
+ printk(KERN_INFO "%s\n", __func__);
+
+ pci_unregister_driver(&hello_driver);
+- class_destroy(hello_class);
+- unregister_chrdev_region(hello_devt, HELLO_MAX_DEVICES);
+ }
+
+ module_init(hello_init);
+diff --git a/hello.h b/hello.h
+deleted file mode 100644
+index cb172d9..0000000
+--- a/hello.h
++++ /dev/null
+@@ -1,7 +0,0 @@
+-#ifndef HELLO_H
+-#define HELLO_H
+-
+-#define HELLO_BASE 0x9F
+-#define HELLO_IOCTL_TOGGLE_LED _IOW(HELLO_BASE, 0x00, unsigned int)
+-
+-#endif /* HELLO_H */
+--
+2.11.0
+