mantis_pci.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. Mantis PCI bridge driver
  4. Copyright (C) Manu Abraham ([email protected])
  5. */
  6. #include <linux/module.h>
  7. #include <linux/moduleparam.h>
  8. #include <linux/kernel.h>
  9. #include <asm/io.h>
  10. #include <asm/page.h>
  11. #include <linux/kmod.h>
  12. #include <linux/vmalloc.h>
  13. #include <linux/init.h>
  14. #include <linux/device.h>
  15. #include <linux/pci.h>
  16. #include <asm/irq.h>
  17. #include <linux/signal.h>
  18. #include <linux/sched.h>
  19. #include <linux/interrupt.h>
  20. #include <media/dmxdev.h>
  21. #include <media/dvbdev.h>
  22. #include <media/dvb_demux.h>
  23. #include <media/dvb_frontend.h>
  24. #include <media/dvb_net.h>
  25. #include "mantis_common.h"
  26. #include "mantis_reg.h"
  27. #include "mantis_pci.h"
  28. #define DRIVER_NAME "Mantis Core"
  29. int mantis_pci_init(struct mantis_pci *mantis)
  30. {
  31. u8 latency;
  32. struct mantis_hwconfig *config = mantis->hwconfig;
  33. struct pci_dev *pdev = mantis->pdev;
  34. int err, ret = 0;
  35. dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
  36. config->model_name,
  37. config->dev_type,
  38. mantis->pdev->bus->number,
  39. PCI_SLOT(mantis->pdev->devfn),
  40. PCI_FUNC(mantis->pdev->devfn));
  41. err = pci_enable_device(pdev);
  42. if (err != 0) {
  43. ret = -ENODEV;
  44. dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err);
  45. goto fail0;
  46. }
  47. err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
  48. if (err != 0) {
  49. dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err);
  50. ret = -ENOMEM;
  51. goto fail1;
  52. }
  53. pci_set_master(pdev);
  54. if (!request_mem_region(pci_resource_start(pdev, 0),
  55. pci_resource_len(pdev, 0),
  56. DRIVER_NAME)) {
  57. dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !");
  58. ret = -ENODEV;
  59. goto fail1;
  60. }
  61. mantis->mmio = ioremap(pci_resource_start(pdev, 0),
  62. pci_resource_len(pdev, 0));
  63. if (!mantis->mmio) {
  64. dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !");
  65. ret = -ENODEV;
  66. goto fail2;
  67. }
  68. pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
  69. mantis->latency = latency;
  70. mantis->revision = pdev->revision;
  71. dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ",
  72. mantis->revision,
  73. mantis->pdev->subsystem_vendor,
  74. mantis->pdev->subsystem_device);
  75. dprintk(MANTIS_ERROR, 0,
  76. "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n",
  77. mantis->pdev->irq,
  78. mantis->latency,
  79. mantis->mantis_addr,
  80. mantis->mmio);
  81. err = request_irq(pdev->irq,
  82. config->irq_handler,
  83. IRQF_SHARED,
  84. DRIVER_NAME,
  85. mantis);
  86. if (err != 0) {
  87. dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err);
  88. ret = -ENODEV;
  89. goto fail3;
  90. }
  91. pci_set_drvdata(pdev, mantis);
  92. return ret;
  93. /* Error conditions */
  94. fail3:
  95. dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret);
  96. if (mantis->mmio)
  97. iounmap(mantis->mmio);
  98. fail2:
  99. dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret);
  100. release_mem_region(pci_resource_start(pdev, 0),
  101. pci_resource_len(pdev, 0));
  102. fail1:
  103. dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret);
  104. pci_disable_device(pdev);
  105. fail0:
  106. dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret);
  107. return ret;
  108. }
  109. EXPORT_SYMBOL_GPL(mantis_pci_init);
  110. void mantis_pci_exit(struct mantis_pci *mantis)
  111. {
  112. struct pci_dev *pdev = mantis->pdev;
  113. dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio);
  114. free_irq(pdev->irq, mantis);
  115. if (mantis->mmio) {
  116. iounmap(mantis->mmio);
  117. release_mem_region(pci_resource_start(pdev, 0),
  118. pci_resource_len(pdev, 0));
  119. }
  120. pci_disable_device(pdev);
  121. }
  122. EXPORT_SYMBOL_GPL(mantis_pci_exit);
  123. MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
  124. MODULE_AUTHOR("Manu Abraham");
  125. MODULE_LICENSE("GPL");