On Thu, Apr 10, 2014 at 03:36:56PM +0300, Tomi Valkeinen wrote:
Hi,
On 10/04/14 14:33, Russell King - ARM Linux wrote:
It looks like this is caused by something in the depths of OMAPDSS. I see a failure to allocate an order-9 page (2MB), which then provokes the OMAP DSS cleanup paths.
Is CONFIG_CMA disabled? I don't think we're able to allocate the framebuffer without CMA, except for very very small framebuffers.
We get to dss_dispc_uninitialize_irq(), which calls devm_free_irq(). Because CONFIG_DEBUG_SHIRQ is enabled, __free_irq ends up calling the handler, and we hang somewhere in the handler.
One for Tomi I think.
My previous boots have succeeded inspite of the allocation failure, so something has changed between 18a1a7a1d862 and a7963eb7f4c4 (Linus' commits) which has caused this to hang.
The last few messages from my debugging are:
omapfb omapfb: failed to allocate framebuffer omapfb omapfb: failed to allocate fbmem omapdss_compat_uninit() APPLY: dss_dispc_uninitialize_irq() omapdss_dispc 58001000.dispc: find_dr: dr=c1363dc0 devm_irq_match: irq 57,57 data c0c0a350,c0c0a350 devm_free_irq: 57 c0c0a350 genirq: __free_irq: calling omap_dispc_irq_handler+0x0/0x11c
The dss irq handler presumes that the DSS hardware is enabled, which is not the case at uninitialize time. So it crashes when the handler tries to access DISPC registers.
This doesn't happen normally, as the DSS IRQ is only shared between two DSS submodules, DISPC and DSI, and when one of them is enabled, effectively both are enabled. But even so, the code is not correct.
That said, I don't understand why it breaks now but not earlier, nothing has changed around that. Hmm, except now we use proper DT bindings, so the IRQ comes from DT. But I don't see why that would affect this.
It looks like the updates stopped DSI from initialising.
Before:
backlight.9 supply power not found, using dummy regulator pwm-backlight backlight.9: unable to request PWM, trying legacy API pwm-backlight backlight.9: unable to request legacy PWM platform backlight.9: Driver pwm-backlight requests probe deferral ------------[ cut here ]------------ WARNING: CPU: 1 PID: 1 at drivers/video/omap2/dss/dss.c:481 dss_set_fck_rate+0x88/0xb4() clk rate mismatch: 153600000 != 170666666 Modules linked in: CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W 3.14.0+ #1 ... [<c02221b4>] (dss_set_fck_rate) from [<c0606bbc>] (omap_dsshw_probe+0x1ec/0x304) r6:c16afc10 r5:5b8d8000 r4:00000001 [<c06069d0>] (omap_dsshw_probe) from [<c028b7c8>] (platform_drv_probe+0x24/0x54) r7:00000000 r6:00000000 r5:c0654e24 r4:c16afc10 [<c028b7a4>] (platform_drv_probe) from [<c0289e68>] (really_probe+0xf8/0x2e8) ... ---[ end trace 3406ff24bd97382f ]--- OMAP DSS rev 4.0 omapdss_dsi.0 supply vdds_dsi not found, using dummy regulator omapdss_hdmi supply vdda_hdmi_dac not found, using dummy regulator omapdss_dsi.1 supply vdds_dsi not found, using dummy regulator swapper/0: page allocation failure: order:9, mode:0xd0 CPU: 1 PID: 1 Comm: swapper/0 Tainted: G W 3.14.0+ #1
After:
platform backlight.9: Driver pwm-backlight requests probe deferral ------------[ cut here ]------------ WARNING: CPU: 1 PID: 1 at drivers/video/omap2/dss/dss.c:483 dss_set_fck_rate+0x88/0xb4() clk rate mismatch: 153600000 != 170666666 ... ---[ end trace 3406ff24bd97382f ]--- OMAP DSS rev 4.0 panel-dsi-cm display.14: Failed to connect to video source omapfb omapfb: failed to connect default display omapfb omapfb: failed to init overlay connections omapfb omapfb: failed to setup omapfb platform omapfb: Driver omapfb requests probe deferral ... backlight.9 supply power not found, using dummy regulator kworker/u4:0: page allocation failure: order:9, mode:0xd0 CPU: 1 PID: 6 Comm: kworker/u4:0 Tainted: G W 3.14.0+ #1 Workqueue: deferwq deferred_probe_work_func ... omapfb omapfb: failed to allocate framebuffer omapfb omapfb: failed to allocate fbmem
I wonder what's the correct way to handle shared interrupts... Should I always keep the HW enabled when an irq handler is registered, or should I check whether the HW is enabled or not in the irq handler?
If the interrupt is registered as a shared interrupt, it means that the interrupt may be shared with another device, which may trigger that interrupt at any moment, whether or not your hardware is accessible.
That means you must: - have some way to make it accessible in the interrupt handler - have some way to know that the interrupt could never have come from the hardware (and this return IRQ_NONE) - not register it as a shared interrupt, thus ensuring that no other device driver could register and raise an interrupt when you're not ready to deal with it
PS, as you can see from the above, there's another bug in OMAPDSS with dss_set_fck_rate().