2 * dwc3-rockchip.c - Rockchip Specific Glue layer
4 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
6 * Authors: William Wu <william.wu@rock-chips.com>
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 of
10 * the License as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/module.h>
19 #include <linux/mutex.h>
20 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/platform_device.h>
23 #include <linux/dma-mapping.h>
24 #include <linux/clk.h>
25 #include <linux/clk-provider.h>
26 #include <linux/debugfs.h>
28 #include <linux/of_platform.h>
29 #include <linux/pm_runtime.h>
30 #include <linux/extcon.h>
31 #include <linux/freezer.h>
32 #include <linux/iopoll.h>
33 #include <linux/reset.h>
34 #include <linux/uaccess.h>
35 #include <linux/usb.h>
36 #include <linux/usb/hcd.h>
37 #include <linux/usb/ch9.h>
41 #include "../host/xhci.h"
43 #define DWC3_ROCKCHIP_AUTOSUSPEND_DELAY 500 /* ms */
44 #define PERIPHERAL_DISCONNECT_TIMEOUT 1000000 /* us */
45 #define WAIT_FOR_HCD_READY_TIMEOUT 5000000 /* us */
46 #define XHCI_TSTCTRL_MASK (0xf << 28)
48 struct dwc3_rockchip {
57 struct reset_control *otg_rst;
58 struct extcon_dev *edev;
59 struct notifier_block device_nb;
60 struct notifier_block host_nb;
61 struct work_struct otg_work;
65 static int dwc3_rockchip_host_testmode_show(struct seq_file *s, void *unused)
67 struct dwc3_rockchip *rockchip = s->private;
68 struct dwc3 *dwc = rockchip->dwc;
69 struct usb_hcd *hcd = dev_get_drvdata(&dwc->xhci->dev);
70 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
71 __le32 __iomem **port_array;
74 if (rockchip->dwc->dr_mode == USB_DR_MODE_PERIPHERAL) {
75 dev_warn(rockchip->dev, "USB HOST not support!\n");
79 if (hcd->state == HC_STATE_HALT) {
80 dev_warn(rockchip->dev, "HOST is halted, set test mode first!\n");
84 port_array = xhci->usb2_ports;
85 reg = readl(port_array[0] + PORTPMSC);
86 reg &= XHCI_TSTCTRL_MASK;
91 seq_puts(s, "U2: no test\n");
94 seq_puts(s, "U2: test_j\n");
97 seq_puts(s, "U2: test_k\n");
100 seq_puts(s, "U2: test_se0_nak\n");
103 seq_puts(s, "U2: test_packet\n");
106 seq_puts(s, "U2: test_force_enable\n");
109 seq_printf(s, "U2: UNKNOWN %d\n", reg);
112 port_array = xhci->usb3_ports;
113 reg = readl(port_array[0]);
114 reg &= PORT_PLS_MASK;
115 if (reg == USB_SS_PORT_LS_COMP_MOD)
116 seq_puts(s, "U3: compliance mode\n");
118 seq_printf(s, "U3: UNKNOWN %d\n", reg >> 5);
123 static int dwc3_rockchip_host_testmode_open(struct inode *inode,
126 return single_open(file, dwc3_rockchip_host_testmode_show,
131 * dwc3_rockchip_set_test_mode - Enables USB2/USB3 HOST Test Modes
132 * @rockchip: pointer to our context structure
133 * @mode: the mode to set (U2: J, K SE0 NAK, Test_packet,
134 * Force Enable; U3: Compliance mode)
136 * This function will return 0 on success or -EINVAL if wrong Test
137 * Selector is passed.
139 static int dwc3_rockchip_set_test_mode(struct dwc3_rockchip *rockchip,
142 struct dwc3 *dwc = rockchip->dwc;
143 struct usb_hcd *hcd = dev_get_drvdata(&dwc->xhci->dev);
144 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
145 __le32 __iomem **port_array;
149 ret = readx_poll_timeout(readl, &hcd->state, val,
150 val != HC_STATE_HALT, 1000,
151 WAIT_FOR_HCD_READY_TIMEOUT);
153 dev_err(rockchip->dev, "Wait for HCD ready timeout\n");
163 port_array = xhci->usb2_ports;
164 reg = readl(port_array[0] + PORTPMSC);
165 reg &= ~XHCI_TSTCTRL_MASK;
167 writel(reg, port_array[0] + PORTPMSC);
169 case USB_SS_PORT_LS_COMP_MOD:
170 port_array = xhci->usb3_ports;
171 xhci_set_link_state(xhci, port_array, 0, mode);
177 dev_info(rockchip->dev, "set USB HOST test mode successfully!\n");
182 static ssize_t dwc3_rockchip_host_testmode_write(struct file *file,
183 const char __user *ubuf,
184 size_t count, loff_t *ppos)
186 struct seq_file *s = file->private_data;
187 struct dwc3_rockchip *rockchip = s->private;
188 struct extcon_dev *edev = rockchip->edev;
192 union extcon_property_value property;
194 if (rockchip->dwc->dr_mode == USB_DR_MODE_PERIPHERAL) {
195 dev_warn(rockchip->dev, "USB HOST not support!\n");
199 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
202 if (!strncmp(buf, "test_j", 6)) {
204 } else if (!strncmp(buf, "test_k", 6)) {
206 } else if (!strncmp(buf, "test_se0_nak", 12)) {
207 testmode = TEST_SE0_NAK;
208 } else if (!strncmp(buf, "test_packet", 11)) {
209 testmode = TEST_PACKET;
210 } else if (!strncmp(buf, "test_force_enable", 17)) {
211 testmode = TEST_FORCE_EN;
212 } else if (!strncmp(buf, "test_u3", 7)) {
213 testmode = USB_SS_PORT_LS_COMP_MOD;
214 } else if (!strncmp(buf, "test_flip_u3", 12)) {
215 testmode = USB_SS_PORT_LS_COMP_MOD;
218 dev_warn(rockchip->dev, "Test cmd not support!\n");
222 if (edev && !extcon_get_cable_state_(edev, EXTCON_USB_HOST)) {
223 if (extcon_get_cable_state_(edev, EXTCON_USB) > 0)
224 extcon_set_cable_state_(edev, EXTCON_USB, false);
226 property.intval = flip;
227 extcon_set_property(edev, EXTCON_USB_HOST,
228 EXTCON_PROP_USB_TYPEC_POLARITY, property);
229 extcon_set_cable_state_(edev, EXTCON_USB_HOST, true);
231 /* Add a delay 1~1.5s to wait for XHCI HCD init */
232 usleep_range(1000000, 1500000);
235 dwc3_rockchip_set_test_mode(rockchip, testmode);
240 static const struct file_operations dwc3_host_testmode_fops = {
241 .open = dwc3_rockchip_host_testmode_open,
242 .write = dwc3_rockchip_host_testmode_write,
245 .release = single_release,
248 static void dwc3_rockchip_debugfs_init(struct dwc3_rockchip *rockchip)
253 root = debugfs_create_dir(dev_name(rockchip->dev), NULL);
254 if (IS_ERR_OR_NULL(root)) {
256 dev_err(rockchip->dev, "Can't create debugfs root\n");
259 rockchip->root = root;
261 if (IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) ||
262 IS_ENABLED(CONFIG_USB_DWC3_HOST)) {
263 file = debugfs_create_file("host_testmode", S_IRUSR | S_IWUSR,
265 &dwc3_host_testmode_fops);
267 dev_dbg(rockchip->dev, "Can't create debugfs host_testmode\n");
271 static int dwc3_rockchip_device_notifier(struct notifier_block *nb,
272 unsigned long event, void *ptr)
274 struct dwc3_rockchip *rockchip =
275 container_of(nb, struct dwc3_rockchip, device_nb);
277 if (!rockchip->suspended)
278 schedule_work(&rockchip->otg_work);
283 static int dwc3_rockchip_host_notifier(struct notifier_block *nb,
284 unsigned long event, void *ptr)
286 struct dwc3_rockchip *rockchip =
287 container_of(nb, struct dwc3_rockchip, host_nb);
289 if (!rockchip->suspended)
290 schedule_work(&rockchip->otg_work);
295 static void dwc3_rockchip_otg_extcon_evt_work(struct work_struct *work)
297 struct dwc3_rockchip *rockchip =
298 container_of(work, struct dwc3_rockchip, otg_work);
299 struct dwc3 *dwc = rockchip->dwc;
300 struct extcon_dev *edev = rockchip->edev;
302 struct xhci_hcd *xhci;
308 mutex_lock(&rockchip->lock);
310 if (extcon_get_cable_state_(edev, EXTCON_USB) > 0) {
311 if (rockchip->connected)
315 * If dr_mode is host only, never to set
316 * the mode to the peripheral mode.
318 if (dwc->dr_mode == USB_DR_MODE_HOST) {
319 dev_warn(rockchip->dev, "USB peripheral not support!\n");
324 * Assert otg reset can put the dwc in P2 state, it's
325 * necessary operation prior to phy power on. However,
326 * asserting the otg reset may affect dwc chip operation.
327 * The reset will clear all of the dwc controller registers.
328 * So we need to reinit the dwc controller after deassert
329 * the reset. We use pm runtime to initialize dwc controller.
330 * Also, there are no synchronization primitives, meaning
331 * the dwc3 core code could at least in theory access chip
332 * registers while the reset is asserted, with unknown impact.
334 if (!rockchip->skip_suspend) {
335 reset_control_assert(rockchip->otg_rst);
336 usleep_range(1000, 1200);
337 reset_control_deassert(rockchip->otg_rst);
339 pm_runtime_get_sync(rockchip->dev);
340 pm_runtime_get_sync(dwc->dev);
342 rockchip->skip_suspend = false;
345 spin_lock_irqsave(&dwc->lock, flags);
346 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
347 spin_unlock_irqrestore(&dwc->lock, flags);
349 rockchip->connected = true;
350 dev_info(rockchip->dev, "USB peripheral connected\n");
351 } else if (extcon_get_cable_state_(edev, EXTCON_USB_HOST) > 0) {
352 if (rockchip->connected)
355 if (rockchip->skip_suspend) {
356 pm_runtime_put(dwc->dev);
357 pm_runtime_put(rockchip->dev);
358 rockchip->skip_suspend = false;
362 * If dr_mode is device only, never to
363 * set the mode to the host mode.
365 if (dwc->dr_mode == USB_DR_MODE_PERIPHERAL) {
366 dev_warn(rockchip->dev, "USB HOST not support!\n");
371 * Assert otg reset can put the dwc in P2 state, it's
372 * necessary operation prior to phy power on. However,
373 * asserting the otg reset may affect dwc chip operation.
374 * The reset will clear all of the dwc controller registers.
375 * So we need to reinit the dwc controller after deassert
376 * the reset. We use pm runtime to initialize dwc controller.
377 * Also, there are no synchronization primitives, meaning
378 * the dwc3 core code could at least in theory access chip
379 * registers while the reset is asserted, with unknown impact.
381 reset_control_assert(rockchip->otg_rst);
382 usleep_range(1000, 1200);
383 reset_control_deassert(rockchip->otg_rst);
386 * In usb3 phy init, it will access usb3 module, so we need
387 * to resume rockchip dev before phy init to make sure usb3
390 pm_runtime_get_sync(rockchip->dev);
393 * Don't abort on errors. If powering on a phy fails,
394 * we still need to init dwc controller and add the
395 * HCDs to avoid a crash when unloading the driver.
397 ret = phy_power_on(dwc->usb2_generic_phy);
399 dev_err(dwc->dev, "Failed to power on usb2 phy\n");
401 ret = phy_power_on(dwc->usb3_generic_phy);
403 phy_power_off(dwc->usb2_generic_phy);
404 dev_err(dwc->dev, "Failed to power on usb3 phy\n");
407 pm_runtime_get_sync(dwc->dev);
409 spin_lock_irqsave(&dwc->lock, flags);
410 dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
411 spin_unlock_irqrestore(&dwc->lock, flags);
414 * The following sleep helps to ensure that inserted USB3
415 * Ethernet devices are discovered if already inserted
418 usleep_range(10000, 11000);
420 hcd = dev_get_drvdata(&dwc->xhci->dev);
422 if (hcd->state == HC_STATE_HALT) {
423 usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
424 usb_add_hcd(hcd->shared_hcd, hcd->irq, IRQF_SHARED);
427 rockchip->connected = true;
428 dev_info(rockchip->dev, "USB HOST connected\n");
430 if (!rockchip->connected)
433 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
436 * xhci does not support runtime pm. If HCDs are not removed
437 * here and and re-added after a cable is inserted, USB3
438 * connections will not work.
439 * A clean(er) solution would be to implement runtime pm
440 * support in xhci. After that is available, this code should
442 * HCDs have to be removed here to prevent attempts by the
443 * xhci code to access xhci registers after the call to
444 * pm_runtime_put_sync_suspend(). On rk3399, this can result
445 * in a crash under certain circumstances (this was observed
446 * on 3399 chromebook if the system is running on battery).
448 if (DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_HOST ||
449 DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_OTG) {
450 hcd = dev_get_drvdata(&dwc->xhci->dev);
451 xhci = hcd_to_xhci(hcd);
453 if (hcd->state != HC_STATE_HALT) {
454 xhci->xhc_state |= XHCI_STATE_REMOVING;
458 * Wait until XHCI controller resume from
459 * PM suspend, them we can remove hcd safely.
461 while (dwc->xhci->dev.power.is_suspended) {
463 dev_err(rockchip->dev,
464 "wait for XHCI resume 10s timeout!\n");
470 #ifdef CONFIG_FREEZER
472 * usb_remove_hcd() may call usb_disconnect() to
473 * remove a block device pluged in before.
474 * Unfortunately, the block layer suspend/resume
475 * path is fundamentally broken due to freezable
476 * kthreads and workqueue and may deadlock if a
477 * block device gets removed while resume is in
480 * We need to add a ugly hack to avoid removing
481 * hcd and kicking off device removal while
482 * freezer is active. This is a joke but does
483 * avoid this particular deadlock when test with
484 * USB-C HUB and USB2/3 flash drive.
487 usleep_range(10000, 11000);
490 usb_remove_hcd(hcd->shared_hcd);
494 phy_power_off(dwc->usb2_generic_phy);
495 phy_power_off(dwc->usb3_generic_phy);
498 if (DWC3_GCTL_PRTCAP(reg) == DWC3_GCTL_PRTCAP_DEVICE) {
499 ret = readx_poll_timeout(atomic_read,
500 &dwc->dev->power.usage_count,
502 val < 2 && !dwc->connected,
504 PERIPHERAL_DISCONNECT_TIMEOUT);
506 rockchip->skip_suspend = true;
507 dev_warn(rockchip->dev, "Peripheral disconnect timeout\n");
511 if (!rockchip->skip_suspend) {
512 pm_runtime_put_sync_suspend(dwc->dev);
513 pm_runtime_put_sync_suspend(rockchip->dev);
516 rockchip->connected = false;
517 dev_info(rockchip->dev, "USB unconnected\n");
521 mutex_unlock(&rockchip->lock);
524 static int dwc3_rockchip_extcon_register(struct dwc3_rockchip *rockchip)
527 struct device *dev = rockchip->dev;
528 struct extcon_dev *edev;
530 if (device_property_read_bool(dev, "extcon")) {
531 edev = extcon_get_edev_by_phandle(dev, 0);
533 if (PTR_ERR(edev) != -EPROBE_DEFER)
534 dev_err(dev, "couldn't get extcon device\n");
535 return PTR_ERR(edev);
538 INIT_WORK(&rockchip->otg_work,
539 dwc3_rockchip_otg_extcon_evt_work);
541 rockchip->device_nb.notifier_call =
542 dwc3_rockchip_device_notifier;
543 ret = extcon_register_notifier(edev, EXTCON_USB,
544 &rockchip->device_nb);
546 dev_err(dev, "failed to register notifier for USB\n");
550 rockchip->host_nb.notifier_call =
551 dwc3_rockchip_host_notifier;
552 ret = extcon_register_notifier(edev, EXTCON_USB_HOST,
555 dev_err(dev, "failed to register notifier for USB HOST\n");
556 extcon_unregister_notifier(edev, EXTCON_USB,
557 &rockchip->device_nb);
561 rockchip->edev = edev;
567 static void dwc3_rockchip_extcon_unregister(struct dwc3_rockchip *rockchip)
572 extcon_unregister_notifier(rockchip->edev, EXTCON_USB,
573 &rockchip->device_nb);
574 extcon_unregister_notifier(rockchip->edev, EXTCON_USB_HOST,
576 cancel_work_sync(&rockchip->otg_work);
579 static int dwc3_rockchip_probe(struct platform_device *pdev)
581 struct dwc3_rockchip *rockchip;
582 struct device *dev = &pdev->dev;
583 struct device_node *np = dev->of_node, *child;
584 struct platform_device *child_pdev;
590 rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL);
595 count = of_clk_get_parent_count(np);
599 rockchip->num_clocks = count;
601 rockchip->clks = devm_kcalloc(dev, rockchip->num_clocks,
602 sizeof(struct clk *), GFP_KERNEL);
606 platform_set_drvdata(pdev, rockchip);
608 mutex_init(&rockchip->lock);
612 mutex_lock(&rockchip->lock);
614 for (i = 0; i < rockchip->num_clocks; i++) {
617 clk = of_clk_get(np, i);
623 ret = clk_prepare_enable(clk);
629 rockchip->clks[i] = clk;
632 pm_runtime_set_active(dev);
633 pm_runtime_enable(dev);
634 ret = pm_runtime_get_sync(dev);
636 dev_err(dev, "get_sync failed with err %d\n", ret);
640 rockchip->otg_rst = devm_reset_control_get(dev, "usb3-otg");
641 if (IS_ERR(rockchip->otg_rst)) {
642 dev_err(dev, "could not get reset controller\n");
643 ret = PTR_ERR(rockchip->otg_rst);
647 child = of_get_child_by_name(np, "dwc3");
649 dev_err(dev, "failed to find dwc3 core node\n");
654 /* Allocate and initialize the core */
655 ret = of_platform_populate(np, NULL, NULL, dev);
657 dev_err(dev, "failed to create dwc3 core\n");
661 child_pdev = of_find_device_by_node(child);
663 dev_err(dev, "failed to find dwc3 core device\n");
668 rockchip->dwc = platform_get_drvdata(child_pdev);
669 if (!rockchip->dwc) {
670 dev_err(dev, "failed to get drvdata dwc3\n");
675 ret = dwc3_rockchip_extcon_register(rockchip);
679 if (rockchip->edev) {
680 if (rockchip->dwc->dr_mode == USB_DR_MODE_HOST ||
681 rockchip->dwc->dr_mode == USB_DR_MODE_OTG) {
682 struct usb_hcd *hcd =
683 dev_get_drvdata(&rockchip->dwc->xhci->dev);
685 dev_err(dev, "fail to get drvdata hcd\n");
689 if (hcd->state != HC_STATE_HALT) {
690 usb_remove_hcd(hcd->shared_hcd);
695 pm_runtime_set_autosuspend_delay(&child_pdev->dev,
696 DWC3_ROCKCHIP_AUTOSUSPEND_DELAY);
697 pm_runtime_allow(&child_pdev->dev);
698 pm_runtime_suspend(&child_pdev->dev);
699 pm_runtime_put_sync(dev);
701 if ((extcon_get_cable_state_(rockchip->edev,
703 (extcon_get_cable_state_(rockchip->edev,
704 EXTCON_USB_HOST) > 0))
705 schedule_work(&rockchip->otg_work);
708 dwc3_rockchip_debugfs_init(rockchip);
710 mutex_unlock(&rockchip->lock);
715 dwc3_rockchip_extcon_unregister(rockchip);
718 of_platform_depopulate(dev);
721 pm_runtime_put_sync(dev);
722 pm_runtime_disable(dev);
725 for (i = 0; i < rockchip->num_clocks && rockchip->clks[i]; i++) {
726 if (!pm_runtime_status_suspended(dev))
727 clk_disable(rockchip->clks[i]);
728 clk_unprepare(rockchip->clks[i]);
729 clk_put(rockchip->clks[i]);
732 mutex_unlock(&rockchip->lock);
737 static int dwc3_rockchip_remove(struct platform_device *pdev)
739 struct dwc3_rockchip *rockchip = platform_get_drvdata(pdev);
740 struct device *dev = &pdev->dev;
743 dwc3_rockchip_extcon_unregister(rockchip);
745 /* Restore hcd state before unregistering xhci */
746 if (rockchip->edev && !rockchip->connected) {
747 struct usb_hcd *hcd =
748 dev_get_drvdata(&rockchip->dwc->xhci->dev);
750 pm_runtime_get_sync(dev);
753 * The xhci code does not expect that HCDs have been removed.
754 * It will unconditionally call usb_remove_hcd() when the xhci
755 * driver is unloaded in of_platform_depopulate(). This results
756 * in a crash if the HCDs were already removed. To avoid this
757 * crash, add the HCDs here as dummy operation.
758 * This code should be removed after pm runtime support
759 * has been added to xhci.
761 if (hcd->state == HC_STATE_HALT) {
762 usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
763 usb_add_hcd(hcd->shared_hcd, hcd->irq, IRQF_SHARED);
767 of_platform_depopulate(dev);
769 pm_runtime_put_sync(dev);
770 pm_runtime_disable(dev);
772 for (i = 0; i < rockchip->num_clocks; i++) {
773 if (!pm_runtime_status_suspended(dev))
774 clk_disable(rockchip->clks[i]);
775 clk_unprepare(rockchip->clks[i]);
776 clk_put(rockchip->clks[i]);
783 static int dwc3_rockchip_runtime_suspend(struct device *dev)
785 struct dwc3_rockchip *rockchip = dev_get_drvdata(dev);
788 for (i = 0; i < rockchip->num_clocks; i++)
789 clk_disable(rockchip->clks[i]);
791 device_init_wakeup(dev, false);
796 static int dwc3_rockchip_runtime_resume(struct device *dev)
798 struct dwc3_rockchip *rockchip = dev_get_drvdata(dev);
801 for (i = 0; i < rockchip->num_clocks; i++)
802 clk_enable(rockchip->clks[i]);
804 device_init_wakeup(dev, true);
809 static int dwc3_rockchip_suspend(struct device *dev)
811 struct dwc3_rockchip *rockchip = dev_get_drvdata(dev);
812 struct dwc3 *dwc = rockchip->dwc;
814 rockchip->suspended = true;
815 cancel_work_sync(&rockchip->otg_work);
817 if (rockchip->edev && dwc->dr_mode != USB_DR_MODE_PERIPHERAL) {
819 * If USB HOST connected, we will do phy power
820 * on in extcon evt work, so need to do phy
821 * power off in suspend. And we just power off
822 * USB2 PHY here because USB3 PHY power on operation
823 * need to be done while DWC3 controller is in P2
824 * state, but after resume DWC3 controller is in
825 * P0 state. So we put USB3 PHY in power on state.
827 if (extcon_get_cable_state_(rockchip->edev,
828 EXTCON_USB_HOST) > 0)
829 phy_power_off(dwc->usb2_generic_phy);
835 static int dwc3_rockchip_resume(struct device *dev)
837 struct dwc3_rockchip *rockchip = dev_get_drvdata(dev);
838 struct dwc3 *dwc = rockchip->dwc;
840 rockchip->suspended = false;
843 schedule_work(&rockchip->otg_work);
845 if (rockchip->edev && dwc->dr_mode != USB_DR_MODE_PERIPHERAL) {
846 if (extcon_get_cable_state_(rockchip->edev,
847 EXTCON_USB_HOST) > 0)
848 phy_power_on(dwc->usb2_generic_phy);
854 static const struct dev_pm_ops dwc3_rockchip_dev_pm_ops = {
855 SET_SYSTEM_SLEEP_PM_OPS(dwc3_rockchip_suspend, dwc3_rockchip_resume)
856 SET_RUNTIME_PM_OPS(dwc3_rockchip_runtime_suspend,
857 dwc3_rockchip_runtime_resume, NULL)
860 #define DEV_PM_OPS (&dwc3_rockchip_dev_pm_ops)
862 #define DEV_PM_OPS NULL
863 #endif /* CONFIG_PM */
865 static const struct of_device_id rockchip_dwc3_match[] = {
866 { .compatible = "rockchip,rk3399-dwc3" },
870 MODULE_DEVICE_TABLE(of, rockchip_dwc3_match);
872 static struct platform_driver dwc3_rockchip_driver = {
873 .probe = dwc3_rockchip_probe,
874 .remove = dwc3_rockchip_remove,
876 .name = "rockchip-dwc3",
877 .of_match_table = rockchip_dwc3_match,
882 module_platform_driver(dwc3_rockchip_driver);
884 MODULE_ALIAS("platform:rockchip-dwc3");
885 MODULE_AUTHOR("William Wu <william.wu@rock-chips.com>");
886 MODULE_LICENSE("GPL v2");
887 MODULE_DESCRIPTION("DesignWare USB3 ROCKCHIP Glue Layer");