linux/drivers/media/pci/mantis/mantis_pci.c
<<
>>
Prefs
   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 = pci_set_consistent_dma_mask(pdev, 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