1/* 2 Mantis PCI bridge driver 3 4 Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#include <linux/module.h> 22#include <linux/moduleparam.h> 23#include <linux/kernel.h> 24#include <asm/io.h> 25#include <asm/page.h> 26#include <linux/kmod.h> 27#include <linux/vmalloc.h> 28#include <linux/init.h> 29#include <linux/device.h> 30#include <linux/pci.h> 31 32#include <asm/irq.h> 33#include <linux/signal.h> 34#include <linux/sched.h> 35#include <linux/interrupt.h> 36 37#include "dmxdev.h" 38#include "dvbdev.h" 39#include "dvb_demux.h" 40#include "dvb_frontend.h" 41#include "dvb_net.h" 42 43#include "mantis_common.h" 44#include "mantis_reg.h" 45#include "mantis_pci.h" 46 47#define DRIVER_NAME "Mantis Core" 48 49int mantis_pci_init(struct mantis_pci *mantis) 50{ 51 u8 latency; 52 struct mantis_hwconfig *config = mantis->hwconfig; 53 struct pci_dev *pdev = mantis->pdev; 54 int err, ret = 0; 55 56 dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", 57 config->model_name, 58 config->dev_type, 59 mantis->pdev->bus->number, 60 PCI_SLOT(mantis->pdev->devfn), 61 PCI_FUNC(mantis->pdev->devfn)); 62 63 err = pci_enable_device(pdev); 64 if (err != 0) { 65 ret = -ENODEV; 66 dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); 67 goto fail0; 68 } 69 70 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 71 if (err != 0) { 72 dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); 73 ret = -ENOMEM; 74 goto fail1; 75 } 76 77 pci_set_master(pdev); 78 79 if (!request_mem_region(pci_resource_start(pdev, 0), 80 pci_resource_len(pdev, 0), 81 DRIVER_NAME)) { 82 83 dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); 84 ret = -ENODEV; 85 goto fail1; 86 } 87 88 mantis->mmio = ioremap(pci_resource_start(pdev, 0), 89 pci_resource_len(pdev, 0)); 90 91 if (!mantis->mmio) { 92 dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); 93 ret = -ENODEV; 94 goto fail2; 95 } 96 97 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); 98 mantis->latency = latency; 99 mantis->revision = pdev->revision; 100 101 dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", 102 mantis->revision, 103 mantis->pdev->subsystem_vendor, 104 mantis->pdev->subsystem_device); 105 106 dprintk(MANTIS_ERROR, 0, 107 "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", 108 mantis->pdev->irq, 109 mantis->latency, 110 mantis->mantis_addr, 111 mantis->mmio); 112 113 err = request_irq(pdev->irq, 114 config->irq_handler, 115 IRQF_SHARED, 116 DRIVER_NAME, 117 mantis); 118 119 if (err != 0) { 120 121 dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); 122 ret = -ENODEV; 123 goto fail3; 124 } 125 126 pci_set_drvdata(pdev, mantis); 127 return ret; 128 129 /* Error conditions */ 130fail3: 131 dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); 132 if (mantis->mmio) 133 iounmap(mantis->mmio); 134 135fail2: 136 dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); 137 release_mem_region(pci_resource_start(pdev, 0), 138 pci_resource_len(pdev, 0)); 139 140fail1: 141 dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); 142 pci_disable_device(pdev); 143 144fail0: 145 dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); 146 return ret; 147} 148EXPORT_SYMBOL_GPL(mantis_pci_init); 149 150void mantis_pci_exit(struct mantis_pci *mantis) 151{ 152 struct pci_dev *pdev = mantis->pdev; 153 154 dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); 155 free_irq(pdev->irq, mantis); 156 if (mantis->mmio) { 157 iounmap(mantis->mmio); 158 release_mem_region(pci_resource_start(pdev, 0), 159 pci_resource_len(pdev, 0)); 160 } 161 162 pci_disable_device(pdev); 163} 164EXPORT_SYMBOL_GPL(mantis_pci_exit); 165 166MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); 167MODULE_AUTHOR("Manu Abraham"); 168MODULE_LICENSE("GPL"); 169