diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-09-20 08:06:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-10-05 21:06:05 -0400 |
commit | 5be452c343331dadf237bed0053fdc7d623e8049 (patch) | |
tree | 01bae823e42146340875112e31c7d02120ab63e1 | |
parent | 01b1d975597dd051515fe90e5b0b09cc700e6aa0 (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.c | 44 |
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 | ||
2200 | vpif_dev_alloc_err: | 2202 | vpif_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); | |
2205 | vpif_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 | } |
2208 | vpif_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 | ||