dwc3-pci.c (cc9b94029e9ef51787af908e9856b1eed314bc00) | dwc3-pci.c (36daf3aa399c08e7cdf499f5562888325f19f92f) |
---|---|
1/** 2 * dwc3-pci.c - PCI Specific glue layer 3 * 4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com 5 * 6 * Authors: Felipe Balbi <balbi@ti.com>, 7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de> 8 * --- 25 unchanged lines hidden (view full) --- 34#define PCI_DEVICE_ID_INTEL_BSW 0x22b7 35#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 36#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 37#define PCI_DEVICE_ID_INTEL_BXT 0x0aaa 38#define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa 39#define PCI_DEVICE_ID_INTEL_APL 0x5aaa 40#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 41 | 1/** 2 * dwc3-pci.c - PCI Specific glue layer 3 * 4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com 5 * 6 * Authors: Felipe Balbi <balbi@ti.com>, 7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de> 8 * --- 25 unchanged lines hidden (view full) --- 34#define PCI_DEVICE_ID_INTEL_BSW 0x22b7 35#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 36#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 37#define PCI_DEVICE_ID_INTEL_BXT 0x0aaa 38#define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa 39#define PCI_DEVICE_ID_INTEL_APL 0x5aaa 40#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0 41 |
42#define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511" 43#define PCI_INTEL_BXT_FUNC_PMU_PWR 4 44#define PCI_INTEL_BXT_STATE_D0 0 45#define PCI_INTEL_BXT_STATE_D3 3 46 47/** 48 * struct dwc3_pci - Driver private structure 49 * @dwc3: child dwc3 platform_device 50 * @pci: our link to PCI bus 51 * @uuid: _DSM UUID 52 * @has_dsm_for_pm: true for devices which need to run _DSM on runtime PM 53 */ 54struct dwc3_pci { 55 struct platform_device *dwc3; 56 struct pci_dev *pci; 57 58 u8 uuid[16]; 59 60 unsigned int has_dsm_for_pm:1; 61}; 62 |
|
42static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; 43static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; 44 45static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = { 46 { "reset-gpios", &reset_gpios, 1 }, 47 { "cs-gpios", &cs_gpios, 1 }, 48 { }, 49}; 50 | 63static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; 64static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; 65 66static const struct acpi_gpio_mapping acpi_dwc3_byt_gpios[] = { 67 { "reset-gpios", &reset_gpios, 1 }, 68 { "cs-gpios", &cs_gpios, 1 }, 69 { }, 70}; 71 |
51static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3) | 72static int dwc3_pci_quirks(struct dwc3_pci *dwc) |
52{ | 73{ |
74 struct platform_device *dwc3 = dwc->dwc3; 75 struct pci_dev *pdev = dwc->pci; 76 |
|
53 if (pdev->vendor == PCI_VENDOR_ID_AMD && 54 pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { 55 struct property_entry properties[] = { 56 PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), 57 PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf), 58 PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"), 59 PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"), 60 PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"), --- 23 unchanged lines hidden (view full) --- 84 PROPERTY_ENTRY_STRING("dr-mode", "peripheral"), 85 { } 86 }; 87 88 ret = platform_device_add_properties(dwc3, properties); 89 if (ret < 0) 90 return ret; 91 | 77 if (pdev->vendor == PCI_VENDOR_ID_AMD && 78 pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { 79 struct property_entry properties[] = { 80 PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), 81 PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf), 82 PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"), 83 PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"), 84 PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"), --- 23 unchanged lines hidden (view full) --- 108 PROPERTY_ENTRY_STRING("dr-mode", "peripheral"), 109 { } 110 }; 111 112 ret = platform_device_add_properties(dwc3, properties); 113 if (ret < 0) 114 return ret; 115 |
116 if (pdev->device == PCI_DEVICE_ID_INTEL_BXT || 117 pdev->device == PCI_DEVICE_ID_INTEL_BXT_M) { 118 acpi_str_to_uuid(PCI_INTEL_BXT_DSM_UUID, dwc->uuid); 119 dwc->has_dsm_for_pm = true; 120 } 121 |
|
92 if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) { 93 struct gpio_desc *gpio; 94 95 acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev), 96 acpi_dwc3_byt_gpios); 97 98 /* 99 * These GPIOs will turn on the USB2 PHY. Note that we have to --- 34 unchanged lines hidden (view full) --- 134 } 135 136 return 0; 137} 138 139static int dwc3_pci_probe(struct pci_dev *pci, 140 const struct pci_device_id *id) 141{ | 122 if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) { 123 struct gpio_desc *gpio; 124 125 acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev), 126 acpi_dwc3_byt_gpios); 127 128 /* 129 * These GPIOs will turn on the USB2 PHY. Note that we have to --- 34 unchanged lines hidden (view full) --- 164 } 165 166 return 0; 167} 168 169static int dwc3_pci_probe(struct pci_dev *pci, 170 const struct pci_device_id *id) 171{ |
172 struct dwc3_pci *dwc; |
|
142 struct resource res[2]; | 173 struct resource res[2]; |
143 struct platform_device *dwc3; | |
144 int ret; 145 struct device *dev = &pci->dev; 146 147 ret = pcim_enable_device(pci); 148 if (ret) { 149 dev_err(dev, "failed to enable pci device\n"); 150 return -ENODEV; 151 } 152 153 pci_set_master(pci); 154 | 174 int ret; 175 struct device *dev = &pci->dev; 176 177 ret = pcim_enable_device(pci); 178 if (ret) { 179 dev_err(dev, "failed to enable pci device\n"); 180 return -ENODEV; 181 } 182 183 pci_set_master(pci); 184 |
155 dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); 156 if (!dwc3) { 157 dev_err(dev, "couldn't allocate dwc3 device\n"); | 185 dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); 186 if (!dwc) |
158 return -ENOMEM; | 187 return -ENOMEM; |
159 } | |
160 | 188 |
189 dwc->dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); 190 if (!dwc->dwc3) 191 return -ENOMEM; 192 |
|
161 memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); 162 163 res[0].start = pci_resource_start(pci, 0); 164 res[0].end = pci_resource_end(pci, 0); 165 res[0].name = "dwc_usb3"; 166 res[0].flags = IORESOURCE_MEM; 167 168 res[1].start = pci->irq; 169 res[1].name = "dwc_usb3"; 170 res[1].flags = IORESOURCE_IRQ; 171 | 193 memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); 194 195 res[0].start = pci_resource_start(pci, 0); 196 res[0].end = pci_resource_end(pci, 0); 197 res[0].name = "dwc_usb3"; 198 res[0].flags = IORESOURCE_MEM; 199 200 res[1].start = pci->irq; 201 res[1].name = "dwc_usb3"; 202 res[1].flags = IORESOURCE_IRQ; 203 |
172 ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); | 204 ret = platform_device_add_resources(dwc->dwc3, res, ARRAY_SIZE(res)); |
173 if (ret) { 174 dev_err(dev, "couldn't add resources to dwc3 device\n"); 175 return ret; 176 } 177 | 205 if (ret) { 206 dev_err(dev, "couldn't add resources to dwc3 device\n"); 207 return ret; 208 } 209 |
178 dwc3->dev.parent = dev; 179 ACPI_COMPANION_SET(&dwc3->dev, ACPI_COMPANION(dev)); | 210 dwc->pci = pci; 211 dwc->dwc3->dev.parent = dev; 212 ACPI_COMPANION_SET(&dwc->dwc3->dev, ACPI_COMPANION(dev)); |
180 | 213 |
181 ret = dwc3_pci_quirks(pci, dwc3); | 214 ret = dwc3_pci_quirks(dwc); |
182 if (ret) 183 goto err; 184 | 215 if (ret) 216 goto err; 217 |
185 ret = platform_device_add(dwc3); | 218 ret = platform_device_add(dwc->dwc3); |
186 if (ret) { 187 dev_err(dev, "failed to register dwc3 device\n"); 188 goto err; 189 } 190 191 device_init_wakeup(dev, true); 192 device_set_run_wake(dev, true); | 219 if (ret) { 220 dev_err(dev, "failed to register dwc3 device\n"); 221 goto err; 222 } 223 224 device_init_wakeup(dev, true); 225 device_set_run_wake(dev, true); |
193 pci_set_drvdata(pci, dwc3); | 226 pci_set_drvdata(pci, dwc); |
194 pm_runtime_put(dev); 195 196 return 0; 197err: | 227 pm_runtime_put(dev); 228 229 return 0; 230err: |
198 platform_device_put(dwc3); | 231 platform_device_put(dwc->dwc3); |
199 return ret; 200} 201 202static void dwc3_pci_remove(struct pci_dev *pci) 203{ | 232 return ret; 233} 234 235static void dwc3_pci_remove(struct pci_dev *pci) 236{ |
237 struct dwc3_pci *dwc = pci_get_drvdata(pci); 238 |
|
204 device_init_wakeup(&pci->dev, false); 205 pm_runtime_get(&pci->dev); 206 acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev)); | 239 device_init_wakeup(&pci->dev, false); 240 pm_runtime_get(&pci->dev); 241 acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev)); |
207 platform_device_unregister(pci_get_drvdata(pci)); | 242 platform_device_unregister(dwc->dwc3); |
208} 209 210static const struct pci_device_id dwc3_pci_id_table[] = { 211 { 212 PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 213 PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), 214 }, 215 { --- 13 unchanged lines hidden (view full) --- 229 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, 230 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, 231 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, 232 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, 233 { } /* Terminating Entry */ 234}; 235MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); 236 | 243} 244 245static const struct pci_device_id dwc3_pci_id_table[] = { 246 { 247 PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, 248 PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), 249 }, 250 { --- 13 unchanged lines hidden (view full) --- 264 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), }, 265 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), }, 266 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), }, 267 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, 268 { } /* Terminating Entry */ 269}; 270MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); 271 |
272#if defined(CONFIG_PM) || defined(CONFIG_PM_SLEEP) 273static int dwc3_pci_dsm(struct dwc3_pci *dwc, int param) 274{ 275 union acpi_object *obj; 276 union acpi_object tmp; 277 union acpi_object argv4 = ACPI_INIT_DSM_ARGV4(1, &tmp); 278 279 if (!dwc->has_dsm_for_pm) 280 return 0; 281 282 tmp.type = ACPI_TYPE_INTEGER; 283 tmp.integer.value = param; 284 285 obj = acpi_evaluate_dsm(ACPI_HANDLE(&dwc->pci->dev), dwc->uuid, 286 1, PCI_INTEL_BXT_FUNC_PMU_PWR, &argv4); 287 if (!obj) { 288 dev_err(&dwc->pci->dev, "failed to evaluate _DSM\n"); 289 return -EIO; 290 } 291 292 ACPI_FREE(obj); 293 294 return 0; 295} 296#endif /* CONFIG_PM || CONFIG_PM_SLEEP */ 297 |
|
237#ifdef CONFIG_PM 238static int dwc3_pci_runtime_suspend(struct device *dev) 239{ | 298#ifdef CONFIG_PM 299static int dwc3_pci_runtime_suspend(struct device *dev) 300{ |
301 struct dwc3_pci *dwc = dev_get_drvdata(dev); 302 |
|
240 if (device_run_wake(dev)) | 303 if (device_run_wake(dev)) |
241 return 0; | 304 return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3); |
242 243 return -EBUSY; 244} 245 246static int dwc3_pci_runtime_resume(struct device *dev) 247{ | 305 306 return -EBUSY; 307} 308 309static int dwc3_pci_runtime_resume(struct device *dev) 310{ |
248 struct platform_device *dwc3 = dev_get_drvdata(dev); | 311 struct dwc3_pci *dwc = dev_get_drvdata(dev); 312 struct platform_device *dwc3 = dwc->dwc3; 313 int ret; |
249 | 314 |
315 ret = dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0); 316 if (ret) 317 return ret; 318 |
|
250 return pm_runtime_get(&dwc3->dev); 251} 252#endif /* CONFIG_PM */ 253 254#ifdef CONFIG_PM_SLEEP | 319 return pm_runtime_get(&dwc3->dev); 320} 321#endif /* CONFIG_PM */ 322 323#ifdef CONFIG_PM_SLEEP |
255static int dwc3_pci_pm_dummy(struct device *dev) | 324static int dwc3_pci_suspend(struct device *dev) |
256{ | 325{ |
257 /* 258 * There's nothing to do here. No, seriously. Everything is either taken 259 * care either by PCI subsystem or dwc3/core.c, so we have nothing 260 * missing here. 261 * 262 * So you'd think we didn't need this at all, but PCI subsystem will 263 * bail out if we don't have a valid callback :-s 264 */ 265 return 0; | 326 struct dwc3_pci *dwc = dev_get_drvdata(dev); 327 328 return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3); |
266} | 329} |
330 331static int dwc3_pci_resume(struct device *dev) 332{ 333 struct dwc3_pci *dwc = dev_get_drvdata(dev); 334 335 return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D0); 336} |
|
267#endif /* CONFIG_PM_SLEEP */ 268 269static struct dev_pm_ops dwc3_pci_dev_pm_ops = { | 337#endif /* CONFIG_PM_SLEEP */ 338 339static struct dev_pm_ops dwc3_pci_dev_pm_ops = { |
270 SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy) | 340 SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) |
271 SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume, 272 NULL) 273}; 274 275static struct pci_driver dwc3_pci_driver = { 276 .name = "dwc3-pci", 277 .id_table = dwc3_pci_id_table, 278 .probe = dwc3_pci_probe, 279 .remove = dwc3_pci_remove, 280 .driver = { 281 .pm = &dwc3_pci_dev_pm_ops, 282 } 283}; 284 285MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 286MODULE_LICENSE("GPL v2"); 287MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); 288 289module_pci_driver(dwc3_pci_driver); | 341 SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume, 342 NULL) 343}; 344 345static struct pci_driver dwc3_pci_driver = { 346 .name = "dwc3-pci", 347 .id_table = dwc3_pci_id_table, 348 .probe = dwc3_pci_probe, 349 .remove = dwc3_pci_remove, 350 .driver = { 351 .pm = &dwc3_pci_dev_pm_ops, 352 } 353}; 354 355MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); 356MODULE_LICENSE("GPL v2"); 357MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer"); 358 359module_pci_driver(dwc3_pci_driver); |