Commit c4a0bbbd authored by Jisheng Zhang's avatar Jisheng Zhang Committed by Peter Chen

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: default avatarJisheng Zhang <jszhang@marvell.com>
Signed-off-by: default avatarPeter Chen <peter.chen@nxp.com>
parent 2ea659a9
...@@ -818,7 +818,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci) ...@@ -818,7 +818,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
{ {
ci_hdrc_gadget_destroy(ci); ci_hdrc_gadget_destroy(ci);
ci_hdrc_host_destroy(ci); ci_hdrc_host_destroy(ci);
if (ci->is_otg) if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
ci_hdrc_otg_destroy(ci); ci_hdrc_otg_destroy(ci);
} }
...@@ -977,27 +977,35 @@ static int ci_hdrc_probe(struct platform_device *pdev) ...@@ -977,27 +977,35 @@ static int ci_hdrc_probe(struct platform_device *pdev)
/* initialize role(s) before the interrupt is requested */ /* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) { if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
ret = ci_hdrc_host_init(ci); ret = ci_hdrc_host_init(ci);
if (ret) if (ret) {
if (ret == -ENXIO)
dev_info(dev, "doesn't support host\n"); dev_info(dev, "doesn't support host\n");
else
goto deinit_phy;
}
} }
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) { if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) {
ret = ci_hdrc_gadget_init(ci); ret = ci_hdrc_gadget_init(ci);
if (ret) if (ret) {
if (ret == -ENXIO)
dev_info(dev, "doesn't support gadget\n"); dev_info(dev, "doesn't support gadget\n");
else
goto deinit_host;
}
} }
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) { if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
dev_err(dev, "no supported roles\n"); dev_err(dev, "no supported roles\n");
ret = -ENODEV; ret = -ENODEV;
goto deinit_phy; goto deinit_gadget;
} }
if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) { if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
ret = ci_hdrc_otg_init(ci); ret = ci_hdrc_otg_init(ci);
if (ret) { if (ret) {
dev_err(dev, "init otg fails, ret = %d\n", ret); dev_err(dev, "init otg fails, ret = %d\n", ret);
goto stop; goto deinit_gadget;
} }
} }
...@@ -1067,7 +1075,12 @@ static int ci_hdrc_probe(struct platform_device *pdev) ...@@ -1067,7 +1075,12 @@ static int ci_hdrc_probe(struct platform_device *pdev)
remove_debug: remove_debug:
dbg_remove_files(ci); dbg_remove_files(ci);
stop: stop:
ci_role_destroy(ci); if (ci->is_otg && ci->roles[CI_ROLE_GADGET])
ci_hdrc_otg_destroy(ci);
deinit_gadget:
ci_hdrc_gadget_destroy(ci);
deinit_host:
ci_hdrc_host_destroy(ci);
deinit_phy: deinit_phy:
ci_usb_phy_exit(ci); ci_usb_phy_exit(ci);
ulpi_exit: ulpi_exit:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment