V4L/DVB (3344c): Pci probing for stradis driver
authorJiri Slaby <xslaby@fi.muni.cz>
Wed, 11 Jan 2006 21:41:13 +0000 (19:41 -0200)
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>
Wed, 11 Jan 2006 21:41:13 +0000 (19:41 -0200)
- Pci probing functions added, some functions were rewritten.

- Use PCI_DEVICE macro.

- dev_ used for printing when pci_dev available.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/saa7146.h
drivers/media/video/stradis.c

index f305ec8..756963f 100644 (file)
@@ -73,7 +73,6 @@ struct saa7146
         unsigned int nr;
        unsigned long irq;          /* IRQ used by SAA7146 card */
        unsigned short id;
-       struct pci_dev *dev;
        unsigned char revision;
        unsigned char boardcfg[64];     /* 64 bytes of config from eeprom */
        unsigned long saa7146_adr;   /* bus address of IO mem from PCI BIOS */
index 6ee54a4..ad6646c 100644 (file)
@@ -1991,12 +1991,10 @@ static struct video_device saa_template =
        .minor          = -1,
 };
 
-static int configure_saa7146(struct pci_dev *dev, int num)
+static int __devinit configure_saa7146(struct pci_dev *pdev, int num)
 {
        int result;
-       struct saa7146 *saa;
-
-       saa = &saa7146s[num];
+       struct saa7146 *saa = &saa7146s[num];
        
        saa->endmarkhead = saa->endmarktail = 0;
        saa->win.x = saa->win.y = 0;
@@ -2013,7 +2011,6 @@ static int configure_saa7146(struct pci_dev *dev, int num)
        saa->picture.contrast = 38768;
        saa->picture.colour = 32768;
        saa->cap = 0;
-       saa->dev = dev;
        saa->nr = num;
        saa->playmode = VID_PLAY_NORMAL;
        memset(saa->boardcfg, 0, 64);   /* clear board config area */
@@ -2033,14 +2030,14 @@ static int configure_saa7146(struct pci_dev *dev, int num)
        init_waitqueue_head(&saa->vidq);
        spin_lock_init(&saa->lock);
 
-       if (pci_enable_device(dev))
+       if (pci_enable_device(pdev))
                return -EIO;
        
-       saa->id = dev->device;
-       saa->irq = dev->irq;
+       saa->id = pdev->device;
+       saa->irq = pdev->irq;
        saa->video_dev.minor = -1;
-       saa->saa7146_adr = pci_resource_start(dev, 0);
-       pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision);
+       saa->saa7146_adr = pci_resource_start(pdev, 0);
+       pci_read_config_byte(pdev, PCI_CLASS_REVISION, &saa->revision);
 
        saa->saa7146_mem = ioremap(saa->saa7146_adr, 0x200);
        if (!saa->saa7146_mem)
@@ -2051,16 +2048,15 @@ static int configure_saa7146(struct pci_dev *dev, int num)
        result = request_irq(saa->irq, saa7146_irq,
                       SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa);
        if (result == -EINVAL)
-               printk(KERN_ERR "stradis%d: Bad irq number or handler\n",
-                      num);
+               dev_err(&pdev->dev, "%d: Bad irq number or handler\n", num);
        if (result == -EBUSY)
-               printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP"
-                      " config in BIOS\n", num, saa->irq);
+               dev_err(&pdev->dev, "%d: IRQ %ld busy, change your PnP config "
+                       "in BIOS\n", num, saa->irq);
        if (result < 0) {
                iounmap(saa->saa7146_mem);
                return result;
        }
-       pci_set_master(dev);
+       pci_set_master(pdev);
        if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {
                iounmap(saa->saa7146_mem);
                return -1;
@@ -2068,10 +2064,11 @@ static int configure_saa7146(struct pci_dev *dev, int num)
        return 0;
 }
 
-static int init_saa7146(int i)
+static int __devinit init_saa7146(int i, struct device *dev)
 {
        struct saa7146 *saa = &saa7146s[i];
 
+       memset(saa, 0, sizeof(*saa));
        saa->user = 0;
        /* reset the saa7146 */
        saawrite(0xffff0000, SAA7146_MC1);
@@ -2104,7 +2101,7 @@ static int init_saa7146(int i)
 
        /* allocate 32k dma buffer + 4k for page table */
        if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i);
+               dev_err(dev, "%d: debi kmalloc failed\n", i);
                return -1;
        }
 #if 0
@@ -2117,19 +2114,19 @@ static int init_saa7146(int i)
        saa->audtail = saa->vidtail = saa->osdtail = 0;
        if (saa->vidbuf == NULL)
                if ((saa->vidbuf = vmalloc(524288)) == NULL) {
-                       printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
+                       dev_err(dev, "%d: malloc failed\n", saa->nr);
                        return -ENOMEM;
                }
        if (saa->audbuf == NULL)
                if ((saa->audbuf = vmalloc(65536)) == NULL) {
-                       printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
+                       dev_err(dev, "%d: malloc failed\n", saa->nr);
                        vfree(saa->vidbuf);
                        saa->vidbuf = NULL;
                        return -ENOMEM;
                }
        if (saa->osdbuf == NULL)
                if ((saa->osdbuf = vmalloc(131072)) == NULL) {
-                       printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr);
+                       dev_err(dev, "%d: malloc failed\n", saa->nr);
                        vfree(saa->vidbuf);
                        vfree(saa->audbuf);
                        saa->vidbuf = saa->audbuf = NULL;
@@ -2137,7 +2134,7 @@ static int init_saa7146(int i)
                }
        /* allocate 81920 byte buffer for clipping */
        if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
-               printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr);
+               dev_err(dev, "%d: clip kmalloc failed\n", saa->nr);
                vfree(saa->vidbuf);
                vfree(saa->audbuf);
                vfree(saa->osdbuf);
@@ -2159,89 +2156,121 @@ static int init_saa7146(int i)
        return 0;
 }
 
-static void release_saa(void)
+static void stradis_release_saa(struct pci_dev *pdev)
 {
        u8 command;
-       int i;
-       struct saa7146 *saa;
+       int i = (int)pci_get_drvdata(pdev);
+       struct saa7146 *saa = &saa7146s[i];
 
-       for (i = 0; i < saa_num; i++) {
-               saa = &saa7146s[i];
+       /* turn off all capturing, DMA and IRQs */
+       saawrite(0xffff0000, SAA7146_MC1);      /* reset chip */
+       saawrite(0, SAA7146_MC2);
+       saawrite(0, SAA7146_IER);
+       saawrite(0xffffffffUL, SAA7146_ISR);
+
+       /* disable PCI bus-mastering */
+       pci_read_config_byte(pdev, PCI_COMMAND, &command);
+       command &= ~PCI_COMMAND_MASTER;
+       pci_write_config_byte(pdev, PCI_COMMAND, command);
+
+       /* unmap and free memory */
+       saa->audhead = saa->audtail = saa->osdhead = 0;
+       saa->vidhead = saa->vidtail = saa->osdtail = 0;
+       vfree(saa->vidbuf);
+       vfree(saa->audbuf);
+       vfree(saa->osdbuf);
+       kfree(saa->dmavid2);
+       saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
+       saa->dmavid2 = NULL;
+       kfree(saa->dmadebi);
+       kfree(saa->dmavid1);
+       kfree(saa->dmavid3);
+       kfree(saa->dmaa1in);
+       kfree(saa->dmaa1out);
+       kfree(saa->dmaa2in);
+       kfree(saa->dmaa2out);
+       kfree(saa->dmaRPS1);
+       kfree(saa->dmaRPS2);
+       free_irq(saa->irq, saa);
+       if (saa->saa7146_mem)
+               iounmap(saa->saa7146_mem);
+       if (saa->video_dev.minor != -1)
+               video_unregister_device(&saa->video_dev);
+}
 
-               /* turn off all capturing, DMA and IRQs */
-               saawrite(0xffff0000, SAA7146_MC1);      /* reset chip */
-               saawrite(0, SAA7146_MC2);
-               saawrite(0, SAA7146_IER);
-               saawrite(0xffffffffUL, SAA7146_ISR);
+static int __devinit stradis_probe(struct pci_dev *pdev,
+       const struct pci_device_id *ent)
+{
+       int retval = -EINVAL;
 
-               /* disable PCI bus-mastering */
-               pci_read_config_byte(saa->dev, PCI_COMMAND, &command);
-               command &= ~PCI_COMMAND_MASTER;
-               pci_write_config_byte(saa->dev, PCI_COMMAND, command);
+       if (saa_num >= SAA7146_MAX)
+               goto err;
 
-               /* unmap and free memory */
-               saa->audhead = saa->audtail = saa->osdhead = 0;
-               saa->vidhead = saa->vidtail = saa->osdtail = 0;
-               vfree(saa->vidbuf);
-               vfree(saa->audbuf);
-               vfree(saa->osdbuf);
-               kfree(saa->dmavid2);
-               saa->audbuf = saa->vidbuf = saa->osdbuf = NULL;
-               saa->dmavid2 = NULL;
-               kfree(saa->dmadebi);
-               kfree(saa->dmavid1);
-               kfree(saa->dmavid3);
-               kfree(saa->dmaa1in);
-               kfree(saa->dmaa1out);
-               kfree(saa->dmaa2in);
-               kfree(saa->dmaa2out);
-               kfree(saa->dmaRPS1);
-               kfree(saa->dmaRPS2);
-               free_irq(saa->irq, saa);
-               if (saa->saa7146_mem)
-                       iounmap(saa->saa7146_mem);
-               if (saa->video_dev.minor != -1)
-                       video_unregister_device(&saa->video_dev);
+       if (!pdev->subsystem_vendor)
+               dev_info(&pdev->dev, "%d: rev1 decoder\n", saa_num);
+       else
+               dev_info(&pdev->dev, "%d: SDM2xx found\n", saa_num);
+
+       pci_set_drvdata(pdev, (void *)saa_num);
+
+       retval = configure_saa7146(pdev, saa_num);
+       if (retval) {
+               dev_err(&pdev->dev, "%d: error in configuring\n", saa_num);
+               goto err;
+       }
+
+       if (init_saa7146(saa_num, &pdev->dev) < 0) {
+               dev_err(&pdev->dev, "%d: error in initialization\n", saa_num);
+               retval = -EIO;
+               goto errrel;
        }
+
+       saa_num++;
+
+       return 0;
+errrel:
+       stradis_release_saa(pdev);
+err:
+       return retval;
 }
 
+static void __devexit stradis_remove(struct pci_dev *pdev)
+{
+       stradis_release_saa(pdev);
+}
+
+static struct pci_device_id stradis_pci_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146) },
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, stradis_pci_tbl);
+
+static struct pci_driver stradis_driver = {
+       .name           = "stradis",
+       .id_table       = stradis_pci_tbl,
+       .probe          = stradis_probe,
+       .remove         = __devexit_p(stradis_remove)
+};
 
-static int __init stradis_init (void)
+int __init stradis_init(void)
 {
-       struct pci_dev *dev = NULL;
-       int result = 0, i;
+       int retval;
 
        saa_num = 0;
 
-       while ((dev = pci_find_device(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, dev))) {
-               if (!dev->subsystem_vendor)
-                       printk(KERN_INFO "stradis%d: rev1 decoder\n", saa_num);
-               else
-                       printk(KERN_INFO "stradis%d: SDM2xx found\n", saa_num); 
-               result = configure_saa7146(dev, saa_num++);
-               if (result)
-                       return result;
-       }
-       if (saa_num)
-               printk(KERN_INFO "stradis: %d card(s) found.\n", saa_num);
-       else
-               return -EINVAL;
-       for (i = 0; i < saa_num; i++)
-               if (init_saa7146(i) < 0) {
-                       release_saa();
-                       return -EIO;
-               }
-       return 0;
+       retval = pci_register_driver(&stradis_driver);
+       if (retval)
+               printk(KERN_ERR "stradis: Unable to register pci driver.\n");
+
+       return retval;
 }
 
 
-static void __exit stradis_exit (void)
+void __exit stradis_exit(void)
 {
-       release_saa();
+       pci_unregister_driver(&stradis_driver);
        printk(KERN_INFO "stradis: module cleanup complete\n");
 }
 
-
 module_init(stradis_init);
 module_exit(stradis_exit);
-