Loading drivers/usb/dwc3/dwc3-msm.c +32 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,7 @@ struct dwc3_msm { struct notifier_block id_nb; struct notifier_block eud_event_nb; struct notifier_block host_restart_nb; struct notifier_block self_power_nb; struct notifier_block host_nb; bool xhci_ss_compliance_enable; Loading Loading @@ -296,6 +297,8 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, unsigned int value); static int dwc3_restart_usb_host_mode(struct notifier_block *nb, unsigned long event, void *ptr); static int dwc3_notify_pd_status(struct notifier_block *nb, unsigned long event, void *ptr); /** * Loading Loading @@ -3041,12 +3044,19 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc, int start_idx) if (!IS_ERR(edev)) { mdwc->extcon_vbus = edev; mdwc->vbus_nb.notifier_call = dwc3_msm_vbus_notifier; mdwc->self_power_nb.notifier_call = dwc3_notify_pd_status; ret = extcon_register_notifier(edev, EXTCON_USB, &mdwc->vbus_nb); if (ret < 0) { dev_err(mdwc->dev, "failed to register notifier for USB\n"); return ret; } ret = extcon_register_blocking_notifier(edev, EXTCON_USB, &mdwc->self_power_nb); if (ret < 0) { dev_err(mdwc->dev, "failed to register blocking notifier\n"); goto err1; } } /* Loading Loading @@ -4148,6 +4158,28 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on) return 0; } static int dwc3_notify_pd_status(struct notifier_block *nb, unsigned long event, void *ptr) { struct dwc3_msm *mdwc; struct dwc3 *dwc; int ret = 0; union extcon_property_value val; mdwc = container_of(nb, struct dwc3_msm, self_power_nb); dwc = platform_get_drvdata(mdwc->dwc3); ret = extcon_get_property(mdwc->extcon_vbus, EXTCON_USB, EXTCON_PROP_USB_PD_CONTRACT, &val); if (!ret) dwc->gadget.self_powered = val.intval; else dwc->gadget.self_powered = 0; return ret; } /* speed: 0 - USB_SPEED_HIGH, 1 - USB_SPEED_SUPER */ static int dwc3_restart_usb_host_mode(struct notifier_block *nb, unsigned long event, void *ptr) Loading drivers/usb/gadget/composite.c +4 −0 Original line number Diff line number Diff line Loading @@ -594,6 +594,10 @@ static int config_buf(struct usb_configuration *config, c->iConfiguration = config->iConfiguration; c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; c->bMaxPower = encode_bMaxPower(speed, config); if (config->cdev->gadget->self_powered) { c->bmAttributes |= USB_CONFIG_ATT_SELFPOWER; c->bMaxPower = 0; } /* There may be e.g. OTG descriptors */ if (config->descriptors) { Loading drivers/usb/pd/policy_engine.c +26 −0 Original line number Diff line number Diff line Loading @@ -533,6 +533,22 @@ static inline void start_usb_peripheral(struct usbpd *pd) extcon_set_state_sync(pd->extcon, EXTCON_USB, 1); } static void notify_pd_contract_status(struct usbpd *pd) { int ret = 0; union extcon_property_value val; if (!pd) return; val.intval = pd->in_explicit_contract; extcon_set_property(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_PD_CONTRACT, val); ret = extcon_blocking_sync(pd->extcon, EXTCON_USB, 0); if (ret) usbpd_err(&pd->dev, "err(%d) while notifying pd status", ret); } /** * This API allows client driver to request for releasing SS lanes. It should * not be called from atomic context. Loading Loading @@ -1252,6 +1268,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SRC_READY: pd->in_explicit_contract = true; notify_pd_contract_status(pd); if (pd->vdm_tx) kick_sm(pd, 0); Loading Loading @@ -1398,6 +1415,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SNK_READY: pd->in_explicit_contract = true; notify_pd_contract_status(pd); if (pd->vdm_tx) kick_sm(pd, 0); Loading Loading @@ -1433,6 +1451,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); pd->in_explicit_contract = false; notify_pd_contract_status(pd); /* * need to update PR bit in message header so that Loading Loading @@ -2012,6 +2031,7 @@ static void usbpd_sm(struct work_struct *w) pd->in_pr_swap = false; pd->pd_connected = false; pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->hard_reset_recvd = false; pd->caps_count = 0; pd->hard_reset_count = 0; Loading Loading @@ -2095,6 +2115,7 @@ static void usbpd_sm(struct work_struct *w) POWER_SUPPLY_PROP_PR_SWAP, &val); pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->selected_pdo = pd->requested_pdo = 0; pd->rdo = 0; rx_msg_cleanup(pd); Loading Loading @@ -2318,6 +2339,7 @@ static void usbpd_sm(struct work_struct *w) pd_send_hard_reset(pd); pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->rdo = 0; rx_msg_cleanup(pd); reset_vdm_state(pd); Loading Loading @@ -2768,6 +2790,7 @@ static void usbpd_sm(struct work_struct *w) pd_send_hard_reset(pd); pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->selected_pdo = pd->requested_pdo = 0; pd->rdo = 0; reset_vdm_state(pd); Loading Loading @@ -2799,6 +2822,7 @@ static void usbpd_sm(struct work_struct *w) power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PR_SWAP, &val); pd->in_explicit_contract = false; notify_pd_contract_status(pd); if (pd->vbus_enabled) { regulator_disable(pd->vbus); Loading Loading @@ -4005,6 +4029,8 @@ struct usbpd *usbpd_create(struct device *parent) /* Support reporting polarity and speed via properties */ extcon_set_property_capability(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY); extcon_set_property_capability(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_PD_CONTRACT); extcon_set_property_capability(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_SS); extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST, Loading include/linux/extcon.h +6 −1 Original line number Diff line number Diff line Loading @@ -113,14 +113,19 @@ * @type: integer (intval) * @value: 0 (USB/USB2) or 1 (USB3) * @default: 0 (USB/USB2) * -EXTCON_PROP_USB_PD_CONTRACT * @type: integer (intval) * @value: 0 (bus powered) or 1 (self powered) * @default: 0 (bus powered) * */ #define EXTCON_PROP_USB_VBUS 0 #define EXTCON_PROP_USB_TYPEC_POLARITY 1 #define EXTCON_PROP_USB_SS 2 #define EXTCON_PROP_USB_PD_CONTRACT 3 #define EXTCON_PROP_USB_MIN 0 #define EXTCON_PROP_USB_MAX 2 #define EXTCON_PROP_USB_MAX 3 #define EXTCON_PROP_USB_CNT (EXTCON_PROP_USB_MAX - EXTCON_PROP_USB_MIN + 1) /* Properties of EXTCON_TYPE_CHG. */ Loading include/linux/usb/gadget.h +1 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,7 @@ struct usb_gadget { u32 extra_buf_alloc; bool l1_supported; bool is_chipidea; bool self_powered; }; #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) Loading Loading
drivers/usb/dwc3/dwc3-msm.c +32 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,7 @@ struct dwc3_msm { struct notifier_block id_nb; struct notifier_block eud_event_nb; struct notifier_block host_restart_nb; struct notifier_block self_power_nb; struct notifier_block host_nb; bool xhci_ss_compliance_enable; Loading Loading @@ -296,6 +297,8 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event, unsigned int value); static int dwc3_restart_usb_host_mode(struct notifier_block *nb, unsigned long event, void *ptr); static int dwc3_notify_pd_status(struct notifier_block *nb, unsigned long event, void *ptr); /** * Loading Loading @@ -3041,12 +3044,19 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc, int start_idx) if (!IS_ERR(edev)) { mdwc->extcon_vbus = edev; mdwc->vbus_nb.notifier_call = dwc3_msm_vbus_notifier; mdwc->self_power_nb.notifier_call = dwc3_notify_pd_status; ret = extcon_register_notifier(edev, EXTCON_USB, &mdwc->vbus_nb); if (ret < 0) { dev_err(mdwc->dev, "failed to register notifier for USB\n"); return ret; } ret = extcon_register_blocking_notifier(edev, EXTCON_USB, &mdwc->self_power_nb); if (ret < 0) { dev_err(mdwc->dev, "failed to register blocking notifier\n"); goto err1; } } /* Loading Loading @@ -4148,6 +4158,28 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on) return 0; } static int dwc3_notify_pd_status(struct notifier_block *nb, unsigned long event, void *ptr) { struct dwc3_msm *mdwc; struct dwc3 *dwc; int ret = 0; union extcon_property_value val; mdwc = container_of(nb, struct dwc3_msm, self_power_nb); dwc = platform_get_drvdata(mdwc->dwc3); ret = extcon_get_property(mdwc->extcon_vbus, EXTCON_USB, EXTCON_PROP_USB_PD_CONTRACT, &val); if (!ret) dwc->gadget.self_powered = val.intval; else dwc->gadget.self_powered = 0; return ret; } /* speed: 0 - USB_SPEED_HIGH, 1 - USB_SPEED_SUPER */ static int dwc3_restart_usb_host_mode(struct notifier_block *nb, unsigned long event, void *ptr) Loading
drivers/usb/gadget/composite.c +4 −0 Original line number Diff line number Diff line Loading @@ -594,6 +594,10 @@ static int config_buf(struct usb_configuration *config, c->iConfiguration = config->iConfiguration; c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes; c->bMaxPower = encode_bMaxPower(speed, config); if (config->cdev->gadget->self_powered) { c->bmAttributes |= USB_CONFIG_ATT_SELFPOWER; c->bMaxPower = 0; } /* There may be e.g. OTG descriptors */ if (config->descriptors) { Loading
drivers/usb/pd/policy_engine.c +26 −0 Original line number Diff line number Diff line Loading @@ -533,6 +533,22 @@ static inline void start_usb_peripheral(struct usbpd *pd) extcon_set_state_sync(pd->extcon, EXTCON_USB, 1); } static void notify_pd_contract_status(struct usbpd *pd) { int ret = 0; union extcon_property_value val; if (!pd) return; val.intval = pd->in_explicit_contract; extcon_set_property(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_PD_CONTRACT, val); ret = extcon_blocking_sync(pd->extcon, EXTCON_USB, 0); if (ret) usbpd_err(&pd->dev, "err(%d) while notifying pd status", ret); } /** * This API allows client driver to request for releasing SS lanes. It should * not be called from atomic context. Loading Loading @@ -1252,6 +1268,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SRC_READY: pd->in_explicit_contract = true; notify_pd_contract_status(pd); if (pd->vdm_tx) kick_sm(pd, 0); Loading Loading @@ -1398,6 +1415,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) case PE_SNK_READY: pd->in_explicit_contract = true; notify_pd_contract_status(pd); if (pd->vdm_tx) kick_sm(pd, 0); Loading Loading @@ -1433,6 +1451,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state) POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val); pd->in_explicit_contract = false; notify_pd_contract_status(pd); /* * need to update PR bit in message header so that Loading Loading @@ -2012,6 +2031,7 @@ static void usbpd_sm(struct work_struct *w) pd->in_pr_swap = false; pd->pd_connected = false; pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->hard_reset_recvd = false; pd->caps_count = 0; pd->hard_reset_count = 0; Loading Loading @@ -2095,6 +2115,7 @@ static void usbpd_sm(struct work_struct *w) POWER_SUPPLY_PROP_PR_SWAP, &val); pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->selected_pdo = pd->requested_pdo = 0; pd->rdo = 0; rx_msg_cleanup(pd); Loading Loading @@ -2318,6 +2339,7 @@ static void usbpd_sm(struct work_struct *w) pd_send_hard_reset(pd); pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->rdo = 0; rx_msg_cleanup(pd); reset_vdm_state(pd); Loading Loading @@ -2768,6 +2790,7 @@ static void usbpd_sm(struct work_struct *w) pd_send_hard_reset(pd); pd->in_explicit_contract = false; notify_pd_contract_status(pd); pd->selected_pdo = pd->requested_pdo = 0; pd->rdo = 0; reset_vdm_state(pd); Loading Loading @@ -2799,6 +2822,7 @@ static void usbpd_sm(struct work_struct *w) power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PR_SWAP, &val); pd->in_explicit_contract = false; notify_pd_contract_status(pd); if (pd->vbus_enabled) { regulator_disable(pd->vbus); Loading Loading @@ -4005,6 +4029,8 @@ struct usbpd *usbpd_create(struct device *parent) /* Support reporting polarity and speed via properties */ extcon_set_property_capability(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY); extcon_set_property_capability(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_PD_CONTRACT); extcon_set_property_capability(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_SS); extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST, Loading
include/linux/extcon.h +6 −1 Original line number Diff line number Diff line Loading @@ -113,14 +113,19 @@ * @type: integer (intval) * @value: 0 (USB/USB2) or 1 (USB3) * @default: 0 (USB/USB2) * -EXTCON_PROP_USB_PD_CONTRACT * @type: integer (intval) * @value: 0 (bus powered) or 1 (self powered) * @default: 0 (bus powered) * */ #define EXTCON_PROP_USB_VBUS 0 #define EXTCON_PROP_USB_TYPEC_POLARITY 1 #define EXTCON_PROP_USB_SS 2 #define EXTCON_PROP_USB_PD_CONTRACT 3 #define EXTCON_PROP_USB_MIN 0 #define EXTCON_PROP_USB_MAX 2 #define EXTCON_PROP_USB_MAX 3 #define EXTCON_PROP_USB_CNT (EXTCON_PROP_USB_MAX - EXTCON_PROP_USB_MIN + 1) /* Properties of EXTCON_TYPE_CHG. */ Loading
include/linux/usb/gadget.h +1 −0 Original line number Diff line number Diff line Loading @@ -539,6 +539,7 @@ struct usb_gadget { u32 extra_buf_alloc; bool l1_supported; bool is_chipidea; bool self_powered; }; #define work_to_gadget(w) (container_of((w), struct usb_gadget, work)) Loading