mantis_pci.c (3599B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 Mantis PCI bridge driver 4 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");