Loading drivers/usb/dwc3/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -1696,6 +1696,7 @@ enum dwc3_notify_event { DWC3_CONTROLLER_NOTIFY_OTG_EVENT, DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT, DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER, DWC3_CONTROLLER_PULLUP, /* USB GSI event buffer related notification */ DWC3_GSI_EVT_BUF_ALLOC, Loading drivers/usb/dwc3/dwc3-msm.c +11 −4 Original line number Diff line number Diff line Loading @@ -498,6 +498,8 @@ struct dwc3_msm { struct usb_role_switch *role_switch; bool ss_release_called; int orientation_override; struct device_node *ss_redriver_node; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ Loading Loading @@ -2381,6 +2383,10 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, dev_dbg(mdwc->dev, "DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT received\n"); schedule_work(&mdwc->vbus_draw_work); break; case DWC3_CONTROLLER_PULLUP: dev_dbg(mdwc->dev, "DWC3_CONTROLLER_PULLUP received\n"); redriver_gadget_pullup(mdwc->ss_redriver_node, value); break; case DWC3_GSI_EVT_BUF_ALLOC: dev_dbg(mdwc->dev, "DWC3_GSI_EVT_BUF_ALLOC\n"); dwc3_gsi_event_buf_alloc(dwc); Loading Loading @@ -4108,7 +4114,6 @@ int dwc3_msm_release_ss_lane(struct device *dev) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = NULL; struct device_node *ssusb_redriver_node; if (mdwc == NULL) { dev_err(dev, "dwc3-msm is not initialized yet.\n"); Loading @@ -4126,9 +4131,7 @@ int dwc3_msm_release_ss_lane(struct device *dev) flush_work(&mdwc->resume_work); drain_workqueue(mdwc->sm_usb_wq); ssusb_redriver_node = of_parse_phandle(mdwc->dev->of_node, "ssusb_redriver", 0); redriver_release_usb_lanes(ssusb_redriver_node); redriver_release_usb_lanes(mdwc->ss_redriver_node); mdwc->ss_release_called = true; if (mdwc->id_state == DWC3_ID_GROUND) { Loading Loading @@ -4444,6 +4447,8 @@ static int dwc3_msm_probe(struct platform_device *pdev) mutex_init(&mdwc->suspend_resume_mutex); mdwc->ss_redriver_node = of_parse_phandle(node, "ssusb_redriver", 0); if (of_property_read_bool(node, "usb-role-switch")) { role_desc.fwnode = dev_fwnode(&pdev->dev); mdwc->role_switch = usb_role_switch_register(mdwc->dev, Loading Loading @@ -4527,6 +4532,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) put_dwc3: usb_role_switch_unregister(mdwc->role_switch); of_node_put(mdwc->ss_redriver_node); platform_device_put(mdwc->dwc3); for (i = 0; i < ARRAY_SIZE(mdwc->icc_paths); i++) icc_put(mdwc->icc_paths[i]); Loading @@ -4545,6 +4551,7 @@ static int dwc3_msm_remove(struct platform_device *pdev) int i, ret_pm; usb_role_switch_unregister(mdwc->role_switch); of_node_put(mdwc->ss_redriver_node); device_remove_file(&pdev->dev, &dev_attr_mode); device_remove_file(&pdev->dev, &dev_attr_speed); device_remove_file(&pdev->dev, &dev_attr_bus_vote); Loading drivers/usb/dwc3/gadget.c +2 −0 Original line number Diff line number Diff line Loading @@ -2232,6 +2232,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) if (is_on) dwc3_device_core_soft_reset(dwc); dwc3_notify_event(dwc, DWC3_CONTROLLER_PULLUP, is_on); spin_lock_irqsave(&dwc->lock, flags); if (dwc->ep0state != EP0_SETUP_PHASE) dbg_event(0xFF, "EP0 is not in SETUP phase\n", dwc->ep0state); Loading drivers/usb/misc/ssusb-redriver-nb7vpq904m.c +39 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ struct ssusb_redriver { u8 loss_match[CHAN_MODE_NUM][CHANNEL_NUM]; u8 flat_gain[CHAN_MODE_NUM][CHANNEL_NUM]; u8 gen_dev_val; struct dentry *debug_root; }; Loading Loading @@ -188,6 +190,8 @@ static void ssusb_redriver_gen_dev_set(struct ssusb_redriver *redriver) break; } redriver->gen_dev_val = val; redriver_i2c_reg_set(redriver, GEN_DEV_SET_REG, val); } Loading Loading @@ -530,6 +534,41 @@ int redriver_release_usb_lanes(struct device_node *node) } EXPORT_SYMBOL(redriver_release_usb_lanes); /* NOTE: DO NOT change mode in this funciton */ int redriver_gadget_pullup(struct device_node *node, int is_on) { struct ssusb_redriver *redriver; struct i2c_client *client; u8 val; if (!node) return -EINVAL; client = of_find_i2c_device_by_node(node); if (!client) return -EINVAL; redriver = i2c_get_clientdata(client); /* * when redriver connect to a USB hub, and do adb root operation, * due to redriver rx termination detection issue, * hub will not detct device logical removal. * workaround to temp disable/enable redriver when usb pullup operation. */ if (redriver->op_mode != OP_MODE_USB) return 0; val = redriver->gen_dev_val; if (!is_on) val &= ~CHIP_EN; redriver_i2c_reg_set(redriver, GEN_DEV_SET_REG, val); return 0; } EXPORT_SYMBOL(redriver_gadget_pullup); static void ssusb_redriver_orientation_gpio_init( struct ssusb_redriver *redriver) { Loading include/linux/usb/redriver.h +6 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #ifdef CONFIG_USB_REDRIVER int redriver_release_usb_lanes(struct device_node *node); int redriver_gadget_pullup(struct device_node *node, int is_on); #else Loading @@ -17,6 +18,11 @@ static inline int redriver_release_usb_lanes(struct device_node *node) return 0; } static inline int redriver_gadget_pullup(struct device_node *node, int is_on) { return 0; } #endif #endif /*__LINUX_USB_REDRIVER_H */ Loading
drivers/usb/dwc3/core.h +1 −0 Original line number Diff line number Diff line Loading @@ -1696,6 +1696,7 @@ enum dwc3_notify_event { DWC3_CONTROLLER_NOTIFY_OTG_EVENT, DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT, DWC3_CONTROLLER_NOTIFY_DISABLE_UPDXFER, DWC3_CONTROLLER_PULLUP, /* USB GSI event buffer related notification */ DWC3_GSI_EVT_BUF_ALLOC, Loading
drivers/usb/dwc3/dwc3-msm.c +11 −4 Original line number Diff line number Diff line Loading @@ -498,6 +498,8 @@ struct dwc3_msm { struct usb_role_switch *role_switch; bool ss_release_called; int orientation_override; struct device_node *ss_redriver_node; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ Loading Loading @@ -2381,6 +2383,10 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, dev_dbg(mdwc->dev, "DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT received\n"); schedule_work(&mdwc->vbus_draw_work); break; case DWC3_CONTROLLER_PULLUP: dev_dbg(mdwc->dev, "DWC3_CONTROLLER_PULLUP received\n"); redriver_gadget_pullup(mdwc->ss_redriver_node, value); break; case DWC3_GSI_EVT_BUF_ALLOC: dev_dbg(mdwc->dev, "DWC3_GSI_EVT_BUF_ALLOC\n"); dwc3_gsi_event_buf_alloc(dwc); Loading Loading @@ -4108,7 +4114,6 @@ int dwc3_msm_release_ss_lane(struct device *dev) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = NULL; struct device_node *ssusb_redriver_node; if (mdwc == NULL) { dev_err(dev, "dwc3-msm is not initialized yet.\n"); Loading @@ -4126,9 +4131,7 @@ int dwc3_msm_release_ss_lane(struct device *dev) flush_work(&mdwc->resume_work); drain_workqueue(mdwc->sm_usb_wq); ssusb_redriver_node = of_parse_phandle(mdwc->dev->of_node, "ssusb_redriver", 0); redriver_release_usb_lanes(ssusb_redriver_node); redriver_release_usb_lanes(mdwc->ss_redriver_node); mdwc->ss_release_called = true; if (mdwc->id_state == DWC3_ID_GROUND) { Loading Loading @@ -4444,6 +4447,8 @@ static int dwc3_msm_probe(struct platform_device *pdev) mutex_init(&mdwc->suspend_resume_mutex); mdwc->ss_redriver_node = of_parse_phandle(node, "ssusb_redriver", 0); if (of_property_read_bool(node, "usb-role-switch")) { role_desc.fwnode = dev_fwnode(&pdev->dev); mdwc->role_switch = usb_role_switch_register(mdwc->dev, Loading Loading @@ -4527,6 +4532,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) put_dwc3: usb_role_switch_unregister(mdwc->role_switch); of_node_put(mdwc->ss_redriver_node); platform_device_put(mdwc->dwc3); for (i = 0; i < ARRAY_SIZE(mdwc->icc_paths); i++) icc_put(mdwc->icc_paths[i]); Loading @@ -4545,6 +4551,7 @@ static int dwc3_msm_remove(struct platform_device *pdev) int i, ret_pm; usb_role_switch_unregister(mdwc->role_switch); of_node_put(mdwc->ss_redriver_node); device_remove_file(&pdev->dev, &dev_attr_mode); device_remove_file(&pdev->dev, &dev_attr_speed); device_remove_file(&pdev->dev, &dev_attr_bus_vote); Loading
drivers/usb/dwc3/gadget.c +2 −0 Original line number Diff line number Diff line Loading @@ -2232,6 +2232,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) if (is_on) dwc3_device_core_soft_reset(dwc); dwc3_notify_event(dwc, DWC3_CONTROLLER_PULLUP, is_on); spin_lock_irqsave(&dwc->lock, flags); if (dwc->ep0state != EP0_SETUP_PHASE) dbg_event(0xFF, "EP0 is not in SETUP phase\n", dwc->ep0state); Loading
drivers/usb/misc/ssusb-redriver-nb7vpq904m.c +39 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,8 @@ struct ssusb_redriver { u8 loss_match[CHAN_MODE_NUM][CHANNEL_NUM]; u8 flat_gain[CHAN_MODE_NUM][CHANNEL_NUM]; u8 gen_dev_val; struct dentry *debug_root; }; Loading Loading @@ -188,6 +190,8 @@ static void ssusb_redriver_gen_dev_set(struct ssusb_redriver *redriver) break; } redriver->gen_dev_val = val; redriver_i2c_reg_set(redriver, GEN_DEV_SET_REG, val); } Loading Loading @@ -530,6 +534,41 @@ int redriver_release_usb_lanes(struct device_node *node) } EXPORT_SYMBOL(redriver_release_usb_lanes); /* NOTE: DO NOT change mode in this funciton */ int redriver_gadget_pullup(struct device_node *node, int is_on) { struct ssusb_redriver *redriver; struct i2c_client *client; u8 val; if (!node) return -EINVAL; client = of_find_i2c_device_by_node(node); if (!client) return -EINVAL; redriver = i2c_get_clientdata(client); /* * when redriver connect to a USB hub, and do adb root operation, * due to redriver rx termination detection issue, * hub will not detct device logical removal. * workaround to temp disable/enable redriver when usb pullup operation. */ if (redriver->op_mode != OP_MODE_USB) return 0; val = redriver->gen_dev_val; if (!is_on) val &= ~CHIP_EN; redriver_i2c_reg_set(redriver, GEN_DEV_SET_REG, val); return 0; } EXPORT_SYMBOL(redriver_gadget_pullup); static void ssusb_redriver_orientation_gpio_init( struct ssusb_redriver *redriver) { Loading
include/linux/usb/redriver.h +6 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #ifdef CONFIG_USB_REDRIVER int redriver_release_usb_lanes(struct device_node *node); int redriver_gadget_pullup(struct device_node *node, int is_on); #else Loading @@ -17,6 +18,11 @@ static inline int redriver_release_usb_lanes(struct device_node *node) return 0; } static inline int redriver_gadget_pullup(struct device_node *node, int is_on) { return 0; } #endif #endif /*__LINUX_USB_REDRIVER_H */