irq.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /* https://github.com/cirosantilli/linux-kernel-module-cheat#irq-ko */
  2. #include <linux/fs.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/kernel.h>
  5. #include <linux/module.h>
  6. #include <linux/uaccess.h> /* copy_from_user, copy_to_user */
  7. #define NAME "lkmc_irq"
  8. #define MAX_IRQS 256
  9. static int irqs[MAX_IRQS];
  10. static int major;
  11. /**
  12. * Return value from kernel docs:*
  13. *
  14. * enum irqreturn
  15. * @IRQ_NONE interrupt was not from this device or was not handled
  16. * @IRQ_HANDLED interrupt was handled by this device
  17. * @IRQ_WAKE_THREAD handler requests to wake the handler thread
  18. */
  19. static irqreturn_t handler(int irq, void *dev)
  20. {
  21. pr_info("handler irq = %d dev = %d\n", irq, *(int *)dev);
  22. return IRQ_NONE;
  23. }
  24. static const struct file_operations fops;
  25. static int myinit(void)
  26. {
  27. int ret, i;
  28. major = register_chrdev(0, NAME, &fops);
  29. for (i = 0; i < MAX_IRQS; ++i) {
  30. ret = request_irq(
  31. i,
  32. handler,
  33. IRQF_SHARED,
  34. "myirqhandler0",
  35. &major
  36. );
  37. irqs[i] = ret;
  38. pr_info("request_irq irq = %d ret = %d\n", i, ret);
  39. }
  40. return 0;
  41. }
  42. static void myexit(void)
  43. {
  44. int i;
  45. for (i = 0; i < MAX_IRQS; ++i) {
  46. if (!irqs[i]) {
  47. free_irq(i, &major);
  48. }
  49. }
  50. unregister_chrdev(major, NAME);
  51. }
  52. module_init(myinit)
  53. module_exit(myexit)
  54. MODULE_LICENSE("GPL");