@@ -482,14 +482,16 @@ struct tegra_xudc {
482
482
bool device_mode ;
483
483
struct work_struct usb_role_sw_work ;
484
484
485
- struct phy * usb3_phy ;
486
- struct phy * utmi_phy ;
485
+ struct phy * * usb3_phy ;
486
+ struct phy * curr_usb3_phy ;
487
+ struct phy * * utmi_phy ;
488
+ struct phy * curr_utmi_phy ;
487
489
488
490
struct tegra_xudc_save_regs saved_regs ;
489
491
bool suspended ;
490
492
bool powergated ;
491
493
492
- struct usb_phy * usbphy ;
494
+ struct usb_phy * * usbphy ;
493
495
struct notifier_block vbus_nb ;
494
496
495
497
struct completion disconnect_complete ;
@@ -521,6 +523,7 @@ struct tegra_xudc_soc {
521
523
unsigned int num_supplies ;
522
524
const char * const * clock_names ;
523
525
unsigned int num_clks ;
526
+ unsigned int num_phys ;
524
527
bool u1_enable ;
525
528
bool u2_enable ;
526
529
bool lpm_enable ;
@@ -602,17 +605,18 @@ static void tegra_xudc_device_mode_on(struct tegra_xudc *xudc)
602
605
603
606
pm_runtime_get_sync (xudc -> dev );
604
607
605
- err = phy_power_on (xudc -> utmi_phy );
608
+ err = phy_power_on (xudc -> curr_utmi_phy );
606
609
if (err < 0 )
607
610
dev_err (xudc -> dev , "utmi power on failed %d\n" , err );
608
611
609
- err = phy_power_on (xudc -> usb3_phy );
612
+ err = phy_power_on (xudc -> curr_usb3_phy );
610
613
if (err < 0 )
611
614
dev_err (xudc -> dev , "usb3 phy power on failed %d\n" , err );
612
615
613
616
dev_dbg (xudc -> dev , "device mode on\n" );
614
617
615
- phy_set_mode_ext (xudc -> utmi_phy , PHY_MODE_USB_OTG , USB_ROLE_DEVICE );
618
+ phy_set_mode_ext (xudc -> curr_utmi_phy , PHY_MODE_USB_OTG ,
619
+ USB_ROLE_DEVICE );
616
620
}
617
621
618
622
static void tegra_xudc_device_mode_off (struct tegra_xudc * xudc )
@@ -627,7 +631,7 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
627
631
628
632
reinit_completion (& xudc -> disconnect_complete );
629
633
630
- phy_set_mode_ext (xudc -> utmi_phy , PHY_MODE_USB_OTG , USB_ROLE_NONE );
634
+ phy_set_mode_ext (xudc -> curr_utmi_phy , PHY_MODE_USB_OTG , USB_ROLE_NONE );
631
635
632
636
pls = (xudc_readl (xudc , PORTSC ) & PORTSC_PLS_MASK ) >>
633
637
PORTSC_PLS_SHIFT ;
@@ -652,11 +656,11 @@ static void tegra_xudc_device_mode_off(struct tegra_xudc *xudc)
652
656
/* Make sure interrupt handler has completed before powergating. */
653
657
synchronize_irq (xudc -> irq );
654
658
655
- err = phy_power_off (xudc -> utmi_phy );
659
+ err = phy_power_off (xudc -> curr_utmi_phy );
656
660
if (err < 0 )
657
661
dev_err (xudc -> dev , "utmi_phy power off failed %d\n" , err );
658
662
659
- err = phy_power_off (xudc -> usb3_phy );
663
+ err = phy_power_off (xudc -> curr_usb3_phy );
660
664
if (err < 0 )
661
665
dev_err (xudc -> dev , "usb3_phy power off failed %d\n" , err );
662
666
@@ -674,12 +678,27 @@ static void tegra_xudc_usb_role_sw_work(struct work_struct *work)
674
678
tegra_xudc_device_mode_off (xudc );
675
679
}
676
680
681
+ static int tegra_xudc_get_phy_index (struct tegra_xudc * xudc ,
682
+ struct usb_phy * usbphy )
683
+ {
684
+ unsigned int i ;
685
+
686
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ ) {
687
+ if (xudc -> usbphy [i ] && usbphy == xudc -> usbphy [i ])
688
+ return i ;
689
+ }
690
+
691
+ dev_info (xudc -> dev , "phy index could not be found for shared USB PHY" );
692
+ return -1 ;
693
+ }
694
+
677
695
static int tegra_xudc_vbus_notify (struct notifier_block * nb ,
678
696
unsigned long action , void * data )
679
697
{
680
698
struct tegra_xudc * xudc = container_of (nb , struct tegra_xudc ,
681
699
vbus_nb );
682
700
struct usb_phy * usbphy = (struct usb_phy * )data ;
701
+ int phy_index ;
683
702
684
703
dev_dbg (xudc -> dev , "%s(): event is %d\n" , __func__ , usbphy -> last_event );
685
704
@@ -693,8 +712,15 @@ static int tegra_xudc_vbus_notify(struct notifier_block *nb,
693
712
xudc -> device_mode = (usbphy -> last_event == USB_EVENT_VBUS ) ? true :
694
713
false;
695
714
696
- if (!xudc -> suspended )
715
+ phy_index = tegra_xudc_get_phy_index (xudc , usbphy );
716
+ dev_dbg (xudc -> dev , "%s(): current phy index is %d\n" , __func__ ,
717
+ phy_index );
718
+
719
+ if (!xudc -> suspended && phy_index != -1 ) {
720
+ xudc -> curr_utmi_phy = xudc -> utmi_phy [phy_index ];
721
+ xudc -> curr_usb3_phy = xudc -> usb3_phy [phy_index ];
697
722
schedule_work (& xudc -> usb_role_sw_work );
723
+ }
698
724
699
725
return NOTIFY_OK ;
700
726
}
@@ -714,9 +740,9 @@ static void tegra_xudc_plc_reset_work(struct work_struct *work)
714
740
715
741
if (pls == PORTSC_PLS_INACTIVE ) {
716
742
dev_info (xudc -> dev , "PLS = Inactive. Toggle VBUS\n" );
717
- phy_set_mode_ext (xudc -> utmi_phy , PHY_MODE_USB_OTG ,
743
+ phy_set_mode_ext (xudc -> curr_utmi_phy , PHY_MODE_USB_OTG ,
718
744
USB_ROLE_NONE );
719
- phy_set_mode_ext (xudc -> utmi_phy , PHY_MODE_USB_OTG ,
745
+ phy_set_mode_ext (xudc -> curr_utmi_phy , PHY_MODE_USB_OTG ,
720
746
USB_ROLE_DEVICE );
721
747
722
748
xudc -> wait_csc = false;
@@ -745,7 +771,8 @@ static void tegra_xudc_port_reset_war_work(struct work_struct *work)
745
771
if (pls == PORTSC_PLS_DISABLED ) {
746
772
dev_dbg (xudc -> dev , "toggle vbus\n" );
747
773
/* PRC doesn't complete in 100ms, toggle the vbus */
748
- ret = tegra_phy_xusb_utmi_port_reset (xudc -> utmi_phy );
774
+ ret = tegra_phy_xusb_utmi_port_reset (
775
+ xudc -> curr_utmi_phy );
749
776
if (ret == 1 )
750
777
xudc -> wait_for_sec_prc = 0 ;
751
778
}
@@ -1934,6 +1961,7 @@ static int tegra_xudc_gadget_start(struct usb_gadget *gadget,
1934
1961
unsigned long flags ;
1935
1962
u32 val ;
1936
1963
int ret ;
1964
+ unsigned int i ;
1937
1965
1938
1966
if (!driver )
1939
1967
return - EINVAL ;
@@ -1969,8 +1997,9 @@ static int tegra_xudc_gadget_start(struct usb_gadget *gadget,
1969
1997
xudc_writel (xudc , val , CTRL );
1970
1998
}
1971
1999
1972
- if (xudc -> usbphy )
1973
- otg_set_peripheral (xudc -> usbphy -> otg , gadget );
2000
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ )
2001
+ if (xudc -> usbphy [i ])
2002
+ otg_set_peripheral (xudc -> usbphy [i ]-> otg , gadget );
1974
2003
1975
2004
xudc -> driver = driver ;
1976
2005
unlock :
@@ -1987,13 +2016,15 @@ static int tegra_xudc_gadget_stop(struct usb_gadget *gadget)
1987
2016
struct tegra_xudc * xudc = to_xudc (gadget );
1988
2017
unsigned long flags ;
1989
2018
u32 val ;
2019
+ unsigned int i ;
1990
2020
1991
2021
pm_runtime_get_sync (xudc -> dev );
1992
2022
1993
2023
spin_lock_irqsave (& xudc -> lock , flags );
1994
2024
1995
- if (xudc -> usbphy )
1996
- otg_set_peripheral (xudc -> usbphy -> otg , NULL );
2025
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ )
2026
+ if (xudc -> usbphy [i ])
2027
+ otg_set_peripheral (xudc -> usbphy [i ]-> otg , NULL );
1997
2028
1998
2029
val = xudc_readl (xudc , CTRL );
1999
2030
val &= ~(CTRL_IE | CTRL_ENABLE );
@@ -3327,33 +3358,120 @@ static void tegra_xudc_device_params_init(struct tegra_xudc *xudc)
3327
3358
xudc_writel (xudc , val , CFG_DEV_SSPI_XFER );
3328
3359
}
3329
3360
3330
- static int tegra_xudc_phy_init (struct tegra_xudc * xudc )
3361
+ static int tegra_xudc_phy_get (struct tegra_xudc * xudc )
3331
3362
{
3332
- int err ;
3363
+ int err = 0 , usb3 ;
3364
+ unsigned int i ;
3333
3365
3334
- err = phy_init (xudc -> utmi_phy );
3335
- if (err < 0 ) {
3336
- dev_err (xudc -> dev , "utmi phy init failed: %d\n" , err );
3337
- return err ;
3338
- }
3366
+ xudc -> utmi_phy = devm_kcalloc (xudc -> dev , xudc -> soc -> num_phys ,
3367
+ sizeof (* xudc -> utmi_phy ), GFP_KERNEL );
3368
+ if (!xudc -> utmi_phy )
3369
+ return - ENOMEM ;
3339
3370
3340
- err = phy_init (xudc -> usb3_phy );
3341
- if (err < 0 ) {
3342
- dev_err (xudc -> dev , "usb3 phy init failed: %d\n" , err );
3343
- goto exit_utmi_phy ;
3371
+ xudc -> usb3_phy = devm_kcalloc (xudc -> dev , xudc -> soc -> num_phys ,
3372
+ sizeof (* xudc -> usb3_phy ), GFP_KERNEL );
3373
+ if (!xudc -> usb3_phy )
3374
+ return - ENOMEM ;
3375
+
3376
+ xudc -> usbphy = devm_kcalloc (xudc -> dev , xudc -> soc -> num_phys ,
3377
+ sizeof (* xudc -> usbphy ), GFP_KERNEL );
3378
+ if (!xudc -> usbphy )
3379
+ return - ENOMEM ;
3380
+
3381
+ xudc -> vbus_nb .notifier_call = tegra_xudc_vbus_notify ;
3382
+
3383
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ ) {
3384
+ char phy_name [] = "usb.-." ;
3385
+
3386
+ /* Get USB2 phy */
3387
+ snprintf (phy_name , sizeof (phy_name ), "usb2-%d" , i );
3388
+ xudc -> utmi_phy [i ] = devm_phy_optional_get (xudc -> dev , phy_name );
3389
+ if (IS_ERR (xudc -> utmi_phy [i ])) {
3390
+ err = PTR_ERR (xudc -> utmi_phy [i ]);
3391
+ if (err != - EPROBE_DEFER )
3392
+ dev_err (xudc -> dev , "failed to get usb2-%d phy: %d\n" ,
3393
+ i , err );
3394
+
3395
+ goto clean_up ;
3396
+ } else if (xudc -> utmi_phy [i ]) {
3397
+ /* Get usb-phy, if utmi phy is available */
3398
+ xudc -> usbphy [i ] = devm_usb_get_phy_by_node (xudc -> dev ,
3399
+ xudc -> utmi_phy [i ]-> dev .of_node ,
3400
+ & xudc -> vbus_nb );
3401
+ if (IS_ERR (xudc -> usbphy [i ])) {
3402
+ err = PTR_ERR (xudc -> usbphy [i ]);
3403
+ dev_err (xudc -> dev , "failed to get usbphy-%d: %d\n" ,
3404
+ i , err );
3405
+ goto clean_up ;
3406
+ }
3407
+ } else if (!xudc -> utmi_phy [i ]) {
3408
+ /* if utmi phy is not available, ignore USB3 phy get */
3409
+ continue ;
3410
+ }
3411
+
3412
+ /* Get USB3 phy */
3413
+ usb3 = tegra_xusb_padctl_get_usb3_companion (xudc -> padctl , i );
3414
+ if (usb3 < 0 )
3415
+ continue ;
3416
+
3417
+ snprintf (phy_name , sizeof (phy_name ), "usb3-%d" , usb3 );
3418
+ xudc -> usb3_phy [i ] = devm_phy_optional_get (xudc -> dev , phy_name );
3419
+ if (IS_ERR (xudc -> usb3_phy [i ])) {
3420
+ err = PTR_ERR (xudc -> usb3_phy [i ]);
3421
+ if (err != - EPROBE_DEFER )
3422
+ dev_err (xudc -> dev , "failed to get usb3-%d phy: %d\n" ,
3423
+ usb3 , err );
3424
+
3425
+ goto clean_up ;
3426
+ } else if (xudc -> usb3_phy [i ])
3427
+ dev_dbg (xudc -> dev , "usb3_phy-%d registered" , usb3 );
3344
3428
}
3345
3429
3346
- return 0 ;
3430
+ return err ;
3431
+
3432
+ clean_up :
3433
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ ) {
3434
+ xudc -> usb3_phy [i ] = NULL ;
3435
+ xudc -> utmi_phy [i ] = NULL ;
3436
+ xudc -> usbphy [i ] = NULL ;
3437
+ }
3347
3438
3348
- exit_utmi_phy :
3349
- phy_exit (xudc -> utmi_phy );
3350
3439
return err ;
3351
3440
}
3352
3441
3353
3442
static void tegra_xudc_phy_exit (struct tegra_xudc * xudc )
3354
3443
{
3355
- phy_exit (xudc -> usb3_phy );
3356
- phy_exit (xudc -> utmi_phy );
3444
+ unsigned int i ;
3445
+
3446
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ ) {
3447
+ phy_exit (xudc -> usb3_phy [i ]);
3448
+ phy_exit (xudc -> utmi_phy [i ]);
3449
+ }
3450
+ }
3451
+
3452
+ static int tegra_xudc_phy_init (struct tegra_xudc * xudc )
3453
+ {
3454
+ int err ;
3455
+ unsigned int i ;
3456
+
3457
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ ) {
3458
+ err = phy_init (xudc -> utmi_phy [i ]);
3459
+ if (err < 0 ) {
3460
+ dev_err (xudc -> dev , "utmi phy init failed: %d\n" , err );
3461
+ goto exit_phy ;
3462
+ }
3463
+
3464
+ err = phy_init (xudc -> usb3_phy [i ]);
3465
+ if (err < 0 ) {
3466
+ dev_err (xudc -> dev , "usb3 phy init failed: %d\n" , err );
3467
+ goto exit_phy ;
3468
+ }
3469
+ }
3470
+ return 0 ;
3471
+
3472
+ exit_phy :
3473
+ tegra_xudc_phy_exit (xudc );
3474
+ return err ;
3357
3475
}
3358
3476
3359
3477
static const char * const tegra210_xudc_supply_names [] = {
@@ -3381,6 +3499,7 @@ static struct tegra_xudc_soc tegra210_xudc_soc_data = {
3381
3499
.num_supplies = ARRAY_SIZE (tegra210_xudc_supply_names ),
3382
3500
.clock_names = tegra210_xudc_clock_names ,
3383
3501
.num_clks = ARRAY_SIZE (tegra210_xudc_clock_names ),
3502
+ .num_phys = 4 ,
3384
3503
.u1_enable = false,
3385
3504
.u2_enable = true,
3386
3505
.lpm_enable = false,
@@ -3393,6 +3512,7 @@ static struct tegra_xudc_soc tegra210_xudc_soc_data = {
3393
3512
static struct tegra_xudc_soc tegra186_xudc_soc_data = {
3394
3513
.clock_names = tegra186_xudc_clock_names ,
3395
3514
.num_clks = ARRAY_SIZE (tegra186_xudc_clock_names ),
3515
+ .num_phys = 4 ,
3396
3516
.u1_enable = true,
3397
3517
.u2_enable = true,
3398
3518
.lpm_enable = false,
@@ -3555,19 +3675,9 @@ static int tegra_xudc_probe(struct platform_device *pdev)
3555
3675
goto put_padctl ;
3556
3676
}
3557
3677
3558
- xudc -> usb3_phy = devm_phy_optional_get (& pdev -> dev , "usb3" );
3559
- if (IS_ERR (xudc -> usb3_phy )) {
3560
- err = PTR_ERR (xudc -> usb3_phy );
3561
- dev_err (xudc -> dev , "failed to get usb3 phy: %d\n" , err );
3562
- goto disable_regulator ;
3563
- }
3564
-
3565
- xudc -> utmi_phy = devm_phy_optional_get (& pdev -> dev , "usb2" );
3566
- if (IS_ERR (xudc -> utmi_phy )) {
3567
- err = PTR_ERR (xudc -> utmi_phy );
3568
- dev_err (xudc -> dev , "failed to get usb2 phy: %d\n" , err );
3678
+ err = tegra_xudc_phy_get (xudc );
3679
+ if (err )
3569
3680
goto disable_regulator ;
3570
- }
3571
3681
3572
3682
err = tegra_xudc_powerdomain_init (xudc );
3573
3683
if (err )
@@ -3596,16 +3706,6 @@ static int tegra_xudc_probe(struct platform_device *pdev)
3596
3706
INIT_DELAYED_WORK (& xudc -> port_reset_war_work ,
3597
3707
tegra_xudc_port_reset_war_work );
3598
3708
3599
- xudc -> vbus_nb .notifier_call = tegra_xudc_vbus_notify ;
3600
- xudc -> usbphy = devm_usb_get_phy_by_node (xudc -> dev ,
3601
- xudc -> utmi_phy -> dev .of_node ,
3602
- & xudc -> vbus_nb );
3603
- if (IS_ERR (xudc -> usbphy )) {
3604
- err = PTR_ERR (xudc -> usbphy );
3605
- dev_err (xudc -> dev , "failed to get USB PHY: %d\n" , err );
3606
- goto free_eps ;
3607
- }
3608
-
3609
3709
pm_runtime_enable (& pdev -> dev );
3610
3710
3611
3711
xudc -> gadget .ops = & tegra_xudc_gadget_ops ;
@@ -3640,6 +3740,7 @@ static int tegra_xudc_probe(struct platform_device *pdev)
3640
3740
static int tegra_xudc_remove (struct platform_device * pdev )
3641
3741
{
3642
3742
struct tegra_xudc * xudc = platform_get_drvdata (pdev );
3743
+ unsigned int i ;
3643
3744
3644
3745
pm_runtime_get_sync (xudc -> dev );
3645
3746
@@ -3655,8 +3756,10 @@ static int tegra_xudc_remove(struct platform_device *pdev)
3655
3756
3656
3757
regulator_bulk_disable (xudc -> soc -> num_supplies , xudc -> supplies );
3657
3758
3658
- phy_power_off (xudc -> utmi_phy );
3659
- phy_power_off (xudc -> usb3_phy );
3759
+ for (i = 0 ; i < xudc -> soc -> num_phys ; i ++ ) {
3760
+ phy_power_off (xudc -> utmi_phy [i ]);
3761
+ phy_power_off (xudc -> usb3_phy [i ]);
3762
+ }
3660
3763
3661
3764
tegra_xudc_phy_exit (xudc );
3662
3765
0 commit comments