On Fri, Sep 11, 2015 at 10:17:20AM -0300, Fabio Estevam wrote: > On Fri, Sep 11, 2015 at 4:52 AM, Peter Chen <peter.chen@xxxxxxxxxxxxx> wrote: > > > Hi Fabio, > > > > Would you please help to test build patches for this issue? > > Tested the patch on a mx27pdk running 4.2 and I got the same crash: > > usbcore: registered new interface driver usb-storage > Unhandled fault: external abort on non-linefetch (0x008) at 0xf4424600 > pgd = c0004000 > [f4424600] *pgd=10000452(bad) > Internal error: : 8 [#1] PREEMPT ARM > Modules linked in: > CPU: 0 PID: 1 Comm: swapper Not tainted 4.2.0-dirty #93 > Hardware name: Freescale i.MX27 (Device Tree Support) > task: c7832b60 ti: c783e000 task.ti: c783e000 > PC is at usbmisc_imx27_init+0x4c/0xbc > LR is at usbmisc_imx27_init+0x40/0xbc > pc : [<c03c4a9c>] lr : [<c03c4a90>] psr: 60000093 > sp : c783fe10 ip : 00000000 fp : 00000000 > r10: 00000000 r9 : 0000009c r8 : c056d488 > r7 : 01000000 r6 : 60000013 r5 : c7a785d0 r4 : c7a782f0 > r3 : f4424600 r2 : 00000000 r1 : 00000001 r0 : 00000001 > Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel > Control: 0005317f Table: a0004000 DAC: 00000017 > Process swapper (pid: 1, stack limit = 0xc783e190) > Stack: (0xc783fe10 to 0xc7840000) > fe00: c03c4a50 c7946410 c7946400 00000000 > fe20: c79b8290 c03c46c4 00000000 c03c5254 c7a77538 c79553c0 00000100 00000000 > fe40: 00000000 c7989c30 00000000 00000008 00000000 00000000 00000000 00000000 > fe60: ffffffed c7946410 fffffdfb c0792418 00000000 c02fdb94 c02fdb4c c7946410 > fe80: c07c19d0 00000000 c0792418 c02fc1f0 c7946410 c0792418 c7946444 00000000 > fea0: c072c0c8 c02fc324 00000000 c0792418 c02fc298 c02fa978 c7895d2c c78d8f10 > fec0: c0792418 c7a5fb20 c077e268 c02fb948 c067f7f4 c0284118 c0792418 c0792418 > fee0: c07502b8 c7a78620 c07ab460 c02fcdc0 00000000 c07502b8 c07502b8 c00095c8 > ff00: c07b372c c78bc980 c053c958 0000004f 00000000 00000000 00000000 c013b43c > ff20: c7ffc890 c0552e20 0000009c c0032448 00000000 c067ff7c c06d5d94 00000006 > ff40: c7ffc897 00000006 c07552f8 c7ffc840 c074b090 00000006 c073f8dc c07ab460 > ff60: c0704594 0000009c c073f8e8 c0704d20 00000006 00000006 00000000 c0704594 > ff80: c78327a0 c052f55c 00000000 c052f55c 00000000 00000000 00000000 00000000 > ffa0: 00000000 c052f564 00000000 c000a320 00000000 00000000 00000000 00000000 > ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 > ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 bfffffff ffffefff > [<c03c4a9c>] (usbmisc_imx27_init) from [<c03c46c4>] (imx_usbmisc_init+0x2c/0x38) > [<c03c46c4>] (imx_usbmisc_init) from [<c03c5254>] > (ci_hdrc_imx_probe+0x208/0x35c) > [<c03c5254>] (ci_hdrc_imx_probe) from [<c02fdb94>] > (platform_drv_probe+0x48/0xa4) > [<c02fdb94>] (platform_drv_probe) from [<c02fc1f0>] > (driver_probe_device+0x1d0/0x278) > [<c02fc1f0>] (driver_probe_device) from [<c02fc324>] (__driver_attach+0x8c/0x90) > [<c02fc324>] (__driver_attach) from [<c02fa978>] (bus_for_each_dev+0x5c/0x8c) > [<c02fa978>] (bus_for_each_dev) from [<c02fb948>] (bus_add_driver+0xe8/0x1f8) > [<c02fb948>] (bus_add_driver) from [<c02fcdc0>] (driver_register+0x78/0xf4) > [<c02fcdc0>] (driver_register) from [<c00095c8>] (do_one_initcall+0x84/0x1f0) > [<c00095c8>] (do_one_initcall) from [<c0704d20>] > (kernel_init_freeable+0xfc/0x1c0) > [<c0704d20>] (kernel_init_freeable) from [<c052f564>] (kernel_init+0x8/0xec) > [<c052f564>] (kernel_init) from [<c000a320>] (ret_from_fork+0x14/0x34) > Code: ebf1cfb7 e5d43008 e3130001 e5953000 (e5932000) > ---[ end trace 69bc01e63a4b5221 ]--- > note: swapper[1] exited with preempt_count 1 > Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b > > ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b > > If I revert 73dea4a912b2("usb: chipidea: usbmisc_imx: delete clock > information") then the board boots fine. > > Regards, > > Fabio Estevam Sorry, a bug at former patch, it the clk_ahb has been override. Mind to try below one? >From ef644a2cfb8050c004ec2b54239fe5982ef0dcda Mon Sep 17 00:00:00 2001 From: Peter Chen <peter.chen@xxxxxxxxxxxxx> Date: Fri, 11 Sep 2015 15:50:22 +0800 Subject: [PATCH 1/1] usb: chipidea: add three clks for imx Signed-off-by: Peter Chen <peter.chen@xxxxxxxxxxxxx> --- arch/arm/boot/dts/imx27.dtsi | 19 +++-- drivers/usb/chipidea/ci_hdrc_imx.c | 140 ++++++++++++++++++++++++++++++++----- drivers/usb/chipidea/udc.c | 1 + 3 files changed, 138 insertions(+), 22 deletions(-) diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index b69be5c..d0dcf4a 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -477,7 +477,11 @@ compatible = "fsl,imx27-usb"; reg = <0x10024000 0x200>; interrupts = <56>; - clocks = <&clks IMX27_CLK_USB_IPG_GATE>; + need-three-clocks; + clocks = <&clks IMX27_CLK_USB_IPG_GATE>, + <&clks IMX27_CLK_USB_AHB_GATE>, + <&clks IMX27_CLK_USB_DIV>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 0>; status = "disabled"; }; @@ -486,7 +490,11 @@ compatible = "fsl,imx27-usb"; reg = <0x10024200 0x200>; interrupts = <54>; - clocks = <&clks IMX27_CLK_USB_IPG_GATE>; + need-three-clocks; + clocks = <&clks IMX27_CLK_USB_IPG_GATE>, + <&clks IMX27_CLK_USB_AHB_GATE>, + <&clks IMX27_CLK_USB_DIV>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 1>; dr_mode = "host"; status = "disabled"; @@ -496,7 +504,11 @@ compatible = "fsl,imx27-usb"; reg = <0x10024400 0x200>; interrupts = <55>; - clocks = <&clks IMX27_CLK_USB_IPG_GATE>; + need-three-clocks; + clocks = <&clks IMX27_CLK_USB_IPG_GATE>, + <&clks IMX27_CLK_USB_AHB_GATE>, + <&clks IMX27_CLK_USB_DIV>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 2>; dr_mode = "host"; status = "disabled"; @@ -506,7 +518,6 @@ #index-cells = <1>; compatible = "fsl,imx27-usbmisc"; reg = <0x10024600 0x200>; - clocks = <&clks IMX27_CLK_USB_AHB_GATE>; }; sahara2: sahara@10025000 { diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 867e9f3..0eec337 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -73,6 +73,12 @@ struct ci_hdrc_imx_data { struct imx_usbmisc_data *usbmisc_data; bool supports_runtime_pm; bool in_lpm; + /* SoC before i.mx6 (except imx23/imx28) needs three clks */ + bool need_three_clks; + struct clk *clk_ipg; + struct clk *clk_ahb; + struct clk *clk_per; + /* --------------------------------- */ }; /* Common functions shared by usbmisc drivers */ @@ -124,6 +130,107 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) } /* End of common functions shared by usbmisc drivers*/ +static int imx_get_clks(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + int ret = 0; + + if (data->need_three_clks) { + data->clk_ipg = devm_clk_get(dev, "ipg"); + if (IS_ERR(data->clk_ipg)) { + ret = PTR_ERR(data->clk_ipg); + dev_err(dev, + "Failed to get ipg clock, err=%d\n", ret); + return ret; + } + + data->clk_ahb = devm_clk_get(dev, "ahb"); + if (IS_ERR(data->clk_ahb)) { + ret = PTR_ERR(data->clk_ahb); + dev_err(dev, + "Failed to get ahb clock, err=%d\n", ret); + return ret; + } + + data->clk_per = devm_clk_get(dev, "per"); + if (IS_ERR(data->clk_per)) { + ret = PTR_ERR(data->clk_per); + dev_err(dev, + "Failed to get per clock, err=%d\n", ret); + return ret; + } + } else { + data->clk = devm_clk_get(dev, NULL); + if (IS_ERR(data->clk)) { + ret = PTR_ERR(data->clk); + dev_err(dev, + "Failed to get clock, err=%d\n", ret); + return ret; + } + } + + return ret; +} + +static int imx_prepare_enable_clks(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + int ret = 0; + + if (data->need_three_clks) { + ret = clk_prepare_enable(data->clk_ipg); + if (ret) { + dev_err(dev, + "Failed to prepare/enable ipg clk, err=%d\n", + ret); + return ret; + } + + ret = clk_prepare_enable(data->clk_ahb); + if (ret) { + dev_err(dev, + "Failed to prepare/enable ahb clk, err=%d\n", + ret); + goto err1; + } + + ret = clk_prepare_enable(data->clk_per); + if (ret) { + dev_err(dev, + "Failed to prepare/enable per clk, err=%d\n", + ret); + goto err2; + } + dev_info(dev, "three clock have enabled\n"); + } else { + ret = clk_prepare_enable(data->clk); + if (ret) { + dev_err(dev, + "Failed to prepare/enable clk, err=%d\n", + ret); + return ret; + } + } + +err2: + clk_disable_unprepare(data->clk_ahb); +err1: + clk_disable_unprepare(data->clk_ipg); + return ret; +} + +static void imx_disable_unprepare_clks(struct device *dev) +{ + struct ci_hdrc_imx_data *data = dev_get_drvdata(dev); + + if (data->need_three_clks) { + clk_disable_unprepare(data->clk_per); + clk_disable_unprepare(data->clk_ahb); + clk_disable_unprepare(data->clk_ipg); + } else { + clk_disable_unprepare(data->clk); + } +} static int ci_hdrc_imx_probe(struct platform_device *pdev) { @@ -137,28 +244,27 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) const struct of_device_id *of_id = of_match_device(ci_hdrc_imx_dt_ids, &pdev->dev); const struct ci_hdrc_imx_platform_flag *imx_platform_flag = of_id->data; + struct device_node *np = pdev->dev.of_node; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; + platform_set_drvdata(pdev, data); data->usbmisc_data = usbmisc_get_init_data(&pdev->dev); if (IS_ERR(data->usbmisc_data)) return PTR_ERR(data->usbmisc_data); - data->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(data->clk)) { - dev_err(&pdev->dev, - "Failed to get clock, err=%ld\n", PTR_ERR(data->clk)); - return PTR_ERR(data->clk); - } + if (of_find_property(np, "need-three-clocks", NULL)) + data->need_three_clks = true; - ret = clk_prepare_enable(data->clk); - if (ret) { - dev_err(&pdev->dev, - "Failed to prepare or enable clock, err=%d\n", ret); + ret = imx_get_clks(&pdev->dev); + if (ret) + return ret; + + ret = imx_prepare_enable_clks(&pdev->dev); + if (ret) return ret; - } data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0); if (IS_ERR(data->phy)) { @@ -201,8 +307,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto disable_device; } - platform_set_drvdata(pdev, data); - if (data->supports_runtime_pm) { pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); @@ -215,7 +319,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) disable_device: ci_hdrc_remove_device(data->ci_pdev); err_clk: - clk_disable_unprepare(data->clk); + imx_disable_unprepare_clks(&pdev->dev); return ret; } @@ -229,7 +333,7 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); } ci_hdrc_remove_device(data->ci_pdev); - clk_disable_unprepare(data->clk); + imx_disable_unprepare_clks(&pdev->dev); return 0; } @@ -241,7 +345,7 @@ static int imx_controller_suspend(struct device *dev) dev_dbg(dev, "at %s\n", __func__); - clk_disable_unprepare(data->clk); + imx_disable_unprepare_clks(dev); data->in_lpm = true; return 0; @@ -259,7 +363,7 @@ static int imx_controller_resume(struct device *dev) return 0; } - ret = clk_prepare_enable(data->clk); + ret = imx_prepare_enable_clks(dev); if (ret) return ret; @@ -274,7 +378,7 @@ static int imx_controller_resume(struct device *dev) return 0; clk_disable: - clk_disable_unprepare(data->clk); + imx_disable_unprepare_clks(dev); return ret; } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 8223fe7..f4a8da3 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1959,6 +1959,7 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci) if (!hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DC)) return -ENXIO; + printk("size of usb_request:%d\n", sizeof (struct usb_request)); rdrv = devm_kzalloc(ci->dev, sizeof(struct ci_role_driver), GFP_KERNEL); if (!rdrv) return -ENOMEM; -- 1.9.1 -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html