aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
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
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')
-rw-r--r--drivers/usb/host/Kconfig8
-rw-r--r--drivers/usb/host/Makefile1
-rw-r--r--drivers/usb/host/ohci-hcd.c18
-rw-r--r--drivers/usb/host/ohci-s3c2410.c128
4 files changed, 66 insertions, 89 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 152c68090cd9..f0f9bf6e20de 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -381,6 +381,14 @@ config USB_OHCI_HCD_SPEAR
381 Enables support for the on-chip OHCI controller on 381 Enables support for the on-chip OHCI controller on
382 ST SPEAr chips. 382 ST SPEAr chips.
383 383
384config USB_OHCI_HCD_S3C2410
385 tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series"
386 depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX)
387 default y
388 ---help---
389 Enables support for the on-chip OHCI controller on
390 S3C24xx/S3C64xx chips.
391
384config USB_OHCI_HCD_AT91 392config USB_OHCI_HCD_AT91
385 tristate "Support for Atmel on-chip OHCI USB controller" 393 tristate "Support for Atmel on-chip OHCI USB controller"
386 depends on USB_OHCI_HCD && ARCH_AT91 394 depends on USB_OHCI_HCD && ARCH_AT91
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 15dc677e7889..96d18dde672c 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_USB_OHCI_HCD_OMAP1) += ohci-omap.o
52obj-$(CONFIG_USB_OHCI_HCD_OMAP3) += ohci-omap3.o 52obj-$(CONFIG_USB_OHCI_HCD_OMAP3) += ohci-omap3.o
53obj-$(CONFIG_USB_OHCI_HCD_SPEAR) += ohci-spear.o 53obj-$(CONFIG_USB_OHCI_HCD_SPEAR) += ohci-spear.o
54obj-$(CONFIG_USB_OHCI_HCD_AT91) += ohci-at91.o 54obj-$(CONFIG_USB_OHCI_HCD_AT91) += ohci-at91.o
55obj-$(CONFIG_USB_OHCI_HCD_S3C2410) += ohci-s3c2410.o
55 56
56obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o 57obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
57obj-$(CONFIG_USB_FHCI_HCD) += fhci.o 58obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2fdaaf81472d..fcfcab503250 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1177,11 +1177,6 @@ MODULE_LICENSE ("GPL");
1177#define SA1111_DRIVER ohci_hcd_sa1111_driver 1177#define SA1111_DRIVER ohci_hcd_sa1111_driver
1178#endif 1178#endif
1179 1179
1180#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX)
1181#include "ohci-s3c2410.c"
1182#define S3C2410_PLATFORM_DRIVER ohci_hcd_s3c2410_driver
1183#endif
1184
1185#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) 1180#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
1186#include "ohci-pxa27x.c" 1181#include "ohci-pxa27x.c"
1187#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver 1182#define PLATFORM_DRIVER ohci_hcd_pxa27x_driver
@@ -1293,12 +1288,6 @@ static int __init ohci_hcd_mod_init(void)
1293 goto error_tmio; 1288 goto error_tmio;
1294#endif 1289#endif
1295 1290
1296#ifdef S3C2410_PLATFORM_DRIVER
1297 retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER);
1298 if (retval < 0)
1299 goto error_s3c2410;
1300#endif
1301
1302#ifdef EP93XX_PLATFORM_DRIVER 1291#ifdef EP93XX_PLATFORM_DRIVER
1303 retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER); 1292 retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER);
1304 if (retval < 0) 1293 if (retval < 0)
@@ -1332,10 +1321,6 @@ static int __init ohci_hcd_mod_init(void)
1332 platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); 1321 platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
1333 error_ep93xx: 1322 error_ep93xx:
1334#endif 1323#endif
1335#ifdef S3C2410_PLATFORM_DRIVER
1336 platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
1337 error_s3c2410:
1338#endif
1339#ifdef TMIO_OHCI_DRIVER 1324#ifdef TMIO_OHCI_DRIVER
1340 platform_driver_unregister(&TMIO_OHCI_DRIVER); 1325 platform_driver_unregister(&TMIO_OHCI_DRIVER);
1341 error_tmio: 1326 error_tmio:
@@ -1382,9 +1367,6 @@ static void __exit ohci_hcd_mod_exit(void)
1382#ifdef EP93XX_PLATFORM_DRIVER 1367#ifdef EP93XX_PLATFORM_DRIVER
1383 platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); 1368 platform_driver_unregister(&EP93XX_PLATFORM_DRIVER);
1384#endif 1369#endif
1385#ifdef S3C2410_PLATFORM_DRIVER
1386 platform_driver_unregister(&S3C2410_PLATFORM_DRIVER);
1387#endif
1388#ifdef TMIO_OHCI_DRIVER 1370#ifdef TMIO_OHCI_DRIVER
1389 platform_driver_unregister(&TMIO_OHCI_DRIVER); 1371 platform_driver_unregister(&TMIO_OHCI_DRIVER);
1390#endif 1372#endif
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");