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