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/of_clk.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/extcon.h>
16 #include <linux/interconnect.h>
17 #include <linux/of_platform.h>
18 #include <linux/platform_device.h>
19 #include <linux/phy/phy.h>
20 #include <linux/usb/of.h>
21 #include <linux/reset.h>
22 #include <linux/iopoll.h>
26 /* USB QSCRATCH Hardware registers */
27 #define QSCRATCH_HS_PHY_CTRL 0x10
28 #define UTMI_OTG_VBUS_VALID BIT(20)
29 #define SW_SESSVLD_SEL BIT(28)
31 #define QSCRATCH_SS_PHY_CTRL 0x30
32 #define LANE0_PWR_PRESENT BIT(24)
34 #define QSCRATCH_GENERAL_CFG 0x08
35 #define PIPE_UTMI_CLK_SEL BIT(0)
36 #define PIPE3_PHYSTATUS_SW BIT(3)
37 #define PIPE_UTMI_CLK_DIS BIT(8)
39 #define PWR_EVNT_IRQ_STAT_REG 0x58
40 #define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
41 #define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
43 #define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
44 #define SDM845_QSCRATCH_SIZE 0x400
45 #define SDM845_DWC3_CORE_SIZE 0xcd00
47 /* Interconnect path bandwidths in MBps */
48 #define USB_MEMORY_AVG_HS_BW MBps_to_icc(240)
49 #define USB_MEMORY_PEAK_HS_BW MBps_to_icc(700)
50 #define USB_MEMORY_AVG_SS_BW MBps_to_icc(1000)
51 #define USB_MEMORY_PEAK_SS_BW MBps_to_icc(2500)
52 #define APPS_USB_AVG_BW 0
53 #define APPS_USB_PEAK_BW MBps_to_icc(40)
55 struct dwc3_acpi_pdata {
56 u32 qscratch_base_offset;
57 u32 qscratch_base_size;
58 u32 dwc3_core_base_size;
60 int dp_hs_phy_irq_index;
61 int dm_hs_phy_irq_index;
67 void __iomem *qscratch_base;
68 struct platform_device *dwc3;
71 struct reset_control *resets;
78 struct extcon_dev *edev;
79 struct extcon_dev *host_edev;
80 struct notifier_block vbus_nb;
81 struct notifier_block host_nb;
83 const struct dwc3_acpi_pdata *acpi_pdata;
85 enum usb_dr_mode mode;
88 struct icc_path *icc_path_ddr;
89 struct icc_path *icc_path_apps;
92 static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val)
96 reg = readl(base + offset);
98 writel(reg, base + offset);
100 /* ensure that above write is through */
101 readl(base + offset);
104 static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val)
108 reg = readl(base + offset);
110 writel(reg, base + offset);
112 /* ensure that above write is through */
113 readl(base + offset);
116 static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom *qcom, bool enable)
119 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
121 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
122 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
124 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL,
126 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL,
127 UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
131 static int dwc3_qcom_vbus_notifier(struct notifier_block *nb,
132 unsigned long event, void *ptr)
134 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb);
136 /* enable vbus override for device mode */
137 dwc3_qcom_vbus_overrride_enable(qcom, event);
138 qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST;
143 static int dwc3_qcom_host_notifier(struct notifier_block *nb,
144 unsigned long event, void *ptr)
146 struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb);
148 /* disable vbus override in host mode */
149 dwc3_qcom_vbus_overrride_enable(qcom, !event);
150 qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL;
155 static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom)
157 struct device *dev = qcom->dev;
158 struct extcon_dev *host_edev;
161 if (!of_property_read_bool(dev->of_node, "extcon"))
164 qcom->edev = extcon_get_edev_by_phandle(dev, 0);
165 if (IS_ERR(qcom->edev))
166 return PTR_ERR(qcom->edev);
168 qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier;
170 qcom->host_edev = extcon_get_edev_by_phandle(dev, 1);
171 if (IS_ERR(qcom->host_edev))
172 qcom->host_edev = NULL;
174 ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB,
177 dev_err(dev, "VBUS notifier register failed\n");
182 host_edev = qcom->host_edev;
184 host_edev = qcom->edev;
186 qcom->host_nb.notifier_call = dwc3_qcom_host_notifier;
187 ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST,
190 dev_err(dev, "Host notifier register failed\n");
194 /* Update initial VBUS override based on extcon state */
195 if (extcon_get_state(qcom->edev, EXTCON_USB) ||
196 !extcon_get_state(host_edev, EXTCON_USB_HOST))
197 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev);
199 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev);
204 static int dwc3_qcom_interconnect_enable(struct dwc3_qcom *qcom)
208 ret = icc_enable(qcom->icc_path_ddr);
212 ret = icc_enable(qcom->icc_path_apps);
214 icc_disable(qcom->icc_path_ddr);
219 static int dwc3_qcom_interconnect_disable(struct dwc3_qcom *qcom)
223 ret = icc_disable(qcom->icc_path_ddr);
227 ret = icc_disable(qcom->icc_path_apps);
229 icc_enable(qcom->icc_path_ddr);
235 * dwc3_qcom_interconnect_init() - Get interconnect path handles
236 * and set bandwidhth.
237 * @qcom: Pointer to the concerned usb core.
240 static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
242 struct device *dev = qcom->dev;
245 qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr");
246 if (IS_ERR(qcom->icc_path_ddr)) {
247 dev_err(dev, "failed to get usb-ddr path: %ld\n",
248 PTR_ERR(qcom->icc_path_ddr));
249 return PTR_ERR(qcom->icc_path_ddr);
252 qcom->icc_path_apps = of_icc_get(dev, "apps-usb");
253 if (IS_ERR(qcom->icc_path_apps)) {
254 dev_err(dev, "failed to get apps-usb path: %ld\n",
255 PTR_ERR(qcom->icc_path_apps));
256 return PTR_ERR(qcom->icc_path_apps);
259 if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
260 usb_get_maximum_speed(&qcom->dwc3->dev) == USB_SPEED_UNKNOWN)
261 ret = icc_set_bw(qcom->icc_path_ddr,
262 USB_MEMORY_AVG_SS_BW, USB_MEMORY_PEAK_SS_BW);
264 ret = icc_set_bw(qcom->icc_path_ddr,
265 USB_MEMORY_AVG_HS_BW, USB_MEMORY_PEAK_HS_BW);
268 dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
272 ret = icc_set_bw(qcom->icc_path_apps,
273 APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
275 dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
283 * dwc3_qcom_interconnect_exit() - Release interconnect path handles
284 * @qcom: Pointer to the concerned usb core.
286 * This function is used to release interconnect path handle.
288 static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom)
290 icc_put(qcom->icc_path_ddr);
291 icc_put(qcom->icc_path_apps);
294 static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom)
296 if (qcom->hs_phy_irq) {
297 disable_irq_wake(qcom->hs_phy_irq);
298 disable_irq_nosync(qcom->hs_phy_irq);
301 if (qcom->dp_hs_phy_irq) {
302 disable_irq_wake(qcom->dp_hs_phy_irq);
303 disable_irq_nosync(qcom->dp_hs_phy_irq);
306 if (qcom->dm_hs_phy_irq) {
307 disable_irq_wake(qcom->dm_hs_phy_irq);
308 disable_irq_nosync(qcom->dm_hs_phy_irq);
311 if (qcom->ss_phy_irq) {
312 disable_irq_wake(qcom->ss_phy_irq);
313 disable_irq_nosync(qcom->ss_phy_irq);
317 static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom)
319 if (qcom->hs_phy_irq) {
320 enable_irq(qcom->hs_phy_irq);
321 enable_irq_wake(qcom->hs_phy_irq);
324 if (qcom->dp_hs_phy_irq) {
325 enable_irq(qcom->dp_hs_phy_irq);
326 enable_irq_wake(qcom->dp_hs_phy_irq);
329 if (qcom->dm_hs_phy_irq) {
330 enable_irq(qcom->dm_hs_phy_irq);
331 enable_irq_wake(qcom->dm_hs_phy_irq);
334 if (qcom->ss_phy_irq) {
335 enable_irq(qcom->ss_phy_irq);
336 enable_irq_wake(qcom->ss_phy_irq);
340 static int dwc3_qcom_suspend(struct dwc3_qcom *qcom)
345 if (qcom->is_suspended)
348 val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG);
349 if (!(val & PWR_EVNT_LPM_IN_L2_MASK))
350 dev_err(qcom->dev, "HS-PHY not in L2\n");
352 for (i = qcom->num_clocks - 1; i >= 0; i--)
353 clk_disable_unprepare(qcom->clks[i]);
355 ret = dwc3_qcom_interconnect_disable(qcom);
357 dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret);
359 qcom->is_suspended = true;
360 dwc3_qcom_enable_interrupts(qcom);
365 static int dwc3_qcom_resume(struct dwc3_qcom *qcom)
370 if (!qcom->is_suspended)
373 dwc3_qcom_disable_interrupts(qcom);
375 for (i = 0; i < qcom->num_clocks; i++) {
376 ret = clk_prepare_enable(qcom->clks[i]);
379 clk_disable_unprepare(qcom->clks[i]);
384 ret = dwc3_qcom_interconnect_enable(qcom);
386 dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret);
388 /* Clear existing events from PHY related to L2 in/out */
389 dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG,
390 PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK);
392 qcom->is_suspended = false;
397 static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data)
399 struct dwc3_qcom *qcom = data;
400 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3);
402 /* If pm_suspended then let pm_resume take care of resuming h/w */
403 if (qcom->pm_suspended)
407 pm_runtime_resume(&dwc->xhci->dev);
412 static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom)
414 /* Configure dwc3 to use UTMI clock as PIPE clock not present */
415 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
418 usleep_range(100, 1000);
420 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
421 PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
423 usleep_range(100, 1000);
425 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG,
429 static int dwc3_qcom_get_irq(struct platform_device *pdev,
430 const char *name, int num)
432 struct device_node *np = pdev->dev.of_node;
436 ret = platform_get_irq_byname(pdev, name);
438 ret = platform_get_irq(pdev, num);
443 static int dwc3_qcom_setup_irq(struct platform_device *pdev)
445 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
446 const struct dwc3_acpi_pdata *pdata = qcom->acpi_pdata;
450 irq = dwc3_qcom_get_irq(pdev, "hs_phy_irq",
451 pdata ? pdata->hs_phy_irq_index : -1);
453 /* Keep wakeup interrupts disabled until suspend */
454 irq_set_status_flags(irq, IRQ_NOAUTOEN);
455 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
456 qcom_dwc3_resume_irq,
457 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
458 "qcom_dwc3 HS", qcom);
460 dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret);
463 qcom->hs_phy_irq = irq;
466 irq = dwc3_qcom_get_irq(pdev, "dp_hs_phy_irq",
467 pdata ? pdata->dp_hs_phy_irq_index : -1);
469 irq_set_status_flags(irq, IRQ_NOAUTOEN);
470 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
471 qcom_dwc3_resume_irq,
472 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
473 "qcom_dwc3 DP_HS", qcom);
475 dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret);
478 qcom->dp_hs_phy_irq = irq;
481 irq = dwc3_qcom_get_irq(pdev, "dm_hs_phy_irq",
482 pdata ? pdata->dm_hs_phy_irq_index : -1);
484 irq_set_status_flags(irq, IRQ_NOAUTOEN);
485 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
486 qcom_dwc3_resume_irq,
487 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
488 "qcom_dwc3 DM_HS", qcom);
490 dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret);
493 qcom->dm_hs_phy_irq = irq;
496 irq = dwc3_qcom_get_irq(pdev, "ss_phy_irq",
497 pdata ? pdata->ss_phy_irq_index : -1);
499 irq_set_status_flags(irq, IRQ_NOAUTOEN);
500 ret = devm_request_threaded_irq(qcom->dev, irq, NULL,
501 qcom_dwc3_resume_irq,
502 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
503 "qcom_dwc3 SS", qcom);
505 dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret);
508 qcom->ss_phy_irq = irq;
514 static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count)
516 struct device *dev = qcom->dev;
517 struct device_node *np = dev->of_node;
526 qcom->num_clocks = count;
528 qcom->clks = devm_kcalloc(dev, qcom->num_clocks,
529 sizeof(struct clk *), GFP_KERNEL);
533 for (i = 0; i < qcom->num_clocks; i++) {
537 clk = of_clk_get(np, i);
540 clk_put(qcom->clks[i]);
544 ret = clk_prepare_enable(clk);
547 clk_disable_unprepare(qcom->clks[i]);
548 clk_put(qcom->clks[i]);
561 static const struct property_entry dwc3_qcom_acpi_properties[] = {
562 PROPERTY_ENTRY_STRING("dr_mode", "host"),
566 static int dwc3_qcom_acpi_register_core(struct platform_device *pdev)
568 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
569 struct device *dev = &pdev->dev;
570 struct resource *res, *child_res = NULL;
574 qcom->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
578 qcom->dwc3->dev.parent = dev;
579 qcom->dwc3->dev.type = dev->type;
580 qcom->dwc3->dev.dma_mask = dev->dma_mask;
581 qcom->dwc3->dev.dma_parms = dev->dma_parms;
582 qcom->dwc3->dev.coherent_dma_mask = dev->coherent_dma_mask;
584 child_res = kcalloc(2, sizeof(*child_res), GFP_KERNEL);
588 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
590 dev_err(&pdev->dev, "failed to get memory resource\n");
595 child_res[0].flags = res->flags;
596 child_res[0].start = res->start;
597 child_res[0].end = child_res[0].start +
598 qcom->acpi_pdata->dwc3_core_base_size;
600 irq = platform_get_irq(pdev, 0);
601 child_res[1].flags = IORESOURCE_IRQ;
602 child_res[1].start = child_res[1].end = irq;
604 ret = platform_device_add_resources(qcom->dwc3, child_res, 2);
606 dev_err(&pdev->dev, "failed to add resources\n");
610 ret = platform_device_add_properties(qcom->dwc3,
611 dwc3_qcom_acpi_properties);
613 dev_err(&pdev->dev, "failed to add properties\n");
617 ret = platform_device_add(qcom->dwc3);
619 dev_err(&pdev->dev, "failed to add device\n");
626 static int dwc3_qcom_of_register_core(struct platform_device *pdev)
628 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
629 struct device_node *np = pdev->dev.of_node, *dwc3_np;
630 struct device *dev = &pdev->dev;
633 dwc3_np = of_get_child_by_name(np, "dwc3");
635 dev_err(dev, "failed to find dwc3 core child\n");
639 ret = of_platform_populate(np, NULL, NULL, dev);
641 dev_err(dev, "failed to register dwc3 core - %d\n", ret);
645 qcom->dwc3 = of_find_device_by_node(dwc3_np);
647 dev_err(dev, "failed to get dwc3 platform device\n");
654 static int dwc3_qcom_probe(struct platform_device *pdev)
656 struct device_node *np = pdev->dev.of_node;
657 struct device *dev = &pdev->dev;
658 struct dwc3_qcom *qcom;
659 struct resource *res, *parent_res = NULL;
661 bool ignore_pipe_clk;
663 qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL);
667 platform_set_drvdata(pdev, qcom);
668 qcom->dev = &pdev->dev;
670 if (has_acpi_companion(dev)) {
671 qcom->acpi_pdata = acpi_device_get_match_data(dev);
672 if (!qcom->acpi_pdata) {
673 dev_err(&pdev->dev, "no supporting ACPI device data\n");
678 qcom->resets = devm_reset_control_array_get_optional_exclusive(dev);
679 if (IS_ERR(qcom->resets)) {
680 ret = PTR_ERR(qcom->resets);
681 dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret);
685 ret = reset_control_assert(qcom->resets);
687 dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret);
691 usleep_range(10, 1000);
693 ret = reset_control_deassert(qcom->resets);
695 dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
699 ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
701 dev_err(dev, "failed to get clocks\n");
705 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
710 parent_res = kmemdup(res, sizeof(struct resource), GFP_KERNEL);
714 parent_res->start = res->start +
715 qcom->acpi_pdata->qscratch_base_offset;
716 parent_res->end = parent_res->start +
717 qcom->acpi_pdata->qscratch_base_size;
720 qcom->qscratch_base = devm_ioremap_resource(dev, parent_res);
721 if (IS_ERR(qcom->qscratch_base)) {
722 dev_err(dev, "failed to map qscratch, err=%d\n", ret);
723 ret = PTR_ERR(qcom->qscratch_base);
727 ret = dwc3_qcom_setup_irq(pdev);
729 dev_err(dev, "failed to setup IRQs, err=%d\n", ret);
734 * Disable pipe_clk requirement if specified. Used when dwc3
735 * operates without SSPHY and only HS/FS/LS modes are supported.
737 ignore_pipe_clk = device_property_read_bool(dev,
738 "qcom,select-utmi-as-pipe-clk");
740 dwc3_qcom_select_utmi_clk(qcom);
743 ret = dwc3_qcom_of_register_core(pdev);
745 ret = dwc3_qcom_acpi_register_core(pdev);
748 dev_err(dev, "failed to register DWC3 Core, err=%d\n", ret);
752 ret = dwc3_qcom_interconnect_init(qcom);
756 qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev);
758 /* enable vbus override for device mode */
759 if (qcom->mode == USB_DR_MODE_PERIPHERAL)
760 dwc3_qcom_vbus_overrride_enable(qcom, true);
762 /* register extcon to override sw_vbus on Vbus change later */
763 ret = dwc3_qcom_register_extcon(qcom);
765 goto interconnect_exit;
767 device_init_wakeup(&pdev->dev, 1);
768 qcom->is_suspended = false;
769 pm_runtime_set_active(dev);
770 pm_runtime_enable(dev);
771 pm_runtime_forbid(dev);
776 dwc3_qcom_interconnect_exit(qcom);
779 of_platform_depopulate(&pdev->dev);
781 platform_device_put(pdev);
783 for (i = qcom->num_clocks - 1; i >= 0; i--) {
784 clk_disable_unprepare(qcom->clks[i]);
785 clk_put(qcom->clks[i]);
788 reset_control_assert(qcom->resets);
793 static int dwc3_qcom_remove(struct platform_device *pdev)
795 struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
796 struct device *dev = &pdev->dev;
799 of_platform_depopulate(dev);
801 for (i = qcom->num_clocks - 1; i >= 0; i--) {
802 clk_disable_unprepare(qcom->clks[i]);
803 clk_put(qcom->clks[i]);
805 qcom->num_clocks = 0;
807 dwc3_qcom_interconnect_exit(qcom);
808 reset_control_assert(qcom->resets);
810 pm_runtime_allow(dev);
811 pm_runtime_disable(dev);
816 static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev)
818 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
821 ret = dwc3_qcom_suspend(qcom);
823 qcom->pm_suspended = true;
828 static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev)
830 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
833 ret = dwc3_qcom_resume(qcom);
835 qcom->pm_suspended = false;
840 static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev)
842 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
844 return dwc3_qcom_suspend(qcom);
847 static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev)
849 struct dwc3_qcom *qcom = dev_get_drvdata(dev);
851 return dwc3_qcom_resume(qcom);
854 static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = {
855 SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume)
856 SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume,
860 static const struct of_device_id dwc3_qcom_of_match[] = {
861 { .compatible = "qcom,dwc3" },
862 { .compatible = "qcom,msm8996-dwc3" },
863 { .compatible = "qcom,msm8998-dwc3" },
864 { .compatible = "qcom,sdm845-dwc3" },
867 MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match);
870 static const struct dwc3_acpi_pdata sdm845_acpi_pdata = {
871 .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET,
872 .qscratch_base_size = SDM845_QSCRATCH_SIZE,
873 .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE,
874 .hs_phy_irq_index = 1,
875 .dp_hs_phy_irq_index = 4,
876 .dm_hs_phy_irq_index = 3,
877 .ss_phy_irq_index = 2
880 static const struct acpi_device_id dwc3_qcom_acpi_match[] = {
881 { "QCOM2430", (unsigned long)&sdm845_acpi_pdata },
884 MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);
887 static struct platform_driver dwc3_qcom_driver = {
888 .probe = dwc3_qcom_probe,
889 .remove = dwc3_qcom_remove,
892 .pm = &dwc3_qcom_dev_pm_ops,
893 .of_match_table = dwc3_qcom_of_match,
894 .acpi_match_table = ACPI_PTR(dwc3_qcom_acpi_match),
898 module_platform_driver(dwc3_qcom_driver);
900 MODULE_LICENSE("GPL v2");
901 MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver");