Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
omap-usb-host.c
Go to the documentation of this file.
1 
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/types.h>
22 #include <linux/slab.h>
23 #include <linux/delay.h>
24 #include <linux/clk.h>
25 #include <linux/dma-mapping.h>
26 #include <linux/spinlock.h>
27 #include <linux/gpio.h>
28 #include <plat/cpu.h>
29 #include <plat/usb.h>
30 #include <linux/pm_runtime.h>
31 
32 #define USBHS_DRIVER_NAME "usbhs_omap"
33 #define OMAP_EHCI_DEVICE "ehci-omap"
34 #define OMAP_OHCI_DEVICE "ohci-omap3"
35 
36 /* OMAP USBHOST Register addresses */
37 
38 /* UHH Register Set */
39 #define OMAP_UHH_REVISION (0x00)
40 #define OMAP_UHH_SYSCONFIG (0x10)
41 #define OMAP_UHH_SYSCONFIG_MIDLEMODE (1 << 12)
42 #define OMAP_UHH_SYSCONFIG_CACTIVITY (1 << 8)
43 #define OMAP_UHH_SYSCONFIG_SIDLEMODE (1 << 3)
44 #define OMAP_UHH_SYSCONFIG_ENAWAKEUP (1 << 2)
45 #define OMAP_UHH_SYSCONFIG_SOFTRESET (1 << 1)
46 #define OMAP_UHH_SYSCONFIG_AUTOIDLE (1 << 0)
47 
48 #define OMAP_UHH_SYSSTATUS (0x14)
49 #define OMAP_UHH_HOSTCONFIG (0x40)
50 #define OMAP_UHH_HOSTCONFIG_ULPI_BYPASS (1 << 0)
51 #define OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS (1 << 0)
52 #define OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS (1 << 11)
53 #define OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS (1 << 12)
54 #define OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN (1 << 2)
55 #define OMAP_UHH_HOSTCONFIG_INCR8_BURST_EN (1 << 3)
56 #define OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN (1 << 4)
57 #define OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN (1 << 5)
58 #define OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS (1 << 8)
59 #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9)
60 #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10)
61 #define OMAP4_UHH_HOSTCONFIG_APP_START_CLK (1 << 31)
62 
63 /* OMAP4-specific defines */
64 #define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2)
65 #define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2)
66 #define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4)
67 #define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4)
68 #define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0)
69 
70 #define OMAP4_P1_MODE_CLEAR (3 << 16)
71 #define OMAP4_P1_MODE_TLL (1 << 16)
72 #define OMAP4_P1_MODE_HSIC (3 << 16)
73 #define OMAP4_P2_MODE_CLEAR (3 << 18)
74 #define OMAP4_P2_MODE_TLL (1 << 18)
75 #define OMAP4_P2_MODE_HSIC (3 << 18)
76 
77 #define OMAP_UHH_DEBUG_CSR (0x44)
78 
79 /* Values of UHH_REVISION - Note: these are not given in the TRM */
80 #define OMAP_USBHS_REV1 0x00000010 /* OMAP3 */
81 #define OMAP_USBHS_REV2 0x50700100 /* OMAP4 */
82 
83 #define is_omap_usbhs_rev1(x) (x->usbhs_rev == OMAP_USBHS_REV1)
84 #define is_omap_usbhs_rev2(x) (x->usbhs_rev == OMAP_USBHS_REV2)
85 
86 #define is_ehci_phy_mode(x) (x == OMAP_EHCI_PORT_MODE_PHY)
87 #define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
88 #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC)
89 
90 
94  struct clk *utmi_p1_fck;
96  struct clk *utmi_p2_fck;
98  struct clk *init_60m_fclk;
100 
102 
103  struct usbhs_omap_platform_data platdata;
104 
107 };
108 /*-------------------------------------------------------------------------*/
109 
111 static u64 usbhs_dmamask = DMA_BIT_MASK(32);
112 
113 /*-------------------------------------------------------------------------*/
114 
115 static inline void usbhs_write(void __iomem *base, u32 reg, u32 val)
116 {
117  __raw_writel(val, base + reg);
118 }
119 
120 static inline u32 usbhs_read(void __iomem *base, u32 reg)
121 {
122  return __raw_readl(base + reg);
123 }
124 
125 static inline void usbhs_writeb(void __iomem *base, u8 reg, u8 val)
126 {
127  __raw_writeb(val, base + reg);
128 }
129 
130 static inline u8 usbhs_readb(void __iomem *base, u8 reg)
131 {
132  return __raw_readb(base + reg);
133 }
134 
135 /*-------------------------------------------------------------------------*/
136 
137 static struct platform_device *omap_usbhs_alloc_child(const char *name,
138  struct resource *res, int num_resources, void *pdata,
139  size_t pdata_size, struct device *dev)
140 {
141  struct platform_device *child;
142  int ret;
143 
144  child = platform_device_alloc(name, 0);
145 
146  if (!child) {
147  dev_err(dev, "platform_device_alloc %s failed\n", name);
148  goto err_end;
149  }
150 
151  ret = platform_device_add_resources(child, res, num_resources);
152  if (ret) {
153  dev_err(dev, "platform_device_add_resources failed\n");
154  goto err_alloc;
155  }
156 
157  ret = platform_device_add_data(child, pdata, pdata_size);
158  if (ret) {
159  dev_err(dev, "platform_device_add_data failed\n");
160  goto err_alloc;
161  }
162 
163  child->dev.dma_mask = &usbhs_dmamask;
164  dma_set_coherent_mask(&child->dev, DMA_BIT_MASK(32));
165  child->dev.parent = dev;
166 
167  ret = platform_device_add(child);
168  if (ret) {
169  dev_err(dev, "platform_device_add failed\n");
170  goto err_alloc;
171  }
172 
173  return child;
174 
175 err_alloc:
176  platform_device_put(child);
177 
178 err_end:
179  return NULL;
180 }
181 
182 static int omap_usbhs_alloc_children(struct platform_device *pdev)
183 {
184  struct device *dev = &pdev->dev;
185  struct usbhs_hcd_omap *omap;
186  struct ehci_hcd_omap_platform_data *ehci_data;
187  struct ohci_hcd_omap_platform_data *ohci_data;
188  struct platform_device *ehci;
189  struct platform_device *ohci;
190  struct resource *res;
191  struct resource resources[2];
192  int ret;
193 
194  omap = platform_get_drvdata(pdev);
195  ehci_data = omap->platdata.ehci_data;
196  ohci_data = omap->platdata.ohci_data;
197 
198  res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci");
199  if (!res) {
200  dev_err(dev, "EHCI get resource IORESOURCE_MEM failed\n");
201  ret = -ENODEV;
202  goto err_end;
203  }
204  resources[0] = *res;
205 
206  res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ehci-irq");
207  if (!res) {
208  dev_err(dev, " EHCI get resource IORESOURCE_IRQ failed\n");
209  ret = -ENODEV;
210  goto err_end;
211  }
212  resources[1] = *res;
213 
214  ehci = omap_usbhs_alloc_child(OMAP_EHCI_DEVICE, resources, 2, ehci_data,
215  sizeof(*ehci_data), dev);
216 
217  if (!ehci) {
218  dev_err(dev, "omap_usbhs_alloc_child failed\n");
219  ret = -ENOMEM;
220  goto err_end;
221  }
222 
223  res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci");
224  if (!res) {
225  dev_err(dev, "OHCI get resource IORESOURCE_MEM failed\n");
226  ret = -ENODEV;
227  goto err_ehci;
228  }
229  resources[0] = *res;
230 
231  res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ohci-irq");
232  if (!res) {
233  dev_err(dev, "OHCI get resource IORESOURCE_IRQ failed\n");
234  ret = -ENODEV;
235  goto err_ehci;
236  }
237  resources[1] = *res;
238 
239  ohci = omap_usbhs_alloc_child(OMAP_OHCI_DEVICE, resources, 2, ohci_data,
240  sizeof(*ohci_data), dev);
241  if (!ohci) {
242  dev_err(dev, "omap_usbhs_alloc_child failed\n");
243  ret = -ENOMEM;
244  goto err_ehci;
245  }
246 
247  return 0;
248 
249 err_ehci:
251 
252 err_end:
253  return ret;
254 }
255 
256 static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
257 {
258  switch (pmode) {
269  return true;
270 
271  default:
272  return false;
273  }
274 }
275 
276 static int usbhs_runtime_resume(struct device *dev)
277 {
278  struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
279  struct usbhs_omap_platform_data *pdata = &omap->platdata;
280  unsigned long flags;
281 
282  dev_dbg(dev, "usbhs_runtime_resume\n");
283 
284  if (!pdata) {
285  dev_dbg(dev, "missing platform_data\n");
286  return -ENODEV;
287  }
288 
289  omap_tll_enable();
290  spin_lock_irqsave(&omap->lock, flags);
291 
292  if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
293  clk_enable(omap->ehci_logic_fck);
294 
295  if (is_ehci_tll_mode(pdata->port_mode[0]))
296  clk_enable(omap->usbhost_p1_fck);
297  if (is_ehci_tll_mode(pdata->port_mode[1]))
298  clk_enable(omap->usbhost_p2_fck);
299 
300  clk_enable(omap->utmi_p1_fck);
301  clk_enable(omap->utmi_p2_fck);
302 
303  spin_unlock_irqrestore(&omap->lock, flags);
304 
305  return 0;
306 }
307 
308 static int usbhs_runtime_suspend(struct device *dev)
309 {
310  struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
311  struct usbhs_omap_platform_data *pdata = &omap->platdata;
312  unsigned long flags;
313 
314  dev_dbg(dev, "usbhs_runtime_suspend\n");
315 
316  if (!pdata) {
317  dev_dbg(dev, "missing platform_data\n");
318  return -ENODEV;
319  }
320 
321  spin_lock_irqsave(&omap->lock, flags);
322 
323  if (is_ehci_tll_mode(pdata->port_mode[0]))
325  if (is_ehci_tll_mode(pdata->port_mode[1]))
327 
328  clk_disable(omap->utmi_p2_fck);
329  clk_disable(omap->utmi_p1_fck);
330 
331  if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
333 
334  spin_unlock_irqrestore(&omap->lock, flags);
336 
337  return 0;
338 }
339 
340 static void omap_usbhs_init(struct device *dev)
341 {
342  struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
343  struct usbhs_omap_platform_data *pdata = &omap->platdata;
344  unsigned long flags;
345  unsigned reg;
346 
347  dev_dbg(dev, "starting TI HSUSB Controller\n");
348 
349  if (pdata->ehci_data->phy_reset) {
350  if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
351  gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
352  GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
353 
354  if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
355  gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
356  GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
357 
358  /* Hold the PHY in RESET for enough time till DIR is high */
359  udelay(10);
360  }
361 
362  pm_runtime_get_sync(dev);
363  spin_lock_irqsave(&omap->lock, flags);
364  omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
365  dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
366 
367  reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG);
368  /* setup ULPI bypass and burst configurations */
374 
375  if (is_omap_usbhs_rev1(omap)) {
376  if (pdata->port_mode[0] == OMAP_USBHS_PORT_MODE_UNUSED)
378  if (pdata->port_mode[1] == OMAP_USBHS_PORT_MODE_UNUSED)
380  if (pdata->port_mode[2] == OMAP_USBHS_PORT_MODE_UNUSED)
382 
383  /* Bypass the TLL module for PHY mode operation */
384  if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) {
385  dev_dbg(dev, "OMAP3 ES version <= ES2.1\n");
386  if (is_ehci_phy_mode(pdata->port_mode[0]) ||
387  is_ehci_phy_mode(pdata->port_mode[1]) ||
388  is_ehci_phy_mode(pdata->port_mode[2]))
390  else
392  } else {
393  dev_dbg(dev, "OMAP3 ES version > ES2.1\n");
394  if (is_ehci_phy_mode(pdata->port_mode[0]))
396  else
398  if (is_ehci_phy_mode(pdata->port_mode[1]))
400  else
402  if (is_ehci_phy_mode(pdata->port_mode[2]))
404  else
406  }
407  } else if (is_omap_usbhs_rev2(omap)) {
408  /* Clear port mode fields for PHY mode*/
409  reg &= ~OMAP4_P1_MODE_CLEAR;
410  reg &= ~OMAP4_P2_MODE_CLEAR;
411 
412  if (is_ehci_tll_mode(pdata->port_mode[0]) ||
413  (is_ohci_port(pdata->port_mode[0])))
414  reg |= OMAP4_P1_MODE_TLL;
415  else if (is_ehci_hsic_mode(pdata->port_mode[0]))
416  reg |= OMAP4_P1_MODE_HSIC;
417 
418  if (is_ehci_tll_mode(pdata->port_mode[1]) ||
419  (is_ohci_port(pdata->port_mode[1])))
420  reg |= OMAP4_P2_MODE_TLL;
421  else if (is_ehci_hsic_mode(pdata->port_mode[1]))
422  reg |= OMAP4_P2_MODE_HSIC;
423  }
424 
425  usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
426  dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
427 
428  spin_unlock_irqrestore(&omap->lock, flags);
429 
430  pm_runtime_put_sync(dev);
431  if (pdata->ehci_data->phy_reset) {
432  /* Hold the PHY in RESET for enough time till
433  * PHY is settled and ready
434  */
435  udelay(10);
436 
437  if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
439  (pdata->ehci_data->reset_gpio_port[0], 1);
440 
441  if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
443  (pdata->ehci_data->reset_gpio_port[1], 1);
444  }
445 }
446 
447 static void omap_usbhs_deinit(struct device *dev)
448 {
449  struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
450  struct usbhs_omap_platform_data *pdata = &omap->platdata;
451 
452  if (pdata->ehci_data->phy_reset) {
453  if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
454  gpio_free(pdata->ehci_data->reset_gpio_port[0]);
455 
456  if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
457  gpio_free(pdata->ehci_data->reset_gpio_port[1]);
458  }
459 }
460 
461 
467 static int __devinit usbhs_omap_probe(struct platform_device *pdev)
468 {
469  struct device *dev = &pdev->dev;
470  struct usbhs_omap_platform_data *pdata = dev->platform_data;
471  struct usbhs_hcd_omap *omap;
472  struct resource *res;
473  int ret = 0;
474  int i;
475 
476  if (!pdata) {
477  dev_err(dev, "Missing platform data\n");
478  ret = -ENOMEM;
479  goto end_probe;
480  }
481 
482  omap = kzalloc(sizeof(*omap), GFP_KERNEL);
483  if (!omap) {
484  dev_err(dev, "Memory allocation failed\n");
485  ret = -ENOMEM;
486  goto end_probe;
487  }
488 
489  spin_lock_init(&omap->lock);
490 
491  for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
492  omap->platdata.port_mode[i] = pdata->port_mode[i];
493 
494  omap->platdata.ehci_data = pdata->ehci_data;
495  omap->platdata.ohci_data = pdata->ohci_data;
496 
497  pm_runtime_enable(dev);
498 
499 
500  for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
501  if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
502  is_ehci_hsic_mode(i)) {
503  omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck");
504  if (IS_ERR(omap->ehci_logic_fck)) {
505  ret = PTR_ERR(omap->ehci_logic_fck);
506  dev_warn(dev, "ehci_logic_fck failed:%d\n",
507  ret);
508  }
509  break;
510  }
511 
512  omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk");
513  if (IS_ERR(omap->utmi_p1_fck)) {
514  ret = PTR_ERR(omap->utmi_p1_fck);
515  dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret);
516  goto err_end;
517  }
518 
519  omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck");
520  if (IS_ERR(omap->xclk60mhsp1_ck)) {
521  ret = PTR_ERR(omap->xclk60mhsp1_ck);
522  dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
523  goto err_utmi_p1_fck;
524  }
525 
526  omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk");
527  if (IS_ERR(omap->utmi_p2_fck)) {
528  ret = PTR_ERR(omap->utmi_p2_fck);
529  dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret);
530  goto err_xclk60mhsp1_ck;
531  }
532 
533  omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck");
534  if (IS_ERR(omap->xclk60mhsp2_ck)) {
535  ret = PTR_ERR(omap->xclk60mhsp2_ck);
536  dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
537  goto err_utmi_p2_fck;
538  }
539 
540  omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk");
541  if (IS_ERR(omap->usbhost_p1_fck)) {
542  ret = PTR_ERR(omap->usbhost_p1_fck);
543  dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret);
544  goto err_xclk60mhsp2_ck;
545  }
546 
547  omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
548  if (IS_ERR(omap->usbhost_p2_fck)) {
549  ret = PTR_ERR(omap->usbhost_p2_fck);
550  dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
551  goto err_usbhost_p1_fck;
552  }
553 
554  omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
555  if (IS_ERR(omap->init_60m_fclk)) {
556  ret = PTR_ERR(omap->init_60m_fclk);
557  dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
558  goto err_usbhost_p2_fck;
559  }
560 
561  if (is_ehci_phy_mode(pdata->port_mode[0])) {
562  /* for OMAP3 , the clk set paretn fails */
563  ret = clk_set_parent(omap->utmi_p1_fck,
564  omap->xclk60mhsp1_ck);
565  if (ret != 0)
566  dev_err(dev, "xclk60mhsp1_ck set parent"
567  "failed error:%d\n", ret);
568  } else if (is_ehci_tll_mode(pdata->port_mode[0])) {
569  ret = clk_set_parent(omap->utmi_p1_fck,
570  omap->init_60m_fclk);
571  if (ret != 0)
572  dev_err(dev, "init_60m_fclk set parent"
573  "failed error:%d\n", ret);
574  }
575 
576  if (is_ehci_phy_mode(pdata->port_mode[1])) {
577  ret = clk_set_parent(omap->utmi_p2_fck,
578  omap->xclk60mhsp2_ck);
579  if (ret != 0)
580  dev_err(dev, "xclk60mhsp2_ck set parent"
581  "failed error:%d\n", ret);
582  } else if (is_ehci_tll_mode(pdata->port_mode[1])) {
583  ret = clk_set_parent(omap->utmi_p2_fck,
584  omap->init_60m_fclk);
585  if (ret != 0)
586  dev_err(dev, "init_60m_fclk set parent"
587  "failed error:%d\n", ret);
588  }
589 
590  res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh");
591  if (!res) {
592  dev_err(dev, "UHH EHCI get resource failed\n");
593  ret = -ENODEV;
594  goto err_init_60m_fclk;
595  }
596 
597  omap->uhh_base = ioremap(res->start, resource_size(res));
598  if (!omap->uhh_base) {
599  dev_err(dev, "UHH ioremap failed\n");
600  ret = -ENOMEM;
601  goto err_init_60m_fclk;
602  }
603 
604  platform_set_drvdata(pdev, omap);
605 
606  omap_usbhs_init(dev);
607  ret = omap_usbhs_alloc_children(pdev);
608  if (ret) {
609  dev_err(dev, "omap_usbhs_alloc_children failed\n");
610  goto err_alloc;
611  }
612 
613  goto end_probe;
614 
615 err_alloc:
616  omap_usbhs_deinit(&pdev->dev);
617  iounmap(omap->uhh_base);
618 
619 err_init_60m_fclk:
620  clk_put(omap->init_60m_fclk);
621 
622 err_usbhost_p2_fck:
623  clk_put(omap->usbhost_p2_fck);
624 
625 err_usbhost_p1_fck:
626  clk_put(omap->usbhost_p1_fck);
627 
628 err_xclk60mhsp2_ck:
629  clk_put(omap->xclk60mhsp2_ck);
630 
631 err_utmi_p2_fck:
632  clk_put(omap->utmi_p2_fck);
633 
634 err_xclk60mhsp1_ck:
635  clk_put(omap->xclk60mhsp1_ck);
636 
637 err_utmi_p1_fck:
638  clk_put(omap->utmi_p1_fck);
639 
640 err_end:
641  clk_put(omap->ehci_logic_fck);
642  pm_runtime_disable(dev);
643  kfree(omap);
644 
645 end_probe:
646  return ret;
647 }
648 
655 static int __devexit usbhs_omap_remove(struct platform_device *pdev)
656 {
657  struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
658 
659  omap_usbhs_deinit(&pdev->dev);
660  iounmap(omap->uhh_base);
661  clk_put(omap->init_60m_fclk);
662  clk_put(omap->usbhost_p2_fck);
663  clk_put(omap->usbhost_p1_fck);
664  clk_put(omap->xclk60mhsp2_ck);
665  clk_put(omap->utmi_p2_fck);
666  clk_put(omap->xclk60mhsp1_ck);
667  clk_put(omap->utmi_p1_fck);
668  clk_put(omap->ehci_logic_fck);
669  pm_runtime_disable(&pdev->dev);
670  kfree(omap);
671 
672  return 0;
673 }
674 
675 static const struct dev_pm_ops usbhsomap_dev_pm_ops = {
676  .runtime_suspend = usbhs_runtime_suspend,
677  .runtime_resume = usbhs_runtime_resume,
678 };
679 
680 static struct platform_driver usbhs_omap_driver = {
681  .driver = {
682  .name = (char *)usbhs_driver_name,
683  .owner = THIS_MODULE,
684  .pm = &usbhsomap_dev_pm_ops,
685  },
686  .remove = __exit_p(usbhs_omap_remove),
687 };
688 
689 MODULE_AUTHOR("Keshava Munegowda <[email protected]>");
690 MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
691 MODULE_LICENSE("GPL v2");
692 MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
693 
694 static int __init omap_usbhs_drvinit(void)
695 {
696  return platform_driver_probe(&usbhs_omap_driver, usbhs_omap_probe);
697 }
698 
699 /*
700  * init before ehci and ohci drivers;
701  * The usbhs core driver should be initialized much before
702  * the omap ehci and ohci probe functions are called.
703  * This usbhs core driver should be initialized after
704  * usb tll driver
705  */
706 fs_initcall_sync(omap_usbhs_drvinit);
707 
708 static void __exit omap_usbhs_drvexit(void)
709 {
710  platform_driver_unregister(&usbhs_omap_driver);
711 }
712 module_exit(omap_usbhs_drvexit);