aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorKeshava Munegowda <keshava_mgowda@ti.com>2011-03-01 09:38:17 -0500
committerFelipe Balbi <balbi@ti.com>2011-03-01 10:02:22 -0500
commit17cdd29d6e1ab4164c792d78c6f096fbafb94e3f (patch)
tree46c8d1055f00eb79db0b035a58bbee5382de6c1c /drivers/mfd
parent181b250cf53233a7a7c6d7e1e9df402506712e93 (diff)
usb: host: omap: common usb host core driver
enabling and disabling the common clocks for ehci and ohci is implemented. usbhs is a common parent platform driver for EHCI and OHCI driver. This driver receives the clock enable and disable requests from ehci and ohci drivers.The UHH and TLL initialization is also performed. Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig9
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/omap-usb-host.c1061
3 files changed, 1071 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fd018366d670..a6dfa37a674d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -624,6 +624,15 @@ config MFD_WL1273_CORE
624 driver connects the radio-wl1273 V4L2 module and the wl1273 624 driver connects the radio-wl1273 V4L2 module and the wl1273
625 audio codec. 625 audio codec.
626 626
627config MFD_OMAP_USB_HOST
628 bool "Support OMAP USBHS core driver"
629 depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
630 default y
631 help
632 This is the core driver for the OAMP EHCI and OHCI drivers.
633 This MFD driver does the required setup functionalities for
634 OMAP USB Host drivers.
635
627endif # MFD_SUPPORT 636endif # MFD_SUPPORT
628 637
629menu "Multimedia Capabilities Port drivers" 638menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a54e2c7c6a1c..91fe384459ab 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -83,3 +83,4 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
83obj-$(CONFIG_MFD_VX855) += vx855.o 83obj-$(CONFIG_MFD_VX855) += vx855.o
84obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o 84obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
85obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o 85obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
86obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
new file mode 100644
index 000000000000..cb01209754e0
--- /dev/null
+++ b/drivers/mfd/omap-usb-host.c
@@ -0,0 +1,1061 @@
1/**
2 * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Keshava Munegowda <keshava_mgowda@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#include <linux/kernel.h>
20#include <linux/types.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/platform_device.h>
24#include <linux/clk.h>
25#include <linux/dma-mapping.h>
26#include <linux/spinlock.h>
27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>
29#include <plat/usb.h>
30
31#define USBHS_DRIVER_NAME "usbhs-omap"
32#define OMAP_EHCI_DEVICE "ehci-omap"
33#define OMAP_OHCI_DEVICE "ohci-omap3"
34
35/* OMAP USBHOST Register addresses */
36
37/* TLL Register Set */
38#define OMAP_USBTLL_REVISION (0x00)
39#define OMAP_USBTLL_SYSCONFIG (0x10)
40#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8)
41#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3)
42#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2)
43#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1)
44#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0)
45
46#define OMAP_USBTLL_SYSSTATUS (0x14)
47#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0)
48
49#define OMAP_USBTLL_IRQSTATUS (0x18)
50#define OMAP_USBTLL_IRQENABLE (0x1C)
51
52#define OMAP_TLL_SHARED_CONF (0x30)
53#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6)
54#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5)
55#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2)
56#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1)
57#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0)
58
59#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
60#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
61#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
62#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
63#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
64#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
65#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
66#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
67
68#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0
69#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1
70#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2
71#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3
72#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4
73#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5
74#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6
75#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7
76#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA
77#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB
78
79#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num)
80#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num)
81#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num)
82#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num)
83#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num)
84#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num)
85#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num)
86#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num)
87#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num)
88
89#define OMAP_TLL_CHANNEL_COUNT 3
90#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0)
91#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1)
92#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2)
93
94/* UHH Register Set */
95#define OMAP_UHH_REVISION (0x00)
96#define OMAP_UHH_SYSCONFIG (0x10)
97#define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12)
98#define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8)
99#define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3)
100#define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2)
101#define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1)
102#define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0)
103
104#define OMAP_UHH_SYSSTATUS (0x14)
105#define OMAP_UHH_HOSTCONFIG (0x40)
106#define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0)
107#define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0)
108#define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11)
109#define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12)
110#define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2)
111#define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3)
112#define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4)
113#define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5)
114#define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8)
115#define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9)
116#define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10)
117#define OMAP4_UHH_HOSTCONFIG_APP_START_CLK (1 << 31)
118
119/* OMAP4-specific defines */
120#define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2)
121#define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2)
122#define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4)
123#define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4)
124#define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0)
125
126#define OMAP4_P1_MODE_CLEAR (3 << 16)
127#define OMAP4_P1_MODE_TLL (1 << 16)
128#define OMAP4_P1_MODE_HSIC (3 << 16)
129#define OMAP4_P2_MODE_CLEAR (3 << 18)
130#define OMAP4_P2_MODE_TLL (1 << 18)
131#define OMAP4_P2_MODE_HSIC (3 << 18)
132
133#define OMAP_REV2_TLL_CHANNEL_COUNT 2
134
135#define OMAP_UHH_DEBUG_CSR (0x44)
136
137/* Values of UHH_REVISION - Note: these are not given in the TRM */
138#define OMAP_USBHS_REV1 0x00000010 /* OMAP3 */
139#define OMAP_USBHS_REV2 0x50700100 /* OMAP4 */
140
141#define is_omap_usbhs_rev1(x) (x->usbhs_rev == OMAP_USBHS_REV1)
142#define is_omap_usbhs_rev2(x) (x->usbhs_rev == OMAP_USBHS_REV2)
143
144#define is_ehci_phy_mode(x) (x == OMAP_EHCI_PORT_MODE_PHY)
145#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
146#define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
147
148
149struct usbhs_hcd_omap {
150 struct clk *usbhost_ick;
151 struct clk *usbhost_hs_fck;
152 struct clk *usbhost_fs_fck;
153 struct clk *xclk60mhsp1_ck;
154 struct clk *xclk60mhsp2_ck;
155 struct clk *utmi_p1_fck;
156 struct clk *usbhost_p1_fck;
157 struct clk *usbtll_p1_fck;
158 struct clk *utmi_p2_fck;
159 struct clk *usbhost_p2_fck;
160 struct clk *usbtll_p2_fck;
161 struct clk *init_60m_fclk;
162 struct clk *usbtll_fck;
163 struct clk *usbtll_ick;
164
165 void __iomem *uhh_base;
166 void __iomem *tll_base;
167
168 struct usbhs_omap_platform_data platdata;
169
170 u32 usbhs_rev;
171 spinlock_t lock;
172 int count;
173};
174/*-------------------------------------------------------------------------*/
175
176const char usbhs_driver_name[] = USBHS_DRIVER_NAME;
177static u64 usbhs_dmamask = ~(u32)0;
178
179/*-------------------------------------------------------------------------*/
180
181static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
182{
183 __raw_writel(val, base + reg);
184}
185
186static inline u32 usbhs_read(void __iomem *base, u32 reg)
187{
188 return __raw_readl(base + reg);
189}
190
191static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val)
192{
193 __raw_writeb(val, base + reg);
194}
195
196static inline u8 usbhs_readb(void __iomem *base, u8 reg)
197{
198 return __raw_readb(base + reg);
199}
200
201/*-------------------------------------------------------------------------*/
202
203static struct platform_device *omap_usbhs_alloc_child(const char *name,
204 struct resource *res, int num_resources, void *pdata,
205 size_t pdata_size, struct device *dev)
206{
207 struct platform_device *child;
208 int ret;
209
210 child = platform_device_alloc(name, 0);
211
212 if (!child) {
213 dev_err(dev, "platform_device_alloc %s failed\n", name);
214 goto err_end;
215 }
216
217 ret = platform_device_add_resources(child, res, num_resources);
218 if (ret) {
219 dev_err(dev, "platform_device_add_resources failed\n");
220 goto err_alloc;
221 }
222
223 ret = platform_device_add_data(child, pdata, pdata_size);
224 if (ret) {
225 dev_err(dev, "platform_device_add_data failed\n");
226 goto err_alloc;
227 }
228
229 child->dev.dma_mask = &usbhs_dmamask;
230 child->dev.coherent_dma_mask = 0xffffffff;
231 child->dev.parent = dev;
232
233 ret = platform_device_add(child);
234 if (ret) {
235 dev_err(dev, "platform_device_add failed\n");
236 goto err_alloc;
237 }
238
239 return child;
240
241err_alloc:
242 platform_device_put(child);
243
244err_end:
245 return NULL;
246}
247
248static int omap_usbhs_alloc_children(struct platform_device *pdev)
249{
250 struct device *dev = &pdev->dev;
251 struct usbhs_hcd_omap *omap;
252 struct ehci_hcd_omap_platform_data *ehci_data;
253 struct ohci_hcd_omap_platform_data *ohci_data;
254 struct platform_device *ehci;
255 struct platform_device *ohci;
256 struct resource *res;
257 struct resource resources[2];
258 int ret;
259
260 omap = platform_get_drvdata(pdev);
261 ehci_data = omap->platdata.ehci_data;
262 ohci_data = omap->platdata.ohci_data;
263
264 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
265 if (!res) {
266 dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
267 ret = -ENODEV;
268 goto err_end;
269 }
270 resources[0] = *res;
271
272 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq");
273 if (!res) {
274 dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n");
275 ret = -ENODEV;
276 goto err_end;
277 }
278 resources[1] = *res;
279
280 ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, ehci_data,
281 sizeof(*ehci_data), dev);
282
283 if (!ehci) {
284 dev_err(dev, "omap_usbhs_alloc_child failed\n");
285 goto err_end;
286 }
287
288 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
289 if (!res) {
290 dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n");
291 ret = -ENODEV;
292 goto err_ehci;
293 }
294 resources[0] = *res;
295
296 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq");
297 if (!res) {
298 dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n");
299 ret = -ENODEV;
300 goto err_ehci;
301 }
302 resources[1] = *res;
303
304 ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, ohci_data,
305 sizeof(*ohci_data), dev);
306 if (!ohci) {
307 dev_err(dev, "omap_usbhs_alloc_child failed\n");
308 goto err_ehci;
309 }
310
311 return 0;
312
313err_ehci:
314 platform_device_put(ehci);
315
316err_end:
317 return ret;
318}
319
320/**
321 * usbhs_omap_probe - initialize TI-based HCDs
322 *
323 * Allocates basic resources for this USB host controller.
324 */
325static int __devinit usbhs_omap_probe(struct platform_device *pdev)
326{
327 struct device *dev = &pdev->dev;
328 struct usbhs_omap_platform_data *pdata = dev->platform_data;
329 struct usbhs_hcd_omap *omap;
330 struct resource *res;
331 int ret = 0;
332 int i;
333
334 if (!pdata) {
335 dev_err(dev, "Missing platfrom data\n");
336 ret = -ENOMEM;
337 goto end_probe;
338 }
339
340 omap = kzalloc(sizeof(*omap), GFP_KERNEL);
341 if (!omap) {
342 dev_err(dev, "Memory allocation failed\n");
343 ret = -ENOMEM;
344 goto end_probe;
345 }
346
347 spin_lock_init(&omap->lock);
348
349 for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
350 omap->platdata.port_mode[i] = pdata->port_mode[i];
351
352 omap->platdata.ehci_data = pdata->ehci_data;
353 omap->platdata.ohci_data = pdata->ohci_data;
354
355 omap->usbhost_ick = clk_get(dev, "usbhost_ick");
356 if (IS_ERR(omap->usbhost_ick)) {
357 ret = PTR_ERR(omap->usbhost_ick);
358 dev_err(dev, "usbhost_ick failed error:%d\n", ret);
359 goto err_end;
360 }
361
362 omap->usbhost_hs_fck = clk_get(dev, "hs_fck");
363 if (IS_ERR(omap->usbhost_hs_fck)) {
364 ret = PTR_ERR(omap->usbhost_hs_fck);
365 dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret);
366 goto err_usbhost_ick;
367 }
368
369 omap->usbhost_fs_fck = clk_get(dev, "fs_fck");
370 if (IS_ERR(omap->usbhost_fs_fck)) {
371 ret = PTR_ERR(omap->usbhost_fs_fck);
372 dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret);
373 goto err_usbhost_hs_fck;
374 }
375
376 omap->usbtll_fck = clk_get(dev, "usbtll_fck");
377 if (IS_ERR(omap->usbtll_fck)) {
378 ret = PTR_ERR(omap->usbtll_fck);
379 dev_err(dev, "usbtll_fck failed error:%d\n", ret);
380 goto err_usbhost_fs_fck;
381 }
382
383 omap->usbtll_ick = clk_get(dev, "usbtll_ick");
384 if (IS_ERR(omap->usbtll_ick)) {
385 ret = PTR_ERR(omap->usbtll_ick);
386 dev_err(dev, "usbtll_ick failed error:%d\n", ret);
387 goto err_usbtll_fck;
388 }
389
390 omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
391 if (IS_ERR(omap->utmi_p1_fck)) {
392 ret = PTR_ERR(omap->utmi_p1_fck);
393 dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
394 goto err_usbtll_ick;
395 }
396
397 omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
398 if (IS_ERR(omap->xclk60mhsp1_ck)) {
399 ret = PTR_ERR(omap->xclk60mhsp1_ck);
400 dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
401 goto err_utmi_p1_fck;
402 }
403
404 omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
405 if (IS_ERR(omap->utmi_p2_fck)) {
406 ret = PTR_ERR(omap->utmi_p2_fck);
407 dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
408 goto err_xclk60mhsp1_ck;
409 }
410
411 omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
412 if (IS_ERR(omap->xclk60mhsp2_ck)) {
413 ret = PTR_ERR(omap->xclk60mhsp2_ck);
414 dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
415 goto err_utmi_p2_fck;
416 }
417
418 omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
419 if (IS_ERR(omap->usbhost_p1_fck)) {
420 ret = PTR_ERR(omap->usbhost_p1_fck);
421 dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
422 goto err_xclk60mhsp2_ck;
423 }
424
425 omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
426 if (IS_ERR(omap->usbtll_p1_fck)) {
427 ret = PTR_ERR(omap->usbtll_p1_fck);
428 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
429 goto err_usbhost_p1_fck;
430 }
431
432 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
433 if (IS_ERR(omap->usbhost_p2_fck)) {
434 ret = PTR_ERR(omap->usbhost_p2_fck);
435 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
436 goto err_usbtll_p1_fck;
437 }
438
439 omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
440 if (IS_ERR(omap->usbtll_p2_fck)) {
441 ret = PTR_ERR(omap->usbtll_p2_fck);
442 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
443 goto err_usbhost_p2_fck;
444 }
445
446 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
447 if (IS_ERR(omap->init_60m_fclk)) {
448 ret = PTR_ERR(omap->init_60m_fclk);
449 dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
450 goto err_usbtll_p2_fck;
451 }
452
453 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
454 if (!res) {
455 dev_err(dev, "UHH EHCI get resource failed\n");
456 ret = -ENODEV;
457 goto err_init_60m_fclk;
458 }
459
460 omap->uhh_base = ioremap(res->start, resource_size(res));
461 if (!omap->uhh_base) {
462 dev_err(dev, "UHH ioremap failed\n");
463 ret = -ENOMEM;
464 goto err_init_60m_fclk;
465 }
466
467 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
468 if (!res) {
469 dev_err(dev, "UHH EHCI get resource failed\n");
470 ret = -ENODEV;
471 goto err_tll;
472 }
473
474 omap->tll_base = ioremap(res->start, resource_size(res));
475 if (!omap->tll_base) {
476 dev_err(dev, "TLL ioremap failed\n");
477 ret = -ENOMEM;
478 goto err_tll;
479 }
480
481 platform_set_drvdata(pdev, omap);
482
483 ret = omap_usbhs_alloc_children(pdev);
484 if (ret) {
485 dev_err(dev, "omap_usbhs_alloc_children failed\n");
486 goto err_alloc;
487 }
488
489 goto end_probe;
490
491err_alloc:
492 iounmap(omap->tll_base);
493
494err_tll:
495 iounmap(omap->uhh_base);
496
497err_init_60m_fclk:
498 clk_put(omap->init_60m_fclk);
499
500err_usbtll_p2_fck:
501 clk_put(omap->usbtll_p2_fck);
502
503err_usbhost_p2_fck:
504 clk_put(omap->usbhost_p2_fck);
505
506err_usbtll_p1_fck:
507 clk_put(omap->usbtll_p1_fck);
508
509err_usbhost_p1_fck:
510 clk_put(omap->usbhost_p1_fck);
511
512err_xclk60mhsp2_ck:
513 clk_put(omap->xclk60mhsp2_ck);
514
515err_utmi_p2_fck:
516 clk_put(omap->utmi_p2_fck);
517
518err_xclk60mhsp1_ck:
519 clk_put(omap->xclk60mhsp1_ck);
520
521err_utmi_p1_fck:
522 clk_put(omap->utmi_p1_fck);
523
524err_usbtll_ick:
525 clk_put(omap->usbtll_ick);
526
527err_usbtll_fck:
528 clk_put(omap->usbtll_fck);
529
530err_usbhost_fs_fck:
531 clk_put(omap->usbhost_fs_fck);
532
533err_usbhost_hs_fck:
534 clk_put(omap->usbhost_hs_fck);
535
536err_usbhost_ick:
537 clk_put(omap->usbhost_ick);
538
539err_end:
540 kfree(omap);
541
542end_probe:
543 return ret;
544}
545
546/**
547 * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs
548 * @pdev: USB Host Controller being removed
549 *
550 * Reverses the effect of usbhs_omap_probe().
551 */
552static int __devexit usbhs_omap_remove(struct platform_device *pdev)
553{
554 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
555
556 if (omap->count != 0) {
557 dev_err(&pdev->dev,
558 "Either EHCI or OHCI is still using usbhs core\n");
559 return -EBUSY;
560 }
561
562 iounmap(omap->tll_base);
563 iounmap(omap->uhh_base);
564 clk_put(omap->init_60m_fclk);
565 clk_put(omap->usbtll_p2_fck);
566 clk_put(omap->usbhost_p2_fck);
567 clk_put(omap->usbtll_p1_fck);
568 clk_put(omap->usbhost_p1_fck);
569 clk_put(omap->xclk60mhsp2_ck);
570 clk_put(omap->utmi_p2_fck);
571 clk_put(omap->xclk60mhsp1_ck);
572 clk_put(omap->utmi_p1_fck);
573 clk_put(omap->usbtll_ick);
574 clk_put(omap->usbtll_fck);
575 clk_put(omap->usbhost_fs_fck);
576 clk_put(omap->usbhost_hs_fck);
577 clk_put(omap->usbhost_ick);
578 kfree(omap);
579
580 return 0;
581}
582
583static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
584{
585 switch (pmode) {
586 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
587 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
588 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
589 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
590 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
591 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
592 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
593 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
594 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
595 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
596 return true;
597
598 default:
599 return false;
600 }
601}
602
603/*
604 * convert the port-mode enum to a value we can use in the FSLSMODE
605 * field of USBTLL_CHANNEL_CONF
606 */
607static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
608{
609 switch (mode) {
610 case OMAP_USBHS_PORT_MODE_UNUSED:
611 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
612 return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
613
614 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
615 return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
616
617 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
618 return OMAP_TLL_FSLSMODE_3PIN_PHY;
619
620 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
621 return OMAP_TLL_FSLSMODE_4PIN_PHY;
622
623 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
624 return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
625
626 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
627 return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
628
629 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
630 return OMAP_TLL_FSLSMODE_3PIN_TLL;
631
632 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
633 return OMAP_TLL_FSLSMODE_4PIN_TLL;
634
635 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
636 return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
637
638 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
639 return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
640 default:
641 pr_warning("Invalid port mode, using default\n");
642 return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
643 }
644}
645
646static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
647{
648 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
649 struct usbhs_omap_platform_data *pdata = dev->platform_data;
650 unsigned reg;
651 int i;
652
653 /* Program Common TLL register */
654 reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF);
655 reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
656 | OMAP_TLL_SHARED_CONF_USB_DIVRATION);
657 reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
658 reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
659
660 usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
661
662 /* Enable channels now */
663 for (i = 0; i < tll_channel_count; i++) {
664 reg = usbhs_read(omap->tll_base,
665 OMAP_TLL_CHANNEL_CONF(i));
666
667 if (is_ohci_port(pdata->port_mode[i])) {
668 reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
669 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
670 reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
671 } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) {
672
673 /* Disable AutoIdle, BitStuffing and use SDR Mode */
674 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
675 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
676 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
677
678 reg |= (1 << (i + 1));
679 } else
680 continue;
681
682 reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
683 usbhs_write(omap->tll_base,
684 OMAP_TLL_CHANNEL_CONF(i), reg);
685
686 usbhs_writeb(omap->tll_base,
687 OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
688 }
689}
690
691static int usbhs_enable(struct device *dev)
692{
693 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
694 struct usbhs_omap_platform_data *pdata = &omap->platdata;
695 unsigned long flags = 0;
696 int ret = 0;
697 unsigned long timeout;
698 unsigned reg;
699
700 dev_dbg(dev, "starting TI HSUSB Controller\n");
701 if (!pdata) {
702 dev_dbg(dev, "missing platform_data\n");
703 ret = -ENODEV;
704 goto end_enable;
705 }
706
707 spin_lock_irqsave(&omap->lock, flags);
708 if (omap->count > 0)
709 goto end_count;
710
711 clk_enable(omap->usbhost_ick);
712 clk_enable(omap->usbhost_hs_fck);
713 clk_enable(omap->usbhost_fs_fck);
714 clk_enable(omap->usbtll_fck);
715 clk_enable(omap->usbtll_ick);
716
717 if (pdata->ehci_data->phy_reset) {
718 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
719 gpio_request(pdata->ehci_data->reset_gpio_port[0],
720 "USB1 PHY reset");
721 gpio_direction_output
722 (pdata->ehci_data->reset_gpio_port[0], 1);
723 }
724
725 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) {
726 gpio_request(pdata->ehci_data->reset_gpio_port[1],
727 "USB2 PHY reset");
728 gpio_direction_output
729 (pdata->ehci_data->reset_gpio_port[1], 1);
730 }
731
732 /* Hold the PHY in RESET for enough time till DIR is high */
733 udelay(10);
734 }
735
736 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
737 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
738
739 /* perform TLL soft reset, and wait until reset is complete */
740 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
741 OMAP_USBTLL_SYSCONFIG_SOFTRESET);
742
743 /* Wait for TLL reset to complete */
744 timeout = jiffies + msecs_to_jiffies(1000);
745 while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
746 & OMAP_USBTLL_SYSSTATUS_RESETDONE)) {
747 cpu_relax();
748
749 if (time_after(jiffies, timeout)) {
750 dev_dbg(dev, "operation timed out\n");
751 ret = -EINVAL;
752 goto err_tll;
753 }
754 }
755
756 dev_dbg(dev, "TLL RESET DONE\n");
757
758 /* (1<<3) = no idle mode only for initial debugging */
759 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG,
760 OMAP_USBTLL_SYSCONFIG_ENAWAKEUP |
761 OMAP_USBTLL_SYSCONFIG_SIDLEMODE |
762 OMAP_USBTLL_SYSCONFIG_AUTOIDLE);
763
764 /* Put UHH in NoIdle/NoStandby mode */
765 reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG);
766 if (is_omap_usbhs_rev1(omap)) {
767 reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP
768 | OMAP_UHH_SYSCONFIG_SIDLEMODE
769 | OMAP_UHH_SYSCONFIG_CACTIVITY
770 | OMAP_UHH_SYSCONFIG_MIDLEMODE);
771 reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE;
772
773
774 } else if (is_omap_usbhs_rev2(omap)) {
775 reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR;
776 reg |= OMAP4_UHH_SYSCONFIG_NOIDLE;
777 reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR;
778 reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY;
779 }
780
781 usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg);
782
783 reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
784 /* setup ULPI bypass and burst configurations */
785 reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN
786 | OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN
787 | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN);
788 reg |= OMAP4_UHH_HOSTCONFIG_APP_START_CLK;
789 reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN;
790
791 if (is_omap_usbhs_rev1(omap)) {
792 if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED)
793 reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS;
794 if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED)
795 reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS;
796 if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED)
797 reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS;
798
799 /* Bypass the TLL module for PHY mode operation */
800 if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) {
801 dev_dbg(dev, "OMAP3 ES version <= ES2.1\n");
802 if (is_ehci_phy_mode(pdata->port_mode[0]) ||
803 is_ehci_phy_mode(pdata->port_mode[1]) ||
804 is_ehci_phy_mode(pdata->port_mode[2]))
805 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
806 else
807 reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS;
808 } else {
809 dev_dbg(dev, "OMAP3 ES version > ES2.1\n");
810 if (is_ehci_phy_mode(pdata->port_mode[0]))
811 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
812 else
813 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS;
814 if (is_ehci_phy_mode(pdata->port_mode[1]))
815 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
816 else
817 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS;
818 if (is_ehci_phy_mode(pdata->port_mode[2]))
819 reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
820 else
821 reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS;
822 }
823 } else if (is_omap_usbhs_rev2(omap)) {
824 /* Clear port mode fields for PHY mode*/
825 reg &= ~OMAP4_P1_MODE_CLEAR;
826 reg &= ~OMAP4_P2_MODE_CLEAR;
827
828 if (is_ehci_phy_mode(pdata->port_mode[0])) {
829 ret = clk_set_parent(omap->utmi_p1_fck,
830 omap->xclk60mhsp1_ck);
831 if (ret != 0) {
832 dev_err(dev, "xclk60mhsp1_ck set parent"
833 "failed error:%d\n", ret);
834 goto err_tll;
835 }
836 } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
837 ret = clk_set_parent(omap->utmi_p1_fck,
838 omap->init_60m_fclk);
839 if (ret != 0) {
840 dev_err(dev, "init_60m_fclk set parent"
841 "failed error:%d\n", ret);
842 goto err_tll;
843 }
844 clk_enable(omap->usbhost_p1_fck);
845 clk_enable(omap->usbtll_p1_fck);
846 }
847
848 if (is_ehci_phy_mode(pdata->port_mode[1])) {
849 ret = clk_set_parent(omap->utmi_p2_fck,
850 omap->xclk60mhsp2_ck);
851 if (ret != 0) {
852 dev_err(dev, "xclk60mhsp1_ck set parent"
853 "failed error:%d\n", ret);
854 goto err_tll;
855 }
856 } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
857 ret = clk_set_parent(omap->utmi_p2_fck,
858 omap->init_60m_fclk);
859 if (ret != 0) {
860 dev_err(dev, "init_60m_fclk set parent"
861 "failed error:%d\n", ret);
862 goto err_tll;
863 }
864 clk_enable(omap->usbhost_p2_fck);
865 clk_enable(omap->usbtll_p2_fck);
866 }
867
868 clk_enable(omap->utmi_p1_fck);
869 clk_enable(omap->utmi_p2_fck);
870
871 if (is_ehci_tll_mode(pdata->port_mode[0]) ||
872 (is_ohci_port(pdata->port_mode[0])))
873 reg |= OMAP4_P1_MODE_TLL;
874 else if (is_ehci_hsic_mode(pdata->port_mode[0]))
875 reg |= OMAP4_P1_MODE_HSIC;
876
877 if (is_ehci_tll_mode(pdata->port_mode[1]) ||
878 (is_ohci_port(pdata->port_mode[1])))
879 reg |= OMAP4_P2_MODE_TLL;
880 else if (is_ehci_hsic_mode(pdata->port_mode[1]))
881 reg |= OMAP4_P2_MODE_HSIC;
882 }
883
884 usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
885 dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
886
887 if (is_ehci_tll_mode(pdata->port_mode[0]) ||
888 is_ehci_tll_mode(pdata->port_mode[1]) ||
889 is_ehci_tll_mode(pdata->port_mode[2]) ||
890 (is_ohci_port(pdata->port_mode[0])) ||
891 (is_ohci_port(pdata->port_mode[1])) ||
892 (is_ohci_port(pdata->port_mode[2]))) {
893
894 /* Enable UTMI mode for required TLL channels */
895 if (is_omap_usbhs_rev2(omap))
896 usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT);
897 else
898 usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
899 }
900
901 if (pdata->ehci_data->phy_reset) {
902 /* Hold the PHY in RESET for enough time till
903 * PHY is settled and ready
904 */
905 udelay(10);
906
907 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
908 gpio_set_value
909 (pdata->ehci_data->reset_gpio_port[0], 0);
910
911 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
912 gpio_set_value
913 (pdata->ehci_data->reset_gpio_port[1], 0);
914 }
915
916end_count:
917 omap->count++;
918 goto end_enable;
919
920err_tll:
921 if (pdata->ehci_data->phy_reset) {
922 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
923 gpio_free(pdata->ehci_data->reset_gpio_port[0]);
924
925 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
926 gpio_free(pdata->ehci_data->reset_gpio_port[1]);
927 }
928
929 clk_disable(omap->usbtll_ick);
930 clk_disable(omap->usbtll_fck);
931 clk_disable(omap->usbhost_fs_fck);
932 clk_disable(omap->usbhost_hs_fck);
933 clk_disable(omap->usbhost_ick);
934
935end_enable:
936 spin_unlock_irqrestore(&omap->lock, flags);
937 return ret;
938}
939
940static void usbhs_disable(struct device *dev)
941{
942 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
943 struct usbhs_omap_platform_data *pdata = &omap->platdata;
944 unsigned long flags = 0;
945 unsigned long timeout;
946
947 dev_dbg(dev, "stopping TI HSUSB Controller\n");
948
949 spin_lock_irqsave(&omap->lock, flags);
950
951 if (omap->count == 0)
952 goto end_disble;
953
954 omap->count--;
955
956 if (omap->count != 0)
957 goto end_disble;
958
959 /* Reset OMAP modules for insmod/rmmod to work */
960 usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG,
961 is_omap_usbhs_rev2(omap) ?
962 OMAP4_UHH_SYSCONFIG_SOFTRESET :
963 OMAP_UHH_SYSCONFIG_SOFTRESET);
964
965 timeout = jiffies + msecs_to_jiffies(100);
966 while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
967 & (1 << 0))) {
968 cpu_relax();
969
970 if (time_after(jiffies, timeout))
971 dev_dbg(dev, "operation timed out\n");
972 }
973
974 while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
975 & (1 << 1))) {
976 cpu_relax();
977
978 if (time_after(jiffies, timeout))
979 dev_dbg(dev, "operation timed out\n");
980 }
981
982 while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS)
983 & (1 << 2))) {
984 cpu_relax();
985
986 if (time_after(jiffies, timeout))
987 dev_dbg(dev, "operation timed out\n");
988 }
989
990 usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1));
991
992 while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS)
993 & (1 << 0))) {
994 cpu_relax();
995
996 if (time_after(jiffies, timeout))
997 dev_dbg(dev, "operation timed out\n");
998 }
999
1000 if (pdata->ehci_data->phy_reset) {
1001 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
1002 gpio_free(pdata->ehci_data->reset_gpio_port[0]);
1003
1004 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
1005 gpio_free(pdata->ehci_data->reset_gpio_port[1]);
1006 }
1007
1008 clk_disable(omap->utmi_p2_fck);
1009 clk_disable(omap->utmi_p1_fck);
1010 clk_disable(omap->usbtll_ick);
1011 clk_disable(omap->usbtll_fck);
1012 clk_disable(omap->usbhost_fs_fck);
1013 clk_disable(omap->usbhost_hs_fck);
1014 clk_disable(omap->usbhost_ick);
1015
1016end_disble:
1017 spin_unlock_irqrestore(&omap->lock, flags);
1018}
1019
1020int omap_usbhs_enable(struct device *dev)
1021{
1022 return usbhs_enable(dev->parent);
1023}
1024EXPORT_SYMBOL_GPL(omap_usbhs_enable);
1025
1026void omap_usbhs_disable(struct device *dev)
1027{
1028 usbhs_disable(dev->parent);
1029}
1030EXPORT_SYMBOL_GPL(omap_usbhs_disable);
1031
1032static struct platform_driver usbhs_omap_driver = {
1033 .driver = {
1034 .name = (char *)usbhs_driver_name,
1035 .owner = THIS_MODULE,
1036 },
1037 .remove = __exit_p(usbhs_omap_remove),
1038};
1039
1040MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
1041MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
1042MODULE_LICENSE("GPL v2");
1043MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
1044
1045static int __init omap_usbhs_drvinit(void)
1046{
1047 return platform_driver_probe(&usbhs_omap_driver, usbhs_omap_probe);
1048}
1049
1050/*
1051 * init before ehci and ohci drivers;
1052 * The usbhs core driver should be initialized much before
1053 * the omap ehci and ohci probe functions are called.
1054 */
1055fs_initcall(omap_usbhs_drvinit);
1056
1057static void __exit omap_usbhs_drvexit(void)
1058{
1059 platform_driver_unregister(&usbhs_omap_driver);
1060}
1061module_exit(omap_usbhs_drvexit);