aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-09-20 08:06:29 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-10-05 21:06:05 -0400
commit5be452c343331dadf237bed0053fdc7d623e8049 (patch)
tree01bae823e42146340875112e31c7d02120ab63e1
parent01b1d975597dd051515fe90e5b0b09cc700e6aa0 (diff)
[media] vpif_capture: fix cleanup code
The cleanup sequence was incorrect and could cause a kernel oops. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Lad, Prabhakar <prabhakar.lad@ti.com> Tested-by: Lad, Prabhakar <prabhakar.lad@ti.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c44
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index 00fdb177d2fc..bcd2a78d3850 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)
2060{ 2060{
2061 struct vpif_subdev_info *subdevdata; 2061 struct vpif_subdev_info *subdevdata;
2062 struct vpif_capture_config *config; 2062 struct vpif_capture_config *config;
2063 int i, j, k, m, q, err; 2063 int i, j, k, err;
2064 int res_idx = 0;
2064 struct i2c_adapter *i2c_adap; 2065 struct i2c_adapter *i2c_adap;
2065 struct channel_obj *ch; 2066 struct channel_obj *ch;
2066 struct common_obj *common; 2067 struct common_obj *common;
@@ -2083,18 +2084,19 @@ static __init int vpif_probe(struct platform_device *pdev)
2083 return err; 2084 return err;
2084 } 2085 }
2085 2086
2086 k = 0; 2087 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, res_idx))) {
2087 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
2088 for (i = res->start; i <= res->end; i++) { 2088 for (i = res->start; i <= res->end; i++) {
2089 if (request_irq(i, vpif_channel_isr, IRQF_SHARED, 2089 if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
2090 "VPIF_Capture", 2090 "VPIF_Capture", (void *)
2091 (void *)(&vpif_obj.dev[k]->channel_id))) { 2091 (&vpif_obj.dev[res_idx]->channel_id))) {
2092 err = -EBUSY; 2092 err = -EBUSY;
2093 i--; 2093 for (j = 0; j < i; j++)
2094 free_irq(j, (void *)
2095 (&vpif_obj.dev[res_idx]->channel_id));
2094 goto vpif_int_err; 2096 goto vpif_int_err;
2095 } 2097 }
2096 } 2098 }
2097 k++; 2099 res_idx++;
2098 } 2100 }
2099 2101
2100 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { 2102 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
@@ -2108,7 +2110,7 @@ static __init int vpif_probe(struct platform_device *pdev)
2108 video_device_release(ch->video_dev); 2110 video_device_release(ch->video_dev);
2109 } 2111 }
2110 err = -ENOMEM; 2112 err = -ENOMEM;
2111 goto vpif_dev_alloc_err; 2113 goto vpif_int_err;
2112 } 2114 }
2113 2115
2114 /* Initialize field of video device */ 2116 /* Initialize field of video device */
@@ -2148,7 +2150,7 @@ static __init int vpif_probe(struct platform_device *pdev)
2148 if (vpif_obj.sd == NULL) { 2150 if (vpif_obj.sd == NULL) {
2149 vpif_err("unable to allocate memory for subdevice pointers\n"); 2151 vpif_err("unable to allocate memory for subdevice pointers\n");
2150 err = -ENOMEM; 2152 err = -ENOMEM;
2151 goto vpif_dev_alloc_err; 2153 goto vpif_sd_error;
2152 } 2154 }
2153 2155
2154 for (i = 0; i < subdev_count; i++) { 2156 for (i = 0; i < subdev_count; i++) {
@@ -2197,21 +2199,19 @@ probe_subdev_out:
2197 /* free sub devices memory */ 2199 /* free sub devices memory */
2198 kfree(vpif_obj.sd); 2200 kfree(vpif_obj.sd);
2199 2201
2200vpif_dev_alloc_err: 2202vpif_sd_error:
2201 k = VPIF_CAPTURE_MAX_DEVICES-1; 2203 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2202 res = platform_get_resource(pdev, IORESOURCE_IRQ, k); 2204 ch = vpif_obj.dev[i];
2203 i = res->end; 2205 /* Note: does nothing if ch->video_dev == NULL */
2204 2206 video_device_release(ch->video_dev);
2205vpif_int_err:
2206 for (q = k; q >= 0; q--) {
2207 for (m = i; m >= (int)res->start; m--)
2208 free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
2209
2210 res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
2211 if (res)
2212 i = res->end;
2213 } 2207 }
2208vpif_int_err:
2214 v4l2_device_unregister(&vpif_obj.v4l2_dev); 2209 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2210 for (i = 0; i < res_idx; i++) {
2211 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
2212 for (j = res->start; j <= res->end; j++)
2213 free_irq(j, (void *)(&vpif_obj.dev[i]->channel_id));
2214 }
2215 return err; 2215 return err;
2216} 2216}
2217 2217