forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/usb/gadget/udc/renesas_usb3.c
....@@ -352,6 +352,8 @@
352352 int disabled_count;
353353
354354 struct usb_request *ep0_req;
355
+
356
+ enum usb_role connection_state;
355357 u16 test_mode;
356358 u8 ep0_buf[USB3_EP0_BUF_SIZE];
357359 bool softconnect;
....@@ -360,6 +362,7 @@
360362 bool extcon_usb; /* check vbus and set EXTCON_USB */
361363 bool forced_b_device;
362364 bool start_to_connect;
365
+ bool role_sw_by_connector;
363366 };
364367
365368 #define gadget_to_renesas_usb3(_gadget) \
....@@ -700,8 +703,11 @@
700703 unsigned long flags;
701704
702705 spin_lock_irqsave(&usb3->lock, flags);
703
- usb3_set_mode_by_role_sw(usb3, host);
704
- usb3_vbus_out(usb3, a_dev);
706
+ if (!usb3->role_sw_by_connector ||
707
+ usb3->connection_state != USB_ROLE_NONE) {
708
+ usb3_set_mode_by_role_sw(usb3, host);
709
+ usb3_vbus_out(usb3, a_dev);
710
+ }
705711 /* for A-Peripheral or forced B-device mode */
706712 if ((!host && a_dev) || usb3->start_to_connect)
707713 usb3_connect(usb3);
....@@ -717,7 +723,8 @@
717723 {
718724 usb3->extcon_host = usb3_is_a_device(usb3);
719725
720
- if (usb3->extcon_host && !usb3->forced_b_device)
726
+ if ((!usb3->role_sw_by_connector && usb3->extcon_host &&
727
+ !usb3->forced_b_device) || usb3->connection_state == USB_ROLE_HOST)
721728 usb3_mode_config(usb3, true, true);
722729 else
723730 usb3_mode_config(usb3, false, false);
....@@ -766,6 +773,18 @@
766773 usb3_disable_irq_1(usb3, USB_INT_1_B2_RSUM);
767774 usb3_start_usb2_connection(usb3);
768775 usb3_transition_to_default_state(usb3, false);
776
+}
777
+
778
+static void usb3_irq_epc_int_1_suspend(struct renesas_usb3 *usb3)
779
+{
780
+ usb3_disable_irq_1(usb3, USB_INT_1_B2_SPND);
781
+
782
+ if (usb3->gadget.speed != USB_SPEED_UNKNOWN &&
783
+ usb3->gadget.state != USB_STATE_NOTATTACHED) {
784
+ if (usb3->driver && usb3->driver->suspend)
785
+ usb3->driver->suspend(&usb3->gadget);
786
+ usb_gadget_set_state(&usb3->gadget, USB_STATE_SUSPENDED);
787
+ }
769788 }
770789
771790 static void usb3_irq_epc_int_1_disable(struct renesas_usb3 *usb3)
....@@ -852,6 +871,9 @@
852871
853872 if (int_sta_1 & USB_INT_1_B2_RSUM)
854873 usb3_irq_epc_int_1_resume(usb3);
874
+
875
+ if (int_sta_1 & USB_INT_1_B2_SPND)
876
+ usb3_irq_epc_int_1_suspend(usb3);
855877
856878 if (int_sta_1 & USB_INT_1_SPEED)
857879 usb3_irq_epc_int_1_speed(usb3);
....@@ -1162,7 +1184,7 @@
11621184 static void usb3_p0_xfer(struct renesas_usb3_ep *usb3_ep,
11631185 struct renesas_usb3_request *usb3_req)
11641186 {
1165
- int ret = -EAGAIN;
1187
+ int ret;
11661188
11671189 if (usb3_ep->dir_in)
11681190 ret = usb3_write_pipe(usb3_ep, usb3_req, USB3_P0_WRITE);
....@@ -1538,10 +1560,10 @@
15381560 static bool usb3_std_req_set_address(struct renesas_usb3 *usb3,
15391561 struct usb_ctrlrequest *ctrl)
15401562 {
1541
- if (ctrl->wValue >= 128)
1563
+ if (le16_to_cpu(ctrl->wValue) >= 128)
15421564 return true; /* stall */
15431565
1544
- usb3_set_device_address(usb3, ctrl->wValue);
1566
+ usb3_set_device_address(usb3, le16_to_cpu(ctrl->wValue));
15451567 usb3_set_p0_con_for_no_data(usb3);
15461568
15471569 return false;
....@@ -1576,6 +1598,7 @@
15761598 struct renesas_usb3_ep *usb3_ep;
15771599 int num;
15781600 u16 status = 0;
1601
+ __le16 tx_data;
15791602
15801603 switch (ctrl->bRequestType & USB_RECIP_MASK) {
15811604 case USB_RECIP_DEVICE:
....@@ -1598,10 +1621,10 @@
15981621 }
15991622
16001623 if (!stall) {
1601
- status = cpu_to_le16(status);
1624
+ tx_data = cpu_to_le16(status);
16021625 dev_dbg(usb3_to_dev(usb3), "get_status: req = %p\n",
16031626 usb_req_to_usb3_req(usb3->ep0_req));
1604
- usb3_pipe0_internal_xfer(usb3, &status, sizeof(status),
1627
+ usb3_pipe0_internal_xfer(usb3, &tx_data, sizeof(tx_data),
16051628 usb3_pipe0_get_status_completion);
16061629 }
16071630
....@@ -1766,7 +1789,7 @@
17661789 static bool usb3_std_req_set_configuration(struct renesas_usb3 *usb3,
17671790 struct usb_ctrlrequest *ctrl)
17681791 {
1769
- if (ctrl->wValue > 0)
1792
+ if (le16_to_cpu(ctrl->wValue) > 0)
17701793 usb3_set_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
17711794 else
17721795 usb3_clear_bit(usb3, USB_COM_CON_CONF, USB3_USB_COM_CON);
....@@ -2333,26 +2356,79 @@
23332356 .set_selfpowered = renesas_usb3_set_selfpowered,
23342357 };
23352358
2336
-static enum usb_role renesas_usb3_role_switch_get(struct device *dev)
2359
+static enum usb_role renesas_usb3_role_switch_get(struct usb_role_switch *sw)
23372360 {
2338
- struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
2361
+ struct renesas_usb3 *usb3 = usb_role_switch_get_drvdata(sw);
23392362 enum usb_role cur_role;
23402363
2341
- pm_runtime_get_sync(dev);
2364
+ pm_runtime_get_sync(usb3_to_dev(usb3));
23422365 cur_role = usb3_is_host(usb3) ? USB_ROLE_HOST : USB_ROLE_DEVICE;
2343
- pm_runtime_put(dev);
2366
+ pm_runtime_put(usb3_to_dev(usb3));
23442367
23452368 return cur_role;
23462369 }
23472370
2348
-static int renesas_usb3_role_switch_set(struct device *dev,
2349
- enum usb_role role)
2371
+static void handle_ext_role_switch_states(struct device *dev,
2372
+ enum usb_role role)
23502373 {
23512374 struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
23522375 struct device *host = usb3->host_dev;
2353
- enum usb_role cur_role = renesas_usb3_role_switch_get(dev);
2376
+ enum usb_role cur_role = renesas_usb3_role_switch_get(usb3->role_sw);
23542377
2355
- pm_runtime_get_sync(dev);
2378
+ switch (role) {
2379
+ case USB_ROLE_NONE:
2380
+ usb3->connection_state = USB_ROLE_NONE;
2381
+ if (cur_role == USB_ROLE_HOST)
2382
+ device_release_driver(host);
2383
+ if (usb3->driver)
2384
+ usb3_disconnect(usb3);
2385
+ usb3_vbus_out(usb3, false);
2386
+ break;
2387
+ case USB_ROLE_DEVICE:
2388
+ if (usb3->connection_state == USB_ROLE_NONE) {
2389
+ usb3->connection_state = USB_ROLE_DEVICE;
2390
+ usb3_set_mode(usb3, false);
2391
+ if (usb3->driver)
2392
+ usb3_connect(usb3);
2393
+ } else if (cur_role == USB_ROLE_HOST) {
2394
+ device_release_driver(host);
2395
+ usb3_set_mode(usb3, false);
2396
+ if (usb3->driver)
2397
+ usb3_connect(usb3);
2398
+ }
2399
+ usb3_vbus_out(usb3, false);
2400
+ break;
2401
+ case USB_ROLE_HOST:
2402
+ if (usb3->connection_state == USB_ROLE_NONE) {
2403
+ if (usb3->driver)
2404
+ usb3_disconnect(usb3);
2405
+
2406
+ usb3->connection_state = USB_ROLE_HOST;
2407
+ usb3_set_mode(usb3, true);
2408
+ usb3_vbus_out(usb3, true);
2409
+ if (device_attach(host) < 0)
2410
+ dev_err(dev, "device_attach(host) failed\n");
2411
+ } else if (cur_role == USB_ROLE_DEVICE) {
2412
+ usb3_disconnect(usb3);
2413
+ /* Must set the mode before device_attach of the host */
2414
+ usb3_set_mode(usb3, true);
2415
+ /* This device_attach() might sleep */
2416
+ if (device_attach(host) < 0)
2417
+ dev_err(dev, "device_attach(host) failed\n");
2418
+ }
2419
+ break;
2420
+ default:
2421
+ break;
2422
+ }
2423
+}
2424
+
2425
+static void handle_role_switch_states(struct device *dev,
2426
+ enum usb_role role)
2427
+{
2428
+ struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
2429
+ struct device *host = usb3->host_dev;
2430
+ enum usb_role cur_role = renesas_usb3_role_switch_get(usb3->role_sw);
2431
+
23562432 if (cur_role == USB_ROLE_HOST && role == USB_ROLE_DEVICE) {
23572433 device_release_driver(host);
23582434 usb3_set_mode(usb3, false);
....@@ -2363,7 +2439,21 @@
23632439 if (device_attach(host) < 0)
23642440 dev_err(dev, "device_attach(host) failed\n");
23652441 }
2366
- pm_runtime_put(dev);
2442
+}
2443
+
2444
+static int renesas_usb3_role_switch_set(struct usb_role_switch *sw,
2445
+ enum usb_role role)
2446
+{
2447
+ struct renesas_usb3 *usb3 = usb_role_switch_get_drvdata(sw);
2448
+
2449
+ pm_runtime_get_sync(usb3_to_dev(usb3));
2450
+
2451
+ if (usb3->role_sw_by_connector)
2452
+ handle_ext_role_switch_states(usb3_to_dev(usb3), role);
2453
+ else
2454
+ handle_role_switch_states(usb3_to_dev(usb3), role);
2455
+
2456
+ pm_runtime_put(usb3_to_dev(usb3));
23672457
23682458 return 0;
23692459 }
....@@ -2464,7 +2554,7 @@
24642554 static void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3,
24652555 struct device *dev)
24662556 {
2467
- usb3->dentry = debugfs_create_dir(dev_name(dev), NULL);
2557
+ usb3->dentry = debugfs_create_dir(dev_name(dev), usb_debug_root);
24682558
24692559 debugfs_create_file("b_device", 0644, usb3->dentry, usb3,
24702560 &renesas_usb3_b_device_fops);
....@@ -2478,6 +2568,7 @@
24782568 debugfs_remove_recursive(usb3->dentry);
24792569 device_remove_file(&pdev->dev, &dev_attr_role);
24802570
2571
+ cancel_work_sync(&usb3->role_work);
24812572 usb_role_switch_unregister(usb3->role_sw);
24822573
24832574 usb_del_gadget_udc(&usb3->gadget);
....@@ -2610,12 +2701,24 @@
26102701 .ramsize_per_pipe = SZ_4K,
26112702 };
26122703
2704
+static const struct renesas_usb3_priv renesas_usb3_priv_r8a77990 = {
2705
+ .ramsize_per_ramif = SZ_16K,
2706
+ .num_ramif = 4,
2707
+ .ramsize_per_pipe = SZ_4K,
2708
+ .workaround_for_vbus = true,
2709
+};
2710
+
26132711 static const struct of_device_id usb3_of_match[] = {
26142712 {
2713
+ .compatible = "renesas,r8a774c0-usb3-peri",
2714
+ .data = &renesas_usb3_priv_r8a77990,
2715
+ }, {
26152716 .compatible = "renesas,r8a7795-usb3-peri",
26162717 .data = &renesas_usb3_priv_gen3,
2617
- },
2618
- {
2718
+ }, {
2719
+ .compatible = "renesas,r8a77990-usb3-peri",
2720
+ .data = &renesas_usb3_priv_r8a77990,
2721
+ }, {
26192722 .compatible = "renesas,rcar-gen3-usb3-peri",
26202723 .data = &renesas_usb3_priv_gen3,
26212724 },
....@@ -2637,7 +2740,7 @@
26372740 EXTCON_NONE,
26382741 };
26392742
2640
-static const struct usb_role_switch_desc renesas_usb3_role_switch_desc = {
2743
+static struct usb_role_switch_desc renesas_usb3_role_switch_desc = {
26412744 .set = renesas_usb3_role_switch_set,
26422745 .get = renesas_usb3_role_switch_get,
26432746 .allow_userspace_control = true,
....@@ -2646,7 +2749,6 @@
26462749 static int renesas_usb3_probe(struct platform_device *pdev)
26472750 {
26482751 struct renesas_usb3 *usb3;
2649
- struct resource *res;
26502752 int irq, ret;
26512753 const struct renesas_usb3_priv *priv;
26522754 const struct soc_device_attribute *attr;
....@@ -2658,17 +2760,14 @@
26582760 priv = of_device_get_match_data(&pdev->dev);
26592761
26602762 irq = platform_get_irq(pdev, 0);
2661
- if (irq < 0) {
2662
- dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq);
2763
+ if (irq < 0)
26632764 return irq;
2664
- }
26652765
26662766 usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL);
26672767 if (!usb3)
26682768 return -ENOMEM;
26692769
2670
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2671
- usb3->reg = devm_ioremap_resource(&pdev->dev, res);
2770
+ usb3->reg = devm_platform_ioremap_resource(pdev, 0);
26722771 if (IS_ERR(usb3->reg))
26732772 return PTR_ERR(usb3->reg);
26742773
....@@ -2727,6 +2826,13 @@
27272826 ret = device_create_file(&pdev->dev, &dev_attr_role);
27282827 if (ret < 0)
27292828 goto err_dev_create;
2829
+
2830
+ if (device_property_read_bool(&pdev->dev, "usb-role-switch")) {
2831
+ usb3->role_sw_by_connector = true;
2832
+ renesas_usb3_role_switch_desc.fwnode = dev_fwnode(&pdev->dev);
2833
+ }
2834
+
2835
+ renesas_usb3_role_switch_desc.driver_data = usb3;
27302836
27312837 INIT_WORK(&usb3->role_work, renesas_usb3_role_work);
27322838 usb3->role_sw = usb_role_switch_register(&pdev->dev,
....@@ -2803,7 +2909,7 @@
28032909 .probe = renesas_usb3_probe,
28042910 .remove = renesas_usb3_remove,
28052911 .driver = {
2806
- .name = (char *)udc_name,
2912
+ .name = udc_name,
28072913 .pm = &renesas_usb3_pm_ops,
28082914 .of_match_table = of_match_ptr(usb3_of_match),
28092915 },