Loading drivers/usb/phy/phy-msm-usb.c +57 −20 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <linux/pm_wakeup.h> #include <linux/reset.h> #include <linux/extcon.h> #include <linux/power_supply.h> #include <soc/qcom/scm.h> #include <linux/usb.h> Loading Loading @@ -3717,6 +3718,46 @@ static int msm_otg_extcon_register(struct msm_otg *motg) return ret; } static void msm_otg_handle_initial_extcon(struct msm_otg *motg) { if (motg->extcon_vbus && extcon_get_cable_state_(motg->extcon_vbus, EXTCON_USB)) msm_otg_vbus_notifier(&motg->vbus_nb, true, motg->extcon_vbus); if (motg->extcon_id && extcon_get_cable_state_(motg->extcon_id, EXTCON_USB_HOST)) msm_otg_id_notifier(&motg->id_nb, true, motg->extcon_id); } static void msm_otg_extcon_register_work(struct work_struct *w) { struct msm_otg *motg = container_of(w, struct msm_otg, extcon_register_work); power_supply_unreg_notifier(&motg->psy_nb); if (msm_otg_extcon_register(motg)) { dev_err(&motg->pdev->dev, "failed to register extcon\n"); return; } msm_otg_handle_initial_extcon(motg); } static int msm_otg_psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) { struct msm_otg *motg = container_of(nb, struct msm_otg, psy_nb); if (strcmp(((struct power_supply *)ptr)->desc->name, "usb") || evt != PSY_EVENT_PROP_CHANGED) return 0; queue_work(motg->otg_wq, &motg->extcon_register_work); return 0; } struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; Loading Loading @@ -4266,6 +4307,7 @@ static int msm_otg_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&motg->perf_vote_work, msm_otg_perf_vote_work); INIT_DELAYED_WORK(&motg->sdp_check, check_for_sdp_connection); INIT_WORK(&motg->notify_charger_work, msm_otg_notify_charger_work); INIT_WORK(&motg->extcon_register_work, msm_otg_extcon_register_work); motg->otg_wq = alloc_ordered_workqueue("k_otg", 0); if (!motg->otg_wq) { pr_err("%s: Unable to create workqueue otg_wq\n", Loading Loading @@ -4474,21 +4516,20 @@ static int msm_otg_probe(struct platform_device *pdev) } } psy = power_supply_get_by_name("usb"); if (!psy) dev_warn(&pdev->dev, "Could not get usb power_supply\n"); /* * Try to register extcon handle from probe; by this time USB psy may or * may not have been registered. If this fails, then wait for the USB * psy to get registered which will again try to register extcon via * notifier call. */ ret = msm_otg_extcon_register(motg); if (ret) goto put_psy; if (motg->extcon_vbus && extcon_get_cable_state_(motg->extcon_vbus, EXTCON_USB)) msm_otg_vbus_notifier(&motg->vbus_nb, true, motg->extcon_vbus); if (motg->extcon_id && extcon_get_cable_state_(motg->extcon_id, EXTCON_USB_HOST)) msm_otg_id_notifier(&motg->id_nb, true, motg->extcon_id); if (ret) { dev_dbg(&pdev->dev, "Registering PSY notifier for extcon\n"); motg->psy_nb.notifier_call = msm_otg_psy_changed; power_supply_reg_notifier(&motg->psy_nb); } else { msm_otg_handle_initial_extcon(motg); } if (gpio_is_valid(motg->pdata->hub_reset_gpio)) { ret = devm_gpio_request(&pdev->dev, Loading Loading @@ -4528,11 +4569,6 @@ static int msm_otg_probe(struct platform_device *pdev) return 0; put_psy: if (psy) power_supply_put(psy); if (pdev->dev.of_node) msm_otg_setup_devices(pdev, motg->pdata->mode, false); remove_cdev: pm_runtime_disable(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_dpdm_pulldown_enable); Loading Loading @@ -4600,7 +4636,7 @@ static int msm_otg_remove(struct platform_device *pdev) return -EBUSY; unregister_pm_notifier(&motg->pm_notify); power_supply_unreg_notifier(&motg->psy_nb); extcon_unregister_notifier(motg->extcon_id, EXTCON_USB_HOST, &motg->id_nb); extcon_unregister_notifier(motg->extcon_vbus, EXTCON_USB, Loading @@ -4618,6 +4654,7 @@ static int msm_otg_remove(struct platform_device *pdev) msm_otg_perf_vote_update(motg, false); cancel_work_sync(&motg->sm_work); cancel_work_sync(&motg->notify_charger_work); cancel_work_sync(&motg->extcon_register_work); destroy_workqueue(motg->otg_wq); pm_runtime_resume(&pdev->dev); Loading include/linux/usb/msm_hsusb.h +4 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,8 @@ enum usb_id_state { nominal mode. * @sdp_check: SDP detection work in case of USB_FLOAT power supply * @notify_charger_work: Charger notification work. * @extcon_register_work: Extcon registration work. * @psy_nb: Notification callback for PSY registration. */ struct msm_otg { struct usb_phy phy; Loading Loading @@ -313,6 +315,8 @@ struct msm_otg { struct delayed_work perf_vote_work; struct delayed_work sdp_check; struct work_struct notify_charger_work; struct work_struct extcon_register_work; struct notifier_block psy_nb; }; struct ci13xxx_platform_data { Loading Loading
drivers/usb/phy/phy-msm-usb.c +57 −20 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ #include <linux/pm_wakeup.h> #include <linux/reset.h> #include <linux/extcon.h> #include <linux/power_supply.h> #include <soc/qcom/scm.h> #include <linux/usb.h> Loading Loading @@ -3717,6 +3718,46 @@ static int msm_otg_extcon_register(struct msm_otg *motg) return ret; } static void msm_otg_handle_initial_extcon(struct msm_otg *motg) { if (motg->extcon_vbus && extcon_get_cable_state_(motg->extcon_vbus, EXTCON_USB)) msm_otg_vbus_notifier(&motg->vbus_nb, true, motg->extcon_vbus); if (motg->extcon_id && extcon_get_cable_state_(motg->extcon_id, EXTCON_USB_HOST)) msm_otg_id_notifier(&motg->id_nb, true, motg->extcon_id); } static void msm_otg_extcon_register_work(struct work_struct *w) { struct msm_otg *motg = container_of(w, struct msm_otg, extcon_register_work); power_supply_unreg_notifier(&motg->psy_nb); if (msm_otg_extcon_register(motg)) { dev_err(&motg->pdev->dev, "failed to register extcon\n"); return; } msm_otg_handle_initial_extcon(motg); } static int msm_otg_psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr) { struct msm_otg *motg = container_of(nb, struct msm_otg, psy_nb); if (strcmp(((struct power_supply *)ptr)->desc->name, "usb") || evt != PSY_EVENT_PROP_CHANGED) return 0; queue_work(motg->otg_wq, &motg->extcon_register_work); return 0; } struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; Loading Loading @@ -4266,6 +4307,7 @@ static int msm_otg_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&motg->perf_vote_work, msm_otg_perf_vote_work); INIT_DELAYED_WORK(&motg->sdp_check, check_for_sdp_connection); INIT_WORK(&motg->notify_charger_work, msm_otg_notify_charger_work); INIT_WORK(&motg->extcon_register_work, msm_otg_extcon_register_work); motg->otg_wq = alloc_ordered_workqueue("k_otg", 0); if (!motg->otg_wq) { pr_err("%s: Unable to create workqueue otg_wq\n", Loading Loading @@ -4474,21 +4516,20 @@ static int msm_otg_probe(struct platform_device *pdev) } } psy = power_supply_get_by_name("usb"); if (!psy) dev_warn(&pdev->dev, "Could not get usb power_supply\n"); /* * Try to register extcon handle from probe; by this time USB psy may or * may not have been registered. If this fails, then wait for the USB * psy to get registered which will again try to register extcon via * notifier call. */ ret = msm_otg_extcon_register(motg); if (ret) goto put_psy; if (motg->extcon_vbus && extcon_get_cable_state_(motg->extcon_vbus, EXTCON_USB)) msm_otg_vbus_notifier(&motg->vbus_nb, true, motg->extcon_vbus); if (motg->extcon_id && extcon_get_cable_state_(motg->extcon_id, EXTCON_USB_HOST)) msm_otg_id_notifier(&motg->id_nb, true, motg->extcon_id); if (ret) { dev_dbg(&pdev->dev, "Registering PSY notifier for extcon\n"); motg->psy_nb.notifier_call = msm_otg_psy_changed; power_supply_reg_notifier(&motg->psy_nb); } else { msm_otg_handle_initial_extcon(motg); } if (gpio_is_valid(motg->pdata->hub_reset_gpio)) { ret = devm_gpio_request(&pdev->dev, Loading Loading @@ -4528,11 +4569,6 @@ static int msm_otg_probe(struct platform_device *pdev) return 0; put_psy: if (psy) power_supply_put(psy); if (pdev->dev.of_node) msm_otg_setup_devices(pdev, motg->pdata->mode, false); remove_cdev: pm_runtime_disable(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_dpdm_pulldown_enable); Loading Loading @@ -4600,7 +4636,7 @@ static int msm_otg_remove(struct platform_device *pdev) return -EBUSY; unregister_pm_notifier(&motg->pm_notify); power_supply_unreg_notifier(&motg->psy_nb); extcon_unregister_notifier(motg->extcon_id, EXTCON_USB_HOST, &motg->id_nb); extcon_unregister_notifier(motg->extcon_vbus, EXTCON_USB, Loading @@ -4618,6 +4654,7 @@ static int msm_otg_remove(struct platform_device *pdev) msm_otg_perf_vote_update(motg, false); cancel_work_sync(&motg->sm_work); cancel_work_sync(&motg->notify_charger_work); cancel_work_sync(&motg->extcon_register_work); destroy_workqueue(motg->otg_wq); pm_runtime_resume(&pdev->dev); Loading
include/linux/usb/msm_hsusb.h +4 −0 Original line number Diff line number Diff line Loading @@ -180,6 +180,8 @@ enum usb_id_state { nominal mode. * @sdp_check: SDP detection work in case of USB_FLOAT power supply * @notify_charger_work: Charger notification work. * @extcon_register_work: Extcon registration work. * @psy_nb: Notification callback for PSY registration. */ struct msm_otg { struct usb_phy phy; Loading Loading @@ -313,6 +315,8 @@ struct msm_otg { struct delayed_work perf_vote_work; struct delayed_work sdp_check; struct work_struct notify_charger_work; struct work_struct extcon_register_work; struct notifier_block psy_nb; }; struct ci13xxx_platform_data { Loading