@@ -544,6 +544,8 @@ static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
544544 if (!IS_ERR_OR_NULL (port -> usb_role_sw )) {
545545 of_platform_depopulate (& port -> dev );
546546 usb_role_switch_unregister (port -> usb_role_sw );
547+ cancel_work_sync (& port -> usb_phy_work );
548+ usb_remove_phy (& port -> usb_phy );
547549 }
548550
549551 device_unregister (& port -> dev );
@@ -562,18 +564,76 @@ static const char * const usb_roles[] = {
562564 [USB_ROLE_DEVICE ] = "device" ,
563565};
564566
567+ static enum usb_phy_events to_usb_phy_event (enum usb_role role )
568+ {
569+ switch (role ) {
570+ case USB_ROLE_DEVICE :
571+ return USB_EVENT_VBUS ;
572+
573+ case USB_ROLE_HOST :
574+ return USB_EVENT_ID ;
575+
576+ default :
577+ return USB_EVENT_NONE ;
578+ }
579+ }
580+
581+ static void tegra_xusb_usb_phy_work (struct work_struct * work )
582+ {
583+ struct tegra_xusb_port * port = container_of (work ,
584+ struct tegra_xusb_port ,
585+ usb_phy_work );
586+ enum usb_role role = usb_role_switch_get_role (port -> usb_role_sw );
587+
588+ usb_phy_set_event (& port -> usb_phy , to_usb_phy_event (role ));
589+
590+ dev_dbg (& port -> dev , "%s(): calling notifier for role %s\n" , __func__ ,
591+ usb_roles [role ]);
592+
593+ atomic_notifier_call_chain (& port -> usb_phy .notifier , 0 , & port -> usb_phy );
594+ }
595+
565596static int tegra_xusb_role_sw_set (struct usb_role_switch * sw ,
566597 enum usb_role role )
567598{
568599 struct tegra_xusb_port * port = usb_role_switch_get_drvdata (sw );
569600
570601 dev_dbg (& port -> dev , "%s(): role %s\n" , __func__ , usb_roles [role ]);
571602
603+ schedule_work (& port -> usb_phy_work );
604+
605+ return 0 ;
606+ }
607+
608+ static int tegra_xusb_set_peripheral (struct usb_otg * otg ,
609+ struct usb_gadget * gadget )
610+ {
611+ struct tegra_xusb_port * port = container_of (otg -> usb_phy ,
612+ struct tegra_xusb_port ,
613+ usb_phy );
614+
615+ if (gadget != NULL )
616+ schedule_work (& port -> usb_phy_work );
617+
572618 return 0 ;
573619}
574620
621+ static int tegra_xusb_set_host (struct usb_otg * otg , struct usb_bus * host )
622+ {
623+ struct tegra_xusb_port * port = container_of (otg -> usb_phy ,
624+ struct tegra_xusb_port ,
625+ usb_phy );
626+
627+ if (host != NULL )
628+ schedule_work (& port -> usb_phy_work );
629+
630+ return 0 ;
631+ }
632+
633+
575634static int tegra_xusb_setup_usb_role_switch (struct tegra_xusb_port * port )
576635{
636+ struct tegra_xusb_lane * lane ;
577637 struct usb_role_switch_desc role_sx_desc = {
578638 .fwnode = dev_fwnode (& port -> dev ),
579639 .set = tegra_xusb_role_sw_set ,
@@ -600,8 +660,32 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
600660 return err ;
601661 }
602662
663+ INIT_WORK (& port -> usb_phy_work , tegra_xusb_usb_phy_work );
603664 usb_role_switch_set_drvdata (port -> usb_role_sw , port );
604665
666+ port -> usb_phy .otg = devm_kzalloc (& port -> dev , sizeof (struct usb_otg ),
667+ GFP_KERNEL );
668+ if (!port -> usb_phy .otg )
669+ return - ENOMEM ;
670+
671+ lane = tegra_xusb_find_lane (port -> padctl , "usb2" , port -> index );
672+
673+ /*
674+ * Assign phy dev to usb-phy dev. Host/device drivers can use phy
675+ * reference to retrieve usb-phy details.
676+ */
677+ port -> usb_phy .dev = & lane -> pad -> lanes [port -> index ]-> dev ;
678+ port -> usb_phy .dev -> driver = port -> padctl -> dev -> driver ;
679+ port -> usb_phy .otg -> usb_phy = & port -> usb_phy ;
680+ port -> usb_phy .otg -> set_peripheral = tegra_xusb_set_peripheral ;
681+ port -> usb_phy .otg -> set_host = tegra_xusb_set_host ;
682+
683+ err = usb_add_phy_dev (& port -> usb_phy );
684+ if (err < 0 ) {
685+ dev_err (& port -> dev , "Failed to add USB PHY: %d\n" , err );
686+ return err ;
687+ }
688+
605689 /* populate connector entry */
606690 of_platform_populate (port -> dev .of_node , NULL , NULL , & port -> dev );
607691
0 commit comments