Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: EHCI: make ehci-mv a separate driver

This is done do that it could be enabled alongside other platform EHCI
glue drivers on multiplatform kernels.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Lubomir Rintel and committed by
Greg Kroah-Hartman
0440fa3d b32abf8f

+43 -61
+1 -1
drivers/usb/host/Kconfig
··· 276 276 Enable support for the Samsung Exynos SOC's on-chip EHCI controller. 277 277 278 278 config USB_EHCI_MV 279 - bool "EHCI support for Marvell PXA/MMP USB controller" 279 + tristate "EHCI support for Marvell PXA/MMP USB controller" 280 280 depends on (ARCH_PXA || ARCH_MMP) 281 281 select USB_EHCI_ROOT_HUB_TT 282 282 ---help---
+1
drivers/usb/host/Makefile
··· 87 87 obj-$(CONFIG_USB_FSL_USB2) += fsl-mph-dr-of.o 88 88 obj-$(CONFIG_USB_EHCI_FSL) += fsl-mph-dr-of.o 89 89 obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o 90 + obj-$(CONFIG_USB_EHCI_MV) += ehci-mv.o 90 91 obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o 91 92 obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o 92 93 obj-$(CONFIG_USB_FOTG210_HCD) += fotg210-hcd.o
-5
drivers/usb/host/ehci-hcd.c
··· 1286 1286 #define PLATFORM_DRIVER ehci_grlib_driver 1287 1287 #endif 1288 1288 1289 - #ifdef CONFIG_USB_EHCI_MV 1290 - #include "ehci-mv.c" 1291 - #define PLATFORM_DRIVER ehci_mv_driver 1292 - #endif 1293 - 1294 1289 static int __init ehci_hcd_init(void) 1295 1290 { 1296 1291 int retval = 0;
+41 -55
drivers/usb/host/ehci-mv.c
··· 12 12 #include <linux/err.h> 13 13 #include <linux/usb/otg.h> 14 14 #include <linux/platform_data/mv_usb.h> 15 + #include <linux/io.h> 16 + 17 + #include <linux/usb/hcd.h> 18 + 19 + #include "ehci.h" 15 20 16 21 #define CAPLENGTH_MASK (0xff) 17 22 18 - struct ehci_hcd_mv { 19 - struct usb_hcd *hcd; 23 + #define hcd_to_ehci_hcd_mv(h) ((struct ehci_hcd_mv *)hcd_to_ehci(h)->priv) 20 24 25 + struct ehci_hcd_mv { 21 26 /* Which mode does this ehci running OTG/Host ? */ 22 27 int mode; 23 28 ··· 71 66 static int mv_ehci_reset(struct usb_hcd *hcd) 72 67 { 73 68 struct device *dev = hcd->self.controller; 74 - struct ehci_hcd_mv *ehci_mv = dev_get_drvdata(dev); 69 + struct ehci_hcd_mv *ehci_mv = hcd_to_ehci_hcd_mv(hcd); 75 70 int retval; 76 71 77 72 if (ehci_mv == NULL) { ··· 88 83 return retval; 89 84 } 90 85 91 - static const struct hc_driver mv_ehci_hc_driver = { 92 - .description = hcd_name, 93 - .product_desc = "Marvell EHCI", 94 - .hcd_priv_size = sizeof(struct ehci_hcd), 86 + static struct hc_driver __read_mostly ehci_platform_hc_driver; 95 87 96 - /* 97 - * generic hardware linkage 98 - */ 99 - .irq = ehci_irq, 100 - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, 101 - 102 - /* 103 - * basic lifecycle operations 104 - */ 105 - .reset = mv_ehci_reset, 106 - .start = ehci_run, 107 - .stop = ehci_stop, 108 - .shutdown = ehci_shutdown, 109 - 110 - /* 111 - * managing i/o requests and associated device resources 112 - */ 113 - .urb_enqueue = ehci_urb_enqueue, 114 - .urb_dequeue = ehci_urb_dequeue, 115 - .endpoint_disable = ehci_endpoint_disable, 116 - .endpoint_reset = ehci_endpoint_reset, 117 - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 118 - 119 - /* 120 - * scheduling support 121 - */ 122 - .get_frame_number = ehci_get_frame, 123 - 124 - /* 125 - * root hub support 126 - */ 127 - .hub_status_data = ehci_hub_status_data, 128 - .hub_control = ehci_hub_control, 129 - .bus_suspend = ehci_bus_suspend, 130 - .bus_resume = ehci_bus_resume, 88 + static const struct ehci_driver_overrides platform_overrides __initconst = { 89 + .reset = mv_ehci_reset, 90 + .extra_priv_size = sizeof(struct ehci_hcd_mv), 131 91 }; 132 92 133 93 static int mv_ehci_probe(struct platform_device *pdev) ··· 113 143 if (usb_disabled()) 114 144 return -ENODEV; 115 145 116 - hcd = usb_create_hcd(&mv_ehci_hc_driver, &pdev->dev, "mv ehci"); 146 + hcd = usb_create_hcd(&ehci_platform_hc_driver, &pdev->dev, "mv ehci"); 117 147 if (!hcd) 118 148 return -ENOMEM; 119 149 120 - ehci_mv = devm_kzalloc(&pdev->dev, sizeof(*ehci_mv), GFP_KERNEL); 121 - if (ehci_mv == NULL) { 122 - retval = -ENOMEM; 123 - goto err_put_hcd; 124 - } 125 - 126 - platform_set_drvdata(pdev, ehci_mv); 150 + platform_set_drvdata(pdev, hcd); 151 + ehci_mv = hcd_to_ehci_hcd_mv(hcd); 127 152 ehci_mv->pdata = pdata; 128 - ehci_mv->hcd = hcd; 129 153 130 154 ehci_mv->clk = devm_clk_get(&pdev->dev, NULL); 131 155 if (IS_ERR(ehci_mv->clk)) { ··· 226 262 227 263 static int mv_ehci_remove(struct platform_device *pdev) 228 264 { 229 - struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); 230 - struct usb_hcd *hcd = ehci_mv->hcd; 265 + struct usb_hcd *hcd = platform_get_drvdata(pdev); 266 + struct ehci_hcd_mv *ehci_mv = hcd_to_ehci_hcd_mv(hcd); 231 267 232 268 if (hcd->rh_registered) 233 269 usb_remove_hcd(hcd); ··· 259 295 260 296 static void mv_ehci_shutdown(struct platform_device *pdev) 261 297 { 262 - struct ehci_hcd_mv *ehci_mv = platform_get_drvdata(pdev); 263 - struct usb_hcd *hcd = ehci_mv->hcd; 298 + struct usb_hcd *hcd = platform_get_drvdata(pdev); 299 + struct ehci_hcd_mv *ehci_mv = hcd_to_ehci_hcd_mv(hcd); 264 300 265 301 if (!hcd->rh_registered) 266 302 return; ··· 279 315 }, 280 316 .id_table = ehci_id_table, 281 317 }; 318 + 319 + static int __init ehci_platform_init(void) 320 + { 321 + if (usb_disabled()) 322 + return -ENODEV; 323 + 324 + ehci_init_driver(&ehci_platform_hc_driver, &platform_overrides); 325 + return platform_driver_register(&ehci_mv_driver); 326 + } 327 + module_init(ehci_platform_init); 328 + 329 + static void __exit ehci_platform_cleanup(void) 330 + { 331 + platform_driver_unregister(&ehci_mv_driver); 332 + } 333 + module_exit(ehci_platform_cleanup); 334 + 335 + MODULE_DESCRIPTION("Marvell EHCI driver"); 336 + MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>"); 337 + MODULE_AUTHOR("Neil Zhang <zhangwm@marvell.com>"); 338 + MODULE_ALIAS("mv-ehci"); 339 + MODULE_LICENSE("GPL");