diff options
| author | Manjunath Goudar <manjunath.goudar@linaro.org> | 2013-09-21 07:08:38 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-26 12:51:58 -0400 |
| commit | 50a97e059bc9ffe05270a1e2dd963cff1b7396bd (patch) | |
| tree | a90295f41a632216daf9b0d4d0c2fbe4132910ac /drivers/usb/host | |
| parent | a60f4f81e4738d1b20cdb9369060211278f177a5 (diff) | |
USB: OHCI: make ohci-exynos a separate driver
Separate the Samsung OHCI EXYNOS 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 kernels on ARM.
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>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Cc: Vivek Gautam <gautam.vivek@samsung.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
| -rw-r--r-- | drivers/usb/host/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/usb/host/Makefile | 1 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-exynos.c | 167 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-hcd.c | 18 |
4 files changed, 72 insertions, 118 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 7e7c52a081ad..d8d39c7846c7 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -454,8 +454,8 @@ config USB_OHCI_SH | |||
| 454 | If you use the PCI OHCI controller, this option is not necessary. | 454 | If you use the PCI OHCI controller, this option is not necessary. |
| 455 | 455 | ||
| 456 | config USB_OHCI_EXYNOS | 456 | config USB_OHCI_EXYNOS |
| 457 | boolean "OHCI support for Samsung EXYNOS SoC Series" | 457 | tristate "OHCI support for Samsung S5P/EXYNOS SoC Series" |
| 458 | depends on ARCH_EXYNOS | 458 | depends on PLAT_S5P || ARCH_EXYNOS |
| 459 | help | 459 | help |
| 460 | Enable support for the Samsung Exynos SOC's on-chip OHCI controller. | 460 | Enable support for the Samsung Exynos SOC's on-chip OHCI controller. |
| 461 | 461 | ||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 29fa3b839d85..78ace5517896 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
| @@ -47,6 +47,7 @@ obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o | |||
| 47 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 47 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
| 48 | obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o | 48 | obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o |
| 49 | obj-$(CONFIG_USB_OHCI_HCD_PLATFORM) += ohci-platform.o | 49 | obj-$(CONFIG_USB_OHCI_HCD_PLATFORM) += ohci-platform.o |
| 50 | obj-$(CONFIG_USB_OHCI_EXYNOS) += ohci-exynos.o | ||
| 50 | 51 | ||
| 51 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 52 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
| 52 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o | 53 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o |
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index dc6ee9adacf5..3e4bc74f76ab 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c | |||
| @@ -12,24 +12,39 @@ | |||
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
| 15 | #include <linux/dma-mapping.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/module.h> | ||
| 15 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 16 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 17 | #include <linux/platform_data/usb-ohci-exynos.h> | 21 | #include <linux/platform_data/usb-ohci-exynos.h> |
| 18 | #include <linux/usb/phy.h> | 22 | #include <linux/usb/phy.h> |
| 19 | #include <linux/usb/samsung_usb_phy.h> | 23 | #include <linux/usb/samsung_usb_phy.h> |
| 24 | #include <linux/usb.h> | ||
| 25 | #include <linux/usb/hcd.h> | ||
| 26 | #include <linux/usb/otg.h> | ||
| 27 | |||
| 28 | #include "ohci.h" | ||
| 29 | |||
| 30 | #define DRIVER_DESC "OHCI EXYNOS driver" | ||
| 31 | |||
| 32 | static const char hcd_name[] = "ohci-exynos"; | ||
| 33 | static struct hc_driver __read_mostly exynos_ohci_hc_driver; | ||
| 34 | |||
| 35 | #define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv) | ||
| 20 | 36 | ||
| 21 | struct exynos_ohci_hcd { | 37 | struct exynos_ohci_hcd { |
| 22 | struct device *dev; | ||
| 23 | struct usb_hcd *hcd; | ||
| 24 | struct clk *clk; | 38 | struct clk *clk; |
| 25 | struct usb_phy *phy; | 39 | struct usb_phy *phy; |
| 26 | struct usb_otg *otg; | 40 | struct usb_otg *otg; |
| 27 | struct exynos4_ohci_platdata *pdata; | 41 | struct exynos4_ohci_platdata *pdata; |
| 28 | }; | 42 | }; |
| 29 | 43 | ||
| 30 | static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) | 44 | static void exynos_ohci_phy_enable(struct platform_device *pdev) |
| 31 | { | 45 | { |
| 32 | struct platform_device *pdev = to_platform_device(exynos_ohci->dev); | 46 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
| 47 | struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); | ||
| 33 | 48 | ||
| 34 | if (exynos_ohci->phy) | 49 | if (exynos_ohci->phy) |
| 35 | usb_phy_init(exynos_ohci->phy); | 50 | usb_phy_init(exynos_ohci->phy); |
| @@ -37,9 +52,10 @@ static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) | |||
| 37 | exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); | 52 | exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); |
| 38 | } | 53 | } |
| 39 | 54 | ||
| 40 | static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) | 55 | static void exynos_ohci_phy_disable(struct platform_device *pdev) |
| 41 | { | 56 | { |
| 42 | struct platform_device *pdev = to_platform_device(exynos_ohci->dev); | 57 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
| 58 | struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); | ||
| 43 | 59 | ||
| 44 | if (exynos_ohci->phy) | 60 | if (exynos_ohci->phy) |
| 45 | usb_phy_shutdown(exynos_ohci->phy); | 61 | usb_phy_shutdown(exynos_ohci->phy); |
| @@ -47,63 +63,11 @@ static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) | |||
| 47 | exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); | 63 | exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); |
| 48 | } | 64 | } |
| 49 | 65 | ||
| 50 | static int ohci_exynos_reset(struct usb_hcd *hcd) | ||
| 51 | { | ||
| 52 | return ohci_init(hcd_to_ohci(hcd)); | ||
| 53 | } | ||
| 54 | |||
| 55 | static int ohci_exynos_start(struct usb_hcd *hcd) | ||
| 56 | { | ||
| 57 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
| 58 | int ret; | ||
| 59 | |||
| 60 | ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci); | ||
| 61 | |||
| 62 | ret = ohci_run(ohci); | ||
| 63 | if (ret < 0) { | ||
| 64 | dev_err(hcd->self.controller, "can't start %s\n", | ||
| 65 | hcd->self.bus_name); | ||
| 66 | ohci_stop(hcd); | ||
| 67 | return ret; | ||
| 68 | } | ||
| 69 | |||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | static const struct hc_driver exynos_ohci_hc_driver = { | ||
| 74 | .description = hcd_name, | ||
| 75 | .product_desc = "EXYNOS OHCI Host Controller", | ||
| 76 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
| 77 | |||
| 78 | .irq = ohci_irq, | ||
| 79 | .flags = HCD_MEMORY|HCD_USB11, | ||
| 80 | |||
| 81 | .reset = ohci_exynos_reset, | ||
| 82 | .start = ohci_exynos_start, | ||
| 83 | .stop = ohci_stop, | ||
| 84 | .shutdown = ohci_shutdown, | ||
| 85 | |||
| 86 | .get_frame_number = ohci_get_frame, | ||
| 87 | |||
| 88 | .urb_enqueue = ohci_urb_enqueue, | ||
| 89 | .urb_dequeue = ohci_urb_dequeue, | ||
| 90 | .endpoint_disable = ohci_endpoint_disable, | ||
| 91 | |||
| 92 | .hub_status_data = ohci_hub_status_data, | ||
| 93 | .hub_control = ohci_hub_control, | ||
| 94 | #ifdef CONFIG_PM | ||
| 95 | .bus_suspend = ohci_bus_suspend, | ||
| 96 | .bus_resume = ohci_bus_resume, | ||
| 97 | #endif | ||
| 98 | .start_port_reset = ohci_start_port_reset, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static int exynos_ohci_probe(struct platform_device *pdev) | 66 | static int exynos_ohci_probe(struct platform_device *pdev) |
| 102 | { | 67 | { |
| 103 | struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev); | 68 | struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev); |
| 104 | struct exynos_ohci_hcd *exynos_ohci; | 69 | struct exynos_ohci_hcd *exynos_ohci; |
| 105 | struct usb_hcd *hcd; | 70 | struct usb_hcd *hcd; |
| 106 | struct ohci_hcd *ohci; | ||
| 107 | struct resource *res; | 71 | struct resource *res; |
| 108 | struct usb_phy *phy; | 72 | struct usb_phy *phy; |
| 109 | int irq; | 73 | int irq; |
| @@ -119,10 +83,14 @@ static int exynos_ohci_probe(struct platform_device *pdev) | |||
| 119 | if (!pdev->dev.coherent_dma_mask) | 83 | if (!pdev->dev.coherent_dma_mask) |
| 120 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 84 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
| 121 | 85 | ||
| 122 | exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd), | 86 | hcd = usb_create_hcd(&exynos_ohci_hc_driver, |
| 123 | GFP_KERNEL); | 87 | &pdev->dev, dev_name(&pdev->dev)); |
| 124 | if (!exynos_ohci) | 88 | if (!hcd) { |
| 89 | dev_err(&pdev->dev, "Unable to create HCD\n"); | ||
| 125 | return -ENOMEM; | 90 | return -ENOMEM; |
| 91 | } | ||
| 92 | |||
| 93 | exynos_ohci = to_exynos_ohci(hcd); | ||
| 126 | |||
