Deleted Added
full compact
omap_ehci.c (276717) omap_ehci.c (283276)
1/*-
2 * Copyright (c) 2011
3 * Ben Gray <ben.r.gray@gmail.com>.
4 * All rights reserved.
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:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
1/*-
2 * Copyright (c) 2011
3 * Ben Gray <ben.r.gray@gmail.com>.
4 * All rights reserved.
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:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28/**
29 * Driver for the High Speed USB EHCI module on the TI OMAP3530 SoC.
30 *
31 * WARNING: I've only tried this driver on a limited number of USB peripherals,
32 * it is still very raw and bound to have numerous bugs in it.
33 *
34 * This driver is based on the FreeBSD IXP4xx EHCI driver with a lot of the
35 * setup sequence coming from the Linux community and their EHCI driver for
36 * OMAP. Without these as a base I don't think I would have been able to get
37 * this driver working.
38 *
39 * The driver only contains the EHCI parts, the module also supports OHCI and
40 * USB on-the-go (OTG), currently neither are supported.
41 *
42 * CAUTION: This driver was written to run on the beaglebaord dev board, so I
43 * have made some assumptions about the type of PHY used and some of the other
44 * settings. Bare that in mind if you intend to use this driver on another
45 * platform.
46 *
47 * NOTE: This module uses a few different clocks, one being a 60Mhz clock for
48 * the TTL part of the module. This clock is derived from DPPL5 which must be
49 * configured prior to loading this driver - it is not configured by the
50 * bootloader. It took me a long time to figure this out, and caused much
51 * frustration. This PLL is now setup in the timer/clocks part of the BSP,
52 * check out the omap_prcm_setup_dpll5() function in omap_prcm.c for more info.
53 *
54 */
55
56#include <sys/cdefs.h>
27#include <sys/cdefs.h>
57__FBSDID("$FreeBSD: head/sys/arm/ti/usb/omap_ehci.c 276717 2015-01-05 20:22:18Z hselasky $");
28__FBSDID("$FreeBSD: head/sys/arm/ti/usb/omap_ehci.c 283276 2015-05-22 03:16:18Z gonzo $");
58
29
59#include "opt_bus.h"
60
61#include <sys/stdint.h>
62#include <sys/stddef.h>
63#include <sys/param.h>
30#include <sys/param.h>
64#include <sys/queue.h>
65#include <sys/types.h>
66#include <sys/systm.h>
31#include <sys/systm.h>
32#include <sys/conf.h>
67#include <sys/kernel.h>
33#include <sys/kernel.h>
68#include <sys/bus.h>
69#include <sys/rman.h>
34#include <sys/rman.h>
70#include <sys/linker_set.h>
71#include <sys/module.h>
35#include <sys/module.h>
72#include <sys/lock.h>
73#include <sys/mutex.h>
36#include <sys/proc.h>
74#include <sys/condvar.h>
37#include <sys/condvar.h>
75#include <sys/sysctl.h>
76#include <sys/sx.h>
77#include <sys/unistd.h>
78#include <sys/callout.h>
79#include <sys/malloc.h>
80#include <sys/priv.h>
81#include <sys/gpio.h>
82
83#include <dev/fdt/fdt_common.h>
38
39#include <dev/fdt/fdt_common.h>
84#include <dev/ofw/openfirm.h>
85#include <dev/ofw/ofw_bus.h>
40#include <dev/fdt/simplebus.h>
86#include <dev/ofw/ofw_bus_subr.h>
87
88#include <dev/usb/usb.h>
89#include <dev/usb/usbdi.h>
90
91#include <dev/usb/usb_core.h>
92#include <dev/usb/usb_busdma.h>
93#include <dev/usb/usb_process.h>
94#include <dev/usb/usb_util.h>
95
96#include <dev/usb/usb_controller.h>
97#include <dev/usb/usb_bus.h>
98#include <dev/usb/controller/ehci.h>
99#include <dev/usb/controller/ehcireg.h>
100
41#include <dev/ofw/ofw_bus_subr.h>
42
43#include <dev/usb/usb.h>
44#include <dev/usb/usbdi.h>
45
46#include <dev/usb/usb_core.h>
47#include <dev/usb/usb_busdma.h>
48#include <dev/usb/usb_process.h>
49#include <dev/usb/usb_util.h>
50
51#include <dev/usb/usb_controller.h>
52#include <dev/usb/usb_bus.h>
53#include <dev/usb/controller/ehci.h>
54#include <dev/usb/controller/ehcireg.h>
55
101#include <arm/ti/tivar.h>
102#include <arm/ti/ti_prcm.h>
103#include <arm/ti/ti_scm.h>
56#include <machine/bus.h>
104
57
58#include <arm/ti/ti_prcm.h>
105#include <arm/ti/usb/omap_usb.h>
106
59#include <arm/ti/usb/omap_usb.h>
60
107#include "gpio_if.h"
61/* EHCI */
62#define OMAP_USBHOST_HCCAPBASE 0x0000
63#define OMAP_USBHOST_HCSPARAMS 0x0004
64#define OMAP_USBHOST_HCCPARAMS 0x0008
65#define OMAP_USBHOST_USBCMD 0x0010
66#define OMAP_USBHOST_USBSTS 0x0014
67#define OMAP_USBHOST_USBINTR 0x0018
68#define OMAP_USBHOST_FRINDEX 0x001C
69#define OMAP_USBHOST_CTRLDSSEGMENT 0x0020
70#define OMAP_USBHOST_PERIODICLISTBASE 0x0024
71#define OMAP_USBHOST_ASYNCLISTADDR 0x0028
72#define OMAP_USBHOST_CONFIGFLAG 0x0050
73#define OMAP_USBHOST_PORTSC(i) (0x0054 + (0x04 * (i)))
74#define OMAP_USBHOST_INSNREG00 0x0090
75#define OMAP_USBHOST_INSNREG01 0x0094
76#define OMAP_USBHOST_INSNREG02 0x0098
77#define OMAP_USBHOST_INSNREG03 0x009C
78#define OMAP_USBHOST_INSNREG04 0x00A0
79#define OMAP_USBHOST_INSNREG05_UTMI 0x00A4
80#define OMAP_USBHOST_INSNREG05_ULPI 0x00A4
81#define OMAP_USBHOST_INSNREG06 0x00A8
82#define OMAP_USBHOST_INSNREG07 0x00AC
83#define OMAP_USBHOST_INSNREG08 0x00B0
108
84
109struct omap_ehci_softc {
110 ehci_softc_t base; /* storage for EHCI code */
85#define OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND (1 << 5)
111
86
112 device_t sc_dev;
113 device_t sc_gpio_dev;
87#define OMAP_USBHOST_INSNREG05_ULPI_CONTROL_SHIFT 31
88#define OMAP_USBHOST_INSNREG05_ULPI_PORTSEL_SHIFT 24
89#define OMAP_USBHOST_INSNREG05_ULPI_OPSEL_SHIFT 22
90#define OMAP_USBHOST_INSNREG05_ULPI_REGADD_SHIFT 16
91#define OMAP_USBHOST_INSNREG05_ULPI_EXTREGADD_SHIFT 8
92#define OMAP_USBHOST_INSNREG05_ULPI_WRDATA_SHIFT 0
114
93
115 /* TLL register set */
116 struct resource* tll_mem_res;
94#define ULPI_FUNC_CTRL_RESET (1 << 5)
117
95
118 /* UHH register set */
119 struct resource* uhh_mem_res;
96/*-------------------------------------------------------------------------*/
120
97
121 /* The revision of the HS USB HOST read from UHH_REVISION */
122 uint32_t ehci_rev;
98/*
99 * Macros for Set and Clear
100 * See ULPI 1.1 specification to find the registers with Set and Clear offsets
101 */
102#define ULPI_SET(a) (a + 1)
103#define ULPI_CLR(a) (a + 2)
123
104
124 /* The following details are provided by conf hints */
125 int port_mode[3];
126 int phy_reset[3];
127 int reset_gpio_pin[3];
128};
105/*-------------------------------------------------------------------------*/
129
106
130static device_attach_t omap_ehci_attach;
131static device_detach_t omap_ehci_detach;
132static device_shutdown_t omap_ehci_shutdown;
133static device_suspend_t omap_ehci_suspend;
134static device_resume_t omap_ehci_resume;
135
136/**
137 * omap_tll_read_4 - read a 32-bit value from the USBTLL registers
138 * omap_tll_write_4 - write a 32-bit value from the USBTLL registers
139 * omap_tll_readb - read an 8-bit value from the USBTLL registers
140 * omap_tll_writeb - write an 8-bit value from the USBTLL registers
141 * @sc: omap ehci device context
142 * @off: byte offset within the register set to read from
143 * @val: the value to write into the register
144 *
145 *
146 * LOCKING:
147 * None
148 *
149 * RETURNS:
150 * nothing in case of write function, if read function returns the value read.
107/*
108 * Register Map
151 */
109 */
152static inline uint32_t
153omap_tll_read_4(struct omap_ehci_softc *sc, bus_size_t off)
154{
155 return bus_read_4(sc->tll_mem_res, off);
156}
110#define ULPI_VENDOR_ID_LOW 0x00
111#define ULPI_VENDOR_ID_HIGH 0x01
112#define ULPI_PRODUCT_ID_LOW 0x02
113#define ULPI_PRODUCT_ID_HIGH 0x03
114#define ULPI_FUNC_CTRL 0x04
115#define ULPI_IFC_CTRL 0x07
116#define ULPI_OTG_CTRL 0x0a
117#define ULPI_USB_INT_EN_RISE 0x0d
118#define ULPI_USB_INT_EN_FALL 0x10
119#define ULPI_USB_INT_STS 0x13
120#define ULPI_USB_INT_LATCH 0x14
121#define ULPI_DEBUG 0x15
122#define ULPI_SCRATCH 0x16
157
123
158static inline void
159omap_tll_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
160{
161 bus_write_4(sc->tll_mem_res, off, val);
162}
124#define OMAP_EHCI_HC_DEVSTR "TI OMAP USB 2.0 controller"
163
125
164static inline uint8_t
165omap_tll_readb(struct omap_ehci_softc *sc, bus_size_t off)
166{
167 return bus_read_1(sc->tll_mem_res, off);
168}
126struct omap_ehci_softc {
127 ehci_softc_t base; /* storage for EHCI code */
128 device_t sc_dev;
129};
169
130
170static inline void
171omap_tll_writeb(struct omap_ehci_softc *sc, bus_size_t off, uint8_t val)
172{
173 bus_write_1(sc->tll_mem_res, off, val);
174}
131static device_attach_t omap_ehci_attach;
132static device_detach_t omap_ehci_detach;
175
176/**
177 * omap_ehci_read_4 - read a 32-bit value from the EHCI registers
178 * omap_ehci_write_4 - write a 32-bit value from the EHCI registers
179 * @sc: omap ehci device context
180 * @off: byte offset within the register set to read from
181 * @val: the value to write into the register
182 *

--- 4 unchanged lines hidden (view full) ---

187 * RETURNS:
188 * nothing in case of write function, if read function returns the value read.
189 */
190static inline uint32_t
191omap_ehci_read_4(struct omap_ehci_softc *sc, bus_size_t off)
192{
193 return (bus_read_4(sc->base.sc_io_res, off));
194}
133
134/**
135 * omap_ehci_read_4 - read a 32-bit value from the EHCI registers
136 * omap_ehci_write_4 - write a 32-bit value from the EHCI registers
137 * @sc: omap ehci device context
138 * @off: byte offset within the register set to read from
139 * @val: the value to write into the register
140 *

--- 4 unchanged lines hidden (view full) ---

145 * RETURNS:
146 * nothing in case of write function, if read function returns the value read.
147 */
148static inline uint32_t
149omap_ehci_read_4(struct omap_ehci_softc *sc, bus_size_t off)
150{
151 return (bus_read_4(sc->base.sc_io_res, off));
152}
153
195static inline void
196omap_ehci_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
197{
198 bus_write_4(sc->base.sc_io_res, off, val);
199}
200
201/**
154static inline void
155omap_ehci_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
156{
157 bus_write_4(sc->base.sc_io_res, off, val);
158}
159
160/**
202 * omap_uhh_read_4 - read a 32-bit value from the UHH registers
203 * omap_uhh_write_4 - write a 32-bit value from the UHH registers
204 * @sc: omap ehci device context
205 * @off: byte offset within the register set to read from
206 * @val: the value to write into the register
207 *
208 *
209 * LOCKING:
210 * None
211 *
212 * RETURNS:
213 * nothing in case of write function, if read function returns the value read.
214 */
215static inline uint32_t
216omap_uhh_read_4(struct omap_ehci_softc *sc, bus_size_t off)
217{
218 return bus_read_4(sc->uhh_mem_res, off);
219}
220static inline void
221omap_uhh_write_4(struct omap_ehci_softc *sc, bus_size_t off, uint32_t val)
222{
223 bus_write_4(sc->uhh_mem_res, off, val);
224}
225
226/**
227 * omap_ehci_utmi_init - initialises the UTMI part of the controller
228 * @isc: omap ehci device context
229 *
230 *
231 *
232 * LOCKING:
233 * none
234 *
235 * RETURNS:
236 * nothing
237 */
238static void
239omap_ehci_utmi_init(struct omap_ehci_softc *isc, unsigned int en_mask)
240{
241 unsigned int i;
242 uint32_t reg;
243
244 /* There are 3 TLL channels, one per USB controller so set them all up the
245 * same, SDR mode, bit stuffing and no autoidle.
246 */
247 for (i=0; i<3; i++) {
248 reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
249
250 reg &= ~(TLL_CHANNEL_CONF_UTMIAUTOIDLE
251 | TLL_CHANNEL_CONF_ULPINOBITSTUFF
252 | TLL_CHANNEL_CONF_ULPIDDRMODE);
253
254 omap_tll_write_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
255 }
256
257 /* Program the common TLL register */
258 reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_SHARED_CONF);
259
260 reg &= ~( TLL_SHARED_CONF_USB_90D_DDR_EN
261 | TLL_SHARED_CONF_USB_DIVRATIO_MASK);
262 reg |= ( TLL_SHARED_CONF_FCLK_IS_ON
263 | TLL_SHARED_CONF_USB_DIVRATIO_2
264 | TLL_SHARED_CONF_USB_180D_SDR_EN);
265
266 omap_tll_write_4(isc, OMAP_USBTLL_TLL_SHARED_CONF, reg);
267
268 /* Enable channels now */
269 for (i = 0; i < 3; i++) {
270 reg = omap_tll_read_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
271
272 /* Enable only the reg that is needed */
273 if ((en_mask & (1 << i)) == 0)
274 continue;
275
276 reg |= TLL_CHANNEL_CONF_CHANEN;
277 omap_tll_write_4(isc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
278 }
279}
280
281/**
282 * omap_ehci_soft_phy_reset - resets the phy using the reset command
283 * @isc: omap ehci device context
284 * @port: port to send the reset over
285 *
286 *
287 * LOCKING:
288 * none
289 *

--- 26 unchanged lines hidden (view full) ---

316 pause("USBPHY_RESET", 1);
317
318 if (timeout-- == 0) {
319 device_printf(isc->sc_dev, "PHY reset operation timed out\n");
320 break;
321 }
322 }
323}
161 * omap_ehci_soft_phy_reset - resets the phy using the reset command
162 * @isc: omap ehci device context
163 * @port: port to send the reset over
164 *
165 *
166 * LOCKING:
167 * none
168 *

--- 26 unchanged lines hidden (view full) ---

195 pause("USBPHY_RESET", 1);
196
197 if (timeout-- == 0) {
198 device_printf(isc->sc_dev, "PHY reset operation timed out\n");
199 break;
200 }
201 }
202}
324
325
326/**
327 * omap_ehci_init - initialises the USB host EHCI controller
328 * @isc: omap ehci device context
329 *
330 * This initialisation routine is quite heavily based on the work done by the
331 * OMAP Linux team (for which I thank them very much). The init sequence is
332 * almost identical, diverging only for the FreeBSD specifics.
333 *
334 * LOCKING:
335 * none
336 *
337 * RETURNS:
338 * 0 on success, a negative error code on failure.
339 */
340static int
341omap_ehci_init(struct omap_ehci_softc *isc)
342{
203
204/**
205 * omap_ehci_init - initialises the USB host EHCI controller
206 * @isc: omap ehci device context
207 *
208 * This initialisation routine is quite heavily based on the work done by the
209 * OMAP Linux team (for which I thank them very much). The init sequence is
210 * almost identical, diverging only for the FreeBSD specifics.
211 *
212 * LOCKING:
213 * none
214 *
215 * RETURNS:
216 * 0 on success, a negative error code on failure.
217 */
218static int
219omap_ehci_init(struct omap_ehci_softc *isc)
220{
343 unsigned long timeout;
344 int ret = 0;
345 uint8_t tll_ch_mask = 0;
346 uint32_t reg = 0;
221 uint32_t reg = 0;
347 int reset_performed = 0;
348 int i;
222 int i;
223 device_t uhh_dev;
349
224
225 uhh_dev = device_get_parent(isc->sc_dev);
350 device_printf(isc->sc_dev, "Starting TI EHCI USB Controller\n");
226 device_printf(isc->sc_dev, "Starting TI EHCI USB Controller\n");
351
352
353 /* Enable Clocks for high speed USBHOST */
354 ti_prcm_clk_enable(USBHSHOST_CLK);
355
356 /* Hold the PHY in reset while configuring */
357 for (int i = 0; i < 3; i++) {
358 if (isc->phy_reset[i]) {
359 /* Configure the GPIO to drive low (hold in reset) */
360 if ((isc->reset_gpio_pin[i] != -1) && (isc->sc_gpio_dev != NULL)) {
361 GPIO_PIN_SETFLAGS(isc->sc_gpio_dev, isc->reset_gpio_pin[i],
362 GPIO_PIN_OUTPUT);
363 GPIO_PIN_SET(isc->sc_gpio_dev, isc->reset_gpio_pin[i],
364 GPIO_PIN_LOW);
365 reset_performed = 1;
366 }
367 }
368 }
369
227
370 /* Hold the PHY in RESET for enough time till DIR is high */
371 if (reset_performed)
372 DELAY(10);
373
374 /* Read the UHH revision */
375 isc->ehci_rev = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_REVISION);
376 device_printf(isc->sc_dev, "UHH revision 0x%08x\n", isc->ehci_rev);
377
378 /* Initilise the low level interface module(s) */
379 if (isc->ehci_rev == OMAP_EHCI_REV1) {
380
381 /* Enable the USB TLL */
382 ti_prcm_clk_enable(USBTLL_CLK);
383
384 /* Perform TLL soft reset, and wait until reset is complete */
385 omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);
386
387 /* Set the timeout to 100ms*/
388 timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
389
390 /* Wait for TLL reset to complete */
391 while ((omap_tll_read_4(isc, OMAP_USBTLL_SYSSTATUS) &
392 TLL_SYSSTATUS_RESETDONE) == 0x00) {
393
394 /* Sleep for a tick */
395 pause("USBRESET", 1);
396
397 if (timeout-- == 0) {
398 device_printf(isc->sc_dev, "TLL reset operation timed out\n");
399 ret = EINVAL;
400 goto err_sys_status;
401 }
402 }
403
404 device_printf(isc->sc_dev, "TLL RESET DONE\n");
405
406 /* CLOCKACTIVITY = 1 : OCP-derived internal clocks ON during idle
407 * SIDLEMODE = 2 : Smart-idle mode. Sidleack asserted after Idlereq
408 * assertion when no more activity on the USB.
409 * ENAWAKEUP = 1 : Wakeup generation enabled
410 */
411 omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_ENAWAKEUP |
412 TLL_SYSCONFIG_AUTOIDLE |
413 TLL_SYSCONFIG_SIDLE_SMART_IDLE |
414 TLL_SYSCONFIG_CACTIVITY);
415
416 } else if (isc->ehci_rev == OMAP_EHCI_REV2) {
417
418 /* For OMAP44xx devices you have to enable the per-port clocks:
419 * PHY_MODE - External ULPI clock
420 * TTL_MODE - Internal UTMI clock
421 * HSIC_MODE - Internal 480Mhz and 60Mhz clocks
422 */
423 if (isc->ehci_rev == OMAP_EHCI_REV2) {
424 if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) {
425 ti_prcm_clk_set_source(USBP1_PHY_CLK, EXT_CLK);
426 ti_prcm_clk_enable(USBP1_PHY_CLK);
427 } else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
428 ti_prcm_clk_enable(USBP1_UTMI_CLK);
429 else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
430 ti_prcm_clk_enable(USBP1_HSIC_CLK);
431
432 if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) {
433 ti_prcm_clk_set_source(USBP2_PHY_CLK, EXT_CLK);
434 ti_prcm_clk_enable(USBP2_PHY_CLK);
435 } else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
436 ti_prcm_clk_enable(USBP2_UTMI_CLK);
437 else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
438 ti_prcm_clk_enable(USBP2_HSIC_CLK);
439 }
440 }
441
442 /* Put UHH in SmartIdle/SmartStandby mode */
443 reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSCONFIG);
444 if (isc->ehci_rev == OMAP_EHCI_REV1) {
445 reg &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK |
446 UHH_SYSCONFIG_MIDLEMODE_MASK);
447 reg |= (UHH_SYSCONFIG_ENAWAKEUP |
448 UHH_SYSCONFIG_AUTOIDLE |
449 UHH_SYSCONFIG_CLOCKACTIVITY |
450 UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE |
451 UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY);
452 } else if (isc->ehci_rev == OMAP_EHCI_REV2) {
453 reg &= ~UHH_SYSCONFIG_IDLEMODE_MASK;
454 reg |= UHH_SYSCONFIG_IDLEMODE_NOIDLE;
455 reg &= ~UHH_SYSCONFIG_STANDBYMODE_MASK;
456 reg |= UHH_SYSCONFIG_STANDBYMODE_NOSTDBY;
457 }
458 omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, reg);
459 device_printf(isc->sc_dev, "OMAP_UHH_SYSCONFIG: 0x%08x\n", reg);
460
461 reg = omap_uhh_read_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG);
462
463 /* Setup ULPI bypass and burst configurations */
464 reg |= (UHH_HOSTCONFIG_ENA_INCR4 |
465 UHH_HOSTCONFIG_ENA_INCR8 |
466 UHH_HOSTCONFIG_ENA_INCR16);
467 reg &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
468
469 if (isc->ehci_rev == OMAP_EHCI_REV1) {
470 if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN)
471 reg &= ~UHH_HOSTCONFIG_P1_CONNECT_STATUS;
472 if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN)
473 reg &= ~UHH_HOSTCONFIG_P2_CONNECT_STATUS;
474 if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN)
475 reg &= ~UHH_HOSTCONFIG_P3_CONNECT_STATUS;
476
477 /* Bypass the TLL module for PHY mode operation */
478 if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) ||
479 (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) ||
480 (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY))
481 reg &= ~UHH_HOSTCONFIG_P1_ULPI_BYPASS;
482 else
483 reg |= UHH_HOSTCONFIG_P1_ULPI_BYPASS;
484
485 } else if (isc->ehci_rev == OMAP_EHCI_REV2) {
486 reg |= UHH_HOSTCONFIG_APP_START_CLK;
487
488 /* Clear port mode fields for PHY mode*/
489 reg &= ~UHH_HOSTCONFIG_P1_MODE_MASK;
490 reg &= ~UHH_HOSTCONFIG_P2_MODE_MASK;
491
492 if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
493 reg |= UHH_HOSTCONFIG_P1_MODE_UTMI_PHY;
494 else if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_HSIC)
495 reg |= UHH_HOSTCONFIG_P1_MODE_HSIC;
496
497 if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
498 reg |= UHH_HOSTCONFIG_P2_MODE_UTMI_PHY;
499 else if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_HSIC)
500 reg |= UHH_HOSTCONFIG_P2_MODE_HSIC;
501 }
502
503 omap_uhh_write_4(isc, OMAP_USBHOST_UHH_HOSTCONFIG, reg);
504 device_printf(isc->sc_dev, "UHH setup done, uhh_hostconfig=0x%08x\n", reg);
505
506
507 /* I found the code and comments in the Linux EHCI driver - thanks guys :)
508 *
509 * "An undocumented "feature" in the OMAP3 EHCI controller, causes suspended
510 * ports to be taken out of suspend when the USBCMD.Run/Stop bit is cleared
511 * (for example when we do ehci_bus_suspend). This breaks suspend-resume if
512 * the root-hub is allowed to suspend. Writing 1 to this undocumented
513 * register bit disables this feature and restores normal behavior."
514 */
515#if 0
516 omap_ehci_write_4(isc, OMAP_USBHOST_INSNREG04,
517 OMAP_USBHOST_INSNREG04_DISABLE_UNSUSPEND);
518#endif
519
520 /* If any of the ports are configured in TLL mode, enable them */
521 if ((isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) ||
522 (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) ||
523 (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)) {
524
525 if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL)
526 tll_ch_mask |= 0x1;
527 if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL)
528 tll_ch_mask |= 0x2;
529 if (isc->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL)
530 tll_ch_mask |= 0x4;
531
532 /* Enable UTMI mode for required TLL channels */
533 omap_ehci_utmi_init(isc, tll_ch_mask);
534 }
535
536
537 /* Release the PHY reset signal now we have configured everything */
538 if (reset_performed) {
539
540 /* Delay for 10ms */
541 DELAY(10000);
542
543 for (i = 0; i < 3; i++) {
544 /* Release reset */
545
546 if (isc->phy_reset[i] && (isc->reset_gpio_pin[i] != -1)
547 && (isc->sc_gpio_dev != NULL)) {
548 GPIO_PIN_SET(isc->sc_gpio_dev,
549 isc->reset_gpio_pin[i], GPIO_PIN_HIGH);
550 }
551 }
552 }
553
554 /* Set the interrupt threshold control, it controls the maximum rate at
555 * which the host controller issues interrupts. We set it to 1 microframe
556 * at startup - the default is 8 mircoframes (equates to 1ms).
557 */
558 reg = omap_ehci_read_4(isc, OMAP_USBHOST_USBCMD);
559 reg &= 0xff00ffff;
560 reg |= (1 << 16);
561 omap_ehci_write_4(isc, OMAP_USBHOST_USBCMD, reg);
562
563 /* Soft reset the PHY using PHY reset command over ULPI */
228 /* Set the interrupt threshold control, it controls the maximum rate at
229 * which the host controller issues interrupts. We set it to 1 microframe
230 * at startup - the default is 8 mircoframes (equates to 1ms).
231 */
232 reg = omap_ehci_read_4(isc, OMAP_USBHOST_USBCMD);
233 reg &= 0xff00ffff;
234 reg |= (1 << 16);
235 omap_ehci_write_4(isc, OMAP_USBHOST_USBCMD, reg);
236
237 /* Soft reset the PHY using PHY reset command over ULPI */
564 if (isc->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY)
565 omap_ehci_soft_phy_reset(isc, 0);
566 if (isc->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY)
567 omap_ehci_soft_phy_reset(isc, 1);
238 for (i = 0; i < OMAP_HS_USB_PORTS; i++) {
239 if (omap_usb_port_mode(uhh_dev, i) == EHCI_HCD_OMAP_MODE_PHY)
240 omap_ehci_soft_phy_reset(isc, i);
568
241
569 return(0);
570
571err_sys_status:
572
573 /* Disable the TLL clocks */
574 ti_prcm_clk_disable(USBTLL_CLK);
575
576 /* Disable Clocks for USBHOST */
577 ti_prcm_clk_disable(USBHSHOST_CLK);
578
579 return(ret);
580}
581
582
583/**
584 * omap_ehci_fini - shutdown the EHCI controller
585 * @isc: omap ehci device context
586 *
587 *
588 *
589 * LOCKING:
590 * none
591 *
592 * RETURNS:
593 * 0 on success, a negative error code on failure.
594 */
595static void
596omap_ehci_fini(struct omap_ehci_softc *isc)
597{
598 unsigned long timeout;
599
600 device_printf(isc->sc_dev, "Stopping TI EHCI USB Controller\n");
601
602 /* Set the timeout */
603 if (hz < 10)
604 timeout = 1;
605 else
606 timeout = (100 * hz) / 1000;
607
608 /* Reset the UHH, OHCI and EHCI modules */
609 omap_uhh_write_4(isc, OMAP_USBHOST_UHH_SYSCONFIG, 0x0002);
610 while ((omap_uhh_read_4(isc, OMAP_USBHOST_UHH_SYSSTATUS) & 0x07) == 0x00) {
611 /* Sleep for a tick */
612 pause("USBRESET", 1);
613
614 if (timeout-- == 0) {
615 device_printf(isc->sc_dev, "operation timed out\n");
616 break;
617 }
618 }
242 }
619
620
243
621 /* Set the timeout */
622 if (hz < 10)
623 timeout = 1;
624 else
625 timeout = (100 * hz) / 1000;
626
627 /* Reset the TLL module */
628 omap_tll_write_4(isc, OMAP_USBTLL_SYSCONFIG, 0x0002);
629 while ((omap_tll_read_4(isc, OMAP_USBTLL_SYSSTATUS) & (0x01)) == 0x00) {
630 /* Sleep for a tick */
631 pause("USBRESET", 1);
632
633 if (timeout-- == 0) {
634 device_printf(isc->sc_dev, "operation timed out\n");
635 break;
636 }
637 }
638
639
640 /* Disable functional and interface clocks for the TLL and HOST modules */
641 ti_prcm_clk_disable(USBTLL_CLK);
642 ti_prcm_clk_disable(USBHSHOST_CLK);
643
644 device_printf(isc->sc_dev, "Clock to USB host has been disabled\n");
645
244 return(0);
646}
647
245}
246
648
649
650/**
247/**
651 * omap_ehci_suspend - suspends the bus
652 * @dev: omap ehci device
653 *
654 * Effectively boilerplate EHCI suspend code.
655 *
656 * TODO: There is a lot more we could do here - i.e. force the controller into
657 * idle mode and disable all the clocks for start.
658 *
659 * LOCKING:
660 * none
661 *
662 * RETURNS:
663 * 0 on success or a positive error code
664 */
665static int
666omap_ehci_suspend(device_t dev)
667{
668 int err;
669
670 err = bus_generic_suspend(dev);
671 if (err)
672 return (err);
673 return (0);
674}
675
676
677/**
678 * omap_ehci_resume - resumes a suspended bus
679 * @dev: omap ehci device
680 *
681 * Effectively boilerplate EHCI resume code.
682 *
683 * LOCKING:
684 * none
685 *
686 * RETURNS:
687 * 0 on success or a positive error code on failure
688 */
689static int
690omap_ehci_resume(device_t dev)
691{
692
693 bus_generic_resume(dev);
694
695 return (0);
696}
697
698
699/**
700 * omap_ehci_shutdown - starts the given command
701 * @dev:
702 *
703 * Effectively boilerplate EHCI shutdown code.
704 *
705 * LOCKING:
706 * none.
707 *
708 * RETURNS:
709 * 0 on success or a positive error code on failure
710 */
711static int
712omap_ehci_shutdown(device_t dev)
713{
714 int err;
715
716 err = bus_generic_shutdown(dev);
717 if (err)
718 return (err);
719
720 return (0);
721}
722
723
724/**
725 * omap_ehci_probe - starts the given command
726 * @dev:
727 *
728 * Effectively boilerplate EHCI resume code.
729 *
730 * LOCKING:
731 * Caller should be holding the OMAP3_MMC lock.
732 *
733 * RETURNS:
734 * EH_HANDLED or EH_NOT_HANDLED
735 */
736static int
737omap_ehci_probe(device_t dev)
738{
739
740 if (!ofw_bus_status_okay(dev))
741 return (ENXIO);
742
248 * omap_ehci_probe - starts the given command
249 * @dev:
250 *
251 * Effectively boilerplate EHCI resume code.
252 *
253 * LOCKING:
254 * Caller should be holding the OMAP3_MMC lock.
255 *
256 * RETURNS:
257 * EH_HANDLED or EH_NOT_HANDLED
258 */
259static int
260omap_ehci_probe(device_t dev)
261{
262
263 if (!ofw_bus_status_okay(dev))
264 return (ENXIO);
265
743 if (!ofw_bus_is_compatible(dev, "ti,usb-ehci"))
266 if (!ofw_bus_is_compatible(dev, "ti,ehci-omap"))
744 return (ENXIO);
745
746 device_set_desc(dev, OMAP_EHCI_HC_DEVSTR);
747
748 return (BUS_PROBE_DEFAULT);
749}
750
751/**

--- 9 unchanged lines hidden (view full) ---

761 *
762 * RETURNS:
763 * 0 on success or a positive error code on failure.
764 */
765static int
766omap_ehci_attach(device_t dev)
767{
768 struct omap_ehci_softc *isc = device_get_softc(dev);
267 return (ENXIO);
268
269 device_set_desc(dev, OMAP_EHCI_HC_DEVSTR);
270
271 return (BUS_PROBE_DEFAULT);
272}
273
274/**

--- 9 unchanged lines hidden (view full) ---

284 *
285 * RETURNS:
286 * 0 on success or a positive error code on failure.
287 */
288static int
289omap_ehci_attach(device_t dev)
290{
291 struct omap_ehci_softc *isc = device_get_softc(dev);
769 phandle_t node;
770 /* 3 ports with 3 cells per port */
771 pcell_t phyconf[3 * 3];
772 pcell_t *phyconf_ptr;
773 ehci_softc_t *sc = &isc->base;
774 int err;
775 int rid;
292 ehci_softc_t *sc = &isc->base;
293 int err;
294 int rid;
776 int len, tuple_size;
777 int i;
778
779 /* initialise some bus fields */
780 sc->sc_bus.parent = dev;
781 sc->sc_bus.devices = sc->sc_devices;
782 sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
783 sc->sc_bus.dma_bits = 32;
784
295
296 /* initialise some bus fields */
297 sc->sc_bus.parent = dev;
298 sc->sc_bus.devices = sc->sc_devices;
299 sc->sc_bus.devices_max = EHCI_MAX_DEVICES;
300 sc->sc_bus.dma_bits = 32;
301
302 sprintf(sc->sc_vendor, "Texas Instruments");
303
785 /* save the device */
786 isc->sc_dev = dev;
787
788 /* get all DMA memory */
789 if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
790 &ehci_iterate_hw_softc)) {
791 return (ENOMEM);
792 }
793
304 /* save the device */
305 isc->sc_dev = dev;
306
307 /* get all DMA memory */
308 if (usb_bus_mem_alloc_all(&sc->sc_bus, USB_GET_DMA_TAG(dev),
309 &ehci_iterate_hw_softc)) {
310 return (ENOMEM);
311 }
312
794 /* When the EHCI driver is added to the tree it is expected that 3
795 * memory resources and 1 interrupt resource is assigned. The memory
796 * resources should be:
797 * 0 => EHCI register range
798 * 1 => UHH register range
799 * 2 => TLL register range
800 *
801 * The interrupt resource is just the single interupt for the controller.
802 */
803
804 /* Allocate resource for the EHCI register set */
805 rid = 0;
806 sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
807 if (!sc->sc_io_res) {
808 device_printf(dev, "Error: Could not map EHCI memory\n");
809 goto error;
810 }
811 /* Request an interrupt resource */
812 rid = 0;
813 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
814 if (sc->sc_irq_res == NULL) {
815 device_printf(dev, "Error: could not allocate irq\n");
816 goto error;
817 }
818
313 /* Allocate resource for the EHCI register set */
314 rid = 0;
315 sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
316 if (!sc->sc_io_res) {
317 device_printf(dev, "Error: Could not map EHCI memory\n");
318 goto error;
319 }
320 /* Request an interrupt resource */
321 rid = 0;
322 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
323 if (sc->sc_irq_res == NULL) {
324 device_printf(dev, "Error: could not allocate irq\n");
325 goto error;
326 }
327
819 /* Allocate resource for the UHH register set */
820 rid = 1;
821 isc->uhh_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
822 if (!isc->uhh_mem_res) {
823 device_printf(dev, "Error: Could not map UHH memory\n");
824 goto error;
825 }
826 /* Allocate resource for the TLL register set */
827 rid = 2;
828 isc->tll_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
829 if (!isc->tll_mem_res) {
830 device_printf(dev, "Error: Could not map TLL memory\n");
831 goto error;
832 }
833
834 /* Add this device as a child of the USBus device */
835 sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
836 if (!sc->sc_bus.bdev) {
837 device_printf(dev, "Error: could not add USB device\n");
838 goto error;
839 }
840
841 device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
842 device_set_desc(sc->sc_bus.bdev, OMAP_EHCI_HC_DEVSTR);
843
328 /* Add this device as a child of the USBus device */
329 sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
330 if (!sc->sc_bus.bdev) {
331 device_printf(dev, "Error: could not add USB device\n");
332 goto error;
333 }
334
335 device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);
336 device_set_desc(sc->sc_bus.bdev, OMAP_EHCI_HC_DEVSTR);
337
844 /* Set the vendor name */
845 sprintf(sc->sc_vendor, "Texas Instruments");
846
847 /* Get the GPIO device, we may need this if the driver needs to toggle
848 * some pins for external PHY resets.
849 */
850 isc->sc_gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
851 if (isc->sc_gpio_dev == NULL) {
852 device_printf(dev, "Error: failed to get the GPIO device\n");
853 goto error;
854 }
855
856 /* Set the defaults for the hints */
857 for (i = 0; i < 3; i++) {
858 isc->phy_reset[i] = 0;
859 isc->port_mode[i] = EHCI_HCD_OMAP_MODE_UNKNOWN;
860 isc->reset_gpio_pin[i] = -1;
861 }
862
863 tuple_size = sizeof(pcell_t) * 3;
864 node = ofw_bus_get_node(dev);
865 len = OF_getprop(node, "phy-config", phyconf, sizeof(phyconf));
866 if (len > 0) {
867 if (len % tuple_size)
868 goto error;
869 if ((len / tuple_size) != 3)
870 goto error;
871
872 phyconf_ptr = phyconf;
873 for (i = 0; i < 3; i++) {
874 isc->port_mode[i] = fdt32_to_cpu(*phyconf_ptr);
875 isc->phy_reset[i] = fdt32_to_cpu(*(phyconf_ptr + 1));
876 isc->reset_gpio_pin[i] = fdt32_to_cpu(*(phyconf_ptr + 2));
877
878 phyconf_ptr += 3;
879 }
880 }
881
882 /* Initialise the ECHI registers */
883 err = omap_ehci_init(isc);
884 if (err) {
885 device_printf(dev, "Error: could not setup OMAP EHCI, %d\n", err);
886 goto error;
887 }
888
338 /* Initialise the ECHI registers */
339 err = omap_ehci_init(isc);
340 if (err) {
341 device_printf(dev, "Error: could not setup OMAP EHCI, %d\n", err);
342 goto error;
343 }
344
889
890 /* Set the tag and size of the register set in the EHCI context */
891 sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
892 sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
893 sc->sc_io_size = rman_get_size(sc->sc_io_res);
894
345 /* Set the tag and size of the register set in the EHCI context */
346 sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
347 sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
348 sc->sc_io_size = rman_get_size(sc->sc_io_res);
349
895
896 /* Setup the interrupt */
897 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
898 NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
899 if (err) {
900 device_printf(dev, "Error: could not setup irq, %d\n", err);
901 sc->sc_intr_hdl = NULL;
902 goto error;
903 }
904
350 /* Setup the interrupt */
351 err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
352 NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
353 if (err) {
354 device_printf(dev, "Error: could not setup irq, %d\n", err);
355 sc->sc_intr_hdl = NULL;
356 goto error;
357 }
358
905
906 /* Finally we are ready to kick off the ECHI host controller */
907 err = ehci_init(sc);
908 if (err == 0) {
909 err = device_probe_and_attach(sc->sc_bus.bdev);
910 }
911 if (err) {
912 device_printf(dev, "Error: USB init failed err=%d\n", err);
913 goto error;

--- 61 unchanged lines hidden (view full) ---

975 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
976 sc->sc_irq_res = NULL;
977 }
978 if (sc->sc_io_res) {
979 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_io_res);
980 sc->sc_io_res = NULL;
981 }
982
359 /* Finally we are ready to kick off the ECHI host controller */
360 err = ehci_init(sc);
361 if (err == 0) {
362 err = device_probe_and_attach(sc->sc_bus.bdev);
363 }
364 if (err) {
365 device_printf(dev, "Error: USB init failed err=%d\n", err);
366 goto error;

--- 61 unchanged lines hidden (view full) ---

428 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
429 sc->sc_irq_res = NULL;
430 }
431 if (sc->sc_io_res) {
432 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_io_res);
433 sc->sc_io_res = NULL;
434 }
435
983 /* Release the other register set memory maps */
984 if (isc->tll_mem_res) {
985 bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->tll_mem_res);
986 isc->tll_mem_res = NULL;
987 }
988 if (isc->uhh_mem_res) {
989 bus_release_resource(dev, SYS_RES_MEMORY, 0, isc->uhh_mem_res);
990 isc->uhh_mem_res = NULL;
991 }
992
993 usb_bus_mem_free_all(&sc->sc_bus, &ehci_iterate_hw_softc);
994
995 omap_ehci_fini(isc);
996
997 return (0);
998}
999
1000static device_method_t ehci_methods[] = {
1001 /* Device interface */
1002 DEVMETHOD(device_probe, omap_ehci_probe),
1003 DEVMETHOD(device_attach, omap_ehci_attach),
1004 DEVMETHOD(device_detach, omap_ehci_detach),
436 return (0);
437}
438
439static device_method_t ehci_methods[] = {
440 /* Device interface */
441 DEVMETHOD(device_probe, omap_ehci_probe),
442 DEVMETHOD(device_attach, omap_ehci_attach),
443 DEVMETHOD(device_detach, omap_ehci_detach),
1005 DEVMETHOD(device_suspend, omap_ehci_suspend),
1006 DEVMETHOD(device_resume, omap_ehci_resume),
1007 DEVMETHOD(device_shutdown, omap_ehci_shutdown),
444
445 DEVMETHOD(device_suspend, bus_generic_suspend),
446 DEVMETHOD(device_resume, bus_generic_resume),
447 DEVMETHOD(device_shutdown, bus_generic_shutdown),
1008
1009 /* Bus interface */
1010 DEVMETHOD(bus_print_child, bus_generic_print_child),
1011
1012 {0, 0}
1013};
1014
1015static driver_t ehci_driver = {
1016 "ehci",
1017 ehci_methods,
1018 sizeof(struct omap_ehci_softc),
1019};
1020
1021static devclass_t ehci_devclass;
1022
448
449 /* Bus interface */
450 DEVMETHOD(bus_print_child, bus_generic_print_child),
451
452 {0, 0}
453};
454
455static driver_t ehci_driver = {
456 "ehci",
457 ehci_methods,
458 sizeof(struct omap_ehci_softc),
459};
460
461static devclass_t ehci_devclass;
462
1023DRIVER_MODULE(ehci, simplebus, ehci_driver, ehci_devclass, 0, 0);
463DRIVER_MODULE(ehci, omap_uhh, ehci_driver, ehci_devclass, 0, 0);