summaryrefslogtreecommitdiff
path: root/drivers/media/dvb/mantis/mantis_pci.c
diff options
context:
space:
mode:
authorManu Abraham <abraham.manu@gmail.com>2009-12-04 05:41:11 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-01-17 11:55:42 -0200
commitb3b961448f702339444036f94252ff2ba7a99feb (patch)
treef31007bb892091072fa97f43f5666105b1ea8f33 /drivers/media/dvb/mantis/mantis_pci.c
parentadd206368462434ba97e8fe4de98e5d47ffdb0a0 (diff)
downloadlwn-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.c310
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");