From f19259fb36ffe74a11325c14ee2260a8e323b8ee Mon Sep 17 00:00:00 2001 From: John Ogness Date: Fri, 15 Feb 2019 13:16:28 +0106 Subject: schulung_tools: drivers: remove modules subdir There is no need for the extra directory level. Move all the example modules to the parent "drivers" directory and delete the modules directory. Signed-off-by: John Ogness --- schulung_tools/drivers/hellodriver/Makefile | 19 ++ schulung_tools/drivers/hellodriver/hello.c | 230 ++++++++++++++ .../drivers/hellodriver/patch-add-sysfs.diff | 57 ++++ .../drivers/hellodriver/patch-hello-dts.diff | 26 ++ .../drivers/hellodriver/patch-kernel-build.diff | 32 ++ ...001-hello-change-from-platform-to-pci-bus.patch | 185 +++++++++++ .../0002-hello-add-pci-memory-mapping.patch | 64 ++++ ...o-add-led-toggling-via-chardev-read-write.patch | 56 ++++ ...-hello-add-led-toggling-via-chardev-ioctl.patch | 124 ++++++++ ...hello-add-led-toggling-via-leds-subsystem.patch | 142 +++++++++ ...lo-remove-chardev-use-only-leds-subsystem.patch | 338 +++++++++++++++++++++ .../drivers/hellodriver/patches-leds/README | 6 + .../drivers/klist/0001-klist-example.patch | 138 +++++++++ .../drivers/modules/hellodriver/Makefile | 19 -- schulung_tools/drivers/modules/hellodriver/hello.c | 230 -------------- .../modules/hellodriver/patch-add-sysfs.diff | 57 ---- .../modules/hellodriver/patch-hello-dts.diff | 26 -- .../modules/hellodriver/patch-kernel-build.diff | 32 -- ...001-hello-change-from-platform-to-pci-bus.patch | 185 ----------- .../0002-hello-add-pci-memory-mapping.patch | 64 ---- ...o-add-led-toggling-via-chardev-read-write.patch | 56 ---- ...-hello-add-led-toggling-via-chardev-ioctl.patch | 124 -------- ...hello-add-led-toggling-via-leds-subsystem.patch | 142 --------- ...lo-remove-chardev-use-only-leds-subsystem.patch | 338 --------------------- .../modules/hellodriver/patches-leds/README | 6 - .../drivers/modules/klist/0001-klist-example.patch | 138 --------- .../drivers/modules/simplemodule/Makefile | 19 -- .../drivers/modules/simplemodule/simple.c | 21 -- schulung_tools/drivers/simplemodule/Makefile | 19 ++ schulung_tools/drivers/simplemodule/simple.c | 21 ++ 30 files changed, 1457 insertions(+), 1457 deletions(-) create mode 100644 schulung_tools/drivers/hellodriver/Makefile create mode 100644 schulung_tools/drivers/hellodriver/hello.c create mode 100644 schulung_tools/drivers/hellodriver/patch-add-sysfs.diff create mode 100644 schulung_tools/drivers/hellodriver/patch-hello-dts.diff create mode 100644 schulung_tools/drivers/hellodriver/patch-kernel-build.diff create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch create mode 100644 schulung_tools/drivers/hellodriver/patches-leds/README create mode 100644 schulung_tools/drivers/klist/0001-klist-example.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/Makefile delete mode 100644 schulung_tools/drivers/modules/hellodriver/hello.c delete mode 100644 schulung_tools/drivers/modules/hellodriver/patch-add-sysfs.diff delete mode 100644 schulung_tools/drivers/modules/hellodriver/patch-hello-dts.diff delete mode 100644 schulung_tools/drivers/modules/hellodriver/patch-kernel-build.diff delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch delete mode 100644 schulung_tools/drivers/modules/hellodriver/patches-leds/README delete mode 100644 schulung_tools/drivers/modules/klist/0001-klist-example.patch delete mode 100644 schulung_tools/drivers/modules/simplemodule/Makefile delete mode 100644 schulung_tools/drivers/modules/simplemodule/simple.c create mode 100644 schulung_tools/drivers/simplemodule/Makefile create mode 100644 schulung_tools/drivers/simplemodule/simple.c (limited to 'schulung_tools/drivers') diff --git a/schulung_tools/drivers/hellodriver/Makefile b/schulung_tools/drivers/hellodriver/Makefile new file mode 100644 index 0000000..764fefd --- /dev/null +++ b/schulung_tools/drivers/hellodriver/Makefile @@ -0,0 +1,19 @@ +MNAME = hello +BDIR = /lib/modules/`uname -r`/build + +ifeq ($(KERNELRELEASE),) +# called from shell + +.PHONY: default clean + +default: + make -C $(BDIR) M=$(shell pwd) modules + +clean: + rm -rf $(MNAME).mod.* $(MNAME).*o .$(MNAME)* .tmp* Module.symvers modules.order + +else +# called from kernel Makefile + + obj-m := $(MNAME).o +endif diff --git a/schulung_tools/drivers/hellodriver/hello.c b/schulung_tools/drivers/hellodriver/hello.c new file mode 100644 index 0000000..7f78d06 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/hello.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 "); +MODULE_DESCRIPTION("a great module for hello-ing!"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("20190101"); diff --git a/schulung_tools/drivers/hellodriver/patch-add-sysfs.diff b/schulung_tools/drivers/hellodriver/patch-add-sysfs.diff new file mode 100644 index 0000000..44c913e --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patch-add-sysfs.diff @@ -0,0 +1,57 @@ +From 9ec20c5b243d6f1f83b38b57474cf532c4575a02 Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Fri, 15 Feb 2019 12:58:25 +0106 +Subject: [PATCH] hello: add custom sysfs files + +Signed-off-by: John Ogness +--- + hello.c | 26 ++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/hello.c b/hello.c +index 7f78d06..4c7989a 100644 +--- a/hello.c ++++ b/hello.c +@@ -77,6 +77,30 @@ static const struct file_operations hello_fops = { + .write = hello_write, + }; + ++static ssize_t major_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sprintf(buf, "%d\n", MAJOR(hello_devt)); ++} ++static DEVICE_ATTR_RO(major); ++ ++static ssize_t minor_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct hello_dev *hello = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%d\n", hello->minor); ++} ++static DEVICE_ATTR_RO(minor); ++ ++static struct attribute *hello_device_attrs[] = { ++ &dev_attr_major.attr, ++ &dev_attr_minor.attr, ++ NULL, ++}; ++ATTRIBUTE_GROUPS(hello_device); ++ + static int hello_probe(struct platform_device *pdev) + { + struct hello_dev *hello; +@@ -187,6 +211,8 @@ static int __init hello_init(void) + goto err_region; + } + ++ hello_class->dev_groups = hello_device_groups; ++ + ret = platform_driver_register(&hello_driver); + if (ret != 0) + goto err_class; +-- +2.1.4 + diff --git a/schulung_tools/drivers/hellodriver/patch-hello-dts.diff b/schulung_tools/drivers/hellodriver/patch-hello-dts.diff new file mode 100644 index 0000000..2d0bf52 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patch-hello-dts.diff @@ -0,0 +1,26 @@ +diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts +index d949fac..4952799 100644 +--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts ++++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts +@@ -132,6 +132,21 @@ + status = "disabled"; + }; + ++ hello@1 { ++ compatible = "virtual,hello"; ++ index = <1>; ++ }; ++ ++ hello@5 { ++ compatible = "virtual,hello"; ++ index = <5>; ++ }; ++ ++ hello@8 { ++ compatible = "virtual,hello"; ++ index = <8>; ++ }; ++ + watchdog@100e5000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x100e5000 0x1000>; diff --git a/schulung_tools/drivers/hellodriver/patch-kernel-build.diff b/schulung_tools/drivers/hellodriver/patch-kernel-build.diff new file mode 100644 index 0000000..8d43ca7 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patch-kernel-build.diff @@ -0,0 +1,32 @@ +diff -urNp a/drivers/char/Kconfig b/drivers/char/Kconfig +--- a/drivers/char/Kconfig 2016-05-16 00:43:13.000000000 +0200 ++++ b/drivers/char/Kconfig 2016-06-08 20:41:14.047205734 +0200 +@@ -6,6 +6,16 @@ menu "Character devices" + + source "drivers/tty/Kconfig" + ++config HELLO ++ tristate "hello demo driver" ++ default n ++ help ++ This driver demonstrates how to create a platform device that is ++ specified in a device tree. ++ ++ It also create a character device to demonstrate how a character ++ device interface can be provided to userspace. ++ + config DEVMEM + bool "/dev/mem virtual device support" + default y +diff -urNp a/drivers/char/Makefile b/drivers/char/Makefile +--- a/drivers/char/Makefile 2016-05-16 00:43:13.000000000 +0200 ++++ b/drivers/char/Makefile 2016-06-08 14:16:44.897437533 +0200 +@@ -16,6 +16,8 @@ obj-$(CONFIG_IBM_BSR) += bsr.o + obj-$(CONFIG_SGI_MBCS) += mbcs.o + obj-$(CONFIG_BFIN_OTP) += bfin-otp.o + ++obj-$(CONFIG_HELLO) += hello.o ++ + obj-$(CONFIG_PRINTER) += lp.o + + obj-$(CONFIG_APM_EMULATION) += apm-emulation.o diff --git a/schulung_tools/drivers/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch b/schulung_tools/drivers/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch new file mode 100644 index 0000000..35dc817 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch @@ -0,0 +1,185 @@ +From 28357d61e0ec39851ca88a09b04ce876b8758448 Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Fri, 15 Feb 2019 12:11:27 +0100 +Subject: [PATCH 2/7] hello: change from platform to pci bus + +Signed-off-by: John Ogness +--- + hello.c | 89 +++++++++++++++++++++++++++++++---------------------------------- + 1 file changed, 43 insertions(+), 46 deletions(-) + +diff --git a/hello.c b/hello.c +index 7f78d06..db50302 100644 +--- a/hello.c ++++ b/hello.c +@@ -5,9 +5,8 @@ + #include + #include + #include +-#include ++#include + #include +-#include + + struct hello_dev { + struct device *dev; +@@ -77,7 +76,7 @@ static const struct file_operations hello_fops = { + .write = hello_write, + }; + +-static int hello_probe(struct platform_device *pdev) ++static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { + struct hello_dev *hello; + struct device *dev; +@@ -90,15 +89,7 @@ static int hello_probe(struct platform_device *pdev) + 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 ++ hello->minor = 1; + + if (hello->minor >= HELLO_MAX_DEVICES) { + dev_err(&pdev->dev, "invalid index: %u\n", hello->minor); +@@ -107,7 +98,27 @@ static int hello_probe(struct platform_device *pdev) + } + + hello->dev = &pdev->dev; +- platform_set_drvdata(pdev, hello); ++ pci_set_drvdata(pdev, hello); ++ ++ ret = pci_enable_device(pdev); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to enable device\n"); ++ goto err_drvdata; ++ } ++ ++ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { ++ dev_err(&pdev->dev, "failed to find base address\n"); ++ ret = -ENODEV; ++ goto err_enable; ++ } ++ ++ ret = pci_request_regions(pdev, "hello"); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to request resources\n"); ++ goto err_enable; ++ } ++ ++ pci_set_master(pdev); + + devt = MKDEV(MAJOR(hello_devt), hello->minor); + +@@ -116,7 +127,7 @@ static int hello_probe(struct platform_device *pdev) + ret = cdev_add(&hello->cdev, devt, 1); + if (ret != 0) { + dev_err(&pdev->dev, "cdev_add failed\n"); +- goto err_drvdata; ++ goto err_regions; + } + + dev = device_create(hello_class, &pdev->dev, devt, hello, +@@ -133,43 +144,41 @@ static int hello_probe(struct platform_device *pdev) + + err_cdev: + cdev_del(&hello->cdev); ++err_regions: ++ pci_release_regions(pdev); ++err_enable: ++ pci_disable_device(pdev); + err_drvdata: +- platform_set_drvdata(pdev, NULL); +-err_out: ++ pci_set_drvdata(pdev, NULL); + return ret; + } + +-static int hello_remove(struct platform_device *pdev) ++static void hello_remove(struct pci_dev *pdev) + { +- struct hello_dev *hello = platform_get_drvdata(pdev); ++ struct hello_dev *hello = pci_get_drvdata(pdev); + + device_destroy(hello_class, MKDEV(MAJOR(hello_devt), hello->minor)); + cdev_del(&hello->cdev); +- platform_set_drvdata(pdev, NULL); ++ 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); +- +- return 0; + } + +-static const struct of_device_id hello_match[] = { +- { .compatible = "virtual,hello", }, ++static const struct pci_device_id hello_id_table[] = { ++ { 0x1af4, 0x1110, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0 }, + { /* end of table */ } + }; ++MODULE_DEVICE_TABLE(pci, hello_id_table); + +-static struct platform_driver hello_driver = { +- .driver = { +- .name = "hello", +- .of_match_table = hello_match, +- }, ++static struct pci_driver hello_driver = { ++ .name = "hello", ++ .id_table = hello_id_table, + .probe = hello_probe, + .remove = hello_remove, + }; + +-#ifndef CONFIG_OF +-static struct platform_device *pdevs[3]; +-#endif +- + static int __init hello_init(void) + { + int ret; +@@ -187,16 +196,10 @@ static int __init hello_init(void) + goto err_region; + } + +- ret = platform_driver_register(&hello_driver); ++ ret = pci_register_driver(&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: +@@ -210,13 +213,7 @@ 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); ++ pci_unregister_driver(&hello_driver); + class_destroy(hello_class); + unregister_chrdev_region(hello_devt, HELLO_MAX_DEVICES); + } +-- +2.11.0 + diff --git a/schulung_tools/drivers/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch b/schulung_tools/drivers/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch new file mode 100644 index 0000000..0a11a57 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch @@ -0,0 +1,64 @@ +From 3afec946845a02a8fce94d00abda9b4c8abcbce0 Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Fri, 15 Feb 2019 11:03:59 +0106 +Subject: [PATCH 3/7] hello: add pci memory mapping + +Signed-off-by: John Ogness +--- + hello.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/hello.c b/hello.c +index db50302..58a64e5 100644 +--- a/hello.c ++++ b/hello.c +@@ -12,6 +12,7 @@ struct hello_dev { + struct device *dev; + struct cdev cdev; + unsigned int minor; ++ void __iomem *mem; + }; + + #define HELLO_MAX_DEVICES 10 +@@ -120,6 +121,12 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + pci_set_master(pdev); + ++ hello->mem = pci_iomap(pdev, 2, 0); ++ if (!hello->mem) { ++ ret = -ENOMEM; ++ goto err_regions; ++ } ++ + devt = MKDEV(MAJOR(hello_devt), hello->minor); + + cdev_init(&hello->cdev, &hello_fops); +@@ -127,7 +134,7 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + ret = cdev_add(&hello->cdev, devt, 1); + if (ret != 0) { + dev_err(&pdev->dev, "cdev_add failed\n"); +- goto err_regions; ++ goto err_iomap; + } + + dev = device_create(hello_class, &pdev->dev, devt, hello, +@@ -144,6 +151,8 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + + err_cdev: + cdev_del(&hello->cdev); ++err_iomap: ++ pci_iounmap(pdev, hello->mem); + err_regions: + pci_release_regions(pdev); + err_enable: +@@ -159,6 +168,7 @@ static void hello_remove(struct pci_dev *pdev) + + 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); +-- +2.11.0 + diff --git a/schulung_tools/drivers/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch b/schulung_tools/drivers/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch new file mode 100644 index 0000000..8f81e39 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch @@ -0,0 +1,56 @@ +From c7a4c4448632af43383818654dd79d2251b27e3e Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Fri, 15 Feb 2019 11:04:56 +0106 +Subject: [PATCH 4/7] hello: add led toggling via chardev read/write + +Signed-off-by: John Ogness +--- + hello.c | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/hello.c b/hello.c +index 58a64e5..f664121 100644 +--- a/hello.c ++++ b/hello.c +@@ -61,11 +61,37 @@ static ssize_t hello_read(struct file *f, char __user *u, size_t s, loff_t *l) + 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; +- dev_info(hello->dev, "%s: size=%zu offset=%llu\n", __func__, s, *l); ++ 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; + } + +-- +2.11.0 + diff --git a/schulung_tools/drivers/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch b/schulung_tools/drivers/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch new file mode 100644 index 0000000..a67bf98 --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch @@ -0,0 +1,124 @@ +From be59ddb43fbf039ed0bc848ac56b7f72f7a619c8 Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Fri, 15 Feb 2019 11:07:10 +0106 +Subject: [PATCH 5/7] hello: add led toggling via chardev ioctl + +Compile userspace application with: + +$ gcc -Wall -Werror hello-led.c -ohello-led + +Signed-off-by: John Ogness +--- + hello-led.c | 38 ++++++++++++++++++++++++++++++++++++++ + hello.c | 22 ++++++++++++++++++++++ + hello.h | 7 +++++++ + 3 files changed, 67 insertions(+) + create mode 100644 hello-led.c + create mode 100644 hello.h + +diff --git a/hello-led.c b/hello-led.c +new file mode 100644 +index 0000000..43230cd +--- /dev/null ++++ b/hello-led.c +@@ -0,0 +1,38 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "hello.h" ++ ++int main(int argc, char *argv[]) ++{ ++ int fd; ++ ++ if (argc != 3) { ++ fprintf(stderr, "usage: %s \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 f664121..c42c75f 100644 +--- a/hello.c ++++ b/hello.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include "hello.h" + + struct hello_dev { + struct device *dev; +@@ -95,12 +96,33 @@ static ssize_t hello_write(struct file *f, const char __user *u, size_t s, + 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 int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +diff --git a/hello.h b/hello.h +new file mode 100644 +index 0000000..cb172d9 +--- /dev/null ++++ b/hello.h +@@ -0,0 +1,7 @@ ++#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 + diff --git a/schulung_tools/drivers/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch b/schulung_tools/drivers/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch new file mode 100644 index 0000000..32f37ce --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch @@ -0,0 +1,142 @@ +From 3caece4ff394938f7544b994d35e784e2ce617cb Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Fri, 15 Feb 2019 11:10:09 +0106 +Subject: [PATCH 6/7] hello: add led toggling via leds subsystem + +Signed-off-by: John Ogness +--- + hello.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 90 insertions(+) + +diff --git a/hello.c b/hello.c +index c42c75f..f9809f3 100644 +--- a/hello.c ++++ b/hello.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include "hello.h" + + struct hello_dev { +@@ -14,6 +15,10 @@ struct hello_dev { + struct cdev cdev; + unsigned int minor; + void __iomem *mem; ++ ++ struct led_classdev led_heartbeat; ++ struct led_classdev led_net; ++ struct led_classdev led_disk; + }; + + #define HELLO_MAX_DEVICES 10 +@@ -125,6 +130,67 @@ static const struct file_operations hello_fops = { + .unlocked_ioctl = hello_ioctl, + }; + ++static void set_brightness(struct hello_dev *hello, int offset, ++ enum led_brightness b) ++{ ++ if (b) ++ writeb(0xff, hello->mem + offset); ++ else ++ writeb(0, hello->mem + offset); ++} ++ ++static enum led_brightness get_brightness(struct hello_dev *hello, int offset) ++{ ++ if (readb(hello->mem + offset)) ++ return 1; ++ return 0; ++} ++ ++static void hello_led_heartbeat_set(struct led_classdev *ldev, ++ enum led_brightness b) ++{ ++ struct hello_dev *hello = container_of(ldev, struct hello_dev, ++ led_heartbeat); ++ set_brightness(hello, 0, b); ++} ++ ++static enum led_brightness hello_led_heartbeat_get(struct led_classdev *ldev) ++{ ++ struct hello_dev *hello = container_of(ldev, struct hello_dev, ++ led_heartbeat); ++ return get_brightness(hello, 0); ++} ++ ++static void hello_led_net_set(struct led_classdev *ldev, ++ enum led_brightness b) ++{ ++ struct hello_dev *hello = container_of(ldev, struct hello_dev, ++ led_net); ++ set_brightness(hello, 1, b); ++} ++ ++static enum led_brightness hello_led_net_get(struct led_classdev *ldev) ++{ ++ struct hello_dev *hello = container_of(ldev, struct hello_dev, ++ led_net); ++ return get_brightness(hello, 1); ++} ++ ++static void hello_led_disk_set(struct led_classdev *ldev, ++ enum led_brightness b) ++{ ++ struct hello_dev *hello = container_of(ldev, struct hello_dev, ++ led_disk); ++ set_brightness(hello, 2, b); ++} ++ ++static enum led_brightness hello_led_disk_get(struct led_classdev *ldev) ++{ ++ struct hello_dev *hello = container_of(ldev, struct hello_dev, ++ led_disk); ++ return get_brightness(hello, 2); ++} ++ + static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { + struct hello_dev *hello; +@@ -193,6 +259,27 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + goto err_cdev; + } + ++ hello->led_heartbeat.name = "heartbeat"; ++ hello->led_heartbeat.brightness = get_brightness(hello, 0); ++ hello->led_heartbeat.max_brightness = 1; ++ hello->led_heartbeat.brightness_set = hello_led_heartbeat_set; ++ hello->led_heartbeat.brightness_get = hello_led_heartbeat_get; ++ led_classdev_register(&pdev->dev, &hello->led_heartbeat); ++ ++ hello->led_net.name = "net"; ++ hello->led_net.brightness = get_brightness(hello, 2); ++ hello->led_net.max_brightness = 1; ++ hello->led_net.brightness_set = hello_led_net_set; ++ hello->led_net.brightness_get = hello_led_net_get; ++ led_classdev_register(&pdev->dev, &hello->led_net); ++ ++ hello->led_disk.name = "disk"; ++ hello->led_disk.brightness = get_brightness(hello, 2); ++ hello->led_disk.max_brightness = 1; ++ hello->led_disk.brightness_set = hello_led_disk_set; ++ 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); + + return 0; +@@ -214,6 +301,9 @@ static void hello_remove(struct pci_dev *pdev) + { + struct hello_dev *hello = pci_get_drvdata(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); +-- +2.11.0 + diff --git a/schulung_tools/drivers/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch b/schulung_tools/drivers/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/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 +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 +--- + 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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "hello.h" +- +-int main(int argc, char *argv[]) +-{ +- int fd; +- +- if (argc != 3) { +- fprintf(stderr, "usage: %s \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 + #include +-#include +-#include +-#include + #include + #include +-#include + #include +-#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 + diff --git a/schulung_tools/drivers/hellodriver/patches-leds/README b/schulung_tools/drivers/hellodriver/patches-leds/README new file mode 100644 index 0000000..51bbffa --- /dev/null +++ b/schulung_tools/drivers/hellodriver/patches-leds/README @@ -0,0 +1,6 @@ +This set of patches show how different subsystems can be used +by the driver to communicate with the hardware and to present +itself to the user. + +For live demonstrations with actual blinking leds, use the +"leds" program. (See the README there for details.) diff --git a/schulung_tools/drivers/klist/0001-klist-example.patch b/schulung_tools/drivers/klist/0001-klist-example.patch new file mode 100644 index 0000000..b52216a --- /dev/null +++ b/schulung_tools/drivers/klist/0001-klist-example.patch @@ -0,0 +1,138 @@ +From 504db8a2bae95d7bafb9b68074fdc46c49f08c9f Mon Sep 17 00:00:00 2001 +From: Manuel Traut +Date: Fri, 4 Jan 2019 09:32:18 +0100 +Subject: [PATCH] klist example + +this can be used to show the usage of klists + +Signed-off-by: Manuel Traut +--- + drivers/staging/Kconfig | 2 + + drivers/staging/Makefile | 1 + + drivers/staging/klist/Kconfig | 5 +++ + drivers/staging/klist/Makefile | 1 + + drivers/staging/klist/klist.c | 68 +++++++++++++++++++++++++++++++++ + 5 files changed, 77 insertions(+) + create mode 100644 drivers/staging/klist/Kconfig + create mode 100644 drivers/staging/klist/Makefile + create mode 100644 drivers/staging/klist/klist.c + +diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig +index bfa2bf720a03..98541d7a41be 100644 +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -24,6 +24,8 @@ menuconfig STAGING + + if STAGING + ++source "drivers/staging/klist/Kconfig" ++ + source "drivers/staging/wlan-ng/Kconfig" + + source "drivers/staging/comedi/Kconfig" +diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile +index 25b3a8eafaa1..7a6d82750008 100644 +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -2,6 +2,7 @@ + # Makefile for staging directory + + obj-y += media/ ++obj-$(CONFIG_KLISTEXAMPLE) += klist/ + obj-$(CONFIG_PRISM2_USB) += wlan-ng/ + obj-$(CONFIG_COMEDI) += comedi/ + obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ +diff --git a/drivers/staging/klist/Kconfig b/drivers/staging/klist/Kconfig +new file mode 100644 +index 000000000000..18f517e56cb9 +--- /dev/null ++++ b/drivers/staging/klist/Kconfig +@@ -0,0 +1,4 @@ ++config KLISTEXAMPLE ++ tristate "module to teach klist usage" ++ ---help--- ++ This is only useful for learning the usage of klist. +diff --git a/drivers/staging/klist/Makefile b/drivers/staging/klist/Makefile +new file mode 100644 +index 000000000000..2939c11d72ff +--- /dev/null ++++ b/drivers/staging/klist/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_KLISTEXAMPLE) += klist.o +diff --git a/drivers/staging/klist/klist.c b/drivers/staging/klist/klist.c +new file mode 100644 +index 000000000000..365acaa3263a +--- /dev/null ++++ b/drivers/staging/klist/klist.c +@@ -0,0 +1,68 @@ ++/* ++ * Example driver for using klist ++ * Copyright (C) 2019, Manuel Traut ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define DRV_NAME "klist" ++ ++struct mynode { ++ struct list_head node; ++ unsigned long val; ++}; ++ ++static struct list_head mylist; ++static char mystring[] = "1 2 3 4 5\n"; ++ ++static void klist_free_list(void) { ++ struct mynode *n, *tmp; ++ list_for_each_entry_safe(n, tmp, &mylist, node) ++ kfree(n); ++} ++ ++static void klist_init_list(void) { ++ unsigned long val; ++ struct mynode *n; ++ char *tok; ++ char *b = kstrdup(mystring, GFP_KERNEL); ++ ++ INIT_LIST_HEAD(&mylist); ++ ++ while ((tok = strsep(&b, " ")) && *tok) { ++ printk(KERN_INFO "adding %s to list\n", tok); ++ if (kstrtoul(tok, 0, &val)) { ++ printk(KERN_ERR "failed to convert %s to int\n", tok); ++ goto exit_init; ++ } ++ n = kzalloc(sizeof(*n), GFP_KERNEL); ++ n->val = val; ++ list_add_tail(&n->node, &mylist); ++ } ++exit_init: ++ kfree(b); ++} ++ ++static int __init klist_init(void) { ++ printk(KERN_INFO "%s\n", __func__); ++ klist_init_list(); ++ return 0; ++} ++ ++static void __exit klist_exit(void) { ++ printk(KERN_INFO "%s\n", __func__); ++ klist_free_list(); ++} ++ ++module_init(klist_init); ++module_exit(klist_exit); ++MODULE_AUTHOR("Manuel Traut"); ++MODULE_LICENSE("GPL"); +-- +2.19.2 + diff --git a/schulung_tools/drivers/modules/hellodriver/Makefile b/schulung_tools/drivers/modules/hellodriver/Makefile deleted file mode 100644 index 764fefd..0000000 --- a/schulung_tools/drivers/modules/hellodriver/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -MNAME = hello -BDIR = /lib/modules/`uname -r`/build - -ifeq ($(KERNELRELEASE),) -# called from shell - -.PHONY: default clean - -default: - make -C $(BDIR) M=$(shell pwd) modules - -clean: - rm -rf $(MNAME).mod.* $(MNAME).*o .$(MNAME)* .tmp* Module.symvers modules.order - -else -# called from kernel Makefile - - obj-m := $(MNAME).o -endif 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 -#include -#include -#include -#include -#include -#include -#include -#include - -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 "); -MODULE_DESCRIPTION("a great module for hello-ing!"); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION("20190101"); diff --git a/schulung_tools/drivers/modules/hellodriver/patch-add-sysfs.diff b/schulung_tools/drivers/modules/hellodriver/patch-add-sysfs.diff deleted file mode 100644 index 44c913e..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patch-add-sysfs.diff +++ /dev/null @@ -1,57 +0,0 @@ -From 9ec20c5b243d6f1f83b38b57474cf532c4575a02 Mon Sep 17 00:00:00 2001 -From: John Ogness -Date: Fri, 15 Feb 2019 12:58:25 +0106 -Subject: [PATCH] hello: add custom sysfs files - -Signed-off-by: John Ogness ---- - hello.c | 26 ++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/hello.c b/hello.c -index 7f78d06..4c7989a 100644 ---- a/hello.c -+++ b/hello.c -@@ -77,6 +77,30 @@ static const struct file_operations hello_fops = { - .write = hello_write, - }; - -+static ssize_t major_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%d\n", MAJOR(hello_devt)); -+} -+static DEVICE_ATTR_RO(major); -+ -+static ssize_t minor_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct hello_dev *hello = platform_get_drvdata(pdev); -+ -+ return sprintf(buf, "%d\n", hello->minor); -+} -+static DEVICE_ATTR_RO(minor); -+ -+static struct attribute *hello_device_attrs[] = { -+ &dev_attr_major.attr, -+ &dev_attr_minor.attr, -+ NULL, -+}; -+ATTRIBUTE_GROUPS(hello_device); -+ - static int hello_probe(struct platform_device *pdev) - { - struct hello_dev *hello; -@@ -187,6 +211,8 @@ static int __init hello_init(void) - goto err_region; - } - -+ hello_class->dev_groups = hello_device_groups; -+ - ret = platform_driver_register(&hello_driver); - if (ret != 0) - goto err_class; --- -2.1.4 - diff --git a/schulung_tools/drivers/modules/hellodriver/patch-hello-dts.diff b/schulung_tools/drivers/modules/hellodriver/patch-hello-dts.diff deleted file mode 100644 index 2d0bf52..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patch-hello-dts.diff +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts -index d949fac..4952799 100644 ---- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts -+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts -@@ -132,6 +132,21 @@ - status = "disabled"; - }; - -+ hello@1 { -+ compatible = "virtual,hello"; -+ index = <1>; -+ }; -+ -+ hello@5 { -+ compatible = "virtual,hello"; -+ index = <5>; -+ }; -+ -+ hello@8 { -+ compatible = "virtual,hello"; -+ index = <8>; -+ }; -+ - watchdog@100e5000 { - compatible = "arm,sp805", "arm,primecell"; - reg = <0x100e5000 0x1000>; diff --git a/schulung_tools/drivers/modules/hellodriver/patch-kernel-build.diff b/schulung_tools/drivers/modules/hellodriver/patch-kernel-build.diff deleted file mode 100644 index 8d43ca7..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patch-kernel-build.diff +++ /dev/null @@ -1,32 +0,0 @@ -diff -urNp a/drivers/char/Kconfig b/drivers/char/Kconfig ---- a/drivers/char/Kconfig 2016-05-16 00:43:13.000000000 +0200 -+++ b/drivers/char/Kconfig 2016-06-08 20:41:14.047205734 +0200 -@@ -6,6 +6,16 @@ menu "Character devices" - - source "drivers/tty/Kconfig" - -+config HELLO -+ tristate "hello demo driver" -+ default n -+ help -+ This driver demonstrates how to create a platform device that is -+ specified in a device tree. -+ -+ It also create a character device to demonstrate how a character -+ device interface can be provided to userspace. -+ - config DEVMEM - bool "/dev/mem virtual device support" - default y -diff -urNp a/drivers/char/Makefile b/drivers/char/Makefile ---- a/drivers/char/Makefile 2016-05-16 00:43:13.000000000 +0200 -+++ b/drivers/char/Makefile 2016-06-08 14:16:44.897437533 +0200 -@@ -16,6 +16,8 @@ obj-$(CONFIG_IBM_BSR) += bsr.o - obj-$(CONFIG_SGI_MBCS) += mbcs.o - obj-$(CONFIG_BFIN_OTP) += bfin-otp.o - -+obj-$(CONFIG_HELLO) += hello.o -+ - obj-$(CONFIG_PRINTER) += lp.o - - obj-$(CONFIG_APM_EMULATION) += apm-emulation.o diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch b/schulung_tools/drivers/modules/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch deleted file mode 100644 index 35dc817..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/0001-hello-change-from-platform-to-pci-bus.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 28357d61e0ec39851ca88a09b04ce876b8758448 Mon Sep 17 00:00:00 2001 -From: John Ogness -Date: Fri, 15 Feb 2019 12:11:27 +0100 -Subject: [PATCH 2/7] hello: change from platform to pci bus - -Signed-off-by: John Ogness ---- - hello.c | 89 +++++++++++++++++++++++++++++++---------------------------------- - 1 file changed, 43 insertions(+), 46 deletions(-) - -diff --git a/hello.c b/hello.c -index 7f78d06..db50302 100644 ---- a/hello.c -+++ b/hello.c -@@ -5,9 +5,8 @@ - #include - #include - #include --#include -+#include - #include --#include - - struct hello_dev { - struct device *dev; -@@ -77,7 +76,7 @@ static const struct file_operations hello_fops = { - .write = hello_write, - }; - --static int hello_probe(struct platform_device *pdev) -+static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - { - struct hello_dev *hello; - struct device *dev; -@@ -90,15 +89,7 @@ static int hello_probe(struct platform_device *pdev) - 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 -+ hello->minor = 1; - - if (hello->minor >= HELLO_MAX_DEVICES) { - dev_err(&pdev->dev, "invalid index: %u\n", hello->minor); -@@ -107,7 +98,27 @@ static int hello_probe(struct platform_device *pdev) - } - - hello->dev = &pdev->dev; -- platform_set_drvdata(pdev, hello); -+ pci_set_drvdata(pdev, hello); -+ -+ ret = pci_enable_device(pdev); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to enable device\n"); -+ goto err_drvdata; -+ } -+ -+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { -+ dev_err(&pdev->dev, "failed to find base address\n"); -+ ret = -ENODEV; -+ goto err_enable; -+ } -+ -+ ret = pci_request_regions(pdev, "hello"); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to request resources\n"); -+ goto err_enable; -+ } -+ -+ pci_set_master(pdev); - - devt = MKDEV(MAJOR(hello_devt), hello->minor); - -@@ -116,7 +127,7 @@ static int hello_probe(struct platform_device *pdev) - ret = cdev_add(&hello->cdev, devt, 1); - if (ret != 0) { - dev_err(&pdev->dev, "cdev_add failed\n"); -- goto err_drvdata; -+ goto err_regions; - } - - dev = device_create(hello_class, &pdev->dev, devt, hello, -@@ -133,43 +144,41 @@ static int hello_probe(struct platform_device *pdev) - - err_cdev: - cdev_del(&hello->cdev); -+err_regions: -+ pci_release_regions(pdev); -+err_enable: -+ pci_disable_device(pdev); - err_drvdata: -- platform_set_drvdata(pdev, NULL); --err_out: -+ pci_set_drvdata(pdev, NULL); - return ret; - } - --static int hello_remove(struct platform_device *pdev) -+static void hello_remove(struct pci_dev *pdev) - { -- struct hello_dev *hello = platform_get_drvdata(pdev); -+ struct hello_dev *hello = pci_get_drvdata(pdev); - - device_destroy(hello_class, MKDEV(MAJOR(hello_devt), hello->minor)); - cdev_del(&hello->cdev); -- platform_set_drvdata(pdev, NULL); -+ 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); -- -- return 0; - } - --static const struct of_device_id hello_match[] = { -- { .compatible = "virtual,hello", }, -+static const struct pci_device_id hello_id_table[] = { -+ { 0x1af4, 0x1110, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0 }, - { /* end of table */ } - }; -+MODULE_DEVICE_TABLE(pci, hello_id_table); - --static struct platform_driver hello_driver = { -- .driver = { -- .name = "hello", -- .of_match_table = hello_match, -- }, -+static struct pci_driver hello_driver = { -+ .name = "hello", -+ .id_table = hello_id_table, - .probe = hello_probe, - .remove = hello_remove, - }; - --#ifndef CONFIG_OF --static struct platform_device *pdevs[3]; --#endif -- - static int __init hello_init(void) - { - int ret; -@@ -187,16 +196,10 @@ static int __init hello_init(void) - goto err_region; - } - -- ret = platform_driver_register(&hello_driver); -+ ret = pci_register_driver(&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: -@@ -210,13 +213,7 @@ 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); -+ pci_unregister_driver(&hello_driver); - class_destroy(hello_class); - unregister_chrdev_region(hello_devt, HELLO_MAX_DEVICES); - } --- -2.11.0 - diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch b/schulung_tools/drivers/modules/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch deleted file mode 100644 index 0a11a57..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/0002-hello-add-pci-memory-mapping.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 3afec946845a02a8fce94d00abda9b4c8abcbce0 Mon Sep 17 00:00:00 2001 -From: John Ogness -Date: Fri, 15 Feb 2019 11:03:59 +0106 -Subject: [PATCH 3/7] hello: add pci memory mapping - -Signed-off-by: John Ogness ---- - hello.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/hello.c b/hello.c -index db50302..58a64e5 100644 ---- a/hello.c -+++ b/hello.c -@@ -12,6 +12,7 @@ struct hello_dev { - struct device *dev; - struct cdev cdev; - unsigned int minor; -+ void __iomem *mem; - }; - - #define HELLO_MAX_DEVICES 10 -@@ -120,6 +121,12 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - - pci_set_master(pdev); - -+ hello->mem = pci_iomap(pdev, 2, 0); -+ if (!hello->mem) { -+ ret = -ENOMEM; -+ goto err_regions; -+ } -+ - devt = MKDEV(MAJOR(hello_devt), hello->minor); - - cdev_init(&hello->cdev, &hello_fops); -@@ -127,7 +134,7 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - ret = cdev_add(&hello->cdev, devt, 1); - if (ret != 0) { - dev_err(&pdev->dev, "cdev_add failed\n"); -- goto err_regions; -+ goto err_iomap; - } - - dev = device_create(hello_class, &pdev->dev, devt, hello, -@@ -144,6 +151,8 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - - err_cdev: - cdev_del(&hello->cdev); -+err_iomap: -+ pci_iounmap(pdev, hello->mem); - err_regions: - pci_release_regions(pdev); - err_enable: -@@ -159,6 +168,7 @@ static void hello_remove(struct pci_dev *pdev) - - 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); --- -2.11.0 - diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch b/schulung_tools/drivers/modules/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch deleted file mode 100644 index 8f81e39..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/0003-hello-add-led-toggling-via-chardev-read-write.patch +++ /dev/null @@ -1,56 +0,0 @@ -From c7a4c4448632af43383818654dd79d2251b27e3e Mon Sep 17 00:00:00 2001 -From: John Ogness -Date: Fri, 15 Feb 2019 11:04:56 +0106 -Subject: [PATCH 4/7] hello: add led toggling via chardev read/write - -Signed-off-by: John Ogness ---- - hello.c | 28 +++++++++++++++++++++++++++- - 1 file changed, 27 insertions(+), 1 deletion(-) - -diff --git a/hello.c b/hello.c -index 58a64e5..f664121 100644 ---- a/hello.c -+++ b/hello.c -@@ -61,11 +61,37 @@ static ssize_t hello_read(struct file *f, char __user *u, size_t s, loff_t *l) - 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; -- dev_info(hello->dev, "%s: size=%zu offset=%llu\n", __func__, s, *l); -+ 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; - } - --- -2.11.0 - diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch b/schulung_tools/drivers/modules/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch deleted file mode 100644 index a67bf98..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/0004-hello-add-led-toggling-via-chardev-ioctl.patch +++ /dev/null @@ -1,124 +0,0 @@ -From be59ddb43fbf039ed0bc848ac56b7f72f7a619c8 Mon Sep 17 00:00:00 2001 -From: John Ogness -Date: Fri, 15 Feb 2019 11:07:10 +0106 -Subject: [PATCH 5/7] hello: add led toggling via chardev ioctl - -Compile userspace application with: - -$ gcc -Wall -Werror hello-led.c -ohello-led - -Signed-off-by: John Ogness ---- - hello-led.c | 38 ++++++++++++++++++++++++++++++++++++++ - hello.c | 22 ++++++++++++++++++++++ - hello.h | 7 +++++++ - 3 files changed, 67 insertions(+) - create mode 100644 hello-led.c - create mode 100644 hello.h - -diff --git a/hello-led.c b/hello-led.c -new file mode 100644 -index 0000000..43230cd ---- /dev/null -+++ b/hello-led.c -@@ -0,0 +1,38 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "hello.h" -+ -+int main(int argc, char *argv[]) -+{ -+ int fd; -+ -+ if (argc != 3) { -+ fprintf(stderr, "usage: %s \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 f664121..c42c75f 100644 ---- a/hello.c -+++ b/hello.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include "hello.h" - - struct hello_dev { - struct device *dev; -@@ -95,12 +96,33 @@ static ssize_t hello_write(struct file *f, const char __user *u, size_t s, - 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 int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -diff --git a/hello.h b/hello.h -new file mode 100644 -index 0000000..cb172d9 ---- /dev/null -+++ b/hello.h -@@ -0,0 +1,7 @@ -+#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 - diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch b/schulung_tools/drivers/modules/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch deleted file mode 100644 index 32f37ce..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/0005-hello-add-led-toggling-via-leds-subsystem.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 3caece4ff394938f7544b994d35e784e2ce617cb Mon Sep 17 00:00:00 2001 -From: John Ogness -Date: Fri, 15 Feb 2019 11:10:09 +0106 -Subject: [PATCH 6/7] hello: add led toggling via leds subsystem - -Signed-off-by: John Ogness ---- - hello.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 90 insertions(+) - -diff --git a/hello.c b/hello.c -index c42c75f..f9809f3 100644 ---- a/hello.c -+++ b/hello.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - #include "hello.h" - - struct hello_dev { -@@ -14,6 +15,10 @@ struct hello_dev { - struct cdev cdev; - unsigned int minor; - void __iomem *mem; -+ -+ struct led_classdev led_heartbeat; -+ struct led_classdev led_net; -+ struct led_classdev led_disk; - }; - - #define HELLO_MAX_DEVICES 10 -@@ -125,6 +130,67 @@ static const struct file_operations hello_fops = { - .unlocked_ioctl = hello_ioctl, - }; - -+static void set_brightness(struct hello_dev *hello, int offset, -+ enum led_brightness b) -+{ -+ if (b) -+ writeb(0xff, hello->mem + offset); -+ else -+ writeb(0, hello->mem + offset); -+} -+ -+static enum led_brightness get_brightness(struct hello_dev *hello, int offset) -+{ -+ if (readb(hello->mem + offset)) -+ return 1; -+ return 0; -+} -+ -+static void hello_led_heartbeat_set(struct led_classdev *ldev, -+ enum led_brightness b) -+{ -+ struct hello_dev *hello = container_of(ldev, struct hello_dev, -+ led_heartbeat); -+ set_brightness(hello, 0, b); -+} -+ -+static enum led_brightness hello_led_heartbeat_get(struct led_classdev *ldev) -+{ -+ struct hello_dev *hello = container_of(ldev, struct hello_dev, -+ led_heartbeat); -+ return get_brightness(hello, 0); -+} -+ -+static void hello_led_net_set(struct led_classdev *ldev, -+ enum led_brightness b) -+{ -+ struct hello_dev *hello = container_of(ldev, struct hello_dev, -+ led_net); -+ set_brightness(hello, 1, b); -+} -+ -+static enum led_brightness hello_led_net_get(struct led_classdev *ldev) -+{ -+ struct hello_dev *hello = container_of(ldev, struct hello_dev, -+ led_net); -+ return get_brightness(hello, 1); -+} -+ -+static void hello_led_disk_set(struct led_classdev *ldev, -+ enum led_brightness b) -+{ -+ struct hello_dev *hello = container_of(ldev, struct hello_dev, -+ led_disk); -+ set_brightness(hello, 2, b); -+} -+ -+static enum led_brightness hello_led_disk_get(struct led_classdev *ldev) -+{ -+ struct hello_dev *hello = container_of(ldev, struct hello_dev, -+ led_disk); -+ return get_brightness(hello, 2); -+} -+ - static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - { - struct hello_dev *hello; -@@ -193,6 +259,27 @@ static int hello_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - goto err_cdev; - } - -+ hello->led_heartbeat.name = "heartbeat"; -+ hello->led_heartbeat.brightness = get_brightness(hello, 0); -+ hello->led_heartbeat.max_brightness = 1; -+ hello->led_heartbeat.brightness_set = hello_led_heartbeat_set; -+ hello->led_heartbeat.brightness_get = hello_led_heartbeat_get; -+ led_classdev_register(&pdev->dev, &hello->led_heartbeat); -+ -+ hello->led_net.name = "net"; -+ hello->led_net.brightness = get_brightness(hello, 2); -+ hello->led_net.max_brightness = 1; -+ hello->led_net.brightness_set = hello_led_net_set; -+ hello->led_net.brightness_get = hello_led_net_get; -+ led_classdev_register(&pdev->dev, &hello->led_net); -+ -+ hello->led_disk.name = "disk"; -+ hello->led_disk.brightness = get_brightness(hello, 2); -+ hello->led_disk.max_brightness = 1; -+ hello->led_disk.brightness_set = hello_led_disk_set; -+ 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); - - return 0; -@@ -214,6 +301,9 @@ static void hello_remove(struct pci_dev *pdev) - { - struct hello_dev *hello = pci_get_drvdata(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); --- -2.11.0 - 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 deleted file mode 100644 index 3274ccd..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/0006-hello-remove-chardev-use-only-leds-subsystem.patch +++ /dev/null @@ -1,338 +0,0 @@ -From 5f05842b160249563a7e4965aaa01998e562f487 Mon Sep 17 00:00:00 2001 -From: John Ogness -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 ---- - 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 --#include --#include --#include --#include --#include --#include --#include --#include "hello.h" -- --int main(int argc, char *argv[]) --{ -- int fd; -- -- if (argc != 3) { -- fprintf(stderr, "usage: %s \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 - #include --#include --#include --#include - #include - #include --#include - #include --#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 - diff --git a/schulung_tools/drivers/modules/hellodriver/patches-leds/README b/schulung_tools/drivers/modules/hellodriver/patches-leds/README deleted file mode 100644 index 51bbffa..0000000 --- a/schulung_tools/drivers/modules/hellodriver/patches-leds/README +++ /dev/null @@ -1,6 +0,0 @@ -This set of patches show how different subsystems can be used -by the driver to communicate with the hardware and to present -itself to the user. - -For live demonstrations with actual blinking leds, use the -"leds" program. (See the README there for details.) diff --git a/schulung_tools/drivers/modules/klist/0001-klist-example.patch b/schulung_tools/drivers/modules/klist/0001-klist-example.patch deleted file mode 100644 index b52216a..0000000 --- a/schulung_tools/drivers/modules/klist/0001-klist-example.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 504db8a2bae95d7bafb9b68074fdc46c49f08c9f Mon Sep 17 00:00:00 2001 -From: Manuel Traut -Date: Fri, 4 Jan 2019 09:32:18 +0100 -Subject: [PATCH] klist example - -this can be used to show the usage of klists - -Signed-off-by: Manuel Traut ---- - drivers/staging/Kconfig | 2 + - drivers/staging/Makefile | 1 + - drivers/staging/klist/Kconfig | 5 +++ - drivers/staging/klist/Makefile | 1 + - drivers/staging/klist/klist.c | 68 +++++++++++++++++++++++++++++++++ - 5 files changed, 77 insertions(+) - create mode 100644 drivers/staging/klist/Kconfig - create mode 100644 drivers/staging/klist/Makefile - create mode 100644 drivers/staging/klist/klist.c - -diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig -index bfa2bf720a03..98541d7a41be 100644 ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -24,6 +24,8 @@ menuconfig STAGING - - if STAGING - -+source "drivers/staging/klist/Kconfig" -+ - source "drivers/staging/wlan-ng/Kconfig" - - source "drivers/staging/comedi/Kconfig" -diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile -index 25b3a8eafaa1..7a6d82750008 100644 ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -2,6 +2,7 @@ - # Makefile for staging directory - - obj-y += media/ -+obj-$(CONFIG_KLISTEXAMPLE) += klist/ - obj-$(CONFIG_PRISM2_USB) += wlan-ng/ - obj-$(CONFIG_COMEDI) += comedi/ - obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ -diff --git a/drivers/staging/klist/Kconfig b/drivers/staging/klist/Kconfig -new file mode 100644 -index 000000000000..18f517e56cb9 ---- /dev/null -+++ b/drivers/staging/klist/Kconfig -@@ -0,0 +1,4 @@ -+config KLISTEXAMPLE -+ tristate "module to teach klist usage" -+ ---help--- -+ This is only useful for learning the usage of klist. -diff --git a/drivers/staging/klist/Makefile b/drivers/staging/klist/Makefile -new file mode 100644 -index 000000000000..2939c11d72ff ---- /dev/null -+++ b/drivers/staging/klist/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_KLISTEXAMPLE) += klist.o -diff --git a/drivers/staging/klist/klist.c b/drivers/staging/klist/klist.c -new file mode 100644 -index 000000000000..365acaa3263a ---- /dev/null -+++ b/drivers/staging/klist/klist.c -@@ -0,0 +1,68 @@ -+/* -+ * Example driver for using klist -+ * Copyright (C) 2019, Manuel Traut -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#define DRV_NAME "klist" -+ -+struct mynode { -+ struct list_head node; -+ unsigned long val; -+}; -+ -+static struct list_head mylist; -+static char mystring[] = "1 2 3 4 5\n"; -+ -+static void klist_free_list(void) { -+ struct mynode *n, *tmp; -+ list_for_each_entry_safe(n, tmp, &mylist, node) -+ kfree(n); -+} -+ -+static void klist_init_list(void) { -+ unsigned long val; -+ struct mynode *n; -+ char *tok; -+ char *b = kstrdup(mystring, GFP_KERNEL); -+ -+ INIT_LIST_HEAD(&mylist); -+ -+ while ((tok = strsep(&b, " ")) && *tok) { -+ printk(KERN_INFO "adding %s to list\n", tok); -+ if (kstrtoul(tok, 0, &val)) { -+ printk(KERN_ERR "failed to convert %s to int\n", tok); -+ goto exit_init; -+ } -+ n = kzalloc(sizeof(*n), GFP_KERNEL); -+ n->val = val; -+ list_add_tail(&n->node, &mylist); -+ } -+exit_init: -+ kfree(b); -+} -+ -+static int __init klist_init(void) { -+ printk(KERN_INFO "%s\n", __func__); -+ klist_init_list(); -+ return 0; -+} -+ -+static void __exit klist_exit(void) { -+ printk(KERN_INFO "%s\n", __func__); -+ klist_free_list(); -+} -+ -+module_init(klist_init); -+module_exit(klist_exit); -+MODULE_AUTHOR("Manuel Traut"); -+MODULE_LICENSE("GPL"); --- -2.19.2 - diff --git a/schulung_tools/drivers/modules/simplemodule/Makefile b/schulung_tools/drivers/modules/simplemodule/Makefile deleted file mode 100644 index 9413c4d..0000000 --- a/schulung_tools/drivers/modules/simplemodule/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -MNAME=simple -BDIR=/home/devel/work/build-linux - -ifeq ($(KERNELRELEASE),) -# called from shell - -.PHONY: default clean - -default: - make -C $(BDIR) M=$(shell pwd) modules - -clean: - rm -rf $(MNAME).mod.* $(MNAME).*o .$(MNAME)* .tmp* Module.symvers modules.order - -else -# called from kernel Makefile - - obj-m := $(MNAME).o -endif diff --git a/schulung_tools/drivers/modules/simplemodule/simple.c b/schulung_tools/drivers/modules/simplemodule/simple.c deleted file mode 100644 index e091f68..0000000 --- a/schulung_tools/drivers/modules/simplemodule/simple.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -static int simple_hello(void) -{ - printk(KERN_ERR "called %s\n", __func__); - return 0; -} - -static void simple_goodbye(void) -{ - printk(KERN_ERR "called %s\n", __func__); -} - -module_init(simple_hello); -module_exit(simple_goodbye); - -MODULE_AUTHOR("John Ogness "); -MODULE_DESCRIPTION("simple"); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION("12345.54321"); diff --git a/schulung_tools/drivers/simplemodule/Makefile b/schulung_tools/drivers/simplemodule/Makefile new file mode 100644 index 0000000..9413c4d --- /dev/null +++ b/schulung_tools/drivers/simplemodule/Makefile @@ -0,0 +1,19 @@ +MNAME=simple +BDIR=/home/devel/work/build-linux + +ifeq ($(KERNELRELEASE),) +# called from shell + +.PHONY: default clean + +default: + make -C $(BDIR) M=$(shell pwd) modules + +clean: + rm -rf $(MNAME).mod.* $(MNAME).*o .$(MNAME)* .tmp* Module.symvers modules.order + +else +# called from kernel Makefile + + obj-m := $(MNAME).o +endif diff --git a/schulung_tools/drivers/simplemodule/simple.c b/schulung_tools/drivers/simplemodule/simple.c new file mode 100644 index 0000000..e091f68 --- /dev/null +++ b/schulung_tools/drivers/simplemodule/simple.c @@ -0,0 +1,21 @@ +#include +#include + +static int simple_hello(void) +{ + printk(KERN_ERR "called %s\n", __func__); + return 0; +} + +static void simple_goodbye(void) +{ + printk(KERN_ERR "called %s\n", __func__); +} + +module_init(simple_hello); +module_exit(simple_goodbye); + +MODULE_AUTHOR("John Ogness "); +MODULE_DESCRIPTION("simple"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("12345.54321"); -- cgit v1.2.3