From patchwork Thu Sep 20 12:06:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 1483951 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from bear.ext.ti.com (bear.ext.ti.com [192.94.94.41]) by patchwork2.kernel.org (Postfix) with ESMTP id 15CEBDF2D2 for ; Thu, 20 Sep 2012 12:10:19 +0000 (UTC) Received: from dlelxv30.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id q8KC8X6l007962; Thu, 20 Sep 2012 07:08:33 -0500 Received: from DLEE74.ent.ti.com (dlee74.ent.ti.com [157.170.170.8]) by dlelxv30.itg.ti.com (8.13.8/8.13.8) with ESMTP id q8KC8X65012324; Thu, 20 Sep 2012 07:08:33 -0500 Received: from dlelxv24.itg.ti.com (172.17.1.199) by DLEE74.ent.ti.com (157.170.170.8) with Microsoft SMTP Server id 14.1.323.3; Thu, 20 Sep 2012 07:08:32 -0500 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlelxv24.itg.ti.com (8.13.8/8.13.8) with ESMTP id q8KC8WAb020347; Thu, 20 Sep 2012 07:08:32 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 5193A8062C; Thu, 20 Sep 2012 07:08:32 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp51.itg.ti.com (dflp51.itg.ti.com [128.247.22.94]) by linux.omap.com (Postfix) with ESMTP id D54C080628 for ; Thu, 20 Sep 2012 07:07:19 -0500 (CDT) Received: from neches.ext.ti.com (neches.ext.ti.com [192.91.81.29]) by dflp51.itg.ti.com (8.13.7/8.13.8) with ESMTP id q8KC7Jkh000871 for ; Thu, 20 Sep 2012 07:07:19 -0500 (CDT) Received: from psmtp.com (na3sys009amx242.postini.com [74.125.149.126]) by neches.ext.ti.com (8.13.7/8.13.7) with SMTP id q8KC7Idg020078 for ; Thu, 20 Sep 2012 07:07:18 -0500 Received: from smtp-vbr6.xs4all.nl ([194.109.24.26]) by na3sys009amx242.postini.com ([74.125.148.10]) with SMTP; Thu, 20 Sep 2012 12:07:18 GMT Received: from alastor.dyndns.org (166.80-203-20.nextgentel.com [80.203.20.166] (may be forged)) (authenticated bits=0) by smtp-vbr6.xs4all.nl (8.13.8/8.13.8) with ESMTP id q8KC6jns092742 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 20 Sep 2012 14:06:46 +0200 (CEST) (envelope-from hverkuil@xs4all.nl) Received: from tschai.lan (tschai.lan [192.168.1.10]) (Authenticated sender: hans) by alastor.dyndns.org (Postfix) with ESMTPSA id 8A7B835C014D; Thu, 20 Sep 2012 14:06:39 +0200 (CEST) From: Hans Verkuil To: Subject: [RFCv2 PATCH 10/14] vpif_capture: fix cleanup code. Date: Thu, 20 Sep 2012 14:06:29 +0200 Message-ID: X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <15fd87671d173ae4b943df4114aafb55d7e958fa.1348142407.git.hans.verkuil@cisco.com> References: <15fd87671d173ae4b943df4114aafb55d7e958fa.1348142407.git.hans.verkuil@cisco.com> X-Virus-Scanned: by XS4ALL Virus Scanner X-pstn-neptune: 0/0/0.00/0 X-pstn-levels: (S:99.90000/99.90000 CV:99.9000 FC:95.5390 LC:95.5390 R:95.9108 P:95.9108 M:97.0282 C:98.6951 ) X-pstn-dkim: 0 skipped:not-enabled X-pstn-settings: 2 (0.5000:0.5000) s cv gt3 gt2 gt1 r p m c X-pstn-addresses: from [82/3] CC: Hans Verkuil , DLOS X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com From: Hans Verkuil The cleanup sequence was incorrect and could cause a kernel oops. Signed-off-by: Hans Verkuil --- drivers/media/platform/davinci/vpif_capture.c | 41 ++++++++++++------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 98423b5..5f81e0f 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -2060,7 +2060,8 @@ static __init int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; struct vpif_capture_config *config; - int i, j, k, m, q, err; + int i, j, k, err; + int res_idx = 0; struct i2c_adapter *i2c_adap; struct channel_obj *ch; struct common_obj *common; @@ -2083,18 +2084,18 @@ static __init int vpif_probe(struct platform_device *pdev) return err; } - k = 0; - while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) { + while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) { for (i = res->start; i <= res->end; i++) { if (request_irq(i, vpif_channel_isr, IRQF_SHARED, "VPIF_Capture", - (void *)(&vpif_obj.dev[k]->channel_id))) { + (void *)(&vpif_obj.dev[res_idx]->channel_id))) { err = -EBUSY; - i--; + for (j = 0; j < i; j++) + free_irq(j, (void *)(&vpif_obj.dev[res_idx]->channel_id)); goto vpif_int_err; } } - k++; + res_idx++; } for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { @@ -2108,7 +2109,7 @@ static __init int vpif_probe(struct platform_device *pdev) video_device_release(ch->video_dev); } err = -ENOMEM; - goto vpif_dev_alloc_err; + goto vpif_int_err; } /* Initialize field of video device */ @@ -2148,7 +2149,7 @@ static __init int vpif_probe(struct platform_device *pdev) if (vpif_obj.sd == NULL) { vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; - goto vpif_dev_alloc_err; + goto vpif_sd_error; } for (i = 0; i < subdev_count; i++) { @@ -2197,21 +2198,19 @@ probe_subdev_out: /* free sub devices memory */ kfree(vpif_obj.sd); -vpif_dev_alloc_err: - k = VPIF_CAPTURE_MAX_DEVICES-1; - res = platform_get_resource(pdev, IORESOURCE_IRQ, k); - i = res->end; - -vpif_int_err: - for (q = k; q >= 0; q--) { - for (m = i; m >= (int)res->start; m--) - free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id)); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1); - if (res) - i = res->end; +vpif_sd_error: + for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { + ch = vpif_obj.dev[i]; + /* Note: does nothing if ch->video_dev == NULL */ + video_device_release(ch->video_dev); } +vpif_int_err: v4l2_device_unregister(&vpif_obj.v4l2_dev); + for (i = 0; i < res_idx; i++) { + res = platform_get_resource(pdev, IORESOURCE_IRQ, i); + for (j = res->start; j <= res->end; j++) + free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id)); + } return err; }