Commit 66aa66ea authored by Trent Piepho's avatar Trent Piepho Committed by Mauro Carvalho Chehab

V4L/DVB (10212): Convert to be a pci driver

This is a really old and crufty driver that wasn't using the long
established pci driver framework.
Signed-off-by: default avatarTrent Piepho <xyzzy@speakeasy.org>
Acked-by: default avatarJean Delvare <khali@linux-fr.org>
[mchehab@redhat.com: Cleaned up a few CodingStyle issues]
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent f90c3c0b
...@@ -153,16 +153,13 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver"); ...@@ -153,16 +153,13 @@ MODULE_DESCRIPTION("Zoran-36057/36067 JPEG codec driver");
MODULE_AUTHOR("Serguei Miridonov"); MODULE_AUTHOR("Serguei Miridonov");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#if (defined(CONFIG_VIDEO_ZORAN_MODULE) && defined(MODULE))
static struct pci_device_id zr36067_pci_tbl[] = { static struct pci_device_id zr36067_pci_tbl[] = {
{PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, { PCI_DEVICE(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057), },
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{0} {0}
}; };
MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl);
#endif
int zoran_num; /* number of Buzs in use */ atomic_t zoran_num = ATOMIC_INIT(0); /* number of Buzs in use */
struct zoran *zoran[BUZ_MAX]; struct zoran *zoran[BUZ_MAX];
/* videocodec bus functions ZR36060 */ /* videocodec bus functions ZR36060 */
...@@ -1146,7 +1143,7 @@ zr36057_init (struct zoran *zr) ...@@ -1146,7 +1143,7 @@ zr36057_init (struct zoran *zr)
strcpy(zr->video_dev->name, ZR_DEVNAME(zr)); strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]); err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0) if (err < 0)
goto exit_unregister; goto exit_free;
zoran_init_hardware(zr); zoran_init_hardware(zr);
if (zr36067_debug > 2) if (zr36067_debug > 2)
...@@ -1161,19 +1158,19 @@ zr36057_init (struct zoran *zr) ...@@ -1161,19 +1158,19 @@ zr36057_init (struct zoran *zr)
zr->initialized = 1; zr->initialized = 1;
return 0; return 0;
exit_unregister:
zoran_unregister_i2c(zr);
exit_free: exit_free:
kfree(zr->stat_com); kfree(zr->stat_com);
kfree(zr->video_dev); kfree(zr->video_dev);
return err; return err;
} }
static void static void __devexit zoran_remove(struct pci_dev *pdev)
zoran_release (struct zoran *zr)
{ {
struct zoran *zr = pci_get_drvdata(pdev);
if (!zr->initialized) if (!zr->initialized)
goto exit_free; goto exit_free;
/* unregister videocodec bus */ /* unregister videocodec bus */
if (zr->codec) { if (zr->codec) {
struct videocodec_master *master = zr->codec->master_data; struct videocodec_master *master = zr->codec->master_data;
...@@ -1202,6 +1199,7 @@ zoran_release (struct zoran *zr) ...@@ -1202,6 +1199,7 @@ zoran_release (struct zoran *zr)
pci_disable_device(zr->pci_dev); pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev); video_unregister_device(zr->video_dev);
exit_free: exit_free:
pci_set_drvdata(pdev, NULL);
kfree(zr); kfree(zr);
} }
...@@ -1264,338 +1262,347 @@ zoran_setup_videocodec (struct zoran *zr, ...@@ -1264,338 +1262,347 @@ zoran_setup_videocodec (struct zoran *zr,
* Scan for a Buz card (actually for the PCI controller ZR36057), * Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory * request the irq and map the io memory
*/ */
static int __devinit static int __devinit zoran_probe(struct pci_dev *pdev,
find_zr36057 (void) const struct pci_device_id *ent)
{ {
unsigned char latency, need_latency; unsigned char latency, need_latency;
struct zoran *zr; struct zoran *zr;
struct pci_dev *dev = NULL;
int result; int result;
struct videocodec_master *master_vfe = NULL; struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL; struct videocodec_master *master_codec = NULL;
int card_num; int card_num;
char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name; char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
unsigned int nr;
zoran_num = 0;
while (zoran_num < BUZ_MAX &&
(dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
card_num = card[zoran_num];
zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
if (!zr) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - kzalloc failed\n",
ZORAN_NAME);
continue;
}
zr->pci_dev = dev;
//zr->zr36057_mem = NULL;
zr->id = zoran_num;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(dev))
goto zr_free_mem;
zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION,
&zr->revision);
if (zr->revision < 2) {
dprintk(1,
KERN_INFO
"%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
zr->zr36057_adr);
if (card_num == -1) { nr = atomic_inc_return(&zoran_num) - 1;
dprintk(1, if (nr >= BUZ_MAX) {
KERN_ERR dprintk(1,
"%s: find_zr36057() - no card specified, please use the card=X insmod option\n", KERN_ERR
ZR_DEVNAME(zr)); "%s: driver limited to %d card(s) maximum\n",
goto zr_free_mem; ZORAN_NAME, BUZ_MAX);
} return -ENOENT;
} else { }
int i;
unsigned short ss_vendor, ss_device;
ss_vendor = zr->pci_dev->subsystem_vendor;
ss_device = zr->pci_dev->subsystem_device;
dprintk(1,
KERN_INFO
"%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
zr->zr36057_adr);
dprintk(1,
KERN_INFO
"%s: subsystem vendor=0x%04x id=0x%04x\n",
ZR_DEVNAME(zr), ss_vendor, ss_device);
if (card_num == -1) {
dprintk(3,
KERN_DEBUG
"%s: find_zr36057() - trying to autodetect card type\n",
ZR_DEVNAME(zr));
for (i=0;i<NUM_CARDS;i++) {
if (ss_vendor == zoran_cards[i].vendor_id &&
ss_device == zoran_cards[i].device_id) {
dprintk(3,
KERN_DEBUG
"%s: find_zr36057() - card %s detected\n",
ZR_DEVNAME(zr),
zoran_cards[i].name);
card_num = i;
break;
}
}
if (i == NUM_CARDS) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - unknown card\n",
ZR_DEVNAME(zr));
goto zr_free_mem;
}
}
}
if (card_num < 0 || card_num >= NUM_CARDS) { card_num = card[nr];
dprintk(2, zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
KERN_ERR if (!zr) {
"%s: find_zr36057() - invalid cardnum %d\n", dprintk(1,
ZR_DEVNAME(zr), card_num); KERN_ERR
goto zr_free_mem; "%s: find_zr36057() - kzalloc failed\n",
} ZORAN_NAME);
/* The entry in zoran[] gets leaked */
return -ENOMEM;
}
zr->pci_dev = pdev;
zr->id = nr;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(pdev))
goto zr_free_mem;
zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0);
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
if (zr->revision < 2) {
dprintk(1,
KERN_INFO
"%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
zr->zr36057_adr);
/* even though we make this a non pointer and thus if (card_num == -1) {
* theoretically allow for making changes to this struct
* on a per-individual card basis at runtime, this is
* strongly discouraged. This structure is intended to
* keep general card information, no settings or anything */
zr->card = zoran_cards[card_num];
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
"%s[%u]", zr->card.name, zr->id);
zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
if (!zr->zr36057_mem) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: find_zr36057() - ioremap failed\n", "%s: find_zr36057() - no card specified, please use the card=X insmod option\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
goto zr_free_mem; goto zr_free_mem;
} }
} else {
int i;
unsigned short ss_vendor, ss_device;
result = request_irq(zr->pci_dev->irq, ss_vendor = zr->pci_dev->subsystem_vendor;
zoran_irq, ss_device = zr->pci_dev->subsystem_device;
IRQF_SHARED | IRQF_DISABLED, dprintk(1,
ZR_DEVNAME(zr), KERN_INFO
(void *) zr); "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
if (result < 0) { ZR_DEVNAME(zr), zr->revision, zr->pci_dev->irq,
if (result == -EINVAL) { zr->zr36057_adr);
dprintk(1,
KERN_INFO
"%s: subsystem vendor=0x%04x id=0x%04x\n",
ZR_DEVNAME(zr), ss_vendor, ss_device);
if (card_num == -1) {
dprintk(3,
KERN_DEBUG
"%s: find_zr36057() - trying to autodetect card type\n",
ZR_DEVNAME(zr));
for (i = 0; i < NUM_CARDS; i++) {
if (ss_vendor == zoran_cards[i].vendor_id &&
ss_device == zoran_cards[i].device_id) {
dprintk(3,
KERN_DEBUG
"%s: find_zr36057() - card %s detected\n",
ZR_DEVNAME(zr),
zoran_cards[i].name);
card_num = i;
break;
}
}
if (i == NUM_CARDS) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: find_zr36057() - bad irq number or handler\n", "%s: find_zr36057() - unknown card\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
} else if (result == -EBUSY) { goto zr_free_mem;
dprintk(1,
KERN_ERR
"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
ZR_DEVNAME(zr), zr->pci_dev->irq);
} else {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't assign irq, error code %d\n",
ZR_DEVNAME(zr), result);
} }
goto zr_unmap;
} }
}
/* set PCI latency timer */ if (card_num < 0 || card_num >= NUM_CARDS) {
pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, dprintk(2,
&latency); KERN_ERR
need_latency = zr->revision > 1 ? 32 : 48; "%s: find_zr36057() - invalid cardnum %d\n",
if (latency != need_latency) { ZR_DEVNAME(zr), card_num);
dprintk(2, goto zr_free_mem;
KERN_INFO }
"%s: Changing PCI latency from %d to %d.\n",
ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev,
PCI_LATENCY_TIMER,
need_latency);
}
zr36057_restart(zr); /* even though we make this a non pointer and thus
/* i2c */ * theoretically allow for making changes to this struct
dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n", * on a per-individual card basis at runtime, this is
* strongly discouraged. This structure is intended to
* keep general card information, no settings or anything */
zr->card = zoran_cards[card_num];
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)),
"%s[%u]", zr->card.name, zr->id);
zr->zr36057_mem = ioremap_nocache(zr->zr36057_adr, 0x1000);
if (!zr->zr36057_mem) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - ioremap failed\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
goto zr_free_mem;
}
/* i2c decoder */ result = request_irq(zr->pci_dev->irq, zoran_irq,
if (decoder[zr->id] != -1) { IRQF_SHARED | IRQF_DISABLED, ZR_DEVNAME(zr), zr);
i2c_dec_name = i2cid_to_modulename(decoder[zr->id]); if (result < 0) {
zr->card.i2c_decoder = decoder[zr->id]; if (result == -EINVAL) {
} else if (zr->card.i2c_decoder != 0) { dprintk(1,
i2c_dec_name = KERN_ERR
i2cid_to_modulename(zr->card.i2c_decoder); "%s: find_zr36057() - bad irq number or handler\n",
ZR_DEVNAME(zr));
} else if (result == -EBUSY) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
ZR_DEVNAME(zr), zr->pci_dev->irq);
} else { } else {
i2c_dec_name = NULL; dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't assign irq, error code %d\n",
ZR_DEVNAME(zr), result);
} }
goto zr_unmap;
}
if (i2c_dec_name) { /* set PCI latency timer */
if ((result = request_module(i2c_dec_name)) < 0) { pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
dprintk(1, &latency);
KERN_ERR need_latency = zr->revision > 1 ? 32 : 48;
"%s: failed to load module %s: %d\n", if (latency != need_latency) {
ZR_DEVNAME(zr), i2c_dec_name, result); dprintk(2,
} KERN_INFO
} "%s: Changing PCI latency from %d to %d\n",
ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
need_latency);
}
/* i2c encoder */ zr36057_restart(zr);
if (encoder[zr->id] != -1) { /* i2c */
i2c_enc_name = i2cid_to_modulename(encoder[zr->id]); dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
zr->card.i2c_encoder = encoder[zr->id]; ZR_DEVNAME(zr));
} else if (zr->card.i2c_encoder != 0) {
i2c_enc_name = /* i2c decoder */
i2cid_to_modulename(zr->card.i2c_encoder); if (decoder[zr->id] != -1) {
} else { i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
i2c_enc_name = NULL; zr->card.i2c_decoder = decoder[zr->id];
} } else if (zr->card.i2c_decoder != 0) {
i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
} else {
i2c_dec_name = NULL;
}
if (i2c_enc_name) { if (i2c_dec_name) {
if ((result = request_module(i2c_enc_name)) < 0) { result = request_module(i2c_dec_name);
dprintk(1, if (result < 0) {
KERN_ERR dprintk(1,
"%s: failed to load module %s: %d\n", KERN_ERR
ZR_DEVNAME(zr), i2c_enc_name, result); "%s: failed to load module %s: %d\n",
} ZR_DEVNAME(zr), i2c_dec_name, result);
} }
}
if (zoran_register_i2c(zr) < 0) { /* i2c encoder */
if (encoder[zr->id] != -1) {
i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
zr->card.i2c_encoder = encoder[zr->id];
} else if (zr->card.i2c_encoder != 0) {
i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
} else {
i2c_enc_name = NULL;
}
if (i2c_enc_name) {
result = request_module(i2c_enc_name);
if (result < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: find_zr36057() - can't initialize i2c bus\n", "%s: failed to load module %s: %d\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr), i2c_enc_name, result);
goto zr_free_irq;
} }
}
dprintk(2, if (zoran_register_i2c(zr) < 0) {
KERN_INFO "%s: Initializing videocodec bus...\n", dprintk(1,
KERN_ERR
"%s: find_zr36057() - can't initialize i2c bus\n",
ZR_DEVNAME(zr)); ZR_DEVNAME(zr));
goto zr_free_irq;
}
if (zr->card.video_codec != 0 && dprintk(2,
(codec_name = KERN_INFO "%s: Initializing videocodec bus...\n",
codecid_to_modulename(zr->card.video_codec)) != NULL) { ZR_DEVNAME(zr));
if ((result = request_module(codec_name)) < 0) {
if (zr->card.video_codec) {
codec_name = codecid_to_modulename(zr->card.video_codec);
if (codec_name) {
result = request_module(codec_name);
if (result) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: failed to load modules %s: %d\n", "%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), codec_name, result); ZR_DEVNAME(zr), codec_name, result);
} }
} }
if (zr->card.video_vfe != 0 && }
(vfe_name = if (zr->card.video_vfe) {
codecid_to_modulename(zr->card.video_vfe)) != NULL) { vfe_name = codecid_to_modulename(zr->card.video_vfe);
if ((result = request_module(vfe_name)) < 0) { if (vfe_name) {
result = request_module(vfe_name);
if (result < 0) {
dprintk(1, dprintk(1,
KERN_ERR KERN_ERR
"%s: failed to load modules %s: %d\n", "%s: failed to load modules %s: %d\n",
ZR_DEVNAME(zr), vfe_name, result); ZR_DEVNAME(zr), vfe_name, result);
} }
} }
}
/* reset JPEG codec */ /* reset JPEG codec */
jpeg_codec_sleep(zr, 1); jpeg_codec_sleep(zr, 1);
jpeg_codec_reset(zr); jpeg_codec_reset(zr);
/* video bus enabled */ /* video bus enabled */
/* display codec revision */ /* display codec revision */
if (zr->card.video_codec != 0) { if (zr->card.video_codec != 0) {
master_codec = zoran_setup_videocodec(zr, master_codec = zoran_setup_videocodec(zr, zr->card.video_codec);
zr->card.video_codec); if (!master_codec)
if (!master_codec) goto zr_unreg_i2c;
goto zr_unreg_i2c; zr->codec = videocodec_attach(master_codec);
zr->codec = videocodec_attach(master_codec); if (!zr->codec) {
if (!zr->codec) { dprintk(1,
dprintk(1, KERN_ERR
KERN_ERR "%s: find_zr36057() - no codec found\n",
"%s: find_zr36057() - no codec found\n", ZR_DEVNAME(zr));
ZR_DEVNAME(zr)); goto zr_free_codec;
goto zr_free_codec;
}
if (zr->codec->type != zr->card.video_codec) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - wrong codec\n",
ZR_DEVNAME(zr));
goto zr_detach_codec;
}
} }
if (zr->card.video_vfe != 0) { if (zr->codec->type != zr->card.video_codec) {
master_vfe = zoran_setup_videocodec(zr, dprintk(1,
zr->card.video_vfe); KERN_ERR
if (!master_vfe) "%s: find_zr36057() - wrong codec\n",
goto zr_detach_codec; ZR_DEVNAME(zr));
zr->vfe = videocodec_attach(master_vfe); goto zr_detach_codec;
if (!zr->vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no VFE found\n",
ZR_DEVNAME(zr));
goto zr_free_vfe;
}
if (zr->vfe->type != zr->card.video_vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() = wrong VFE\n",
ZR_DEVNAME(zr));
goto zr_detach_vfe;
}
} }
/* Success so keep the pci_dev referenced */
pci_dev_get(zr->pci_dev);
zoran[zoran_num++] = zr;
continue;
// Init errors
zr_detach_vfe:
videocodec_detach(zr->vfe);
zr_free_vfe:
kfree(master_vfe);
zr_detach_codec:
videocodec_detach(zr->codec);
zr_free_codec:
kfree(master_codec);
zr_unreg_i2c:
zoran_unregister_i2c(zr);
zr_free_irq:
btwrite(0, ZR36057_SPGPPCR);
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
zr_free_mem:
kfree(zr);
continue;
} }
if (dev) /* Clean up ref count on early exit */ if (zr->card.video_vfe != 0) {
pci_dev_put(dev); master_vfe = zoran_setup_videocodec(zr, zr->card.video_vfe);
if (!master_vfe)
goto zr_detach_codec;
zr->vfe = videocodec_attach(master_vfe);
if (!zr->vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() - no VFE found\n",
ZR_DEVNAME(zr));
goto zr_free_vfe;
}
if (zr->vfe->type != zr->card.video_vfe) {
dprintk(1,
KERN_ERR
"%s: find_zr36057() = wrong VFE\n",
ZR_DEVNAME(zr));
goto zr_detach_vfe;
}
}
zoran[nr] = zr;
if (zoran_num == 0) { /* take care of Natoma chipset and a revision 1 zr36057 */
dprintk(1, KERN_INFO "No known MJPEG cards found.\n"); if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
dprintk(1,
KERN_INFO
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
ZR_DEVNAME(zr));
} }
return zoran_num;
if (zr36057_init(zr) < 0)
goto zr_detach_vfe;
zoran_proc_init(zr);
pci_set_drvdata(pdev, zr);
return 0;
zr_detach_vfe:
videocodec_detach(zr->vfe);
zr_free_vfe:
kfree(master_vfe);
zr_detach_codec:
videocodec_detach(zr->codec);
zr_free_codec:
kfree(master_codec);
zr_unreg_i2c:
zoran_unregister_i2c(zr);
zr_free_irq:
btwrite(0, ZR36057_SPGPPCR);
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
zr_free_mem:
kfree(zr);
return -ENODEV;
} }
static int __init static struct pci_driver zoran_driver = {
init_dc10_cards (void) .name = "zr36067",
.id_table = zr36067_pci_tbl,
.probe = zoran_probe,
.remove = zoran_remove,
};
static int __init zoran_init(void)
{ {
int i; int res;
memset(zoran, 0, sizeof(zoran)); memset(zoran, 0, sizeof(zoran));
printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n", printk(KERN_INFO "Zoran MJPEG board driver version %d.%d.%d\n",
MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION); MAJOR_VERSION, MINOR_VERSION, RELEASE_VERSION);
/* Look for cards */
if (find_zr36057() < 0) {
return -EIO;
}
if (zoran_num == 0)
return -ENODEV;
dprintk(1, KERN_INFO "%s: %d card(s) found\n", ZORAN_NAME,
zoran_num);
/* check the parameters we have been given, adjust if necessary */ /* check the parameters we have been given, adjust if necessary */
if (v4l_nbufs < 2) if (v4l_nbufs < 2)
v4l_nbufs = 2; v4l_nbufs = 2;
...@@ -1637,37 +1644,22 @@ init_dc10_cards (void) ...@@ -1637,37 +1644,22 @@ init_dc10_cards (void)
ZORAN_NAME); ZORAN_NAME);
} }
/* take care of Natoma chipset and a revision 1 zr36057 */ res = pci_register_driver(&zoran_driver);
for (i = 0; i < zoran_num; i++) { if (res) {
struct zoran *zr = zoran[i]; dprintk(1,
KERN_ERR
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { "%s: Unable to register ZR36057 driver\n",
zr->jpg_buffers.need_contiguous = 1; ZORAN_NAME);
dprintk(1, return res;
KERN_INFO
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
ZR_DEVNAME(zr));
}
if (zr36057_init(zr) < 0) {
for (i = 0; i < zoran_num; i++)
zoran_release(zoran[i]);
return -EIO;
}
zoran_proc_init(zr);
} }
return 0; return 0;
} }
static void __exit static void __exit zoran_exit(void)
unload_dc10_cards (void)
{ {
int i; pci_unregister_driver(&zoran_driver);
for (i = 0; i < zoran_num; i++)
zoran_release(zoran[i]);
} }
module_init(init_dc10_cards); module_init(zoran_init);
module_exit(unload_dc10_cards); module_exit(zoran_exit);
...@@ -40,7 +40,7 @@ extern int zr36067_debug; ...@@ -40,7 +40,7 @@ extern int zr36067_debug;
/* Anybody who uses more than four? */ /* Anybody who uses more than four? */
#define BUZ_MAX 4 #define BUZ_MAX 4
extern int zoran_num; extern atomic_t zoran_num;
extern struct zoran *zoran[BUZ_MAX]; extern struct zoran *zoran[BUZ_MAX];
extern struct video_device zoran_template; extern struct video_device zoran_template;
......
...@@ -1206,7 +1206,7 @@ zoran_open(struct file *file) ...@@ -1206,7 +1206,7 @@ zoran_open(struct file *file)
lock_kernel(); lock_kernel();
/* find the device */ /* find the device */
for (i = 0; i < zoran_num; i++) { for (i = 0; i < atomic_read(&zoran_num); i++) {
if (zoran[i]->video_dev->minor == minor) { if (zoran[i]->video_dev->minor == minor) {
zr = zoran[i]; zr = zoran[i];
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment