From patchwork Fri Feb 19 19:35:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roel Kluin X-Patchwork-Id: 80810 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1JJSlkG010164 for ; Fri, 19 Feb 2010 19:28:47 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755702Ab0BST2S (ORCPT ); Fri, 19 Feb 2010 14:28:18 -0500 Received: from mail-ew0-f228.google.com ([209.85.219.228]:45577 "EHLO mail-ew0-f228.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755699Ab0BST2O (ORCPT ); Fri, 19 Feb 2010 14:28:14 -0500 Received: by ewy28 with SMTP id 28so508114ewy.28 for ; Fri, 19 Feb 2010 11:28:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; bh=Q9kILbnHdIV1xPbHr9zjOGuqsVwI6AoOMfOsARLeCb0=; b=gKD+D1IgG45bHdGAlKTaGa5FwoowYfgGkC7xVgKGcYG2ozdFt/BR0X703ZHy3+C+Ut 9TH3jD7+7qe6oENgixIub391itwNMzIdJzBlU12/W2RcFKJAK7zLHWwEqlY/rtYuq7R/ 52MSQC0eiBpGwTc1q+DD5n463TuKr1VCILxys= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; b=eQmicA178tbuyfDSI5BgzzNIF57E5s6Nft1t+9jZE0fwM0xBLbJlhx4nlaXCoHyOXU 6qarQyDG/7gkFUEinwB2SvmyW88FoIQS7sX8H8NahN7hS7hMFrmob7/tA6GnWVhryVii 9pXGQeUFn9EOrjnfPI6LUjR5AWO4nqwozrzEY= Received: by 10.213.102.202 with SMTP id h10mr1275178ebo.94.1266607692529; Fri, 19 Feb 2010 11:28:12 -0800 (PST) Received: from zoinx.mars (d133062.upc-d.chello.nl [213.46.133.62]) by mx.google.com with ESMTPS id 24sm1845646eyx.30.2010.02.19.11.28.09 (version=SSLv3 cipher=RC4-MD5); Fri, 19 Feb 2010 11:28:10 -0800 (PST) Message-ID: <4B7EE81C.4020701@gmail.com> Date: Fri, 19 Feb 2010 20:35:56 +0100 From: Roel Kluin User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100120 Fedora/3.0.1-1.fc12 Thunderbird/3.0.1 MIME-Version: 1.0 To: "Karicheri, Muralidharan" CC: Mauro Carvalho Chehab , "linux-media@vger.kernel.org" , Andrew Morton , LKML Subject: Re: [PATCH] video_device: don't free_irq() an element past array vpif_obj.dev[] and fix test References: <4B714E15.4020909@gmail.com> <25e057c01002181202v346f488bk571d099f679fea83@mail.gmail.com> In-Reply-To: Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Fri, 19 Feb 2010 19:28:48 +0000 (UTC) diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index dfddef7..ae8ca94 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -383,7 +383,7 @@ static int vpif_get_std_info(struct channel_obj *ch) int index; std_info->stdid = vid_ch->stdid; - if (!std_info) + if (!std_info->stdid) return -1; for (index = 0; index < ARRAY_SIZE(ch_params); index++) { @@ -1423,7 +1423,7 @@ static __init int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; struct vpif_display_config *config; - int i, j = 0, k, q, m, err = 0; + int i, j, k, err; struct i2c_adapter *i2c_adap; struct common_obj *common; struct channel_obj *ch; @@ -1452,12 +1452,18 @@ static __init int vpif_probe(struct platform_device *pdev) if (request_irq(i, vpif_channel_isr, IRQF_DISABLED, "DM646x_Display", (void *)(&vpif_obj.dev[k]->channel_id))) { + i--; err = -EBUSY; + vpif_err("VPIF IRQ request failed\n"); goto vpif_int_err; } } k++; + if (k >= VPIF_DISPLAY_MAX_DEVICES) + break; } + if (k == 0) + return -ENODEV; for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { @@ -1472,7 +1478,7 @@ static __init int vpif_probe(struct platform_device *pdev) video_device_release(ch->video_dev); } err = -ENOMEM; - goto vpif_int_err; + goto alloc_vid_fail; } /* Initialize field of video device */ @@ -1489,13 +1495,13 @@ static __init int vpif_probe(struct platform_device *pdev) ch->video_dev = vfd; } - for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) { - ch = vpif_obj.dev[j]; + for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { + ch = vpif_obj.dev[i]; /* Initialize field of the channel objects */ atomic_set(&ch->usrs, 0); - for (k = 0; k < VPIF_NUMOBJECTS; k++) { - ch->common[k].numbuffers = 0; - common = &ch->common[k]; + for (j = 0; j < VPIF_NUMOBJECTS; j++) { + ch->common[j].numbuffers = 0; + common = &ch->common[j]; common->io_usrs = 0; common->started = 0; spin_lock_init(&common->irqlock); @@ -1506,12 +1512,12 @@ static __init int vpif_probe(struct platform_device *pdev) common->ctop_off = common->cbtm_off = 0; common->cur_frm = common->next_frm = NULL; memset(&common->fmt, 0, sizeof(common->fmt)); - common->numbuffers = config_params.numbuffers[k]; + common->numbuffers = config_params.numbuffers[j]; } ch->initialized = 0; - ch->channel_id = j; - if (j < 2) + ch->channel_id = i; + if (i < 2) ch->common[VPIF_VIDEO_INDEX].numbuffers = config_params.numbuffers[ch->channel_id]; else @@ -1529,7 +1535,7 @@ static __init int vpif_probe(struct platform_device *pdev) (int)ch, (int)&ch->video_dev); err = video_register_device(ch->video_dev, - VFL_TYPE_GRABBER, (j ? 3 : 2)); + VFL_TYPE_GRABBER, (i ? 3 : 2)); if (err < 0) goto probe_out; @@ -1567,20 +1573,35 @@ static __init int vpif_probe(struct platform_device *pdev) probe_subdev_out: kfree(vpif_obj.sd); probe_out: - for (k = 0; k < j; k++) { - ch = vpif_obj.dev[k]; + for (j = 0; j < i; j++) { + ch = vpif_obj.dev[j]; video_unregister_device(ch->video_dev); video_device_release(ch->video_dev); ch->video_dev = NULL; } +alloc_vid_fail: + while (k--) { + res = platform_get_resource(pdev, IORESOURCE_IRQ, k); + if (res != NULL) + break; + vpif_err("Couldn't get resource %d, irqs not freed.\n", k); + } + if (res == NULL) { + vpif_err("Couldn't get any resource.\n"); + return err; + } + + i = res->end; vpif_int_err: v4l2_device_unregister(&vpif_obj.v4l2_dev); - vpif_err("VPIF IRQ request failed\n"); - for (q = k; k >= 0; k--) { - for (m = i; m >= res->start; m--) - free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id)); - res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1); - m = res->end; + + for (j = i; j >= res->start; j--) + free_irq(j, (void *)(&vpif_obj.dev[k]->channel_id)); + + while (k--) { + res = platform_get_resource(pdev, IORESOURCE_IRQ, k); + for (j = res->end; j >= res->start; j--) + free_irq(j, (void *)(&vpif_obj.dev[k]->channel_id)); } return err;