diff options
author | Manu Abraham <abraham.manu@gmail.com> | 2009-12-04 05:41:11 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-01-17 11:55:42 -0200 |
commit | b3b961448f702339444036f94252ff2ba7a99feb (patch) | |
tree | f31007bb892091072fa97f43f5666105b1ea8f33 /drivers/media/dvb/mantis/mantis_pci.c | |
parent | add206368462434ba97e8fe4de98e5d47ffdb0a0 (diff) | |
download | lwn-b3b961448f702339444036f94252ff2ba7a99feb.tar.gz lwn-b3b961448f702339444036f94252ff2ba7a99feb.zip |
V4L/DVB (13795): [Mantis/Hopper] Code overhaul, add Hopper devices into the PCI ID list
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/mantis/mantis_pci.c')
-rw-r--r-- | drivers/media/dvb/mantis/mantis_pci.c | 310 |
1 files changed, 99 insertions, 211 deletions
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c index d1eac4083fcc..5165a390e07a 100644 --- a/drivers/media/dvb/mantis/mantis_pci.c +++ b/drivers/media/dvb/mantis/mantis_pci.c @@ -18,6 +18,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> #include <asm/io.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -25,264 +28,149 @@ #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/device.h> -#include "mantis_common.h" -#include "mantis_core.h" -#include "mantis_uart.h" +#include <linux/pci.h> #include <asm/irq.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> -unsigned int verbose = 1; -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); - -unsigned int devs; - -#define PCI_VENDOR_ID_MANTIS 0x1822 -#define PCI_DEVICE_ID_MANTIS_R11 0x4e35 -#define DRIVER_NAME "Mantis" - -static struct pci_device_id mantis_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_MANTIS, PCI_DEVICE_ID_MANTIS_R11) }, - { 0 }, -}; - -MODULE_DEVICE_TABLE(pci, mantis_pci_table); - -static irqreturn_t mantis_pci_irq(int irq, void *dev_id) -{ - u32 stat = 0, mask = 0, lstat = 0, mstat = 0; - u32 rst_stat = 0, rst_mask = 0; +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" +#include "dvb_net.h" - struct mantis_pci *mantis; - struct mantis_ca *ca; +#include <asm/irq.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> - mantis = (struct mantis_pci *) dev_id; - if (unlikely(mantis == NULL)) { - dprintk(verbose, MANTIS_ERROR, 1, "Mantis == NULL"); - return IRQ_NONE; - } - ca = mantis->mantis_ca; - - stat = mmread(MANTIS_INT_STAT); - mask = mmread(MANTIS_INT_MASK); - mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; - if (!(stat & mask)) - return IRQ_NONE; - - rst_mask = MANTIS_GPIF_WRACK | - MANTIS_GPIF_OTHERR | - MANTIS_SBUF_WSTO | - MANTIS_GPIF_EXTIRQ; - - rst_stat = mmread(MANTIS_GPIF_STATUS); - rst_stat &= rst_mask; - mmwrite(rst_stat, MANTIS_GPIF_STATUS); - - mantis->mantis_int_stat = stat; - mantis->mantis_int_mask = mask; - dprintk(verbose, MANTIS_DEBUG, 0, "=== Interrupts[%04x/%04x]= [", stat, mask); - if (stat & MANTIS_INT_RISCEN) { - dprintk(verbose, MANTIS_DEBUG, 0, "* DMA enabl *"); - } - if (stat & MANTIS_INT_IRQ0) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT IRQ-0 *"); - mantis->gpif_status = rst_stat; - wake_up(&ca->hif_write_wq); - schedule_work(&ca->hif_evm_work); - } - if (stat & MANTIS_INT_IRQ1) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT IRQ-1 *"); - schedule_work(&mantis->uart_work); - } - if (stat & MANTIS_INT_OCERR) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT OCERR *"); - } - if (stat & MANTIS_INT_PABORT) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT PABRT *"); - } - if (stat & MANTIS_INT_RIPERR) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT RIPRR *"); - } - if (stat & MANTIS_INT_PPERR) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT PPERR *"); - } - if (stat & MANTIS_INT_FTRGT) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT FTRGT *"); - } - if (stat & MANTIS_INT_RISCI) { - dprintk(verbose, MANTIS_DEBUG, 0, "* INT RISCI *"); - mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; - tasklet_schedule(&mantis->tasklet); - } - if (stat & MANTIS_INT_I2CDONE) { - dprintk(verbose, MANTIS_DEBUG, 0, "* I2C DONE *"); - wake_up(&mantis->i2c_wq); - } - mmwrite(stat, MANTIS_INT_STAT); - stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE | - MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 | - MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 | - MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 | - MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 | - MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 | - MANTIS_INT_IRQ0 | MANTIS_INT_OCERR | - MANTIS_INT_PABORT | MANTIS_INT_RIPERR | - MANTIS_INT_PPERR | MANTIS_INT_FTRGT | - MANTIS_INT_RISCI); - - if (stat) - dprintk(verbose, MANTIS_DEBUG, 0, "* Unknown [%04x] *", stat); - - dprintk(verbose, MANTIS_DEBUG, 0, "] ===\n"); - - return IRQ_HANDLED; -} +#include "mantis_common.h" +#include "mantis_reg.h" +#include "mantis_pci.h" +#define DRIVER_NAME "Mantis Core" -static int __devinit mantis_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *mantis_pci_table) +int __devinit mantis_pci_init(struct mantis_pci *mantis) { u8 revision, latency; - struct mantis_pci *mantis; - int ret = 0; + struct mantis_hwconfig *config = mantis->hwconfig; + struct pci_dev *pdev = mantis->pdev; + int err, ret = 0; + + dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", + config->model_name, + config->dev_type, + mantis->pdev->bus->number, + PCI_SLOT(mantis->pdev->devfn), + PCI_FUNC(mantis->pdev->devfn)); + + err = pci_enable_device(pdev); + if (err != 0) { + ret = -ENODEV; + dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err); + goto fail0; + } - mantis = kmalloc(sizeof (struct mantis_pci), GFP_KERNEL); - if (mantis == NULL) { - printk("%s: Out of memory\n", __func__); + err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + if (err != 0) { + dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err); ret = -ENOMEM; - goto err; + goto fail1; } - memset(mantis, 0, sizeof (struct mantis_pci)); - mantis->num = devs; - devs++; - if (pci_enable_device(pdev)) { - dprintk(verbose, MANTIS_ERROR, 1, "Mantis PCI enable failed"); - ret = -ENODEV; - goto err; - } - mantis->mantis_addr = pci_resource_start(pdev, 0); - if (!request_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0), DRIVER_NAME)) { - ret = -ENODEV; - goto err0; - } + pci_set_master(pdev); - mantis->mantis_mmio = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); + if (!request_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0), + DRIVER_NAME)) { - if (!mantis->mantis_mmio) { - dprintk(verbose, MANTIS_ERROR, 1, "IO remap failed"); + dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !"); ret = -ENODEV; - goto err1; + goto fail1; } - // Clear and disable all interrupts at startup - // to avoid lockup situations - mmwrite(0x00, MANTIS_INT_MASK); - if (request_irq(pdev->irq, - mantis_pci_irq, - IRQF_SHARED, - DRIVER_NAME, - mantis) < 0) { + mantis->mmio = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); - dprintk(verbose, MANTIS_ERROR, 1, "Mantis IRQ reg failed"); + if (!mantis->mmio) { + dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !"); ret = -ENODEV; - goto err2; + goto fail2; } - pci_set_master(pdev); - pci_set_drvdata(pdev, mantis); + pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); mantis->latency = latency; mantis->revision = revision; - mantis->pdev = pdev; - mantis->subsystem_vendor = pdev->subsystem_vendor; - mantis->subsystem_device = pdev->subsystem_device; - init_waitqueue_head(&mantis->i2c_wq); - mantis_set_direction(mantis, 0); /* CAM bypass */ + dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", + mantis->revision, + mantis->pdev->subsystem_vendor, + mantis->pdev->subsystem_device); + + dprintk(MANTIS_ERROR, 0, + "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", + mantis->pdev->irq, + mantis->latency, + mantis->mantis_addr, + mantis->mmio); - if (!latency) - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 32); + err = request_irq(pdev->irq, + config->irq_handler, + IRQF_SHARED, + DRIVER_NAME, + mantis); - dprintk(verbose, MANTIS_ERROR, 0, - "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", - pdev->irq, mantis->latency, - mantis->mantis_addr, mantis->mantis_mmio); + if (err != 0) { - // No more PCI specific stuff ! - if (mantis_core_init(mantis) < 0) { - dprintk(verbose, MANTIS_ERROR, 1, "Mantis core init failed"); + dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err); ret = -ENODEV; - goto err2; + goto fail3; } - return 0; + pci_set_drvdata(pdev, mantis); + return ret; - // Error conditions .. -err2: - dprintk(verbose, MANTIS_DEBUG, 1, "Err: IO Unmap"); - if (mantis->mantis_mmio) - iounmap(mantis->mantis_mmio); -err1: - dprintk(verbose, MANTIS_DEBUG, 1, "Err: Release regions"); + /* Error conditions */ +fail3: + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret); + if (mantis->mmio) + iounmap(mantis->mmio); + +fail2: + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret); release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); + pci_resource_len(pdev, 0)); + +fail1: + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret); pci_disable_device(pdev); -err0: - dprintk(verbose, MANTIS_DEBUG, 1, "Err: Free"); - kfree(mantis); -err: - dprintk(verbose, MANTIS_DEBUG, 1, "Err:"); + +fail0: + dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret); + pci_set_drvdata(pdev, NULL); return ret; } +EXPORT_SYMBOL_GPL(mantis_pci_init); -static void __devexit mantis_pci_remove(struct pci_dev *pdev) +void __devexit mantis_pci_exit(struct mantis_pci *mantis) { - struct mantis_pci *mantis = pci_get_drvdata(pdev); - - if (mantis == NULL) { - dprintk(verbose, MANTIS_ERROR, 1, "Aeio, Mantis NULL ptr"); - return; - } - mantis_core_exit(mantis); - dprintk(verbose, MANTIS_ERROR, 1, "Removing -->Mantis irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p", - pdev->irq, mantis->latency, mantis->mantis_addr, - mantis->mantis_mmio); + struct pci_dev *pdev = mantis->pdev; + dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio); free_irq(pdev->irq, mantis); - pci_release_regions(pdev); - if (mantis_dma_exit(mantis) < 0) - dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); + if (mantis->mmio) { + iounmap(mantis->mmio); + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + } - pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - kfree(mantis); -} - -static struct pci_driver mantis_pci_driver = { - .name = DRIVER_NAME, - .id_table = mantis_pci_table, - .probe = mantis_pci_probe, - .remove = mantis_pci_remove, -}; - -static int __devinit mantis_pci_init(void) -{ - return pci_register_driver(&mantis_pci_driver); -} - -static void __devexit mantis_pci_exit(void) -{ - pci_unregister_driver(&mantis_pci_driver); + pci_set_drvdata(pdev, NULL); } - -module_init(mantis_pci_init); -module_exit(mantis_pci_exit); +EXPORT_SYMBOL_GPL(mantis_pci_exit); MODULE_DESCRIPTION("Mantis PCI DTV bridge driver"); MODULE_AUTHOR("Manu Abraham"); |