cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dwc3-pci.c (16173B)


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