Skip to content

Commit 99f7003

Browse files
aakoskinFelipe Balbi
authored andcommitted
USB: omap_udc: fix crashes on probe error and module removal
We currently crash if usb_add_gadget_udc_release() fails, since the udc->done is not initialized until in the remove function. Furthermore, on module removal the udc data is accessed although the release function is already triggered by usb_del_gadget_udc() early in the function. Fix by rewriting the release and remove functions, basically moving all the cleanup into the release function, and doing the completion only in the module removal case. The patch fixes omap_udc module probe with a failing gadged, and also allows the removal of omap_udc. Tested by running "modprobe omap_udc; modprobe -r omap_udc" in a loop. Signed-off-by: Aaro Koskinen <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 286afdd commit 99f7003

File tree

1 file changed

+19
-31
lines changed

1 file changed

+19
-31
lines changed

drivers/usb/gadget/udc/omap_udc.c

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,9 +2593,22 @@ omap_ep_setup(char *name, u8 addr, u8 type,
25932593

25942594
static void omap_udc_release(struct device *dev)
25952595
{
2596-
complete(udc->done);
2596+
pullup_disable(udc);
2597+
if (!IS_ERR_OR_NULL(udc->transceiver)) {
2598+
usb_put_phy(udc->transceiver);
2599+
udc->transceiver = NULL;
2600+
}
2601+
omap_writew(0, UDC_SYSCON1);
2602+
remove_proc_file();
2603+
if (udc->dc_clk) {
2604+
if (udc->clk_requested)
2605+
omap_udc_enable_clock(0);
2606+
clk_put(udc->hhc_clk);
2607+
clk_put(udc->dc_clk);
2608+
}
2609+
if (udc->done)
2610+
complete(udc->done);
25972611
kfree(udc);
2598-
udc = NULL;
25992612
}
26002613

26012614
static int
@@ -2900,12 +2913,8 @@ static int omap_udc_probe(struct platform_device *pdev)
29002913
}
29012914

29022915
create_proc_file();
2903-
status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
2904-
omap_udc_release);
2905-
if (!status)
2906-
return 0;
2907-
2908-
remove_proc_file();
2916+
return usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
2917+
omap_udc_release);
29092918

29102919
cleanup1:
29112920
kfree(udc);
@@ -2932,36 +2941,15 @@ static int omap_udc_remove(struct platform_device *pdev)
29322941
{
29332942
DECLARE_COMPLETION_ONSTACK(done);
29342943

2935-
if (!udc)
2936-
return -ENODEV;
2937-
2938-
usb_del_gadget_udc(&udc->gadget);
2939-
if (udc->driver)
2940-
return -EBUSY;
2941-
29422944
udc->done = &done;
29432945

2944-
pullup_disable(udc);
2945-
if (!IS_ERR_OR_NULL(udc->transceiver)) {
2946-
usb_put_phy(udc->transceiver);
2947-
udc->transceiver = NULL;
2948-
}
2949-
omap_writew(0, UDC_SYSCON1);
2950-
2951-
remove_proc_file();
2946+
usb_del_gadget_udc(&udc->gadget);
29522947

2953-
if (udc->dc_clk) {
2954-
if (udc->clk_requested)
2955-
omap_udc_enable_clock(0);
2956-
clk_put(udc->hhc_clk);
2957-
clk_put(udc->dc_clk);
2958-
}
2948+
wait_for_completion(&done);
29592949

29602950
release_mem_region(pdev->resource[0].start,
29612951
pdev->resource[0].end - pdev->resource[0].start + 1);
29622952

2963-
wait_for_completion(&done);
2964-
29652953
return 0;
29662954
}
29672955

0 commit comments

Comments
 (0)