Skip to content

Commit c4a0bbb

Browse files
Jisheng ZhangPeter Chen
authored andcommitted
usb: chipidea: properly handle host or gadget initialization failure
If ci_hdrc_host_init() or ci_hdrc_gadget_init() returns error and the error != -ENXIO, as Peter pointed out, "it stands for initialization for host or gadget has failed", so we'd better return failure rather continue. And before destroying the otg, i.e ci_hdrc_otg_destroy(ci), we should also check ci->roles[CI_ROLE_GADGET]. Signed-off-by: Jisheng Zhang <[email protected]> Signed-off-by: Peter Chen <[email protected]>
1 parent 2ea659a commit c4a0bbb

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

drivers/usb/chipidea/core.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
818818
{
819819
ci_hdrc_gadget_destroy(ci);
820820
ci_hdrc_host_destroy(ci);
821-
if (ci->is_otg)
821+
if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
822822
ci_hdrc_otg_destroy(ci);
823823
}
824824

@@ -977,27 +977,35 @@ static int ci_hdrc_probe(struct platform_device *pdev)
977977
/* initialize role(s) before the interrupt is requested */
978978
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
979979
ret = ci_hdrc_host_init(ci);
980-
if (ret)
981-
dev_info(dev, "doesn't support host\n");
980+
if (ret) {
981+
if (ret == -ENXIO)
982+
dev_info(dev, "doesn't support host\n");
983+
else
984+
goto deinit_phy;
985+
}
982986
}
983987

984988
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
985989
ret = ci_hdrc_gadget_init(ci);
986-
if (ret)
987-
dev_info(dev, "doesn't support gadget\n");
990+
if (ret) {
991+
if (ret == -ENXIO)
992+
dev_info(dev, "doesn't support gadget\n");
993+
else
994+
goto deinit_host;
995+
}
988996
}
989997

990998
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
991999
dev_err(dev, "no supported roles\n");
9921000
ret = -ENODEV;
993-
goto deinit_phy;
1001+
goto deinit_gadget;
9941002
}
9951003

9961004
if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
9971005
ret = ci_hdrc_otg_init(ci);
9981006
if (ret) {
9991007
dev_err(dev, "init otg fails, ret = %d\n", ret);
1000-
goto stop;
1008+
goto deinit_gadget;
10011009
}
10021010
}
10031011

@@ -1067,7 +1075,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
10671075
remove_debug:
10681076
dbg_remove_files(ci);
10691077
stop:
1070-
ci_role_destroy(ci);
1078+
if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
1079+
ci_hdrc_otg_destroy(ci);
1080+
deinit_gadget:
1081+
ci_hdrc_gadget_destroy(ci);
1082+
deinit_host:
1083+
ci_hdrc_host_destroy(ci);
10711084
deinit_phy:
10721085
ci_usb_phy_exit(ci);
10731086
ulpi_exit:

0 commit comments

Comments
 (0)