1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * Inspired by dwc3-of-simple.c
7 #include <linux/acpi.h>
10 #include <linux/clk.h>
11 #include <linux/irq.h>
12 #include <linux/clk-provider.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/extcon.h>
16 #include <linux/of_platform.h>
17 #include <linux/platform_device.h>
18 #include <linux/phy/phy.h>
19 #include <linux/usb/of.h>
20 #include <linux/reset.h>
21 #include <linux/iopoll.h>
25 /* USB QSCRATCH Hardware registers */
26 #define QSCRATCH_HS_PHY_CTRL 0x10
27 #define UTMI_OTG_VBUS_VALID BIT(20)
28 #define SW_SESSVLD_SEL BIT(28)
30 #define QSCRATCH_SS_PHY_CTRL 0x30
31 #define LANE0_PWR_PRESENT BIT(24)
33 #define QSCRATCH_GENERAL_CFG 0x08
34 #define PIPE_UTMI_CLK_SEL BIT(0)
35 #define PIPE3_PHYSTATUS_SW BIT(3)
36 #define PIPE_UTMI_CLK_DIS BIT(8)
38 #define PWR_EVNT_IRQ_STAT_REG 0x58
39 #define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
40 #define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
42 #define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
43 #define SDM845_QSCRATCH_SIZE 0x400
44 #define SDM845_DWC3_CORE_SIZE 0xcd00
46 struct dwc3_acpi_pdata
{
47 u32 qscratch_base_offset
;
48 u32 qscratch_base_size
;
49 u32 dwc3_core_base_size
;
51 int dp_hs_phy_irq_index
;
52 int dm_hs_phy_irq_index
;
58 void __iomem
*qscratch_base
;
59 struct platform_device
*dwc3
;
62 struct reset_control
*resets
;
69 struct extcon_dev
*edev
;
70 struct extcon_dev
*host_edev
;
71 struct notifier_block vbus_nb
;
72 struct notifier_block host_nb
;
74 const struct dwc3_acpi_pdata
*acpi_pdata
;
76 enum usb_dr_mode mode
;
81 static inline void dwc3_qcom_setbits(void __iomem
*base
, u32 offset
, u32 val
)
85 reg
= readl(base
+ offset
);
87 writel(reg
, base
+ offset
);
89 /* ensure that above write is through */
93 static inline void dwc3_qcom_clrbits(void __iomem
*base
, u32 offset
, u32 val
)
97 reg
= readl(base
+ offset
);
99 writel(reg
, base
+ offset
);
101 /* ensure that above write is through */
102 readl(base
+ offset
);
105 static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom
*qcom
, bool enable
)
108 dwc3_qcom_setbits(qcom
->qscratch_base
, QSCRATCH_SS_PHY_CTRL
,
110 dwc3_qcom_setbits(qcom
->qscratch_base
, QSCRATCH_HS_PHY_CTRL
,
111 UTMI_OTG_VBUS_VALID
| SW_SESSVLD_SEL
);
113 dwc3_qcom_clrbits(qcom
->qscratch_base
, QSCRATCH_SS_PHY_CTRL
,
115 dwc3_qcom_clrbits(qcom
->qscratch_base
, QSCRATCH_HS_PHY_CTRL
,
116 UTMI_OTG_VBUS_VALID
| SW_SESSVLD_SEL
);
120 static int dwc3_qcom_vbus_notifier(struct notifier_block
*nb
,
121 unsigned long event
, void *ptr
)
123 struct dwc3_qcom
*qcom
= container_of(nb
, struct dwc3_qcom
, vbus_nb
);
125 /* enable vbus override for device mode */
126 dwc3_qcom_vbus_overrride_enable(qcom
, event
);
127 qcom
->mode
= event
? USB_DR_MODE_PERIPHERAL
: USB_DR_MODE_HOST
;
132 static int dwc3_qcom_host_notifier(struct notifier_block
*nb
,
133 unsigned long event
, void *ptr
)
135 struct dwc3_qcom
*qcom
= container_of(nb
, struct dwc3_qcom
, host_nb
);
137 /* disable vbus override in host mode */
138 dwc3_qcom_vbus_overrride_enable(qcom
, !event
);
139 qcom
->mode
= event
? USB_DR_MODE_HOST
: USB_DR_MODE_PERIPHERAL
;
144 static int dwc3_qcom_register_extcon(struct dwc3_qcom
*qcom
)
146 struct device
*dev
= qcom
->dev
;
147 struct extcon_dev
*host_edev
;
150 if (!of_property_read_bool(dev
->of_node
, "extcon"))
153 qcom
->edev
= extcon_get_edev_by_phandle(dev
, 0);
154 if (IS_ERR(qcom
->edev
))
155 return PTR_ERR(qcom
->edev
);
157 qcom
->vbus_nb
.notifier_call
= dwc3_qcom_vbus_notifier
;
159 qcom
->host_edev
= extcon_get_edev_by_phandle(dev
, 1);
160 if (IS_ERR(qcom
->host_edev
))
161 qcom
->host_edev
= NULL
;
163 ret
= devm_extcon_register_notifier(dev
, qcom
->edev
, EXTCON_USB
,
166 dev_err(dev
, "VBUS notifier register failed\n");
171 host_edev
= qcom
->host_edev
;
173 host_edev
= qcom
->edev
;
175 qcom
->host_nb
.notifier_call
= dwc3_qcom_host_notifier
;
176 ret
= devm_extcon_register_notifier(dev
, host_edev
, EXTCON_USB_HOST
,
179 dev_err(dev
, "Host notifier register failed\n");
183 /* Update initial VBUS override based on extcon state */
184 if (extcon_get_state(qcom
->edev
, EXTCON_USB
) ||
185 !extcon_get_state(host_edev
, EXTCON_USB_HOST
))
186 dwc3_qcom_vbus_notifier(&qcom
->vbus_nb
, true, qcom
->edev
);
188 dwc3_qcom_vbus_notifier(&qcom
->vbus_nb
, false, qcom
->edev
);
193 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom
*qcom
)
195 if (qcom
->hs_phy_irq
) {
196 disable_irq_wake(qcom
->hs_phy_irq
);
197 disable_irq_nosync(qcom
->hs_phy_irq
);
200 if (qcom
->dp_hs_phy_irq
) {
201 disable_irq_wake(qcom
->dp_hs_phy_irq
);
202 disable_irq_nosync(qcom
->dp_hs_phy_irq
);
205 if (qcom
->dm_hs_phy_irq
) {
206 disable_irq_wake(qcom
->dm_hs_phy_irq
);
207 disable_irq_nosync(qcom
->dm_hs_phy_irq
);
210 if (qcom
->ss_phy_irq
) {
211 disable_irq_wake(qcom
->ss_phy_irq
);
212 disable_irq_nosync(qcom
->ss_phy_irq
);
216 static void dwc3_qcom_enable_interrupts(struct dwc3_qcom
*qcom
)
218 if (qcom
->hs_phy_irq
) {
219 enable_irq(qcom
->hs_phy_irq
);
220 enable_irq_wake(qcom
->hs_phy_irq
);
223 if (qcom
->dp_hs_phy_irq
) {
224 enable_irq(qcom
->dp_hs_phy_irq
);
225 enable_irq_wake(qcom
->dp_hs_phy_irq
);
228 if (qcom
->dm_hs_phy_irq
) {
229 enable_irq(qcom
->dm_hs_phy_irq
);
230 enable_irq_wake(qcom
->dm_hs_phy_irq
);
233 if (qcom
->ss_phy_irq
) {
234 enable_irq(qcom
->ss_phy_irq
);
235 enable_irq_wake(qcom
->ss_phy_irq
);
239 static int dwc3_qcom_suspend(struct dwc3_qcom
*qcom
)
244 if (qcom
->is_suspended
)
247 val
= readl(qcom
->qscratch_base
+ PWR_EVNT_IRQ_STAT_REG
);
248 if (!(val
& PWR_EVNT_LPM_IN_L2_MASK
))
249 dev_err(qcom
->dev
, "HS-PHY not in L2\n");
251 for (i
= qcom
->num_clocks
- 1; i
>= 0; i
--)
252 clk_disable_unprepare(qcom
->clks
[i
]);
254 qcom
->is_suspended
= true;
255 dwc3_qcom_enable_interrupts(qcom
);
260 static int dwc3_qcom_resume(struct dwc3_qcom
*qcom
)
265 if (!qcom
->is_suspended
)
268 dwc3_qcom_disable_interrupts(qcom
);
270 for (i
= 0; i
< qcom
->num_clocks
; i
++) {
271 ret
= clk_prepare_enable(qcom
->clks
[i
]);
274 clk_disable_unprepare(qcom
->clks
[i
]);
279 /* Clear existing events from PHY related to L2 in/out */
280 dwc3_qcom_setbits(qcom
->qscratch_base
, PWR_EVNT_IRQ_STAT_REG
,
281 PWR_EVNT_LPM_IN_L2_MASK
| PWR_EVNT_LPM_OUT_L2_MASK
);
283 qcom
->is_suspended
= false;
288 static irqreturn_t
qcom_dwc3_resume_irq(int irq
, void *data
)
290 struct dwc3_qcom
*qcom
= data
;
291 struct dwc3
*dwc
= platform_get_drvdata(qcom
->dwc3
);
293 /* If pm_suspended then let pm_resume take care of resuming h/w */
294 if (qcom
->pm_suspended
)
298 pm_runtime_resume(&dwc
->xhci
->dev
);
303 static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom
*qcom
)
305 /* Configure dwc3 to use UTMI clock as PIPE clock not present */
306 dwc3_qcom_setbits(qcom
->qscratch_base
, QSCRATCH_GENERAL_CFG
,
309 usleep_range(100, 1000);
311 dwc3_qcom_setbits(qcom
->qscratch_base
, QSCRATCH_GENERAL_CFG
,
312 PIPE_UTMI_CLK_SEL
| PIPE3_PHYSTATUS_SW
);
314 usleep_range(100, 1000);
316 dwc3_qcom_clrbits(qcom
->qscratch_base
, QSCRATCH_GENERAL_CFG
,
320 static int dwc3_qcom_get_irq(struct platform_device
*pdev
,
321 const char *name
, int num
)
323 struct device_node
*np
= pdev
->dev
.of_node
;
327 ret
= platform_get_irq_byname(pdev
, name
);
329 ret
= platform_get_irq(pdev
, num
);
334 static int dwc3_qcom_setup_irq(struct platform_device
*pdev
)
336 struct dwc3_qcom
*qcom
= platform_get_drvdata(pdev
);
337 const struct dwc3_acpi_pdata
*pdata
= qcom
->acpi_pdata
;
339 irq
= dwc3_qcom_get_irq(pdev
, "hs_phy_irq",
340 pdata
? pdata
->hs_phy_irq_index
: -1);
342 /* Keep wakeup interrupts disabled until suspend */
343 irq_set_status_flags(irq
, IRQ_NOAUTOEN
);
344 ret
= devm_request_threaded_irq(qcom
->dev
, irq
, NULL
,
345 qcom_dwc3_resume_irq
,
346 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
347 "qcom_dwc3 HS", qcom
);
349 dev_err(qcom
->dev
, "hs_phy_irq failed: %d\n", ret
);
352 qcom
->hs_phy_irq
= irq
;
355 irq
= dwc3_qcom_get_irq(pdev
, "dp_hs_phy_irq",
356 pdata
? pdata
->dp_hs_phy_irq_index
: -1);
358 irq_set_status_flags(irq
, IRQ_NOAUTOEN
);
359 ret
= devm_request_threaded_irq(qcom
->dev
, irq
, NULL
,
360 qcom_dwc3_resume_irq
,
361 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
362 "qcom_dwc3 DP_HS", qcom
);
364 dev_err(qcom
->dev
, "dp_hs_phy_irq failed: %d\n", ret
);
367 qcom
->dp_hs_phy_irq
= irq
;
370 irq
= dwc3_qcom_get_irq(pdev
, "dm_hs_phy_irq",
371 pdata
? pdata
->dm_hs_phy_irq_index
: -1);
373 irq_set_status_flags(irq
, IRQ_NOAUTOEN
);
374 ret
= devm_request_threaded_irq(qcom
->dev
, irq
, NULL
,
375 qcom_dwc3_resume_irq
,
376 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
377 "qcom_dwc3 DM_HS", qcom
);
379 dev_err(qcom
->dev
, "dm_hs_phy_irq failed: %d\n", ret
);
382 qcom
->dm_hs_phy_irq
= irq
;
385 irq
= dwc3_qcom_get_irq(pdev
, "ss_phy_irq",
386 pdata
? pdata
->ss_phy_irq_index
: -1);
388 irq_set_status_flags(irq
, IRQ_NOAUTOEN
);
389 ret
= devm_request_threaded_irq(qcom
->dev
, irq
, NULL
,
390 qcom_dwc3_resume_irq
,
391 IRQF_TRIGGER_HIGH
| IRQF_ONESHOT
,
392 "qcom_dwc3 SS", qcom
);
394 dev_err(qcom
->dev
, "ss_phy_irq failed: %d\n", ret
);
397 qcom
->ss_phy_irq
= irq
;
403 static int dwc3_qcom_clk_init(struct dwc3_qcom
*qcom
, int count
)
405 struct device
*dev
= qcom
->dev
;
406 struct device_node
*np
= dev
->of_node
;
415 qcom
->num_clocks
= count
;
417 qcom
->clks
= devm_kcalloc(dev
, qcom
->num_clocks
,
418 sizeof(struct clk
*), GFP_KERNEL
);
422 for (i
= 0; i
< qcom
->num_clocks
; i
++) {
426 clk
= of_clk_get(np
, i
);
429 clk_put(qcom
->clks
[i
]);
433 ret
= clk_prepare_enable(clk
);
436 clk_disable_unprepare(qcom
->clks
[i
]);
437 clk_put(qcom
->clks
[i
]);
450 static const struct property_entry dwc3_qcom_acpi_properties
[] = {
451 PROPERTY_ENTRY_STRING("dr_mode", "host"),
455 static int dwc3_qcom_acpi_register_core(struct platform_device
*pdev
)
457 struct dwc3_qcom
*qcom
= platform_get_drvdata(pdev
);
458 struct device
*dev
= &pdev
->dev
;
459 struct resource
*res
, *child_res
= NULL
;
463 qcom
->dwc3
= platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO
);
467 qcom
->dwc3
->dev
.parent
= dev
;
468 qcom
->dwc3
->dev
.type
= dev
->type
;
469 qcom
->dwc3
->dev
.dma_mask
= dev
->dma_mask
;
470 qcom
->dwc3
->dev
.dma_parms
= dev
->dma_parms
;
471 qcom
->dwc3
->dev
.coherent_dma_mask
= dev
->coherent_dma_mask
;
473 child_res
= kcalloc(2, sizeof(*child_res
), GFP_KERNEL
);
477 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
479 dev_err(&pdev
->dev
, "failed to get memory resource\n");
484 child_res
[0].flags
= res
->flags
;
485 child_res
[0].start
= res
->start
;
486 child_res
[0].end
= child_res
[0].start
+
487 qcom
->acpi_pdata
->dwc3_core_base_size
;
489 irq
= platform_get_irq(pdev
, 0);
490 child_res
[1].flags
= IORESOURCE_IRQ
;
491 child_res
[1].start
= child_res
[1].end
= irq
;
493 ret
= platform_device_add_resources(qcom
->dwc3
, child_res
, 2);
495 dev_err(&pdev
->dev
, "failed to add resources\n");
499 ret
= platform_device_add_properties(qcom
->dwc3
,
500 dwc3_qcom_acpi_properties
);
502 dev_err(&pdev
->dev
, "failed to add properties\n");
506 ret
= platform_device_add(qcom
->dwc3
);
508 dev_err(&pdev
->dev
, "failed to add device\n");
515 static int dwc3_qcom_of_register_core(struct platform_device
*pdev
)
517 struct dwc3_qcom
*qcom
= platform_get_drvdata(pdev
);
518 struct device_node
*np
= pdev
->dev
.of_node
, *dwc3_np
;
519 struct device
*dev
= &pdev
->dev
;
522 dwc3_np
= of_get_child_by_name(np
, "dwc3");
524 dev_err(dev
, "failed to find dwc3 core child\n");
528 ret
= of_platform_populate(np
, NULL
, NULL
, dev
);
530 dev_err(dev
, "failed to register dwc3 core - %d\n", ret
);
534 qcom
->dwc3
= of_find_device_by_node(dwc3_np
);
536 dev_err(dev
, "failed to get dwc3 platform device\n");
543 static const struct dwc3_acpi_pdata sdm845_acpi_pdata
= {
544 .qscratch_base_offset
= SDM845_QSCRATCH_BASE_OFFSET
,
545 .qscratch_base_size
= SDM845_QSCRATCH_SIZE
,
546 .dwc3_core_base_size
= SDM845_DWC3_CORE_SIZE
,
547 .hs_phy_irq_index
= 1,
548 .dp_hs_phy_irq_index
= 4,
549 .dm_hs_phy_irq_index
= 3,
550 .ss_phy_irq_index
= 2
553 static int dwc3_qcom_probe(struct platform_device
*pdev
)
555 struct device_node
*np
= pdev
->dev
.of_node
;
556 struct device
*dev
= &pdev
->dev
;
557 struct dwc3_qcom
*qcom
;
558 struct resource
*res
, *parent_res
= NULL
;
560 bool ignore_pipe_clk
;
562 qcom
= devm_kzalloc(&pdev
->dev
, sizeof(*qcom
), GFP_KERNEL
);
566 platform_set_drvdata(pdev
, qcom
);
567 qcom
->dev
= &pdev
->dev
;
569 if (has_acpi_companion(dev
)) {
570 qcom
->acpi_pdata
= acpi_device_get_match_data(dev
);
571 if (!qcom
->acpi_pdata
) {
572 dev_err(&pdev
->dev
, "no supporting ACPI device data\n");
577 qcom
->resets
= devm_reset_control_array_get_optional_exclusive(dev
);
578 if (IS_ERR(qcom
->resets
)) {
579 ret
= PTR_ERR(qcom
->resets
);
580 dev_err(&pdev
->dev
, "failed to get resets, err=%d\n", ret
);
584 ret
= reset_control_assert(qcom
->resets
);
586 dev_err(&pdev
->dev
, "failed to assert resets, err=%d\n", ret
);
590 usleep_range(10, 1000);
592 ret
= reset_control_deassert(qcom
->resets
);
594 dev_err(&pdev
->dev
, "failed to deassert resets, err=%d\n", ret
);
598 ret
= dwc3_qcom_clk_init(qcom
, of_clk_get_parent_count(np
));
600 dev_err(dev
, "failed to get clocks\n");
604 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
609 parent_res
= kmemdup(res
, sizeof(struct resource
), GFP_KERNEL
);
613 parent_res
->start
= res
->start
+
614 qcom
->acpi_pdata
->qscratch_base_offset
;
615 parent_res
->end
= parent_res
->start
+
616 qcom
->acpi_pdata
->qscratch_base_size
;
619 qcom
->qscratch_base
= devm_ioremap_resource(dev
, parent_res
);
620 if (IS_ERR(qcom
->qscratch_base
)) {
621 dev_err(dev
, "failed to map qscratch, err=%d\n", ret
);
622 ret
= PTR_ERR(qcom
->qscratch_base
);
626 ret
= dwc3_qcom_setup_irq(pdev
);
628 dev_err(dev
, "failed to setup IRQs, err=%d\n", ret
);
633 * Disable pipe_clk requirement if specified. Used when dwc3
634 * operates without SSPHY and only HS/FS/LS modes are supported.
636 ignore_pipe_clk
= device_property_read_bool(dev
,
637 "qcom,select-utmi-as-pipe-clk");
639 dwc3_qcom_select_utmi_clk(qcom
);
642 ret
= dwc3_qcom_of_register_core(pdev
);
644 ret
= dwc3_qcom_acpi_register_core(pdev
);
647 dev_err(dev
, "failed to register DWC3 Core, err=%d\n", ret
);
651 qcom
->mode
= usb_get_dr_mode(&qcom
->dwc3
->dev
);
653 /* enable vbus override for device mode */
654 if (qcom
->mode
== USB_DR_MODE_PERIPHERAL
)
655 dwc3_qcom_vbus_overrride_enable(qcom
, true);
657 /* register extcon to override sw_vbus on Vbus change later */
658 ret
= dwc3_qcom_register_extcon(qcom
);
662 device_init_wakeup(&pdev
->dev
, 1);
663 qcom
->is_suspended
= false;
664 pm_runtime_set_active(dev
);
665 pm_runtime_enable(dev
);
666 pm_runtime_forbid(dev
);
672 of_platform_depopulate(&pdev
->dev
);
674 platform_device_put(pdev
);
676 for (i
= qcom
->num_clocks
- 1; i
>= 0; i
--) {
677 clk_disable_unprepare(qcom
->clks
[i
]);
678 clk_put(qcom
->clks
[i
]);
681 reset_control_assert(qcom
->resets
);
686 static int dwc3_qcom_remove(struct platform_device
*pdev
)
688 struct dwc3_qcom
*qcom
= platform_get_drvdata(pdev
);
689 struct device
*dev
= &pdev
->dev
;
692 of_platform_depopulate(dev
);
694 for (i
= qcom
->num_clocks
- 1; i
>= 0; i
--) {
695 clk_disable_unprepare(qcom
->clks
[i
]);
696 clk_put(qcom
->clks
[i
]);
698 qcom
->num_clocks
= 0;
700 reset_control_assert(qcom
->resets
);
702 pm_runtime_allow(dev
);
703 pm_runtime_disable(dev
);
708 static int __maybe_unused
dwc3_qcom_pm_suspend(struct device
*dev
)
710 struct dwc3_qcom
*qcom
= dev_get_drvdata(dev
);
713 ret
= dwc3_qcom_suspend(qcom
);
715 qcom
->pm_suspended
= true;
720 static int __maybe_unused
dwc3_qcom_pm_resume(struct device
*dev
)
722 struct dwc3_qcom
*qcom
= dev_get_drvdata(dev
);
725 ret
= dwc3_qcom_resume(qcom
);
727 qcom
->pm_suspended
= false;
732 static int __maybe_unused
dwc3_qcom_runtime_suspend(struct device
*dev
)
734 struct dwc3_qcom
*qcom
= dev_get_drvdata(dev
);
736 return dwc3_qcom_suspend(qcom
);
739 static int __maybe_unused
dwc3_qcom_runtime_resume(struct device
*dev
)
741 struct dwc3_qcom
*qcom
= dev_get_drvdata(dev
);
743 return dwc3_qcom_resume(qcom
);
746 static const struct dev_pm_ops dwc3_qcom_dev_pm_ops
= {
747 SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend
, dwc3_qcom_pm_resume
)
748 SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend
, dwc3_qcom_runtime_resume
,
752 static const struct of_device_id dwc3_qcom_of_match
[] = {
753 { .compatible
= "qcom,dwc3" },
754 { .compatible
= "qcom,msm8996-dwc3" },
755 { .compatible
= "qcom,msm8998-dwc3" },
756 { .compatible
= "qcom,sdm845-dwc3" },
759 MODULE_DEVICE_TABLE(of
, dwc3_qcom_of_match
);
761 static const struct acpi_device_id dwc3_qcom_acpi_match
[] = {
762 { "QCOM2430", (unsigned long)&sdm845_acpi_pdata
},
765 MODULE_DEVICE_TABLE(acpi
, dwc3_qcom_acpi_match
);
767 static struct platform_driver dwc3_qcom_driver
= {
768 .probe
= dwc3_qcom_probe
,
769 .remove
= dwc3_qcom_remove
,
772 .pm
= &dwc3_qcom_dev_pm_ops
,
773 .of_match_table
= dwc3_qcom_of_match
,
774 .acpi_match_table
= ACPI_PTR(dwc3_qcom_acpi_match
),
778 module_platform_driver(dwc3_qcom_driver
);
780 MODULE_LICENSE("GPL v2");
781 MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");