summaryrefslogtreecommitdiff
path: root/drivers/usb/chipidea/core.c
diff options
context:
space:
mode:
authorJisheng Zhang <jszhang@marvell.com>2017-04-26 11:59:34 +0300
committerPeter Chen <peter.chen@nxp.com>2017-05-18 03:55:22 +0300
commitc4a0bbbdb7f6e3c37fa6deb3ef28c5ed99da6175 (patch)
tree1830586f3287e1a393115c05211103ee986185f5 /drivers/usb/chipidea/core.c
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
downloadlinux-c4a0bbbdb7f6e3c37fa6deb3ef28c5ed99da6175.tar.xz
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 <jszhang@marvell.com> Signed-off-by: Peter Chen <peter.chen@nxp.com>
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r--drivers/usb/chipidea/core.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 9e217b1361ea..4cad8a9b6f17 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -818,7 +818,7 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)
{
ci_hdrc_gadget_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);
}
@@ -977,27 +977,35 @@ static int ci_hdrc_probe(struct platform_device *pdev)
/* initialize role(s) before the interrupt is requested */
if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) {
ret = ci_hdrc_host_init(ci);
- if (ret)
- dev_info(dev, "doesn't support host\n");
+ if (ret) {
+ if (ret == -ENXIO)
+ 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) {
ret = ci_hdrc_gadget_init(ci);
- if (ret)
- dev_info(dev, "doesn't support gadget\n");
+ if (ret) {
+ if (ret == -ENXIO)
+ dev_info(dev, "doesn't support gadget\n");
+ else
+ goto deinit_host;
+ }
}
if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
dev_err(dev, "no supported roles\n");
ret = -ENODEV;
- goto deinit_phy;
+ goto deinit_gadget;
}
if (ci->is_otg && ci->roles[CI_ROLE_GADGET]) {
ret = ci_hdrc_otg_init(ci);
if (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)
remove_debug:
dbg_remove_files(ci);
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:
ci_usb_phy_exit(ci);
ulpi_exit: