From patchwork Thu Sep 20 12:06:28 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 1483811 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id F22913FD40 for ; Thu, 20 Sep 2012 12:07:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753060Ab2ITMHg (ORCPT ); Thu, 20 Sep 2012 08:07:36 -0400 Received: from smtp-vbr7.xs4all.nl ([194.109.24.27]:4918 "EHLO smtp-vbr7.xs4all.nl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752612Ab2ITMHe (ORCPT ); Thu, 20 Sep 2012 08:07:34 -0400 Received: from alastor.dyndns.org (166.80-203-20.nextgentel.com [80.203.20.166]) (authenticated bits=0) by smtp-vbr7.xs4all.nl (8.13.8/8.13.8) with ESMTP id q8KC6oeN046634 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 20 Sep 2012 14:06:51 +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 60FD435C014C; Thu, 20 Sep 2012 14:06:39 +0200 (CEST) From: Hans Verkuil To: linux-media@vger.kernel.org Cc: Prabhakar Lad , DLOS , Hans Verkuil Subject: [RFCv2 PATCH 09/14] vpif_display: fix cleanup code. Date: Thu, 20 Sep 2012 14:06:28 +0200 Message-Id: <3cd9a57d4eadfcd1ec18760e0796d7485236fc73.1348142407.git.hans.verkuil@cisco.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1348142793-27157-1-git-send-email-hverkuil@xs4all.nl> References: <1348142793-27157-1-git-send-email-hverkuil@xs4all.nl> 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 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Hans Verkuil The cleanup sequence was incorrect and could cause a kernel oops. Signed-off-by: Hans Verkuil --- drivers/media/platform/davinci/vpif_display.c | 30 +++++++++++++++---------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index e71c88f..66b4b32 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1607,7 +1607,8 @@ 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 = 0, k, err = 0; + int res_idx = 0; struct i2c_adapter *i2c_adap; struct common_obj *common; struct channel_obj *ch; @@ -1630,21 +1631,21 @@ 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_Display", - (void *)(&vpif_obj.dev[k]->channel_id))) { + (void *)(&vpif_obj.dev[res_idx]->channel_id))) { err = -EBUSY; + 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_DISPLAY_MAX_DEVICES; i++) { - /* Get the pointer to the channel object */ ch = vpif_obj.dev[i]; @@ -1698,7 +1699,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_int_err; + goto vpif_sd_error; } for (i = 0; i < subdev_count; i++) { @@ -1775,14 +1776,19 @@ probe_out: } probe_subdev_out: kfree(vpif_obj.sd); +vpif_sd_error: + for (i = 0; i < VPIF_DISPLAY_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); 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 (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;