@@ -544,6 +544,8 @@ static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
544
544
if (!IS_ERR_OR_NULL (port -> usb_role_sw )) {
545
545
of_platform_depopulate (& port -> dev );
546
546
usb_role_switch_unregister (port -> usb_role_sw );
547
+ cancel_work_sync (& port -> usb_phy_work );
548
+ usb_remove_phy (& port -> usb_phy );
547
549
}
548
550
549
551
device_unregister (& port -> dev );
@@ -562,18 +564,76 @@ static const char * const usb_roles[] = {
562
564
[USB_ROLE_DEVICE ] = "device" ,
563
565
};
564
566
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
+
565
596
static int tegra_xusb_role_sw_set (struct usb_role_switch * sw ,
566
597
enum usb_role role )
567
598
{
568
599
struct tegra_xusb_port * port = usb_role_switch_get_drvdata (sw );
569
600
570
601
dev_dbg (& port -> dev , "%s(): role %s\n" , __func__ , usb_roles [role ]);
571
602
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
+
572
618
return 0 ;
573
619
}
574
620
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
+
575
634
static int tegra_xusb_setup_usb_role_switch (struct tegra_xusb_port * port )
576
635
{
636
+ struct tegra_xusb_lane * lane ;
577
637
struct usb_role_switch_desc role_sx_desc = {
578
638
.fwnode = dev_fwnode (& port -> dev ),
579
639
.set = tegra_xusb_role_sw_set ,
@@ -600,8 +660,32 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
600
660
return err ;
601
661
}
602
662
663
+ INIT_WORK (& port -> usb_phy_work , tegra_xusb_usb_phy_work );
603
664
usb_role_switch_set_drvdata (port -> usb_role_sw , port );
604
665
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
+
605
689
/* populate connector entry */
606
690
of_platform_populate (port -> dev .of_node , NULL , NULL , & port -> dev );
607
691
0 commit comments