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