forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/usb/dwc3/drd.c
....@@ -1,8 +1,8 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/**
2
+/*
33 * drd.c - DesignWare USB3 DRD Controller Dual-role support
44 *
5
- * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com
5
+ * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com
66 *
77 * Authors: Roger Quadros <rogerq@ti.com>
88 */
....@@ -56,7 +56,7 @@
5656 spin_lock(&dwc->lock);
5757 if (dwc->otg_restart_host) {
5858 dwc3_otg_host_init(dwc);
59
- dwc->otg_restart_host = 0;
59
+ dwc->otg_restart_host = false;
6060 }
6161
6262 spin_unlock(&dwc->lock);
....@@ -82,7 +82,7 @@
8282
8383 if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST &&
8484 !(reg & DWC3_OEVT_DEVICEMODE))
85
- dwc->otg_restart_host = 1;
85
+ dwc->otg_restart_host = true;
8686 dwc3_writel(dwc->regs, DWC3_OEVT, reg);
8787 ret = IRQ_WAKE_THREAD;
8888 }
....@@ -139,14 +139,14 @@
139139 struct platform_device *dwc3_pdev = to_platform_device(dwc->dev);
140140 int irq;
141141
142
- irq = platform_get_irq_byname(dwc3_pdev, "otg");
142
+ irq = platform_get_irq_byname_optional(dwc3_pdev, "otg");
143143 if (irq > 0)
144144 goto out;
145145
146146 if (irq == -EPROBE_DEFER)
147147 goto out;
148148
149
- irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3");
149
+ irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3");
150150 if (irq > 0)
151151 goto out;
152152
....@@ -156,9 +156,6 @@
156156 irq = platform_get_irq(dwc3_pdev, 0);
157157 if (irq > 0)
158158 goto out;
159
-
160
- if (irq != -EPROBE_DEFER)
161
- dev_err(dwc->dev, "missing OTG IRQ\n");
162159
163160 if (!irq)
164161 irq = -EINVAL;
....@@ -423,6 +420,12 @@
423420 id = extcon_get_state(dwc->edev, EXTCON_USB_HOST);
424421 if (id < 0)
425422 id = 0;
423
+
424
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
425
+ if (extcon_get_state(dwc->edev, EXTCON_USB))
426
+ dwc->desired_role_sw_mode = USB_DR_MODE_PERIPHERAL;
427
+#endif
428
+
426429 dwc3_set_mode(dwc, id ?
427430 DWC3_GCTL_PRTCAP_HOST :
428431 DWC3_GCTL_PRTCAP_DEVICE);
....@@ -434,6 +437,15 @@
434437 {
435438 struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb);
436439
440
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
441
+ if (extcon_get_state(dwc->edev, EXTCON_USB))
442
+ dwc->desired_role_sw_mode = USB_DR_MODE_PERIPHERAL;
443
+ else if (extcon_get_state(dwc->edev, EXTCON_USB_HOST))
444
+ dwc->desired_role_sw_mode = USB_DR_MODE_HOST;
445
+ else
446
+ dwc->desired_role_sw_mode = USB_DR_MODE_UNKNOWN;
447
+#endif
448
+
437449 dwc3_set_mode(dwc, event ?
438450 DWC3_GCTL_PRTCAP_HOST :
439451 DWC3_GCTL_PRTCAP_DEVICE);
....@@ -444,8 +456,8 @@
444456 static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
445457 {
446458 struct device *dev = dwc->dev;
447
- struct device_node *np_phy, *np_conn;
448
- struct extcon_dev *edev;
459
+ struct device_node *np_phy;
460
+ struct extcon_dev *edev = NULL;
449461 const char *name;
450462
451463 if (device_property_read_bool(dev, "extcon"))
....@@ -465,23 +477,127 @@
465477 return edev;
466478 }
467479
480
+ /*
481
+ * Try to get an extcon device from the USB PHY controller's "port"
482
+ * node. Check if it has the "port" node first, to avoid printing the
483
+ * error message from underlying code, as it's a valid case: extcon
484
+ * device (and "port" node) may be missing in case of "usb-role-switch"
485
+ * or OTG mode.
486
+ */
468487 np_phy = of_parse_phandle(dev->of_node, "phys", 0);
469
- np_conn = of_graph_get_remote_node(np_phy, -1, -1);
488
+ if (of_graph_is_present(np_phy)) {
489
+ struct device_node *np_conn;
470490
471
- if (np_conn)
472
- edev = extcon_find_edev_by_node(np_conn);
473
- else
474
- edev = NULL;
475
-
476
- of_node_put(np_conn);
491
+ np_conn = of_graph_get_remote_node(np_phy, -1, -1);
492
+ if (np_conn)
493
+ edev = extcon_find_edev_by_node(np_conn);
494
+ of_node_put(np_conn);
495
+ }
477496 of_node_put(np_phy);
478497
479498 return edev;
480499 }
481500
501
+#if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
502
+#define ROLE_SWITCH 1
503
+static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
504
+ enum usb_role role)
505
+{
506
+ struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
507
+ u32 mode;
508
+
509
+#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI)
510
+ dwc->desired_role_sw_mode = role;
511
+ phy_set_mode_ext(dwc->usb2_generic_phy, PHY_MODE_USB_OTG, role);
512
+#endif
513
+
514
+ switch (role) {
515
+ case USB_ROLE_HOST:
516
+ mode = DWC3_GCTL_PRTCAP_HOST;
517
+ break;
518
+ case USB_ROLE_DEVICE:
519
+ mode = DWC3_GCTL_PRTCAP_DEVICE;
520
+ break;
521
+ default:
522
+ if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
523
+ mode = DWC3_GCTL_PRTCAP_HOST;
524
+ else
525
+ mode = DWC3_GCTL_PRTCAP_DEVICE;
526
+ break;
527
+ }
528
+
529
+ dwc3_set_mode(dwc, mode);
530
+ return 0;
531
+}
532
+
533
+static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw)
534
+{
535
+ struct dwc3 *dwc = usb_role_switch_get_drvdata(sw);
536
+ unsigned long flags;
537
+ enum usb_role role;
538
+
539
+ spin_lock_irqsave(&dwc->lock, flags);
540
+ switch (dwc->current_dr_role) {
541
+ case DWC3_GCTL_PRTCAP_HOST:
542
+ role = USB_ROLE_HOST;
543
+ break;
544
+ case DWC3_GCTL_PRTCAP_DEVICE:
545
+ role = USB_ROLE_DEVICE;
546
+ break;
547
+ case DWC3_GCTL_PRTCAP_OTG:
548
+ role = dwc->current_otg_role;
549
+ break;
550
+ default:
551
+ if (dwc->role_switch_default_mode == USB_DR_MODE_HOST)
552
+ role = USB_ROLE_HOST;
553
+ else
554
+ role = USB_ROLE_DEVICE;
555
+ break;
556
+ }
557
+ spin_unlock_irqrestore(&dwc->lock, flags);
558
+ return role;
559
+}
560
+
561
+static int dwc3_setup_role_switch(struct dwc3 *dwc)
562
+{
563
+ struct usb_role_switch_desc dwc3_role_switch = {NULL};
564
+ const char *str;
565
+ u32 mode;
566
+ int ret;
567
+
568
+ ret = device_property_read_string(dwc->dev, "role-switch-default-mode",
569
+ &str);
570
+ if (ret >= 0 && !strncmp(str, "host", strlen("host"))) {
571
+ dwc->role_switch_default_mode = USB_DR_MODE_HOST;
572
+ mode = DWC3_GCTL_PRTCAP_HOST;
573
+ } else {
574
+ dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL;
575
+ mode = DWC3_GCTL_PRTCAP_DEVICE;
576
+ }
577
+
578
+ dwc3_role_switch.fwnode = dev_fwnode(dwc->dev);
579
+ dwc3_role_switch.set = dwc3_usb_role_switch_set;
580
+ dwc3_role_switch.get = dwc3_usb_role_switch_get;
581
+ dwc3_role_switch.driver_data = dwc;
582
+ dwc->role_sw = usb_role_switch_register(dwc->dev, &dwc3_role_switch);
583
+ if (IS_ERR(dwc->role_sw))
584
+ return PTR_ERR(dwc->role_sw);
585
+
586
+ dwc3_set_mode(dwc, mode);
587
+ return 0;
588
+}
589
+#else
590
+#define ROLE_SWITCH 0
591
+#define dwc3_setup_role_switch(x) 0
592
+#endif
593
+
482594 int dwc3_drd_init(struct dwc3 *dwc)
483595 {
484596 int ret, irq;
597
+
598
+ if (ROLE_SWITCH &&
599
+ device_property_read_bool(dwc->dev, "usb-role-switch"))
600
+ return dwc3_setup_role_switch(dwc);
485601
486602 dwc->edev = dwc3_get_extcon(dwc);
487603 if (IS_ERR(dwc->edev))
....@@ -534,6 +650,9 @@
534650 {
535651 unsigned long flags;
536652
653
+ if (dwc->role_sw)
654
+ usb_role_switch_unregister(dwc->role_sw);
655
+
537656 if (dwc->edev)
538657 extcon_unregister_notifier(dwc->edev, EXTCON_USB_HOST,
539658 &dwc->edev_nb);
....@@ -560,6 +679,6 @@
560679 break;
561680 }
562681
563
- if (!dwc->edev)
682
+ if (dwc->otg_irq)
564683 free_irq(dwc->otg_irq, dwc);
565684 }