Commit | Line | Data |
---|---|---|
5fd54ace | 1 | // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) |
99882e3f PZ |
2 | /* |
3 | * pci.c - DesignWare HS OTG Controller PCI driver | |
4 | * | |
5 | * Copyright (C) 2004-2013 Synopsys, Inc. | |
99882e3f PZ |
6 | */ |
7 | ||
8 | /* | |
9 | * Provides the initialization and cleanup entry points for the DWC_otg PCI | |
10 | * driver | |
11 | */ | |
12 | #include <linux/kernel.h> | |
13 | #include <linux/module.h> | |
14 | #include <linux/moduleparam.h> | |
15 | #include <linux/spinlock.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/io.h> | |
18 | #include <linux/slab.h> | |
19 | #include <linux/pci.h> | |
20 | #include <linux/usb.h> | |
21 | ||
22 | #include <linux/usb/hcd.h> | |
23 | #include <linux/usb/ch11.h> | |
9024c495 JY |
24 | #include <linux/platform_device.h> |
25 | #include <linux/usb/usb_phy_generic.h> | |
99882e3f | 26 | |
e16d5f14 | 27 | #include "core.h" |
99882e3f | 28 | |
9024c495 JY |
29 | static const char dwc2_driver_name[] = "dwc2-pci"; |
30 | ||
31 | struct dwc2_pci_glue { | |
32 | struct platform_device *dwc2; | |
33 | struct platform_device *phy; | |
99882e3f PZ |
34 | }; |
35 | ||
6fb914d7 | 36 | /** |
81d708bc | 37 | * dwc2_pci_remove() - Provides the cleanup entry points for the DWC_otg PCI |
6fb914d7 GT |
38 | * driver |
39 | * | |
40 | * @pci: The programming view of DWC_otg PCI | |
41 | */ | |
9024c495 | 42 | static void dwc2_pci_remove(struct pci_dev *pci) |
99882e3f | 43 | { |
9024c495 | 44 | struct dwc2_pci_glue *glue = pci_get_drvdata(pci); |
99882e3f | 45 | |
9024c495 JY |
46 | platform_device_unregister(glue->dwc2); |
47 | usb_phy_generic_unregister(glue->phy); | |
9024c495 | 48 | pci_set_drvdata(pci, NULL); |
99882e3f PZ |
49 | } |
50 | ||
9024c495 | 51 | static int dwc2_pci_probe(struct pci_dev *pci, |
9da51974 | 52 | const struct pci_device_id *id) |
99882e3f | 53 | { |
9024c495 JY |
54 | struct resource res[2]; |
55 | struct platform_device *dwc2; | |
56 | struct platform_device *phy; | |
57 | int ret; | |
58 | struct device *dev = &pci->dev; | |
59 | struct dwc2_pci_glue *glue; | |
60 | ||
61 | ret = pcim_enable_device(pci); | |
62 | if (ret) { | |
63 | dev_err(dev, "failed to enable pci device\n"); | |
64 | return -ENODEV; | |
65 | } | |
66 | ||
67 | pci_set_master(pci); | |
99882e3f | 68 | |
a127cccd VM |
69 | phy = usb_phy_generic_register(); |
70 | if (IS_ERR(phy)) { | |
71 | dev_err(dev, "error registering generic PHY (%ld)\n", | |
72 | PTR_ERR(phy)); | |
73 | return PTR_ERR(phy); | |
74 | } | |
75 | ||
9024c495 JY |
76 | dwc2 = platform_device_alloc("dwc2", PLATFORM_DEVID_AUTO); |
77 | if (!dwc2) { | |
78 | dev_err(dev, "couldn't allocate dwc2 device\n"); | |
3c135e89 | 79 | ret = -ENOMEM; |
ecd29dab | 80 | goto err; |
9024c495 | 81 | } |
99882e3f | 82 | |
9024c495 | 83 | memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); |
99882e3f | 84 | |
9024c495 JY |
85 | res[0].start = pci_resource_start(pci, 0); |
86 | res[0].end = pci_resource_end(pci, 0); | |
87 | res[0].name = "dwc2"; | |
88 | res[0].flags = IORESOURCE_MEM; | |
99882e3f | 89 | |
9024c495 JY |
90 | res[1].start = pci->irq; |
91 | res[1].name = "dwc2"; | |
92 | res[1].flags = IORESOURCE_IRQ; | |
99882e3f | 93 | |
9024c495 JY |
94 | ret = platform_device_add_resources(dwc2, res, ARRAY_SIZE(res)); |
95 | if (ret) { | |
96 | dev_err(dev, "couldn't add resources to dwc2 device\n"); | |
ecd29dab | 97 | goto err; |
9024c495 | 98 | } |
99882e3f | 99 | |
9024c495 | 100 | dwc2->dev.parent = dev; |
db8178c3 | 101 | |
fb50aacd | 102 | glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); |
fe70dce9 WY |
103 | if (!glue) { |
104 | ret = -ENOMEM; | |
ecd29dab | 105 | goto err; |
fe70dce9 | 106 | } |
fb50aacd | 107 | |
9024c495 JY |
108 | ret = platform_device_add(dwc2); |
109 | if (ret) { | |
110 | dev_err(dev, "failed to register dwc2 device\n"); | |
111 | goto err; | |
112 | } | |
113 | ||
9024c495 JY |
114 | glue->phy = phy; |
115 | glue->dwc2 = dwc2; | |
116 | pci_set_drvdata(pci, glue); | |
99882e3f | 117 | |
9024c495 JY |
118 | return 0; |
119 | err: | |
120 | usb_phy_generic_unregister(phy); | |
121 | platform_device_put(dwc2); | |
122 | return ret; | |
99882e3f PZ |
123 | } |
124 | ||
99882e3f PZ |
125 | static struct pci_driver dwc2_pci_driver = { |
126 | .name = dwc2_driver_name, | |
127 | .id_table = dwc2_pci_ids, | |
9024c495 JY |
128 | .probe = dwc2_pci_probe, |
129 | .remove = dwc2_pci_remove, | |
99882e3f PZ |
130 | }; |
131 | ||
132 | module_pci_driver(dwc2_pci_driver); | |
133 | ||
134 | MODULE_DESCRIPTION("DESIGNWARE HS OTG PCI Bus Glue"); | |
135 | MODULE_AUTHOR("Synopsys, Inc."); | |
136 | MODULE_LICENSE("Dual BSD/GPL"); |