aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Rankin <rankincj@yahoo.com>2011-08-20 07:28:17 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-03 19:50:00 -0400
commit6c03e38b34dcfcdfa2f10cf984995a48f030f039 (patch)
tree96d32284bbc7adc3e423c4a7df1ee6f51520c864
parent38b61eb2dac06fdc42815b004e9824d8196cfcfb (diff)
[media] em28xx: clean up resources should init fail
This patch ensures that the em28xx_init_dev() function cleans up after itself, in the event that it fails. This isimportant because the struct em28xx will be deallocated if em28xx_init_dev() returns an error. [mchehab@redhat.com: Fix merge conflicts and simplify the goto labels] Signed-off-by: Chris Rankin <rankincj@yahoo.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c64
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c18
2 files changed, 37 insertions, 45 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 677db1454071..5fddcd0869de 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2806,7 +2806,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2806{ 2806{
2807 struct em28xx *dev = *devhandle; 2807 struct em28xx *dev = *devhandle;
2808 int retval; 2808 int retval;
2809 int errCode;
2810 2809
2811 dev->udev = udev; 2810 dev->udev = udev;
2812 mutex_init(&dev->ctrl_urb_lock); 2811 mutex_init(&dev->ctrl_urb_lock);
@@ -2883,8 +2882,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2883 } 2882 }
2884 2883
2885 if (dev->is_audio_only) { 2884 if (dev->is_audio_only) {
2886 errCode = em28xx_audio_setup(dev); 2885 retval = em28xx_audio_setup(dev);
2887 if (errCode) 2886 if (retval)
2888 return -ENODEV; 2887 return -ENODEV;
2889 em28xx_add_into_devlist(dev); 2888 em28xx_add_into_devlist(dev);
2890 em28xx_init_extension(dev); 2889 em28xx_init_extension(dev);
@@ -2903,7 +2902,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2903 /* Resets I2C speed */ 2902 /* Resets I2C speed */
2904 em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); 2903 em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed);
2905 if (retval < 0) { 2904 if (retval < 0) {
2906 em28xx_errdev("%s: em28xx_write_regs_req failed!" 2905 em28xx_errdev("%s: em28xx_write_reg failed!"
2907 " retval [%d]\n", 2906 " retval [%d]\n",
2908 __func__, retval); 2907 __func__, retval);
2909 return retval; 2908 return retval;
@@ -2917,12 +2916,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2917 } 2916 }
2918 2917
2919 /* register i2c bus */ 2918 /* register i2c bus */
2920 errCode = em28xx_i2c_register(dev); 2919 retval = em28xx_i2c_register(dev);
2921 if (errCode < 0) { 2920 if (retval < 0) {
2922 v4l2_device_unregister(&dev->v4l2_dev); 2921 em28xx_errdev("%s: em28xx_i2c_register - error [%d]!\n",
2923 em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n", 2922 __func__, retval);
2924 __func__, errCode); 2923 goto unregister_dev;
2925 return errCode;
2926 } 2924 }
2927 2925
2928 /* 2926 /*
@@ -2936,11 +2934,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2936 em28xx_card_setup(dev); 2934 em28xx_card_setup(dev);
2937 2935
2938 /* Configure audio */ 2936 /* Configure audio */
2939 errCode = em28xx_audio_setup(dev); 2937 retval = em28xx_audio_setup(dev);
2940 if (errCode < 0) { 2938 if (retval < 0) {
2941 v4l2_device_unregister(&dev->v4l2_dev); 2939 em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
2942 em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n", 2940 __func__, retval);
2943 __func__, errCode); 2941 goto fail;
2944 } 2942 }
2945 2943
2946 /* wake i2c devices */ 2944 /* wake i2c devices */
@@ -2954,31 +2952,28 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2954 2952
2955 if (dev->board.has_msp34xx) { 2953 if (dev->board.has_msp34xx) {
2956 /* Send a reset to other chips via gpio */ 2954 /* Send a reset to other chips via gpio */
2957 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); 2955 retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
2958 if (errCode < 0) { 2956 if (retval < 0) {
2959 em28xx_errdev("%s: em28xx_write_regs_req - " 2957 em28xx_errdev("%s: em28xx_write_reg - "
2960 "msp34xx(1) failed! errCode [%d]\n", 2958 "msp34xx(1) failed! error [%d]\n",
2961 __func__, errCode); 2959 __func__, retval);
2962 return errCode; 2960 goto fail;
2963 } 2961 }
2964 msleep(3); 2962 msleep(3);
2965 2963
2966 errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); 2964 retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
2967 if (errCode < 0) { 2965 if (retval < 0) {
2968 em28xx_errdev("%s: em28xx_write_regs_req - " 2966 em28xx_errdev("%s: em28xx_write_reg - "
2969 "msp34xx(2) failed! errCode [%d]\n", 2967 "msp34xx(2) failed! error [%d]\n",
2970 __func__, errCode); 2968 __func__, retval);
2971 return errCode; 2969 goto fail;
2972 } 2970 }
2973 msleep(3); 2971 msleep(3);
2974 } 2972 }
2975 2973
2976 em28xx_add_into_devlist(dev);
2977
2978 retval = em28xx_register_analog_devices(dev); 2974 retval = em28xx_register_analog_devices(dev);
2979 if (retval < 0) { 2975 if (retval < 0) {
2980 em28xx_release_resources(dev); 2976 goto fail;
2981 goto fail_reg_devices;
2982 } 2977 }
2983 2978
2984 em28xx_init_extension(dev); 2979 em28xx_init_extension(dev);
@@ -2988,7 +2983,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2988 2983
2989 return 0; 2984 return 0;
2990 2985
2991fail_reg_devices: 2986fail:
2987 em28xx_i2c_unregister(dev);
2988
2989unregister_dev:
2990 v4l2_device_unregister(&dev->v4l2_dev);
2991
2992 return retval; 2992 return retval;
2993} 2993}
2994 2994
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 57b1b5c6d885..ebff91709b57 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1195,13 +1195,6 @@ void em28xx_remove_from_devlist(struct em28xx *dev)
1195 mutex_unlock(&em28xx_devlist_mutex); 1195 mutex_unlock(&em28xx_devlist_mutex);
1196}; 1196};
1197 1197
1198void em28xx_add_into_devlist(struct em28xx *dev)
1199{
1200 mutex_lock(&em28xx_devlist_mutex);
1201 list_add_tail(&dev->devlist, &em28xx_devlist);
1202 mutex_unlock(&em28xx_devlist_mutex);
1203};
1204
1205/* 1198/*
1206 * Extension interface 1199 * Extension interface
1207 */ 1200 */
@@ -1239,14 +1232,13 @@ EXPORT_SYMBOL(em28xx_unregister_extension);
1239 1232
1240void em28xx_init_extension(struct em28xx *dev) 1233void em28xx_init_extension(struct em28xx *dev)
1241{ 1234{
1242 struct em28xx_ops *ops = NULL; 1235 const struct em28xx_ops *ops = NULL;
1243 1236
1244 mutex_lock(&em28xx_devlist_mutex); 1237 mutex_lock(&em28xx_devlist_mutex);
1245 if (!list_empty(&em28xx_extension_devlist)) { 1238 list_add_tail(&dev->devlist, &em28xx_devlist);
1246 list_for_each_entry(ops, &em28xx_extension_devlist, next) { 1239 list_for_each_entry(ops, &em28xx_extension_devlist, next) {
1247 if (ops->init) 1240 if (ops->init)
1248 ops->init(dev); 1241 ops->init(dev);
1249 }
1250 } 1242 }
1251 mutex_unlock(&em28xx_devlist_mutex); 1243 mutex_unlock(&em28xx_devlist_mutex);
1252} 1244}