diff options
author | make shi <b15407@freescale.com> | 2012-11-08 15:26:22 +0800 |
---|---|---|
committer | make shi <b15407@freescale.com> | 2012-11-14 17:52:09 +0800 |
commit | b8ee7558dca70f7db6a93c0d18d8c7a2bf87476b (patch) | |
tree | 3b47b35967972c0d9af8b20a8f3bb10e5ca2e4f2 | |
parent | ea1a4f6134acf027884434988e265f3fa4930ddd (diff) |
ENGR00233051-03 Mx6 USB: msl implementation for USB OTG modulization
- remove mx6_usb_dr_init() in board specific initialization files
- Add module_init(mx6_usb_dr_init) and module_exit(mx6_usb_dr_exit)
in usb_dr.c to support the usb_dr modulization
- Export necessary function which is used in usb_dr.c
Signed-off-by: make shi <b15407@freescale.com>
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_arm2.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabreauto.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabrelite.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6q_sabresd.c | 2 | ||||
-rwxr-xr-x | arch/arm/mach-mx6/board-mx6sl_arm2.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6sl_evk.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx6/usb_dr.c | 108 | ||||
-rw-r--r-- | arch/arm/mach-mx6/usb_h1.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-mx6/usb_h2.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-mx6/usb_h3.c | 1 | ||||
-rw-r--r-- | arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c | 52 | ||||
-rw-r--r-- | arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c | 53 | ||||
-rw-r--r-- | arch/arm/plat-mxc/devices/platform-mxc-ehci.c | 50 | ||||
-rwxr-xr-x | arch/arm/plat-mxc/usb_common.c | 23 |
14 files changed, 244 insertions, 58 deletions
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index 50f26ddafffb..27c404525e64 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -1244,7 +1244,7 @@ static void __init mx6_arm2_init_usb(void) mxc_iomux_set_gpr_register(1, 13, 1, 1); mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); - mx6_usb_dr_init(); + #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); mx6_usb_h3_init(); diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c index 649ead2c8162..146adad4580e 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -769,7 +769,6 @@ static void __init imx6q_sabreauto_init_usb(void) mxc_iomux_set_gpr_register(1, 13, 1, 0); mx6_set_otghost_vbus_func(imx6q_sabreauto_usbotg_vbus); - mx6_usb_dr_init(); mx6_set_host1_vbus_func(imx6q_sabreauto_usbhost1_vbus); #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index eff81acb3208..3289b1a5a98e 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -670,7 +670,6 @@ static void __init imx6q_sabrelite_init_usb(void) mxc_iomux_set_gpr_register(1, 13, 1, 1); mx6_set_otghost_vbus_func(imx6q_sabrelite_usbotg_vbus); - mx6_usb_dr_init(); } /* HW Initialization, if return 0, initialization is successful. */ diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c index ab24bb41cbad..863b2b1b8a88 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -1113,7 +1113,7 @@ static void __init imx6q_sabresd_init_usb(void) mxc_iomux_set_gpr_register(1, 13, 1, 0); mx6_set_otghost_vbus_func(imx6q_sabresd_usbotg_vbus); - mx6_usb_dr_init(); + } /* HW Initialization, if return 0, initialization is successful. */ diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index a7f20edf524f..f62a97f5465e 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -1079,7 +1079,6 @@ static void __init mx6_arm2_init_usb(void) gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); - mx6_usb_dr_init(); #ifdef CONFIG_USB_EHCI_ARC_HSIC mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_DAT, PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK); diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 47e8a8954c7d..6836310b7d17 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -1264,7 +1264,7 @@ static void __init mx6_evk_init_usb(void) gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); mx6_set_otghost_vbus_func(imx6_evk_usbotg_vbus); - mx6_usb_dr_init(); + #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); #endif diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c index 7b79d98c7d5c..3c66f1793b67 100644 --- a/arch/arm/mach-mx6/usb_dr.c +++ b/arch/arm/mach-mx6/usb_dr.c @@ -35,6 +35,8 @@ static void usbotg_uninit_ext(struct platform_device *pdev); static void usbotg_clock_gate(bool on); static void _dr_discharge_line(bool enable); extern bool usb_icbug_swfix_need(void); +static void enter_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, \ + bool enable); /* The usb_phy1_clk do not have enable/disable function at clock.c * and PLL output for usb1's phy should be always enabled. @@ -190,8 +192,8 @@ static int usbotg_init_ext(struct platform_device *pdev) return ret; } if (!otg_used) { - usbotg_internal_phy_clock_gate(true); usb_phy_enable(pdev->dev.platform_data); + enter_phy_lowpower_suspend(pdev->dev.platform_data, false); /*after the phy reset,can not read the readingvalue for id/vbus at * the register of otgsc ,cannot read at once ,need delay 3 ms */ @@ -204,16 +206,17 @@ static int usbotg_init_ext(struct platform_device *pdev) static void usbotg_uninit_ext(struct platform_device *pdev) { - struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; - - clk_disable(usb_phy1_clk); - clk_put(usb_phy1_clk); + otg_used--; + if (!otg_used) { + enter_phy_lowpower_suspend(pdev->dev.platform_data, true); + mdelay(3); - clk_disable(usb_oh3_clk); - clk_put(usb_oh3_clk); + clk_disable(usb_phy1_clk); + clk_put(usb_phy1_clk); - usbotg_uninit(pdata); - otg_used--; + clk_disable(usb_oh3_clk); + clk_put(usb_oh3_clk); + } } static void usbotg_clock_gate(bool on) @@ -236,10 +239,6 @@ static void dr_platform_phy_power_on(void) anatop_base_addr + HW_ANADIG_ANA_MISC0_SET); } -void mx6_set_otghost_vbus_func(driver_vbus_func driver_vbus) -{ - dr_utmi_config.platform_driver_vbus = driver_vbus; -} static void _dr_discharge_line(bool enable) { @@ -604,18 +603,45 @@ static void device_wakeup_handler(struct fsl_usb2_platform_data *pdata) /* end of device related operation for DR port */ #endif /* CONFIG_USB_GADGET_ARC */ -void __init mx6_usb_dr_init(void) +static struct platform_device *pdev[3], *pdev_wakeup; +static driver_vbus_func mx6_set_usb_otg_vbus; +static int devnum; +static int __init mx6_usb_dr_init(void) { - struct platform_device *pdev, *pdev_wakeup; + int i = 0; void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); + struct imx_fsl_usb2_wakeup_data imx6q_fsl_otg_wakeup_data = + imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 0, OTG); + struct imx_mxc_ehci_data imx6q_mxc_ehci_otg_data = + imx_mxc_ehci_data_entry_single(MX6Q, 0, OTG); + struct imx_fsl_usb2_udc_data imx6q_fsl_usb2_udc_data = + imx_fsl_usb2_udc_data_entry_single(MX6Q); + struct imx_fsl_usb2_otg_data imx6q_fsl_usb2_otg_data = + imx_fsl_usb2_otg_data_entry_single(MX6Q); + + /* Some phy and power's special controls for otg + * 1. The external charger detector needs to be disabled + * or the signal at DP will be poor + * 2. The EN_USB_CLKS is always enabled. + * The PLL's power is controlled by usb and others who + * use pll3 too. + */ + __raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B \ + | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B, \ + anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT); + __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, + anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); + mx6_get_otghost_vbus_func(&mx6_set_usb_otg_vbus); + dr_utmi_config.platform_driver_vbus = mx6_set_usb_otg_vbus; #ifdef CONFIG_USB_OTG /* wake_up_enable is useless, just for usb_register_remote_wakeup execution*/ dr_utmi_config.wake_up_enable = _device_wakeup_enable; dr_utmi_config.operating_mode = FSL_USB2_DR_OTG; dr_utmi_config.wakeup_pdata = &dr_wakeup_config; - pdev = imx6q_add_fsl_usb2_otg(&dr_utmi_config); - dr_wakeup_config.usb_pdata[0] = pdev->dev.platform_data; + pdev[i] = imx6q_add_fsl_usb2_otg(&dr_utmi_config); + dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data; + i++; #endif #ifdef CONFIG_USB_EHCI_ARC_OTG dr_utmi_config.operating_mode = DR_HOST_MODE; @@ -633,8 +659,9 @@ void __init mx6_usb_dr_init(void) dr_utmi_config.wakeup_pdata = &dr_wakeup_config; dr_utmi_config.wakeup_handler = host_wakeup_handler; dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on; - pdev = imx6q_add_fsl_ehci_otg(&dr_utmi_config); - dr_wakeup_config.usb_pdata[1] = pdev->dev.platform_data; + pdev[i] = imx6q_add_fsl_ehci_otg(&dr_utmi_config); + dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data; + i++; #endif #ifdef CONFIG_USB_GADGET_ARC dr_utmi_config.operating_mode = DR_UDC_MODE; @@ -648,25 +675,38 @@ void __init mx6_usb_dr_init(void) dr_utmi_config.wakeup_handler = device_wakeup_handler; dr_utmi_config.charger_base_addr = anatop_base_addr; dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on; - pdev = imx6q_add_fsl_usb2_udc(&dr_utmi_config); - dr_wakeup_config.usb_pdata[2] = pdev->dev.platform_data; + pdev[i] = imx6q_add_fsl_usb2_udc(&dr_utmi_config); + dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data; + i++; #endif + devnum = i; /* register wakeup device */ pdev_wakeup = imx6q_add_fsl_usb2_otg_wakeup(&dr_wakeup_config); - if (pdev != NULL) - ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = + for (i = 0; i < devnum; i++) { + platform_device_add(pdev[i]); + ((struct fsl_usb2_platform_data *)(pdev[i]->dev.platform_data))->wakeup_pdata = (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data); + } + + return 0; +} +arch_initcall(mx6_usb_dr_init); + +static void __exit mx6_usb_dr_exit(void) +{ + int i; + void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); + + for (i = 0; i < devnum; i++) + platform_device_del(pdev[devnum-i-1]); + platform_device_unregister(pdev_wakeup); + otg_used = 0; - /* Some phy and power's special controls for otg - * 1. The external charger detector needs to be disabled - * or the signal at DP will be poor - * 2. The EN_USB_CLKS is always enabled. - * The PLL's power is controlled by usb and others who - * use pll3 too. - */ - __raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B \ - | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B, \ - anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT); __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, - anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); + anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_CLR); + return ; } +module_exit(mx6_usb_dr_exit); + +MODULE_AUTHOR("Freescale Semiconductor"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index f86a4f42b0bd..eeac0c401d22 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -400,7 +400,7 @@ static int __init mx6_usb_h1_init(void) struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] = { imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)}; - mx6_set_usb_host1_vbus_func(&mx6_set_usb_host1_vbus); + mx6_get_host1_vbus_func(&mx6_set_usb_host1_vbus); if (mx6_set_usb_host1_vbus) mx6_set_usb_host1_vbus(true); @@ -438,11 +438,12 @@ static int __init mx6_usb_h1_init(void) pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config); else pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config); + platform_device_add(pdev); ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data); return 0; } -module_init(mx6_usb_h1_init); +arch_initcall(mx6_usb_h1_init); static void __exit mx6_usb_h1_exit(void) { diff --git a/arch/arm/mach-mx6/usb_h2.c b/arch/arm/mach-mx6/usb_h2.c index 37cad034d173..be092ab8c97c 100644 --- a/arch/arm/mach-mx6/usb_h2.c +++ b/arch/arm/mach-mx6/usb_h2.c @@ -237,6 +237,7 @@ void __init mx6_usb_h2_init(void) pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); else pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); + platform_device_add(pdev); ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = pdev_wakeup->dev.platform_data; /* Some phy and power's special controls for host2 diff --git a/arch/arm/mach-mx6/usb_h3.c b/arch/arm/mach-mx6/usb_h3.c index 820ecd903d25..e25c01621b52 100644 --- a/arch/arm/mach-mx6/usb_h3.c +++ b/arch/arm/mach-mx6/usb_h3.c @@ -227,6 +227,7 @@ void __init mx6_usb_h3_init(void) pdev = imx6q_add_fsl_ehci_hs(3, &usbh3_config); usbh3_wakeup_config.usb_pdata[0] = pdev->dev.platform_data; pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(3, &usbh3_wakeup_config); + platform_device_add(pdev); ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = pdev_wakeup->dev.platform_data; diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c index f32593c27ccd..da7b22140293 100644 --- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c +++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved. * * Based on Uwe Kleine-Koenig's platform-fsl-usb2-udc.c * Copyright (C) 2010 Pengutronix @@ -39,7 +39,51 @@ struct platform_device *__init imx_add_fsl_usb2_otg( .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device_dmamask("fsl-usb2-otg", -1, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); + + int ret = -ENOMEM; + const char *name = "fsl-usb2-otg"; + int id = -1; + unsigned int num_resources = ARRAY_SIZE(res); + size_t size_data = sizeof(*pdata); + u64 dmamask = DMA_BIT_MASK(32); + struct platform_device *pdev; + + pdev = platform_device_alloc(name, id); + if (!pdev) + goto err; + + if (dmamask) { + /* + * This memory isn't freed when the device is put, + * I don't have a nice idea for that though. Conceptually + * dma_mask in struct device should not be a pointer. + * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 + */ + pdev->dev.dma_mask = + kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); + if (!pdev->dev.dma_mask) + /* ret is still -ENOMEM; */ + goto err; + + *pdev->dev.dma_mask = dmamask; + pdev->dev.coherent_dma_mask = dmamask; + } + + ret = platform_device_add_resources(pdev, res, num_resources); + if (ret) + goto err; + + if (data) { + ret = platform_device_add_data(pdev, pdata, size_data); + if (ret) + goto err; + } + + return pdev; +err: + if (dmamask) + kfree(pdev->dev.dma_mask); + platform_device_put(pdev); + return ERR_PTR(ret); } +EXPORT_SYMBOL(imx_add_fsl_usb2_otg); diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c index 34e522a06247..4c54e1109f9d 100644 --- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c +++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved. * * Copyright (C) 2010 Pengutronix * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> @@ -58,7 +58,52 @@ struct platform_device *__init imx_add_fsl_usb2_udc( .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device_dmamask("fsl-usb2-udc", -1, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); + + int ret = -ENOMEM; + const char *name = "fsl-usb2-udc"; + int id = -1; + unsigned int num_resources = ARRAY_SIZE(res); + size_t size_data = sizeof(*pdata); + u64 dmamask = DMA_BIT_MASK(32); + struct platform_device *pdev; + + pdev = platform_device_alloc(name, id); + if (!pdev) + goto err; + + if (dmamask) { + /* + * This memory isn't freed when the device is put, + * I don't have a nice idea for that though. Conceptually + * dma_mask in struct device should not be a pointer. + * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 + */ + pdev->dev.dma_mask = + kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); + if (!pdev->dev.dma_mask) + /* ret is still -ENOMEM; */ + goto err; + + *pdev->dev.dma_mask = dmamask; + pdev->dev.coherent_dma_mask = dmamask; + } + + ret = platform_device_add_resources(pdev, res, num_resources); + if (ret) + goto err; + + if (data) { + ret = platform_device_add_data(pdev, pdata, size_data); + if (ret) + goto err; + } + + return pdev; + +err: + if (dmamask) + kfree(pdev->dev.dma_mask); + platform_device_put(pdev); + return ERR_PTR(ret); } +EXPORT_SYMBOL(imx_add_fsl_usb2_udc); diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c index 2b9cdff2ff97..984fa296951f 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c +++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c @@ -101,8 +101,52 @@ struct platform_device *__init imx_add_fsl_ehci( .flags = IORESOURCE_IRQ, }, }; - return imx_add_platform_device_dmamask("fsl-ehci", data->id, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); + int ret = -ENOMEM; + const char *name = "fsl-ehci"; + int id = data->id; + unsigned int num_resources = ARRAY_SIZE(res); + size_t size_data = sizeof(*pdata); + u64 dmamask = DMA_BIT_MASK(32); + struct platform_device *pdev; + + pdev = platform_device_alloc(name, id); + if (!pdev) + goto err; + + if (dmamask) { + /* + * This memory isn't freed when the device is put, + * I don't have a nice idea for that though. Conceptually + * dma_mask in struct device should not be a pointer. + * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 + */ + pdev->dev.dma_mask = + kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); + if (!pdev->dev.dma_mask) + /* ret is still -ENOMEM; */ + goto err; + + *pdev->dev.dma_mask = dmamask; + pdev->dev.coherent_dma_mask = dmamask; + } + + ret = platform_device_add_resources(pdev, res, num_resources); + if (ret) + goto err; + + if (data) { + ret = platform_device_add_data(pdev, pdata, size_data); + if (ret) + goto err; + } + + return pdev; + +err: + if (dmamask) + kfree(pdev->dev.dma_mask); + platform_device_put(pdev); + return ERR_PTR(ret); + } EXPORT_SYMBOL(imx_add_fsl_ehci); diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c index 97d963a54a54..a327d3016619 100755 --- a/arch/arm/plat-mxc/usb_common.c +++ b/arch/arm/plat-mxc/usb_common.c @@ -52,7 +52,8 @@ typedef void (*driver_vbus_func)(bool); void __iomem *imx_otg_base; -static driver_vbus_func s_driver_vbus; +static driver_vbus_func s_h1_driver_vbus; +static driver_vbus_func s_otg_driver_vbus; EXPORT_SYMBOL(imx_otg_base); @@ -73,14 +74,26 @@ EXPORT_SYMBOL(usb_icbug_swfix_need); void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus) { - s_driver_vbus = driver_vbus; + s_h1_driver_vbus = driver_vbus; } -void mx6_set_usb_host1_vbus_func(driver_vbus_func *driver_vbus) +void mx6_get_host1_vbus_func(driver_vbus_func *driver_vbus) { - *driver_vbus = s_driver_vbus; + *driver_vbus = s_h1_driver_vbus; } -EXPORT_SYMBOL(mx6_set_usb_host1_vbus_func); +EXPORT_SYMBOL(mx6_get_host1_vbus_func); + +void mx6_set_otghost_vbus_func(driver_vbus_func driver_vbus) +{ + s_otg_driver_vbus = driver_vbus; +} + +void mx6_get_otghost_vbus_func(driver_vbus_func *driver_vbus) +{ + *driver_vbus = s_otg_driver_vbus; +} +EXPORT_SYMBOL(mx6_get_otghost_vbus_func); + enum fsl_usb2_modes get_usb_mode(struct fsl_usb2_platform_data *pdata) |