aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-s3c2410.c
diff options
context:
space:
mode:
authorManjunath Goudar <manjunath.goudar@linaro.org>2013-09-21 07:08:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-09-26 14:35:02 -0400
commitf23b71f3fe63b760a665406f453fa479ff90aad5 (patch)
tree6b534944beb4a91b8b318ef1c52de1fbc8c47c6d /drivers/usb/host/ohci-s3c2410.c
parente3825b48e2cc8014b3088f8bff1c5f35652f298d (diff)
USB: OHCI: make ohci-s3c2410 a separate driver
Separate the Samsung OHCI S3C24xx/S3C64xx host controller driver from ohci-hcd host code so that it can be built as a separate driver module.This work is part of enabling multi-platform. Signed-off-by: Manjunath Goudar <manjunath.goudar@linaro.org> Signed-off-by: Deepak Saxena <dsaxena@linaro.org> Acked-by: Alan Stern <stern@rowland.harvard.edu> Reviewed-by: Tomasz Figa <t.figa@samsung.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ohci-s3c2410.c')
-rw-r--r--drivers/usb/host/ohci-s3c2410.c128
1 files changed, 57 insertions, 71 deletions
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 4919afa4125e..be3429e08d90 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,19 +19,36 @@
19 * This file is licenced under the GPL. 19 * This file is licenced under the GPL.
20*/ 20*/
21 21
22#include <linux/platform_device.h>
23#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
24#include <linux/platform_data/usb-ohci-s3c2410.h> 27#include <linux/platform_data/usb-ohci-s3c2410.h>
28#include <linux/usb.h>
29#include <linux/usb/hcd.h>
30
31#include "ohci.h"
32
25 33
26#define valid_port(idx) ((idx) == 1 || (idx) == 2) 34#define valid_port(idx) ((idx) == 1 || (idx) == 2)
27 35
28/* clock device associated with the hcd */ 36/* clock device associated with the hcd */
29 37
38
39#define DRIVER_DESC "OHCI S3C2410 driver"
40
41static const char hcd_name[] = "ohci-s3c2410";
42
30static struct clk *clk; 43static struct clk *clk;
31static struct clk *usb_clk; 44static struct clk *usb_clk;
32 45
33/* forward definitions */ 46/* forward definitions */
34 47
48static int (*orig_ohci_hub_control)(struct usb_hcd *hcd, u16 typeReq,
49 u16 wValue, u16 wIndex, char *buf, u16 wLength);
50static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
51
35static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc); 52static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
36 53
37/* conversion functions */ 54/* conversion functions */
@@ -93,7 +110,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)
93 int orig; 110 int orig;
94 int portno; 111 int portno;
95 112
96 orig = ohci_hub_status_data(hcd, buf); 113 orig = orig_ohci_hub_status_data(hcd, buf);
97 114
98 if (info == NULL) 115 if (info == NULL)
99 return orig; 116 return orig;
@@ -164,7 +181,7 @@ static int ohci_s3c2410_hub_control(
164 * process the request straight away and exit */ 181 * process the request straight away and exit */
165 182
166 if (info == NULL) { 183 if (info == NULL) {
167 ret = ohci_hub_control(hcd, typeReq, wValue, 184 ret = orig_ohci_hub_control(hcd, typeReq, wValue,
168 wIndex, buf, wLength); 185 wIndex, buf, wLength);
169 goto out; 186 goto out;
170 } 187 }
@@ -214,7 +231,7 @@ static int ohci_s3c2410_hub_control(
214 break; 231 break;
215 } 232 }
216 233
217 ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); 234 ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
218 if (ret) 235 if (ret)
219 goto out; 236 goto out;
220 237
@@ -374,8 +391,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
374 391
375 s3c2410_start_hc(dev, hcd); 392 s3c2410_start_hc(dev, hcd);
376 393
377 ohci_hcd_init(hcd_to_ohci(hcd));
378
379 retval = usb_add_hcd(hcd, dev->resource[1].start, 0); 394 retval = usb_add_hcd(hcd, dev->resource[1].start, 0);
380 if (retval != 0) 395 if (retval != 0)
381 goto err_ioremap; 396 goto err_ioremap;
@@ -392,71 +407,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,
392 407
393/*-------------------------------------------------------------------------*/ 408/*-------------------------------------------------------------------------*/
394 409
395static int 410static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;
396ohci_s3c2410_start(struct usb_hcd *hcd)
397{
398 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
399 int ret;
400
401 ret = ohci_init(ohci);
402 if (ret < 0)
403 return ret;
404
405 ret = ohci_run(ohci);
406 if (ret < 0) {
407 dev_err(hcd->self.controller, "can't start %s\n",
408 hcd->self.bus_name);
409 ohci_stop(hcd);
410 return ret;
411 }
412
413 return 0;
414}
415
416
417static const struct hc_driver ohci_s3c2410_hc_driver = {
418 .description = hcd_name,
419 .product_desc = "S3C24XX OHCI",
420 .hcd_priv_size = sizeof(struct ohci_hcd),
421
422 /*
423 * generic hardware linkage
424 */
425 .irq = ohci_irq,
426 .flags = HCD_USB11 | HCD_MEMORY,
427
428 /*
429 * basic lifecycle operations
430 */
431 .start = ohci_s3c2410_start,
432 .stop = ohci_stop,
433 .shutdown = ohci_shutdown,
434
435 /*
436 * managing i/o requests and associated device resources
437 */
438 .urb_enqueue = ohci_urb_enqueue,
439 .urb_dequeue = ohci_urb_dequeue,
440 .endpoint_disable = ohci_endpoint_disable,
441
442 /*
443 * scheduling support
444 */
445 .get_frame_number = ohci_get_frame,
446
447 /*
448 * root hub support
449 */
450 .hub_status_data = ohci_s3c2410_hub_status_data,
451 .hub_control = ohci_s3c2410_hub_control,
452#ifdef CONFIG_PM
453 .bus_suspend = ohci_bus_suspend,
454 .bus_resume = ohci_bus_resume,
455#endif
456 .start_port_reset = ohci_start_port_reset,
457};
458
459/* device driver */
460 411
461static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev) 412static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)
462{ 413{
@@ -533,4 +484,39 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
533 }, 484 },
534}; 485};
535 486
487static int __init ohci_s3c2410_init(void)
488{
489 if (usb_disabled())
490 return -ENODEV;
491
492 pr_info("%s: " DRIVER_DESC "\n", hcd_name);
493 ohci_init_driver(&ohci_s3c2410_hc_driver, NULL);
494
495 /*
496 * The Samsung HW has some unusual quirks, which require
497 * Sumsung-specific workarounds. We override certain hc_driver
498 * functions here to achieve that. We explicitly do not enhance
499 * ohci_driver_overrides to allow this more easily, since this
500 * is an unusual case, and we don't want to encourage others to
501 * override these functions by making it too easy.
502 */
503
504 orig_ohci_hub_control = ohci_s3c2410_hc_driver.hub_control;
505 orig_ohci_hub_status_data = ohci_s3c2410_hc_driver.hub_status_data;
506
507 ohci_s3c2410_hc_driver.hub_status_data = ohci_s3c2410_hub_status_data;
508 ohci_s3c2410_hc_driver.hub_control = ohci_s3c2410_hub_control;
509
510 return platform_driver_register(&ohci_hcd_s3c2410_driver);
511}
512module_init(ohci_s3c2410_init);
513
514static void __exit ohci_s3c2410_cleanup(void)
515{
516 platform_driver_unregister(&ohci_hcd_s3c2410_driver);
517}
518module_exit(ohci_s3c2410_cleanup);
519
520MODULE_DESCRIPTION(DRIVER_DESC);
521MODULE_LICENSE("GPL");
536MODULE_ALIAS("platform:s3c2410-ohci"); 522MODULE_ALIAS("platform:s3c2410-ohci");