1283276Sgonzo/*-
2283276Sgonzo * Copyright (c) 2011
3283276Sgonzo *	Ben Gray <ben.r.gray@gmail.com>.
4283276Sgonzo * All rights reserved.
5283276Sgonzo *
6283276Sgonzo * Redistribution and use in source and binary forms, with or without
7283276Sgonzo * modification, are permitted provided that the following conditions
8283276Sgonzo * are met:
9283276Sgonzo * 1. Redistributions of source code must retain the above copyright
10283276Sgonzo *    notice, this list of conditions and the following disclaimer.
11283276Sgonzo * 2. Redistributions in binary form must reproduce the above copyright
12283276Sgonzo *    notice, this list of conditions and the following disclaimer in the
13283276Sgonzo *    documentation and/or other materials provided with the distribution.
14283276Sgonzo *
15283276Sgonzo * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16283276Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17283276Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18283276Sgonzo * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19283276Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20283276Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21283276Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22283276Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23283276Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24283276Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25283276Sgonzo * SUCH DAMAGE.
26283276Sgonzo */
27283276Sgonzo
28283276Sgonzo#include <sys/cdefs.h>
29283276Sgonzo__FBSDID("$FreeBSD$");
30283276Sgonzo
31283276Sgonzo#include <sys/param.h>
32283276Sgonzo#include <sys/systm.h>
33283276Sgonzo#include <sys/conf.h>
34283276Sgonzo#include <sys/kernel.h>
35283276Sgonzo#include <sys/rman.h>
36283276Sgonzo#include <sys/module.h>
37283276Sgonzo
38283276Sgonzo#include <dev/fdt/fdt_common.h>
39283276Sgonzo#include <dev/ofw/ofw_bus_subr.h>
40283276Sgonzo
41283276Sgonzo#include <machine/bus.h>
42283276Sgonzo
43283276Sgonzo#include <arm/ti/ti_prcm.h>
44283276Sgonzo#include <arm/ti/usb/omap_usb.h>
45283276Sgonzo
46283276Sgonzo/*
47283276Sgonzo * USB TLL Module
48283276Sgonzo */
49283276Sgonzo#define	OMAP_USBTLL_REVISION                        0x0000
50283276Sgonzo#define	OMAP_USBTLL_SYSCONFIG                       0x0010
51283276Sgonzo#define	OMAP_USBTLL_SYSSTATUS                       0x0014
52283276Sgonzo#define	OMAP_USBTLL_IRQSTATUS                       0x0018
53283276Sgonzo#define	OMAP_USBTLL_IRQENABLE                       0x001C
54283276Sgonzo#define	OMAP_USBTLL_TLL_SHARED_CONF                 0x0030
55283276Sgonzo#define	OMAP_USBTLL_TLL_CHANNEL_CONF(i)             (0x0040 + (0x04 * (i)))
56283276Sgonzo#define	OMAP_USBTLL_SAR_CNTX(i)                     (0x0400 + (0x04 * (i)))
57283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_ID_LO(i)            (0x0800 + (0x100 * (i)))
58283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_ID_HI(i)            (0x0801 + (0x100 * (i)))
59283276Sgonzo#define	OMAP_USBTLL_ULPI_PRODUCT_ID_LO(i)           (0x0802 + (0x100 * (i)))
60283276Sgonzo#define	OMAP_USBTLL_ULPI_PRODUCT_ID_HI(i)           (0x0803 + (0x100 * (i)))
61283276Sgonzo#define	OMAP_USBTLL_ULPI_FUNCTION_CTRL(i)           (0x0804 + (0x100 * (i)))
62283276Sgonzo#define	OMAP_USBTLL_ULPI_FUNCTION_CTRL_SET(i)       (0x0805 + (0x100 * (i)))
63283276Sgonzo#define	OMAP_USBTLL_ULPI_FUNCTION_CTRL_CLR(i)       (0x0806 + (0x100 * (i)))
64283276Sgonzo#define	OMAP_USBTLL_ULPI_INTERFACE_CTRL(i)          (0x0807 + (0x100 * (i)))
65283276Sgonzo#define	OMAP_USBTLL_ULPI_INTERFACE_CTRL_SET(i)      (0x0808 + (0x100 * (i)))
66283276Sgonzo#define	OMAP_USBTLL_ULPI_INTERFACE_CTRL_CLR(i)      (0x0809 + (0x100 * (i)))
67283276Sgonzo#define	OMAP_USBTLL_ULPI_OTG_CTRL(i)                (0x080A + (0x100 * (i)))
68283276Sgonzo#define	OMAP_USBTLL_ULPI_OTG_CTRL_SET(i)            (0x080B + (0x100 * (i)))
69283276Sgonzo#define	OMAP_USBTLL_ULPI_OTG_CTRL_CLR(i)            (0x080C + (0x100 * (i)))
70283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE(i)         (0x080D + (0x100 * (i)))
71283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE_SET(i)     (0x080E + (0x100 * (i)))
72283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i)     (0x080F + (0x100 * (i)))
73283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL(i)         (0x0810 + (0x100 * (i)))
74283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL_SET(i)     (0x0811 + (0x100 * (i)))
75283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i)     (0x0812 + (0x100 * (i)))
76283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_STATUS(i)          (0x0813 + (0x100 * (i)))
77283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_LATCH(i)           (0x0814 + (0x100 * (i)))
78283276Sgonzo#define	OMAP_USBTLL_ULPI_DEBUG(i)                   (0x0815 + (0x100 * (i)))
79283276Sgonzo#define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER(i)        (0x0816 + (0x100 * (i)))
80283276Sgonzo#define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER_SET(i)    (0x0817 + (0x100 * (i)))
81283276Sgonzo#define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i)    (0x0818 + (0x100 * (i)))
82283276Sgonzo#define	OMAP_USBTLL_ULPI_EXTENDED_SET_ACCESS(i)     (0x082F + (0x100 * (i)))
83283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN(i)        (0x0830 + (0x100 * (i)))
84283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i)    (0x0831 + (0x100 * (i)))
85283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i)    (0x0832 + (0x100 * (i)))
86283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i)    (0x0833 + (0x100 * (i)))
87283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i)     (0x0834 + (0x100 * (i)))
88283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VSTATUS(i)            (0x0835 + (0x100 * (i)))
89283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VSTATUS_SET(i)        (0x0836 + (0x100 * (i)))
90283276Sgonzo#define	OMAP_USBTLL_ULPI_UTMI_VSTATUS_CLR(i)        (0x0837 + (0x100 * (i)))
91283276Sgonzo#define	OMAP_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i)     (0x0838 + (0x100 * (i)))
92283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_INT_EN(i)           (0x083B + (0x100 * (i)))
93283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_INT_EN_SET(i)       (0x083C + (0x100 * (i)))
94283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_INT_EN_CLR(i)       (0x083D + (0x100 * (i)))
95283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_INT_STATUS(i)       (0x083E + (0x100 * (i)))
96283276Sgonzo#define	OMAP_USBTLL_ULPI_VENDOR_INT_LATCH(i)        (0x083F + (0x100 * (i)))
97283276Sgonzo
98283276Sgonzo/* TLL Register Set */
99283276Sgonzo#define	TLL_SYSCONFIG_CACTIVITY                 (1UL << 8)
100283276Sgonzo#define	TLL_SYSCONFIG_SIDLE_SMART_IDLE          (2UL << 3)
101283276Sgonzo#define	TLL_SYSCONFIG_SIDLE_NO_IDLE             (1UL << 3)
102283276Sgonzo#define	TLL_SYSCONFIG_SIDLE_FORCED_IDLE         (0UL << 3)
103283276Sgonzo#define	TLL_SYSCONFIG_ENAWAKEUP                 (1UL << 2)
104283276Sgonzo#define	TLL_SYSCONFIG_SOFTRESET                 (1UL << 1)
105283276Sgonzo#define	TLL_SYSCONFIG_AUTOIDLE                  (1UL << 0)
106283276Sgonzo
107283276Sgonzo#define	TLL_SYSSTATUS_RESETDONE                 (1UL << 0)
108283276Sgonzo
109283276Sgonzo#define TLL_SHARED_CONF_USB_90D_DDR_EN          (1UL << 6)
110283276Sgonzo#define TLL_SHARED_CONF_USB_180D_SDR_EN         (1UL << 5)
111283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_MASK       (7UL << 2)
112283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_128        (7UL << 2)
113283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_64         (6UL << 2)
114283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_32         (5UL << 2)
115283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_16         (4UL << 2)
116283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_8          (3UL << 2)
117283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_4          (2UL << 2)
118283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_2          (1UL << 2)
119283276Sgonzo#define TLL_SHARED_CONF_USB_DIVRATIO_1          (0UL << 2)
120283276Sgonzo#define TLL_SHARED_CONF_FCLK_REQ                (1UL << 1)
121283276Sgonzo#define TLL_SHARED_CONF_FCLK_IS_ON              (1UL << 0)
122283276Sgonzo
123283276Sgonzo#define TLL_CHANNEL_CONF_DRVVBUS                (1UL << 16)
124283276Sgonzo#define TLL_CHANNEL_CONF_CHRGVBUS               (1UL << 15)
125283276Sgonzo#define TLL_CHANNEL_CONF_ULPINOBITSTUFF         (1UL << 11)
126283276Sgonzo#define TLL_CHANNEL_CONF_ULPIAUTOIDLE           (1UL << 10)
127283276Sgonzo#define TLL_CHANNEL_CONF_UTMIAUTOIDLE           (1UL << 9)
128283276Sgonzo#define TLL_CHANNEL_CONF_ULPIDDRMODE            (1UL << 8)
129283276Sgonzo#define TLL_CHANNEL_CONF_ULPIOUTCLKMODE         (1UL << 7)
130283276Sgonzo#define TLL_CHANNEL_CONF_TLLFULLSPEED           (1UL << 6)
131283276Sgonzo#define TLL_CHANNEL_CONF_TLLCONNECT             (1UL << 5)
132283276Sgonzo#define TLL_CHANNEL_CONF_TLLATTACH              (1UL << 4)
133283276Sgonzo#define TLL_CHANNEL_CONF_UTMIISADEV             (1UL << 3)
134283276Sgonzo#define TLL_CHANNEL_CONF_CHANEN                 (1UL << 0)
135283276Sgonzo
136283276Sgonzostruct omap_tll_softc {
137283276Sgonzo	device_t		sc_dev;
138283276Sgonzo
139283276Sgonzo	/* TLL register set */
140283276Sgonzo	struct resource*	tll_mem_res;
141283276Sgonzo	int			tll_mem_rid;
142283276Sgonzo};
143283276Sgonzo
144283276Sgonzostatic struct omap_tll_softc *omap_tll_sc;
145283276Sgonzo
146283276Sgonzostatic int omap_tll_attach(device_t dev);
147283276Sgonzostatic int omap_tll_detach(device_t dev);
148283276Sgonzo
149283276Sgonzostatic inline uint32_t
150283276Sgonzoomap_tll_read_4(struct omap_tll_softc *sc, bus_size_t off)
151283276Sgonzo{
152283276Sgonzo	return bus_read_4(sc->tll_mem_res, off);
153283276Sgonzo}
154283276Sgonzo
155283276Sgonzostatic inline void
156283276Sgonzoomap_tll_write_4(struct omap_tll_softc *sc, bus_size_t off, uint32_t val)
157283276Sgonzo{
158283276Sgonzo	bus_write_4(sc->tll_mem_res, off, val);
159283276Sgonzo}
160283276Sgonzo
161283276Sgonzovoid
162283276Sgonzoomap_tll_utmi_enable(unsigned int en_mask)
163283276Sgonzo{
164283276Sgonzo	struct omap_tll_softc *sc;
165283276Sgonzo	unsigned int i;
166283276Sgonzo	uint32_t reg;
167283276Sgonzo
168283276Sgonzo	sc = omap_tll_sc;
169283276Sgonzo	if (sc == NULL)
170283276Sgonzo		return;
171283276Sgonzo
172283276Sgonzo	/* There are 3 TLL channels, one per USB controller so set them all up the
173283276Sgonzo	 * same, SDR mode, bit stuffing and no autoidle.
174283276Sgonzo	 */
175283276Sgonzo	for (i=0; i<3; i++) {
176283276Sgonzo		reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
177283276Sgonzo
178283276Sgonzo		reg &= ~(TLL_CHANNEL_CONF_UTMIAUTOIDLE
179283276Sgonzo				 | TLL_CHANNEL_CONF_ULPINOBITSTUFF
180283276Sgonzo				 | TLL_CHANNEL_CONF_ULPIDDRMODE);
181283276Sgonzo
182283276Sgonzo		omap_tll_write_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
183283276Sgonzo	}
184283276Sgonzo
185283276Sgonzo	/* Program the common TLL register */
186283276Sgonzo	reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_SHARED_CONF);
187283276Sgonzo
188283276Sgonzo	reg &= ~( TLL_SHARED_CONF_USB_90D_DDR_EN
189283276Sgonzo			| TLL_SHARED_CONF_USB_DIVRATIO_MASK);
190283276Sgonzo	reg |=  ( TLL_SHARED_CONF_FCLK_IS_ON
191283276Sgonzo			| TLL_SHARED_CONF_USB_DIVRATIO_2
192283276Sgonzo			| TLL_SHARED_CONF_USB_180D_SDR_EN);
193283276Sgonzo
194283276Sgonzo	omap_tll_write_4(sc, OMAP_USBTLL_TLL_SHARED_CONF, reg);
195283276Sgonzo
196283276Sgonzo	/* Enable channels now */
197283276Sgonzo	for (i = 0; i < 3; i++) {
198283276Sgonzo		reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
199283276Sgonzo
200283276Sgonzo		/* Enable only the reg that is needed */
201283276Sgonzo		if ((en_mask & (1 << i)) == 0)
202283276Sgonzo			continue;
203283276Sgonzo
204283276Sgonzo		reg |= TLL_CHANNEL_CONF_CHANEN;
205283276Sgonzo		omap_tll_write_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
206283276Sgonzo	}
207283276Sgonzo}
208283276Sgonzo
209283276Sgonzostatic int
210283276Sgonzoomap_tll_init(struct omap_tll_softc *sc)
211283276Sgonzo{
212283276Sgonzo	unsigned long timeout;
213283276Sgonzo	int ret = 0;
214283276Sgonzo
215283276Sgonzo	/* Enable the USB TLL */
216283276Sgonzo	ti_prcm_clk_enable(USBTLL_CLK);
217283276Sgonzo
218283276Sgonzo	/* Perform TLL soft reset, and wait until reset is complete */
219283276Sgonzo	omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);
220283276Sgonzo
221283276Sgonzo	/* Set the timeout to 100ms*/
222283276Sgonzo	timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
223283276Sgonzo
224283276Sgonzo	/* Wait for TLL reset to complete */
225283276Sgonzo	while ((omap_tll_read_4(sc, OMAP_USBTLL_SYSSTATUS) &
226283276Sgonzo	        TLL_SYSSTATUS_RESETDONE) == 0x00) {
227283276Sgonzo
228283276Sgonzo		/* Sleep for a tick */
229283276Sgonzo		pause("USBRESET", 1);
230283276Sgonzo
231283276Sgonzo		if (timeout-- == 0) {
232283276Sgonzo			device_printf(sc->sc_dev, "TLL reset operation timed out\n");
233283276Sgonzo			ret = EINVAL;
234283276Sgonzo			goto err_sys_status;
235283276Sgonzo		}
236283276Sgonzo	}
237283276Sgonzo
238283276Sgonzo	/* CLOCKACTIVITY = 1 : OCP-derived internal clocks ON during idle
239283276Sgonzo	 * SIDLEMODE = 2     : Smart-idle mode. Sidleack asserted after Idlereq
240283276Sgonzo	 *                     assertion when no more activity on the USB.
241283276Sgonzo	 * ENAWAKEUP = 1     : Wakeup generation enabled
242283276Sgonzo	 */
243283276Sgonzo	omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_ENAWAKEUP |
244283276Sgonzo	                                            TLL_SYSCONFIG_AUTOIDLE |
245283276Sgonzo	                                            TLL_SYSCONFIG_SIDLE_SMART_IDLE |
246283276Sgonzo	                                            TLL_SYSCONFIG_CACTIVITY);
247283276Sgonzo
248283276Sgonzo	return(0);
249283276Sgonzo
250283276Sgonzoerr_sys_status:
251283276Sgonzo	/* Disable the TLL clocks */
252283276Sgonzo	ti_prcm_clk_disable(USBTLL_CLK);
253283276Sgonzo
254283276Sgonzo	return(ret);
255283276Sgonzo}
256283276Sgonzo
257283276Sgonzostatic void
258283276Sgonzoomap_tll_disable(struct omap_tll_softc *sc)
259283276Sgonzo{
260283276Sgonzo	unsigned long timeout;
261283276Sgonzo
262283276Sgonzo	timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
263283276Sgonzo
264283276Sgonzo	/* Reset the TLL module */
265283276Sgonzo	omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, 0x0002);
266283276Sgonzo	while ((omap_tll_read_4(sc, OMAP_USBTLL_SYSSTATUS) & (0x01)) == 0x00) {
267283276Sgonzo		/* Sleep for a tick */
268283276Sgonzo		pause("USBRESET", 1);
269283276Sgonzo
270283276Sgonzo		if (timeout-- == 0) {
271283276Sgonzo			device_printf(sc->sc_dev, "operation timed out\n");
272283276Sgonzo			break;
273283276Sgonzo		}
274283276Sgonzo	}
275283276Sgonzo
276283276Sgonzo	/* Disable functional and interface clocks for the TLL and HOST modules */
277283276Sgonzo	ti_prcm_clk_disable(USBTLL_CLK);
278283276Sgonzo}
279283276Sgonzo
280283276Sgonzostatic int
281283276Sgonzoomap_tll_probe(device_t dev)
282283276Sgonzo{
283283276Sgonzo
284283276Sgonzo	if (!ofw_bus_status_okay(dev))
285283276Sgonzo		return (ENXIO);
286283276Sgonzo
287283276Sgonzo	if (!ofw_bus_is_compatible(dev, "ti,usbhs-tll"))
288283276Sgonzo		return (ENXIO);
289283276Sgonzo
290283276Sgonzo	device_set_desc(dev, "TI OMAP USB 2.0 TLL module");
291283276Sgonzo
292283276Sgonzo	return (BUS_PROBE_DEFAULT);
293283276Sgonzo}
294283276Sgonzo
295283276Sgonzostatic int
296283276Sgonzoomap_tll_attach(device_t dev)
297283276Sgonzo{
298283276Sgonzo	struct omap_tll_softc *sc;
299283276Sgonzo
300283276Sgonzo	sc = device_get_softc(dev);
301283276Sgonzo	/* save the device */
302283276Sgonzo	sc->sc_dev = dev;
303283276Sgonzo
304283276Sgonzo	/* Allocate resource for the TLL register set */
305283276Sgonzo	sc->tll_mem_rid = 0;
306283276Sgonzo	sc->tll_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
307283276Sgonzo	    &sc->tll_mem_rid, RF_ACTIVE);
308283276Sgonzo	if (!sc->tll_mem_res) {
309283276Sgonzo		device_printf(dev, "Error: Could not map TLL memory\n");
310283276Sgonzo		goto error;
311283276Sgonzo	}
312283276Sgonzo
313283276Sgonzo	omap_tll_init(sc);
314283276Sgonzo
315283276Sgonzo	omap_tll_sc = sc;
316283276Sgonzo
317283276Sgonzo	return (0);
318283276Sgonzo
319283276Sgonzoerror:
320283276Sgonzo	omap_tll_detach(dev);
321283276Sgonzo	return (ENXIO);
322283276Sgonzo}
323283276Sgonzo
324283276Sgonzostatic int
325283276Sgonzoomap_tll_detach(device_t dev)
326283276Sgonzo{
327283276Sgonzo	struct omap_tll_softc *sc;
328283276Sgonzo
329283276Sgonzo	sc = device_get_softc(dev);
330283276Sgonzo	omap_tll_disable(sc);
331283276Sgonzo
332283276Sgonzo	/* Release the other register set memory maps */
333283276Sgonzo	if (sc->tll_mem_res) {
334283276Sgonzo		bus_release_resource(dev, SYS_RES_MEMORY,
335283276Sgonzo		    sc->tll_mem_rid, sc->tll_mem_res);
336283276Sgonzo		sc->tll_mem_res = NULL;
337283276Sgonzo	}
338283276Sgonzo
339283276Sgonzo	omap_tll_sc = NULL;
340283276Sgonzo
341283276Sgonzo	return (0);
342283276Sgonzo}
343283276Sgonzo
344283276Sgonzostatic device_method_t omap_tll_methods[] = {
345283276Sgonzo	/* Device interface */
346283276Sgonzo	DEVMETHOD(device_probe, omap_tll_probe),
347283276Sgonzo	DEVMETHOD(device_attach, omap_tll_attach),
348283276Sgonzo	DEVMETHOD(device_detach, omap_tll_detach),
349283276Sgonzo	DEVMETHOD(device_suspend, bus_generic_suspend),
350283276Sgonzo	DEVMETHOD(device_resume, bus_generic_resume),
351283276Sgonzo	DEVMETHOD(device_shutdown, bus_generic_shutdown),
352283276Sgonzo
353283276Sgonzo	{0, 0}
354283276Sgonzo};
355283276Sgonzo
356283276Sgonzostatic driver_t omap_tll_driver = {
357283276Sgonzo	"omap_tll",
358283276Sgonzo	omap_tll_methods,
359283276Sgonzo	sizeof(struct omap_tll_softc),
360283276Sgonzo};
361283276Sgonzo
362283276Sgonzostatic devclass_t omap_tll_devclass;
363283276Sgonzo
364283276SgonzoDRIVER_MODULE(omap_tll, simplebus, omap_tll_driver, omap_tll_devclass, 0, 0);
365