diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index 158c8e28ed2c..753c96bdbc63 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -1577,6 +1577,8 @@ int gspca_dev_probe2(struct usb_interface *intf, v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); v4l2_device_unregister(&gspca_dev->v4l2_dev); kfree(gspca_dev->usb_buf); + if (sd_desc->unconfig) + sd_desc->unconfig(gspca_dev); kfree(gspca_dev); return ret; } diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h index b0ced2e14006..9f9a2be0a5ee 100644 --- a/drivers/media/usb/gspca/gspca.h +++ b/drivers/media/usb/gspca/gspca.h @@ -108,6 +108,7 @@ struct sd_desc { cam_op start; /* called on stream on after URBs creation */ cam_pkt_op pkt_scan; /* optional operations */ + cam_v_op unconfig; /* called to remove allocations on probe failures */ cam_op isoc_init; /* called on stream on before getting the EP */ cam_op isoc_nego; /* called when URB submit failed with NOSPC */ cam_v_op stopN; /* called on stream off - main alt */ diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 95673fc0a99c..8faef2f519c0 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -528,6 +528,7 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, static int stv06xx_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id); +static void stv06xx_unconfig(struct gspca_dev *gspca_dev); /* sub-driver description */ static const struct sd_desc sd_desc = { @@ -540,6 +541,7 @@ static const struct sd_desc sd_desc = { .pkt_scan = stv06xx_pkt_scan, .isoc_init = stv06xx_isoc_init, .isoc_nego = stv06xx_isoc_nego, + .unconfig = stv06xx_unconfig, #if IS_ENABLED(CONFIG_INPUT) .int_pkt_scan = sd_int_pkt_scan, #endif @@ -583,7 +585,13 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, return -ENODEV; } +/* deallocate any fields of sd and sd on probe/config failures */ +static void stv06xx_unconfig(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + kfree(sd->sensor_priv); +} /* -- module initialisation -- */ static const struct usb_device_id device_table[] = {