linux/drivers/media/dvb/mantis/mantis_pci.c
<<
>>
Prefs
   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 __devinit 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        pci_set_drvdata(pdev, NULL);
 147        return ret;
 148}
 149EXPORT_SYMBOL_GPL(mantis_pci_init);
 150
 151void mantis_pci_exit(struct mantis_pci *mantis)
 152{
 153        struct pci_dev *pdev = mantis->pdev;
 154
 155        dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio);
 156        free_irq(pdev->irq, mantis);
 157        if (mantis->mmio) {
 158                iounmap(mantis->mmio);
 159                release_mem_region(pci_resource_start(pdev, 0),
 160                                   pci_resource_len(pdev, 0));
 161        }
 162
 163        pci_disable_device(pdev);
 164        pci_set_drvdata(pdev, NULL);
 165}
 166EXPORT_SYMBOL_GPL(mantis_pci_exit);
 167
 168MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
 169MODULE_AUTHOR("Manu Abraham");
 170MODULE_LICENSE("GPL");
 171