pci_min.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <linux/cdev.h>
  2. #include <linux/fs.h>
  3. #include <linux/init.h>
  4. #include <linux/interrupt.h>
  5. #include <linux/kernel.h>
  6. #include <linux/module.h>
  7. #include <linux/pci.h>
  8. #include <linux/uaccess.h> /* copy_from_user, copy_to_user */
  9. #define BAR 0
  10. #define CDEV_NAME "lkmc_hw_pci_min"
  11. #define EDU_DEVICE_ID 0x11e9
  12. #define QEMU_VENDOR_ID 0x1234
  13. static struct pci_device_id id_table[] = {
  14. { PCI_DEVICE(QEMU_VENDOR_ID, EDU_DEVICE_ID), },
  15. { 0, }
  16. };
  17. MODULE_DEVICE_TABLE(pci, id_table);
  18. static int major;
  19. static struct pci_dev *pdev;
  20. static void __iomem *mmio;
  21. static struct file_operations fops = {
  22. .owner = THIS_MODULE,
  23. };
  24. static irqreturn_t irq_handler(int irq, void *dev)
  25. {
  26. pr_info("irq_handler irq = %d dev = %d\n", irq, *(int *)dev);
  27. iowrite32(0, mmio + 4);
  28. return IRQ_HANDLED;
  29. }
  30. static int probe(struct pci_dev *dev, const struct pci_device_id *id)
  31. {
  32. pr_info("probe\n");
  33. major = register_chrdev(0, CDEV_NAME, &fops);
  34. pdev = dev;
  35. if (pci_enable_device(dev) < 0) {
  36. dev_err(&(pdev->dev), "pci_enable_device\n");
  37. goto error;
  38. }
  39. if (pci_request_region(dev, BAR, "myregion0")) {
  40. dev_err(&(pdev->dev), "pci_request_region\n");
  41. goto error;
  42. }
  43. mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR));
  44. pr_info("dev->irq = %u\n", dev->irq);
  45. if (request_irq(dev->irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major) < 0) {
  46. dev_err(&(dev->dev), "request_irq\n");
  47. goto error;
  48. }
  49. iowrite32(0x12345678, mmio);
  50. return 0;
  51. error:
  52. return 1;
  53. }
  54. static void remove(struct pci_dev *dev)
  55. {
  56. pr_info("remove\n");
  57. free_irq(dev->irq, &major);
  58. pci_release_region(dev, BAR);
  59. unregister_chrdev(major, CDEV_NAME);
  60. }
  61. static struct pci_driver pci_driver = {
  62. .name = CDEV_NAME,
  63. .id_table = id_table,
  64. .probe = probe,
  65. .remove = remove,
  66. };
  67. static int myinit(void)
  68. {
  69. if (pci_register_driver(&pci_driver) < 0) {
  70. return 1;
  71. }
  72. return 0;
  73. }
  74. static void myexit(void)
  75. {
  76. pci_unregister_driver(&pci_driver);
  77. }
  78. module_init(myinit);
  79. module_exit(myexit);
  80. MODULE_LICENSE("GPL");