From faa222f516ae381f7b73448b947aca997129a40a Mon Sep 17 00:00:00 2001 From: make shi Date: Wed, 25 Jul 2012 10:10:45 +0800 Subject: [PATCH] ENGR00215520-03 Mx6:USB host: USB Host1 modulization - remove mx6_usb_h1_init() in board specific initialization files - Add module_init(mx6_usb_h1_init) and module_exit(mx6_usb_h1_exit) in usb_h1.c to support the usb_h1 modulization - Export necessary function which is used in usb_h1.c Signed-off-by: make shi --- arch/arm/mach-mx6/board-mx6q_arm2.c | 1 - arch/arm/mach-mx6/board-mx6q_sabreauto.c | 1 - arch/arm/mach-mx6/board-mx6q_sabrelite.c | 1 - arch/arm/mach-mx6/board-mx6q_sabresd.c | 1 - arch/arm/mach-mx6/board-mx6sl_arm2.c | 1 - arch/arm/mach-mx6/usb_h1.c | 72 +++++++++++++------ .../devices/platform-fsl-usb2-wakeup.c | 1 + arch/arm/plat-mxc/devices/platform-mxc-ehci.c | 2 + arch/arm/plat-mxc/usb_common.c | 17 +++++ arch/arm/plat-mxc/usb_wakeup.c | 11 ++- 10 files changed, 82 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c index 5ef310bdc070..8b500c7dfda0 100644 --- a/arch/arm/mach-mx6/board-mx6q_arm2.c +++ b/arch/arm/mach-mx6/board-mx6q_arm2.c @@ -1239,7 +1239,6 @@ static void __init mx6_arm2_init_usb(void) mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); mx6_usb_dr_init(); - mx6_usb_h1_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 5bd85eb26606..d57badc98a65 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c +++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c @@ -756,7 +756,6 @@ static void __init imx6q_sabreauto_init_usb(void) mx6_set_otghost_vbus_func(imx6q_sabreauto_usbotg_vbus); mx6_usb_dr_init(); mx6_set_host1_vbus_func(imx6q_sabreauto_usbhost1_vbus); - mx6_usb_h1_init(); #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); mx6_usb_h3_init(); diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c index 3098e0d5d5d0..bb334fb20763 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c +++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c @@ -659,7 +659,6 @@ static void __init imx6q_sabrelite_init_usb(void) mx6_set_otghost_vbus_func(imx6q_sabrelite_usbotg_vbus); mx6_usb_dr_init(); - mx6_usb_h1_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 13d7241210e1..a9a516f5b38e 100644 --- a/arch/arm/mach-mx6/board-mx6q_sabresd.c +++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c @@ -1111,7 +1111,6 @@ static void __init imx6q_sabresd_init_usb(void) mx6_set_otghost_vbus_func(imx6q_sabresd_usbotg_vbus); mx6_usb_dr_init(); - mx6_usb_h1_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 77e4bc465f50..4c146c67e3f4 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -1127,7 +1127,6 @@ static void __init mx6_arm2_init_usb(void) mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); mx6_usb_dr_init(); - mx6_usb_h1_init(); #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); #endif diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c index bff9a29aef02..01b3ed8b78d6 100644 --- a/arch/arm/mach-mx6/usb_h1.c +++ b/arch/arm/mach-mx6/usb_h1.c @@ -34,7 +34,6 @@ static struct clk *usb_oh3_clk; extern int clk_get_usecount(struct clk *clk); static struct fsl_usb2_platform_data usbh1_config; -extern bool usb_icbug_swfix_need(void); static void fsl_platform_h1_set_usb_phy_dis( struct fsl_usb2_platform_data *pdata, bool enable) @@ -170,11 +169,6 @@ static void usbh1_clock_gate(bool on) } } -void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus) -{ - usbh1_config.platform_driver_vbus = driver_vbus; -} - static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR); @@ -347,10 +341,41 @@ static struct fsl_usb2_wakeup_platform_data usbh1_wakeup_config = { .usb_wakeup_exhandle = usbh1_wakeup_event_clear, }; -void __init mx6_usb_h1_init(void) +static struct platform_device *pdev, *pdev_wakeup; +static driver_vbus_func mx6_set_usb_host1_vbus; + +static int __init mx6_usb_h1_init(void) { - struct platform_device *pdev, *pdev_wakeup; static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); + struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] = { + imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1)}; + struct imx_fsl_usb2_wakeup_data imx6sl_fsl_hs_wakeup_data[] = { + imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1)}; + struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] = { + imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1)}; + 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); + if (mx6_set_usb_host1_vbus) + mx6_set_usb_host1_vbus(true); + + /* Some phy and power's special controls for host1 + * 1. The external charger detector needs to be disabled + * or the signal at DP will be poor + * 2. The PLL's power and output to usb for host 1 + * is totally controlled by IC, so the Software only needs + * to enable them at initializtion. + */ + __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B \ + | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \ + anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT); + __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS, + anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR); + __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE \ + | BM_ANADIG_USB2_PLL_480_CTRL_POWER \ + | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \ + anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET); usbh1_config.wakeup_pdata = &usbh1_wakeup_config; if (usb_icbug_swfix_need()) { @@ -371,21 +396,28 @@ void __init mx6_usb_h1_init(void) pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config); ((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); - /* Some phy and power's special controls for host1 - * 1. The external charger detector needs to be disabled - * or the signal at DP will be poor - * 2. The PLL's power and output to usb for host 1 - * is totally controlled by IC, so the Software only needs - * to enable them at initializtion. - */ - __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B \ - | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \ - anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT); +static void __exit mx6_usb_h1_exit(void) +{ + static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); + + platform_device_unregister(pdev); + platform_device_unregister(pdev_wakeup); __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS, - anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR); + anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET); __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE \ | BM_ANADIG_USB2_PLL_480_CTRL_POWER \ | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \ - anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET); + anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR); + if (mx6_set_usb_host1_vbus) + mx6_set_usb_host1_vbus(false); + + return ; } +module_exit(mx6_usb_h1_exit); + +MODULE_AUTHOR("Freescale Semiconductor"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c index 986b766fabde..3dacd287c6b8 100644 --- a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c +++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c @@ -52,3 +52,4 @@ struct platform_device *__init imx_add_fsl_usb2_wakeup( res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); } +EXPORT_SYMBOL(imx_add_fsl_usb2_wakeup); diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c index c39f6d7561c6..2b9cdff2ff97 100644 --- a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c +++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c @@ -83,6 +83,7 @@ struct platform_device *__init imx_add_mxc_ehci( res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); } +EXPORT_SYMBOL(imx_add_mxc_ehci); /* FSL internal non-upstream code */ struct platform_device *__init imx_add_fsl_ehci( @@ -104,3 +105,4 @@ struct platform_device *__init imx_add_fsl_ehci( res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32)); } +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 b18f5239c8b9..168808e77a18 100755 --- a/arch/arm/plat-mxc/usb_common.c +++ b/arch/arm/plat-mxc/usb_common.c @@ -49,8 +49,12 @@ #include #include #include +typedef void (*driver_vbus_func)(bool); void __iomem *imx_otg_base; +static driver_vbus_func s_driver_vbus; + +EXPORT_SYMBOL(imx_otg_base); #define MXC_NUMBER_USB_TRANSCEIVER 6 struct fsl_xcvr_ops *g_xc_ops[MXC_NUMBER_USB_TRANSCEIVER] = { NULL }; @@ -62,6 +66,19 @@ bool usb_icbug_swfix_need(void) else return true; } +EXPORT_SYMBOL(usb_icbug_swfix_need); + +void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus) +{ + s_driver_vbus = driver_vbus; +} + +void mx6_set_usb_host1_vbus_func(driver_vbus_func *driver_vbus) +{ + *driver_vbus = s_driver_vbus; +} +EXPORT_SYMBOL(mx6_set_usb_host1_vbus_func); + enum fsl_usb2_modes get_usb_mode(struct fsl_usb2_platform_data *pdata) { diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c index 4704eae91a51..e67c2219e52d 100755 --- a/arch/arm/plat-mxc/usb_wakeup.c +++ b/arch/arm/plat-mxc/usb_wakeup.c @@ -32,6 +32,7 @@ struct wakeup_ctrl { int wakeup_irq; int usb_irq; + bool thread_close; struct fsl_usb2_wakeup_platform_data *pdata; struct task_struct *thread; struct completion event; @@ -145,12 +146,18 @@ static int wakeup_event_thread(void *param) { struct wakeup_ctrl *ctrl = (struct wakeup_ctrl *)param; struct sched_param sch_param = {.sched_priority = 1}; + u32 timeout = 0; sched_setscheduler(current, SCHED_RR, &sch_param); while (1) { wait_for_completion_interruptible(&ctrl->event); - if (kthread_should_stop()) + if (ctrl->thread_close) { + while (!kthread_should_stop() && (timeout < 1000)) { + timeout++; + msleep(1); + } break; + } wakeup_event_handler(ctrl); enable_irq(ctrl->wakeup_irq); if ((ctrl->usb_irq > 0) && (ctrl->wakeup_irq != ctrl->usb_irq)) @@ -184,6 +191,7 @@ static int wakeup_dev_probe(struct platform_device *pdev) */ ctrl->wakeup_irq = platform_get_irq(pdev, 1); ctrl->usb_irq = platform_get_irq(pdev, 1); + ctrl->thread_close = false; if (ctrl->wakeup_irq != ctrl->usb_irq) interrupt_flag = IRQF_DISABLED; else @@ -210,6 +218,7 @@ error1: static int wakeup_dev_exit(struct platform_device *pdev) { if (g_ctrl->thread) { + g_ctrl->thread_close = true; complete(&g_ctrl->event); kthread_stop(g_ctrl->thread); } -- 2.39.5