Commit | Line | Data |
---|---|---|
5b9974b1 MK |
1 | /* |
2 | * platform.c - DesignWare HS OTG Controller platform driver | |
3 | * | |
4 | * Copyright (C) Matthijs Kooijman <matthijs@stdin.nl> | |
5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions, and the following disclaimer, | |
11 | * without modification. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * 3. The names of the above-listed copyright holders may not be used | |
16 | * to endorse or promote products derived from this software without | |
17 | * specific prior written permission. | |
18 | * | |
19 | * ALTERNATIVELY, this software may be distributed under the terms of the | |
20 | * GNU General Public License ("GPL") as published by the Free Software | |
21 | * Foundation; either version 2 of the License, or (at your option) any | |
22 | * later version. | |
23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | |
25 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
26 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
27 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
28 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
29 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
30 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
31 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
32 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
35 | */ | |
36 | ||
37 | #include <linux/kernel.h> | |
38 | #include <linux/module.h> | |
39 | #include <linux/slab.h> | |
40 | #include <linux/device.h> | |
41 | #include <linux/dma-mapping.h> | |
42 | #include <linux/platform_device.h> | |
43 | ||
44 | #include "core.h" | |
45 | #include "hcd.h" | |
46 | ||
47 | static const char dwc2_driver_name[] = "dwc2"; | |
48 | ||
49 | /** | |
50 | * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the | |
51 | * DWC_otg driver | |
52 | * | |
53 | * @dev: Platform device | |
54 | * | |
55 | * This routine is called, for example, when the rmmod command is executed. The | |
56 | * device may or may not be electrically present. If it is present, the driver | |
57 | * stops device processing. Any resources used on behalf of this device are | |
58 | * freed. | |
59 | */ | |
60 | static int dwc2_driver_remove(struct platform_device *dev) | |
61 | { | |
62 | struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); | |
63 | ||
64 | dwc2_hcd_remove(hsotg); | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
69 | /** | |
70 | * dwc2_driver_probe() - Called when the DWC_otg core is bound to the DWC_otg | |
71 | * driver | |
72 | * | |
73 | * @dev: Platform device | |
74 | * | |
75 | * This routine creates the driver components required to control the device | |
76 | * (core, HCD, and PCD) and initializes the device. The driver components are | |
77 | * stored in a dwc2_hsotg structure. A reference to the dwc2_hsotg is saved | |
78 | * in the device private data. This allows the driver to access the dwc2_hsotg | |
79 | * structure on subsequent calls to driver methods for this device. | |
80 | */ | |
81 | static int dwc2_driver_probe(struct platform_device *dev) | |
82 | { | |
83 | struct dwc2_hsotg *hsotg; | |
84 | struct resource *res; | |
85 | int retval; | |
86 | int irq; | |
87 | struct dwc2_core_params params; | |
88 | ||
89 | /* Default all params to autodetect */ | |
90 | dwc2_set_all_params(¶ms, -1); | |
91 | ||
92 | hsotg = devm_kzalloc(&dev->dev, sizeof(*hsotg), GFP_KERNEL); | |
93 | if (!hsotg) | |
94 | return -ENOMEM; | |
95 | ||
96 | hsotg->dev = &dev->dev; | |
97 | ||
642f2ecc MK |
98 | /* |
99 | * Use reasonable defaults so platforms don't have to provide these. | |
100 | */ | |
101 | if (!dev->dev.dma_mask) | |
102 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; | |
103 | if (!dev->dev.coherent_dma_mask) | |
104 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | |
105 | ||
5b9974b1 MK |
106 | irq = platform_get_irq(dev, 0); |
107 | if (irq < 0) { | |
108 | dev_err(&dev->dev, "missing IRQ resource\n"); | |
109 | return -EINVAL; | |
110 | } | |
111 | ||
112 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | |
5b9974b1 MK |
113 | hsotg->regs = devm_ioremap_resource(&dev->dev, res); |
114 | if (IS_ERR(hsotg->regs)) | |
115 | return PTR_ERR(hsotg->regs); | |
116 | ||
117 | dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", | |
118 | (unsigned long)res->start, hsotg->regs); | |
119 | ||
120 | retval = dwc2_hcd_init(hsotg, irq, ¶ms); | |
121 | if (retval) | |
122 | return retval; | |
123 | ||
124 | platform_set_drvdata(dev, hsotg); | |
125 | ||
126 | return retval; | |
127 | } | |
128 | ||
129 | static const struct of_device_id dwc2_of_match_table[] = { | |
130 | { .compatible = "snps,dwc2" }, | |
131 | {}, | |
132 | }; | |
133 | MODULE_DEVICE_TABLE(of, dwc2_of_match_table); | |
134 | ||
135 | static struct platform_driver dwc2_platform_driver = { | |
136 | .driver = { | |
137 | .name = (char *)dwc2_driver_name, | |
138 | .of_match_table = dwc2_of_match_table, | |
139 | }, | |
140 | .probe = dwc2_driver_probe, | |
141 | .remove = dwc2_driver_remove, | |
142 | }; | |
143 | ||
144 | module_platform_driver(dwc2_platform_driver); | |
145 | ||
146 | MODULE_DESCRIPTION("DESIGNWARE HS OTG Platform Glue"); | |
147 | MODULE_AUTHOR("Matthijs Kooijman <matthijs@stdin.nl>"); | |
148 | MODULE_LICENSE("Dual BSD/GPL"); |