GNU Linux-libre 6.1.24-gnu
[releases.git] / drivers / usb / dwc3 / dwc3-pci.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * dwc3-pci.c - PCI Specific glue layer
4  *
5  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
6  *
7  * Authors: Felipe Balbi <balbi@ti.com>,
8  *          Sebastian Andrzej Siewior <bigeasy@linutronix.de>
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/pci.h>
15 #include <linux/workqueue.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/platform_device.h>
18 #include <linux/gpio/consumer.h>
19 #include <linux/gpio/machine.h>
20 #include <linux/acpi.h>
21 #include <linux/delay.h>
22
23 #define PCI_DEVICE_ID_INTEL_BYT                 0x0f37
24 #define PCI_DEVICE_ID_INTEL_MRFLD               0x119e
25 #define PCI_DEVICE_ID_INTEL_BSW                 0x22b7
26 #define PCI_DEVICE_ID_INTEL_SPTLP               0x9d30
27 #define PCI_DEVICE_ID_INTEL_SPTH                0xa130
28 #define PCI_DEVICE_ID_INTEL_BXT                 0x0aaa
29 #define PCI_DEVICE_ID_INTEL_BXT_M               0x1aaa
30 #define PCI_DEVICE_ID_INTEL_APL                 0x5aaa
31 #define PCI_DEVICE_ID_INTEL_KBP                 0xa2b0
32 #define PCI_DEVICE_ID_INTEL_CMLLP               0x02ee
33 #define PCI_DEVICE_ID_INTEL_CMLH                0x06ee
34 #define PCI_DEVICE_ID_INTEL_GLK                 0x31aa
35 #define PCI_DEVICE_ID_INTEL_CNPLP               0x9dee
36 #define PCI_DEVICE_ID_INTEL_CNPH                0xa36e
37 #define PCI_DEVICE_ID_INTEL_CNPV                0xa3b0
38 #define PCI_DEVICE_ID_INTEL_ICLLP               0x34ee
39 #define PCI_DEVICE_ID_INTEL_EHL                 0x4b7e
40 #define PCI_DEVICE_ID_INTEL_TGPLP               0xa0ee
41 #define PCI_DEVICE_ID_INTEL_TGPH                0x43ee
42 #define PCI_DEVICE_ID_INTEL_JSP                 0x4dee
43 #define PCI_DEVICE_ID_INTEL_ADL                 0x460e
44 #define PCI_DEVICE_ID_INTEL_ADL_PCH             0x51ee
45 #define PCI_DEVICE_ID_INTEL_ADLN                0x465e
46 #define PCI_DEVICE_ID_INTEL_ADLN_PCH            0x54ee
47 #define PCI_DEVICE_ID_INTEL_ADLS                0x7ae1
48 #define PCI_DEVICE_ID_INTEL_RPL                 0xa70e
49 #define PCI_DEVICE_ID_INTEL_RPLS                0x7a61
50 #define PCI_DEVICE_ID_INTEL_MTLM                0x7eb1
51 #define PCI_DEVICE_ID_INTEL_MTLP                0x7ec1
52 #define PCI_DEVICE_ID_INTEL_MTLS                0x7f6f
53 #define PCI_DEVICE_ID_INTEL_MTL                 0x7e7e
54 #define PCI_DEVICE_ID_INTEL_TGL                 0x9a15
55 #define PCI_DEVICE_ID_AMD_MR                    0x163a
56
57 #define PCI_INTEL_BXT_DSM_GUID          "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
58 #define PCI_INTEL_BXT_FUNC_PMU_PWR      4
59 #define PCI_INTEL_BXT_STATE_D0          0
60 #define PCI_INTEL_BXT_STATE_D3          3
61
62 #define GP_RWBAR                        1
63 #define GP_RWREG1                       0xa0
64 #define GP_RWREG1_ULPI_REFCLK_DISABLE   (1 << 17)
65
66 /**
67  * struct dwc3_pci - Driver private structure
68  * @dwc3: child dwc3 platform_device
69  * @pci: our link to PCI bus
70  * @guid: _DSM GUID
71  * @has_dsm_for_pm: true for devices which need to run _DSM on runtime PM
72  * @wakeup_work: work for asynchronous resume
73  */
74 struct dwc3_pci {
75         struct platform_device *dwc3;
76         struct pci_dev *pci;
77
78         guid_t guid;
79
80         unsigned int has_dsm_for_pm:1;
81         struct work_struct wakeup_work;
82 };
83
84 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
85 static const struct acpi_gpio_params cs_gpios = { 1, 0, false };
86
87 static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = {
88         { "reset-gpios", &reset_gpios, 1 },
89         { "cs-gpios", &cs_gpios, 1 },
90         { },
91 };
92
93 static struct gpiod_lookup_table platform_bytcr_gpios = {
94         .dev_id         = "0000:00:16.0",
95         .table          = {
96                 GPIO_LOOKUP("INT33FC:00", 54, "cs", GPIO_ACTIVE_HIGH),
97                 GPIO_LOOKUP("INT33FC:02", 14, "reset", GPIO_ACTIVE_HIGH),
98                 {}
99         },
100 };
101
102 static int dwc3_byt_enable_ulpi_refclock(struct pci_dev *pci)
103 {
104         void __iomem    *reg;
105         u32             value;
106
107         reg = pcim_iomap(pci, GP_RWBAR, 0);
108         if (!reg)
109                 return -ENOMEM;
110
111         value = readl(reg + GP_RWREG1);
112         if (!(value & GP_RWREG1_ULPI_REFCLK_DISABLE))
113                 goto unmap; /* ULPI refclk already enabled */
114
115         value &= ~GP_RWREG1_ULPI_REFCLK_DISABLE;
116         writel(value, reg + GP_RWREG1);
117         /* This comes from the Intel Android x86 tree w/o any explanation */
118         msleep(100);
119 unmap:
120         pcim_iounmap(pci, reg);
121         return 0;
122 }
123
124 static const struct property_entry dwc3_pci_intel_properties[] = {
125         PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
126         PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
127         {}
128 };
129
130 static const struct property_entry dwc3_pci_intel_phy_charger_detect_properties[] = {
131         PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
132         PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
133         PROPERTY_ENTRY_BOOL("linux,phy_charger_detect"),
134         PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
135         {}
136 };
137
138 static const struct property_entry dwc3_pci_intel_byt_properties[] = {
139         PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
140         PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
141         PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
142         {}
143 };
144
145 static const struct property_entry dwc3_pci_mrfld_properties[] = {
146         PROPERTY_ENTRY_STRING("dr_mode", "otg"),
147         PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"),
148         PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
149         PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
150         PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"),
151         PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
152         {}
153 };
154
155 static const struct property_entry dwc3_pci_amd_properties[] = {
156         PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"),
157         PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf),
158         PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"),
159         PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"),
160         PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"),
161         PROPERTY_ENTRY_BOOL("snps,del_p1p2p3_quirk"),
162         PROPERTY_ENTRY_BOOL("snps,del_phy_power_chg_quirk"),
163         PROPERTY_ENTRY_BOOL("snps,lfps_filter_quirk"),
164         PROPERTY_ENTRY_BOOL("snps,rx_detect_poll_quirk"),
165         PROPERTY_ENTRY_BOOL("snps,tx_de_emphasis_quirk"),
166         PROPERTY_ENTRY_U8("snps,tx_de_emphasis", 1),
167         /* FIXME these quirks should be removed when AMD NL tapes out */
168         PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"),
169         PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
170         PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
171         PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
172         {}
173 };
174
175 static const struct property_entry dwc3_pci_mr_properties[] = {
176         PROPERTY_ENTRY_STRING("dr_mode", "otg"),
177         PROPERTY_ENTRY_BOOL("usb-role-switch"),
178         PROPERTY_ENTRY_STRING("role-switch-default-mode", "host"),
179         PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
180         {}
181 };
182
183 static const struct software_node dwc3_pci_intel_swnode = {
184         .properties = dwc3_pci_intel_properties,
185 };
186
187 static const struct software_node dwc3_pci_intel_phy_charger_detect_swnode = {
188         .properties = dwc3_pci_intel_phy_charger_detect_properties,
189 };
190
191 static const struct software_node dwc3_pci_intel_byt_swnode = {
192         .properties = dwc3_pci_intel_byt_properties,
193 };
194
195 static const struct software_node dwc3_pci_intel_mrfld_swnode = {
196         .properties = dwc3_pci_mrfld_properties,
197 };
198
199 static const struct software_node dwc3_pci_amd_swnode = {
200         .properties = dwc3_pci_amd_properties,
201 };
202
203 static const struct software_node dwc3_pci_amd_mr_swnode = {
204         .properties = dwc3_pci_mr_properties,
205 };
206
207 static int dwc3_pci_quirks(struct dwc3_pci *dwc,
208                            const struct software_node *swnode)
209 {
210         struct pci_dev                  *pdev = dwc->pci;
211
212         if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
213                 if (pdev->device == PCI_DEVICE_ID_INTEL_BXT ||
214                     pdev->device == PCI_DEVICE_ID_INTEL_BXT_M ||
215                     pdev->device == PCI_DEVICE_ID_INTEL_EHL) {
216                         guid_parse(PCI_INTEL_BXT_DSM_GUID, &dwc->guid);
217                         dwc->has_dsm_for_pm = true;
218                 }
219
220                 if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) {
221                         struct gpio_desc *gpio;
222                         int ret;
223
224                         /* On BYT the FW does not always enable the refclock */
225                         ret = dwc3_byt_enable_ulpi_refclock(pdev);
226                         if (ret)
227                                 return ret;
228
229                         ret = devm_acpi_dev_add_driver_gpios(&pdev->dev,
230                                         acpi_dwc3_byt_gpios);
231                         if (ret)
232                                 dev_dbg(&pdev->dev, "failed to add mapping table\n");
233
234                         /*
235                          * A lot of BYT devices lack ACPI resource entries for
236                          * the GPIOs, add a fallback mapping to the reference
237                          * design GPIOs which all boards seem to use.
238                          */
239                         gpiod_add_lookup_table(&platform_bytcr_gpios);
240
241                         /*
242                          * These GPIOs will turn on the USB2 PHY. Note that we have to
243                          * put the gpio descriptors again here because the phy driver
244                          * might want to grab them, too.
245                          */
246                         gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW);
247                         if (IS_ERR(gpio))
248                                 return PTR_ERR(gpio);
249
250                         gpiod_set_value_cansleep(gpio, 1);
251                         gpiod_put(gpio);
252
253                         gpio = gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
254                         if (IS_ERR(gpio))
255                                 return PTR_ERR(gpio);
256
257                         if (gpio) {
258                                 gpiod_set_value_cansleep(gpio, 1);
259                                 gpiod_put(gpio);
260                                 usleep_range(10000, 11000);
261                         }
262
263                         /*
264                          * Make the pdev name predictable (only 1 DWC3 on BYT)
265                          * and patch the phy dev-name into the lookup table so
266                          * that the phy-driver can get the GPIOs.
267                          */
268                         dwc->dwc3->id = PLATFORM_DEVID_NONE;
269                         platform_bytcr_gpios.dev_id = "dwc3.ulpi";
270
271                         /*
272                          * Some Android tablets with a Crystal Cove PMIC
273                          * (INT33FD), rely on the TUSB1211 phy for charger
274                          * detection. These can be identified by them _not_
275                          * using the standard ACPI battery and ac drivers.
276                          */
277                         if (acpi_dev_present("INT33FD", "1", 2) &&
278                             acpi_quirk_skip_acpi_ac_and_battery()) {
279                                 dev_info(&pdev->dev, "Using TUSB1211 phy for charger detection\n");
280                                 swnode = &dwc3_pci_intel_phy_charger_detect_swnode;
281                         }
282                 }
283         }
284
285         return device_add_software_node(&dwc->dwc3->dev, swnode);
286 }
287
288 #ifdef CONFIG_PM
289 static void dwc3_pci_resume_work(struct work_struct *work)
290 {
291         struct dwc3_pci *dwc = container_of(work, struct dwc3_pci, wakeup_work);
292         struct platform_device *dwc3 = dwc->dwc3;
293         int ret;
294
295         ret = pm_runtime_get_sync(&dwc3->dev);
296         if (ret < 0) {
297                 pm_runtime_put_sync_autosuspend(&dwc3->dev);
298                 return;
299         }
300
301         pm_runtime_mark_last_busy(&dwc3->dev);
302         pm_runtime_put_sync_autosuspend(&dwc3->dev);
303 }
304 #endif
305
306 static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
307 {
308         struct dwc3_pci         *dwc;
309         struct resource         res[2];
310         int                     ret;
311         struct device           *dev = &pci->dev;
312
313         ret = pcim_enable_device(pci);
314         if (ret) {
315                 dev_err(dev, "failed to enable pci device\n");
316                 return -ENODEV;
317         }
318
319         pci_set_master(pci);
320
321         dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL);
322         if (!dwc)
323                 return -ENOMEM;
324
325         dwc->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
326         if (!dwc->dwc3)
327                 return -ENOMEM;
328
329         memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
330
331         res[0].start    = pci_resource_start(pci, 0);
332         res[0].end      = pci_resource_end(pci, 0);
333         res[0].name     = "dwc_usb3";
334         res[0].flags    = IORESOURCE_MEM;
335
336         res[1].start    = pci->irq;
337         res[1].name     = "dwc_usb3";
338         res[1].flags    = IORESOURCE_IRQ;
339
340         ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res));
341         if (ret) {
342                 dev_err(dev, "couldn't add resources to dwc3 device\n");
343                 goto err;
344         }
345
346         dwc->pci = pci;
347         dwc->dwc3->dev.parent = dev;
348         ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev));
349
350         ret = dwc3_pci_quirks(dwc, (void *)id->driver_data);
351         if (ret)
352                 goto err;
353
354         ret = platform_device_add(dwc->dwc3);
355         if (ret) {
356                 dev_err(dev, "failed to register dwc3 device\n");
357                 goto err;
358         }
359
360         device_init_wakeup(dev, true);
361         pci_set_drvdata(pci, dwc);
362         pm_runtime_put(dev);
363 #ifdef CONFIG_PM
364         INIT_WORK(&dwc->wakeup_work, dwc3_pci_resume_work);
365 #endif
366
367         return 0;
368 err:
369         device_remove_software_node(&dwc->dwc3->dev);
370         platform_device_put(dwc->dwc3);
371         return ret;
372 }
373
374 static void dwc3_pci_remove(struct pci_dev *pci)
375 {
376         struct dwc3_pci         *dwc = pci_get_drvdata(pci);
377         struct pci_dev          *pdev = dwc->pci;
378
379         if (pdev->device == PCI_DEVICE_ID_INTEL_BYT)
380                 gpiod_remove_lookup_table(&platform_bytcr_gpios);
381 #ifdef CONFIG_PM
382         cancel_work_sync(&dwc->wakeup_work);
383 #endif
384         device_init_wakeup(&pci->dev, false);
385         pm_runtime_get(&pci->dev);
386         device_remove_software_node(&dwc->dwc3->dev);
387         platform_device_unregister(dwc->dwc3);
388 }
389
390 static const struct pci_device_id dwc3_pci_id_table[] = {
391         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BSW),
392           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
393
394         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BYT),
395           (kernel_ulong_t) &dwc3_pci_intel_byt_swnode, },
396
397         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MRFLD),
398           (kernel_ulong_t) &dwc3_pci_intel_mrfld_swnode, },
399
400         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLLP),
401           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
402
403         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CMLH),
404           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
405
406         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SPTLP),
407           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
408
409         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SPTH),
410           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
411
412         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BXT),
413           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
414
415         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_BXT_M),
416           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
417
418         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_APL),
419           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
420
421         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_KBP),
422           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
423
424         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_GLK),
425           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
426
427         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPLP),
428           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
429
430         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPH),
431           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
432
433         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPV),
434           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
435
436         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICLLP),
437           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
438
439         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_EHL),
440           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
441
442         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGPLP),
443           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
444
445         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGPH),
446           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
447
448         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_JSP),
449           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
450
451         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADL),
452           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
453
454         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADL_PCH),
455           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
456
457         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLN),
458           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
459
460         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLN_PCH),
461           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
462
463         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS),
464           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
465
466         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPL),
467           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
468
469         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS),
470           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
471
472         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLM),
473           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
474
475         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLP),
476           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
477
478         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLS),
479           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
480
481         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL),
482           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
483
484         { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL),
485           (kernel_ulong_t) &dwc3_pci_intel_swnode, },
486
487         { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_NL_USB),
488           (kernel_ulong_t) &dwc3_pci_amd_swnode, },
489
490         { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MR),
491           (kernel_ulong_t)&dwc3_pci_amd_mr_swnode, },
492
493         {  }    /* Terminating Entry */
494 };
495 MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
496
497 #if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP)
498 static int dwc3_pci_dsm(struct dwc3_pci *dwc, int param)
499 {
500         union acpi_object *obj;
501         union acpi_object tmp;
502         union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp);
503
504         if (!dwc->has_dsm_for_pm)
505                 return 0;
506
507         tmp.type = ACPI_TYPE_INTEGER;
508         tmp.integer.value = param;
509
510         obj = acpi_evaluate_dsm(ACPI_HANDLE(&dwc->pci->dev), &dwc->guid,
511                         1, PCI_INTEL_BXT_FUNC_PMU_PWR, &argv4);
512         if (!obj) {
513                 dev_err(&dwc->pci->dev, "failed to evaluate _DSM\n");
514                 return -EIO;
515         }
516
517         ACPI_FREE(obj);
518
519         return 0;
520 }
521 #endif /* CONFIG_PM || CONFIG_PM_SLEEP */
522
523 #ifdef CONFIG_PM
524 static int dwc3_pci_runtime_suspend(struct device *dev)
525 {
526         struct dwc3_pci         *dwc = dev_get_drvdata(dev);
527
528         if (device_can_wakeup(dev))
529                 return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
530
531         return -EBUSY;
532 }
533
534 static int dwc3_pci_runtime_resume(struct device *dev)
535 {
536         struct dwc3_pci         *dwc = dev_get_drvdata(dev);
537         int                     ret;
538
539         ret = dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
540         if (ret)
541                 return ret;
542
543         queue_work(pm_wq, &dwc->wakeup_work);
544
545         return 0;
546 }
547 #endif /* CONFIG_PM */
548
549 #ifdef CONFIG_PM_SLEEP
550 static int dwc3_pci_suspend(struct device *dev)
551 {
552         struct dwc3_pci         *dwc = dev_get_drvdata(dev);
553
554         return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
555 }
556
557 static int dwc3_pci_resume(struct device *dev)
558 {
559         struct dwc3_pci         *dwc = dev_get_drvdata(dev);
560
561         return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0);
562 }
563 #endif /* CONFIG_PM_SLEEP */
564
565 static const struct dev_pm_ops dwc3_pci_dev_pm_ops = {
566         SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume)
567         SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume,
568                 NULL)
569 };
570
571 static struct pci_driver dwc3_pci_driver = {
572         .name           = "dwc3-pci",
573         .id_table       = dwc3_pci_id_table,
574         .probe          = dwc3_pci_probe,
575         .remove         = dwc3_pci_remove,
576         .driver         = {
577                 .pm     = &dwc3_pci_dev_pm_ops,
578         }
579 };
580
581 MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
582 MODULE_LICENSE("GPL v2");
583 MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer");
584
585 module_pci_driver(dwc3_pci_driver);