galileo-uio-gpio.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Don't try this at home...
  3. *
  4. * Copyright (c) Siemens AG, 2016
  5. *
  6. * Authors:
  7. * Jan Kiszka <jan.kiszka@siemens.com>
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2. See
  10. * the COPYING file in the top-level directory.
  11. *
  12. * Derived from drivers/mfd/intel_qrk_gip_gpio.c of meta-intel-galileo
  13. */
  14. #include <linux/module.h>
  15. #include <linux/pci.h>
  16. #include <linux/uio_driver.h>
  17. #define GIP_GPIO_BAR 1
  18. #define SCH_GPIOBASE 0x44
  19. #define SCH_GPIO_IO_SIZE 64
  20. static struct pci_dev *gip_dev;
  21. static struct pci_dev *sch_dev;
  22. static struct uio_info uio_gip;
  23. static struct uio_info uio_sch;
  24. static void __iomem *gip_reg_base;
  25. int init_module(void)
  26. {
  27. resource_size_t start, len;
  28. unsigned int base_addr_cfg;
  29. int err;
  30. gip_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0934, NULL);
  31. if (!gip_dev)
  32. return -ENODEV;
  33. start = pci_resource_start(gip_dev, GIP_GPIO_BAR);
  34. len = pci_resource_len(gip_dev, GIP_GPIO_BAR);
  35. gip_reg_base = ioremap_nocache(start, len);
  36. if (!gip_reg_base) {
  37. err = -EFAULT;
  38. goto err_gip_devput;
  39. }
  40. uio_gip.mem[0].addr = start;
  41. uio_gip.mem[0].internal_addr = gip_reg_base;
  42. uio_gip.mem[0].size = len;
  43. uio_gip.mem[0].memtype = UIO_MEM_PHYS;
  44. uio_gip.mem[0].name = "gpio_regs";
  45. uio_gip.name = "gpio uio";
  46. uio_gip.version = "0.0.1";
  47. err = uio_register_device(&gip_dev->dev, &uio_gip);
  48. if (err)
  49. goto err_gip_unmap;
  50. sch_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
  51. PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB, NULL);
  52. if (!sch_dev) {
  53. err = -ENODEV;
  54. goto err_gip_unregister;
  55. }
  56. pci_read_config_dword(sch_dev, SCH_GPIOBASE, &base_addr_cfg);
  57. if (!(base_addr_cfg & (1 << 31))) {
  58. err = -EIO;
  59. goto err_sch_devput;
  60. }
  61. uio_sch.port[0].start = (unsigned short)base_addr_cfg;
  62. uio_sch.port[0].size = SCH_GPIO_IO_SIZE;
  63. uio_sch.port[0].porttype = UIO_PORT_X86;
  64. uio_sch.port[0].name = "gpio_regs";
  65. uio_sch.name = "sch_gpio";
  66. uio_sch.version = "0.0.1";
  67. err = uio_register_device(&sch_dev->dev, &uio_sch);
  68. if (err)
  69. goto err_sch_devput;
  70. return 0;
  71. err_sch_devput:
  72. pci_dev_put(gip_dev);
  73. err_gip_unregister:
  74. uio_unregister_device(&uio_gip);
  75. err_gip_unmap:
  76. iounmap(gip_reg_base);
  77. err_gip_devput:
  78. pci_dev_put(gip_dev);
  79. return err;
  80. }
  81. void cleanup_module(void)
  82. {
  83. uio_unregister_device(&uio_sch);
  84. pci_dev_put(sch_dev);
  85. uio_unregister_device(&uio_gip);
  86. iounmap(gip_reg_base);
  87. pci_dev_put(gip_dev);
  88. }
  89. MODULE_LICENSE("GPL");