From mboxrd@z Thu Jan 1 00:00:00 1970 From: balbi@ti.com (Felipe Balbi) Date: Tue, 16 Jul 2013 15:37:09 +0300 Subject: Division by zero caused by CCF Message-ID: <20130716123709.GA15036@arwen.pp.htv.fi> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi, trying to get USB host verified on OMAP5 uEVM with v3.11-rc1. The clk_set_rate() call ends up in a division by zero, which is quite interesting provided the driver will only call clk_set_rate() if the clock is valid and clk_rate is != 0. [ 22.009238] Division by zero in kernel. [ 22.009250] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 3.11.0-rc1-00081-g3310d44-dirty #118 [ 22.009275] [] (unwind_backtrace+0x0/0xf0) from [] (show_stack+0x10/0x14) [ 22.009289] [] (show_stack+0x10/0x14) from [] (dump_stack+0x70/0x8c) [ 22.009304] [] (dump_stack+0x70/0x8c) from [] (Ldiv0+0x8/0x10) [ 22.009319] [] (Ldiv0+0x8/0x10) from [] (clk_divider_set_rate+0x10/0xdc) [ 22.009331] [] (clk_divider_set_rate+0x10/0xdc) from [] (clk_change_rate+0x38/0xb0) [ 22.009341] [] (clk_change_rate+0x38/0xb0) from [] (clk_set_rate+0x70/0xa8) [ 22.009354] [] (clk_set_rate+0x70/0xa8) from [] (nop_usb_xceiv_probe+0x1fc/0x2f8) [ 22.009369] [] (nop_usb_xceiv_probe+0x1fc/0x2f8) from [] (platform_drv_probe+0x18/0x1c) [ 22.009380] [] (platform_drv_probe+0x18/0x1c) from [] (really_probe+0x70/0x1f4) [ 22.009390] [] (really_probe+0x70/0x1f4) from [] (driver_probe_device+0x30/0x48) [ 22.009401] [] (driver_probe_device+0x30/0x48) from [] (__driver_attach+0x94/0x98) [ 22.009411] [] (__driver_attach+0x94/0x98) from [] (bus_for_each_dev+0x54/0x88) [ 22.009420] [] (bus_for_each_dev+0x54/0x88) from [] (bus_add_driver+0xdc/0x29c) [ 22.009430] [] (bus_add_driver+0xdc/0x29c) from [] (driver_register+0x78/0x190) [ 22.009440] [] (driver_register+0x78/0x190) from [] (do_one_initcall+0x34/0x164) [ 22.009453] [] (do_one_initcall+0x34/0x164) from [] (do_basic_setup+0x90/0xc4) [ 22.009466] [] (do_basic_setup+0x90/0xc4) from [] (kernel_init_freeable+0x74/0x110) [ 22.009478] [] (kernel_init_freeable+0x74/0x110) from [] (kernel_init+0x8/0xe4) [ 22.009491] [] (kernel_init+0x8/0xe4) from [] (ret_from_fork+0x14/0x2c) I believe the problem is the actual division reaching clk_divider_set_rate(). drivers/clk/clk-divider.c::clk_divider_set_rate() | static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, | unsigned long parent_rate) | { | struct clk_divider *divider = to_clk_divider(hw); | unsigned int div, value; | unsigned long flags = 0; | u32 val; | | div = parent_rate / rate; right here, but how come rate would zero provided driver checks for it as below. drivers/usb/phy/phy-nop.c::nop_usb_xceiv_probe() | if (!IS_ERR(nop->clk) && clk_rate) { | err = clk_set_rate(nop->clk, clk_rate); | if (err) { | dev_err(&pdev->dev, "Error setting clock rate\n"); | return err; | } | } I've added a few prints around CCF to try and track what's going on: [ 21.592690] ====> nop_usb_xceiv_probe rate 19200000 [ 21.592700] ====> clk_set_rate rate 19200000 [ 21.592707] ====> clk_calc_new_rates rate 19200000 [ 21.592713] ====> clk_divider_round_rate rate 19200000 [ 21.592719] ====> clk_divider_bestdiv rate 19200000 [ 21.592726] ====> clk_change_rate best_parent_rate 0 [ 21.592732] ====> clk_divider_set_rate rate 0 [ 21.592737] Division by zero in kernel. [ 21.592747] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G W 3.11.0-rc1-00081-g3310d44-dirty #121 [ 21.592773] [] (unwind_backtrace+0x0/0xf0) from [] (show_stack+0x10/0x14) [ 21.592787] [] (show_stack+0x10/0x14) from [] (dump_stack+0x70/0x8c) [ 21.592803] [] (dump_stack+0x70/0x8c) from [] (Ldiv0+0x8/0x10) [ 21.592819] [] (Ldiv0+0x8/0x10) from [] (clk_divider_set_rate+0x2c/0x100) [ 21.592831] [] (clk_divider_set_rate+0x2c/0x100) from [] (clk_change_rate+0x48/0xe0) [ 21.592841] [] (clk_change_rate+0x48/0xe0) from [] (clk_set_rate+0x8c/0xc0) [ 21.592855] [] (clk_set_rate+0x8c/0xc0) from [] (nop_usb_xceiv_probe+0x20c/0x304) [ 21.592869] [] (nop_usb_xceiv_probe+0x20c/0x304) from [] (platform_drv_probe+0x18/0x1c) [ 21.592880] [] (platform_drv_probe+0x18/0x1c) from [] (really_probe+0x70/0x1f4) [ 21.592891] [] (really_probe+0x70/0x1f4) from [] (driver_probe_device+0x30/0x48) [ 21.592901] [] (driver_probe_device+0x30/0x48) from [] (__driver_attach+0x94/0x98) [ 21.592911] [] (__driver_attach+0x94/0x98) from [] (bus_for_each_dev+0x54/0x88) [ 21.592921] [] (bus_for_each_dev+0x54/0x88) from [] (bus_add_driver+0xdc/0x29c) [ 21.592930] [] (bus_add_driver+0xdc/0x29c) from [] (driver_register+0x78/0x190) [ 21.592941] [] (driver_register+0x78/0x190) from [] (do_one_initcall+0x34/0x164) [ 21.592954] [] (do_one_initcall+0x34/0x164) from [] (do_basic_setup+0x90/0xc4) [ 21.592966] [] (do_basic_setup+0x90/0xc4) from [] (kernel_init_freeable+0x74/0x110) [ 21.592980] [] (kernel_init_freeable+0x74/0x110) from [] (kernel_init+0x8/0xe4) [ 21.592992] [] (kernel_init+0x8/0xe4) from [] (ret_from_fork+0x14/0x2c) even though driver passed 19.2MHz, best_parent_rate ends up being zero which triggers the division by zero above. cheers -- balbi -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: