Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: chipidea: handle single role for usb role class

If usb port is configed to be single role, but usb role class
is trying to set unavailable role, don't try to do role change.

Signed-off-by: Jun Li <jun.li@nxp.com>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Link: https://lore.kernel.org/r/20200122014639.22667-2-peter.chen@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jun Li and committed by
Greg Kroah-Hartman
27bf5be8 1e31d3ca

+13 -1
+10
drivers/usb/chipidea/ci.h
··· 302 302 return USB_ROLE_NONE; 303 303 } 304 304 305 + static inline enum ci_role usb_role_to_ci_role(enum usb_role role) 306 + { 307 + if (role == USB_ROLE_HOST) 308 + return CI_ROLE_HOST; 309 + else if (role == USB_ROLE_DEVICE) 310 + return CI_ROLE_GADGET; 311 + else 312 + return CI_ROLE_END; 313 + } 314 + 305 315 /** 306 316 * hw_read_id_reg: reads from a identification register 307 317 * @ci: the controller
+3 -1
drivers/usb/chipidea/core.c
··· 618 618 struct ci_hdrc *ci = dev_get_drvdata(dev); 619 619 struct ci_hdrc_cable *cable = NULL; 620 620 enum usb_role current_role = ci_role_to_usb_role(ci); 621 + enum ci_role ci_role = usb_role_to_ci_role(role); 621 622 unsigned long flags; 622 623 623 - if (current_role == role) 624 + if ((ci_role != CI_ROLE_END && !ci->roles[ci_role]) || 625 + (current_role == role)) 624 626 return 0; 625 627 626 628 pm_runtime_get_sync(ci->dev);