Re: [PATCH] ARM: omap2plus_defconfig: Enable MUSB DMA support
On Fri, Aug 28, 2015 at 12:19:42PM -0700, Tony Lindgren wrote: > With recent MUSB changes we can now build in support for multiple > DMA implementations. So let's enable DMA by default to make life > easier for distro use. > > Cc: Felipe Balbi > Signed-off-by: Tony Lindgren Acked-by: Felipe Balbi > --- > arch/arm/configs/omap2plus_defconfig | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/arch/arm/configs/omap2plus_defconfig > b/arch/arm/configs/omap2plus_defconfig > index 789fa5a8..1d5f80f 100644 > --- a/arch/arm/configs/omap2plus_defconfig > +++ b/arch/arm/configs/omap2plus_defconfig > @@ -350,6 +350,8 @@ CONFIG_USB_MUSB_HDRC=m > CONFIG_USB_MUSB_OMAP2PLUS=m > CONFIG_USB_MUSB_AM35X=m > CONFIG_USB_MUSB_DSPS=m > +CONFIG_USB_INVENTRA_DMA=y > +CONFIG_USB_TI_CPPI41_DMA=y > CONFIG_USB_DWC3=m > CONFIG_USB_TEST=m > CONFIG_AM335X_PHY_USB=y > -- > 2.1.4 > -- balbi signature.asc Description: Digital signature
Re: CONFIG_DEBUG_SHIRQ and PM
On Tue, 25 Aug 2015, Felipe Balbi wrote: > Hi Ingo, Thanks for not cc'ing the irq maintainer > I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using > devm_request_*irq(). > > If we using devm_request_*irq(), that irq will be freed after device > drivers' ->remove() gets called. If on ->remove(), we're calling > pm_runtime_put_sync(); pm_runtime_disable(), device's clocks might get > gated and, because we do an extra call to the device's IRQ handler when > CONFIG_DEBUG_SHIRQ=y, we might trigger an abort exception if, inside the > IRQ handler, we try to read a register which is clocked by the device's > clock. > > This is, of course, really old code which has been in tree for many, > many years. I guess nobody has been running their tests in the setup > mentioned above (CONFIG_DEBUG_SHIRQ=y, pm_runtime_put_sync() on > ->remove(), a register read on IRQ handler, and a shared IRQ handler), > so that's why we never caught this before. > > Disabling CONFIG_DEBUG_SHIRQ, of course, makes the problem go away, but > if driver *must* be ready to receive, and handle, an IRQ even during > module removal, I wonder what the IRQ handler should do. We can't, in > most cases, call pm_runtime_put_sync() from IRQ handler. Well, a shared interrupt handler must handle this situation, no matter what. Assume the following: irqreturn_t dev_irq(int irq, void *data) { struct devdata *dd = data; u32 state; state = readl(dd->base); ... } void module_exit(void) { /* Write to the device interrupt register */ disable_device_irq(dd->base); /* * After this point the device does not longer * raise an interrupt */ iounmap(dd->base); free_irq(); If the other device which shares the interrupt line raises an interrupt after the unmap and before free_irq() removed the device handler from the irq, the machine is toast, because the dev_irq handler is still called. If the handler is shut down after critical parts of the driver/device are shut down, then you can - either can change the setup/teardown ordering disable_device_irq(dd->base); free_irq(); iounmap(dd->base); - or have a proper flag in the private data which tells the interrupt handler to sod off. irqreturn_t dev_irq(int irq, void *data) { struct devdata *dd = data; if (dd->shutdown) return IRQ_NONE; ... void module_exit(void) { disable_device_irq(dd->base); dd->shutdown = 1; /* On an SMP machine you also need: */ synchronize_irq(dd->irq); So for the problem at hand, the devm magic needs to make sure that the crucial parts are still alive when the devm allocated irq is released. I have no idea how that runtime PM stuff is integrated into devm (I fear not at all), so it's hard to give you a proper advise on that. Thanks, tglx -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: omap2plus_defconfig: Enable MUSB DMA support
With recent MUSB changes we can now build in support for multiple DMA implementations. So let's enable DMA by default to make life easier for distro use. Cc: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/configs/omap2plus_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 789fa5a8..1d5f80f 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -350,6 +350,8 @@ CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_OMAP2PLUS=m CONFIG_USB_MUSB_AM35X=m CONFIG_USB_MUSB_DSPS=m +CONFIG_USB_INVENTRA_DMA=y +CONFIG_USB_TI_CPPI41_DMA=y CONFIG_USB_DWC3=m CONFIG_USB_TEST=m CONFIG_AM335X_PHY_USB=y -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: OMAP2+: Fix booting if no timer parent clock is available
When bringing up a new SoC we needlessly prevent booting at timer init if timer clock_set_parent fails. This can fail if the system is booting on bootloader configured PLL values until the clock framework driver for the PLL is implemented. Let's just WARN instead, this will provide helpful information for anybody bringing up a new SoC what needs to be fixed. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/timer.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index e4d8701..a556551 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -297,12 +297,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (IS_ERR(src)) return PTR_ERR(src); - r = clk_set_parent(timer->fclk, src); - if (r < 0) { - pr_warn("%s: %s cannot set source\n", __func__, oh->name); - clk_put(src); - return r; - } + WARN(clk_set_parent(timer->fclk, src) < 0, +"Cannot set timer parent clock, no PLL clock driver?"); clk_put(src); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 02/15] mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get
* Olof Johansson [150828 11:11]: > Hi, > > On Thu, Aug 27, 2015 at 2:13 AM, Kishon Vijay Abraham I wrote: > > Now return error only if the return value of > > devm_regulator_get_optional() is not the same as -ENODEV, since with > > -EPROBE_DEFER, the regulator can be obtained later and all other > > errors are fatal. > > > > Signed-off-by: Kishon Vijay Abraham I > > Tested-by: Tony Lindgren > > I bisected boot failures on Panda ES with multi_v7_defconfig down to > this commit on last night's -next build: > > http://arm-soc.lixom.net/bootlogs/next/next-20150828/pandaes-arm-multi_v7_defconfig.html MMC is working for me at least on Duovero. Interesting that you also have all kind of errors there, I guess this is some older revision of the board. Anyways, Kishon, care to look into what might be causing this? Regards, Tony -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] net/smsc911x: Fix deferred probe for interrupt
The interrupt handler may not be available when smsc911x probes if the interrupt handler is a GPIO controller for example. Let's fix that by adding handling for -EPROBE_DEFER. Cc: Steve Glendinning Signed-off-by: Tony Lindgren --- drivers/net/ethernet/smsc/smsc911x.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 959aeea..cb9f166f 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2435,7 +2435,10 @@ static int smsc911x_drv_probe(struct platform_device *pdev) res_size = resource_size(res); irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq == -EPROBE_DEFER) { + retval = -EPROBE_DEFER; + goto out_0; + } else if (irq <= 0) { pr_warn("Could not allocate irq resource\n"); retval = -ENODEV; goto out_0; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] gpio: omap: Fix gpiochip_add() handling for deferred probe
Currently we gpio-omap breaks if gpiochip_add() returns -EPROBE_DEFER: [0.57] gpiochip_add: GPIOs 0..31 (gpio) failed to register [0.57] omap_gpio 4831.gpio: Could not register gpio chip -517 ... [3.67] omap_gpio 4831.gpio: Unbalanced pm_runtime_enable! Let's fix the issue by adding the missing pm_runtime_put() on error. Cc: Grygorii Strashko Cc: Javier Martinez Canillas Cc: Kevin Hilman Cc: Santosh Shilimkar Signed-off-by: Tony Lindgren --- drivers/gpio/gpio-omap.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index b0c57d5..f09bf0b 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1232,8 +1232,11 @@ static int omap_gpio_probe(struct platform_device *pdev) omap_gpio_mod_init(bank); ret = omap_gpio_chip_init(bank, irqc); - if (ret) + if (ret) { + pm_runtime_put_sync(bank->dev); + pm_runtime_disable(bank->dev); return ret; + } omap_gpio_show_rev(bank); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 02/15] mmc: host: omap_hsmmc: return on fatal errors from omap_hsmmc_reg_get
Hi, On Thu, Aug 27, 2015 at 2:13 AM, Kishon Vijay Abraham I wrote: > Now return error only if the return value of > devm_regulator_get_optional() is not the same as -ENODEV, since with > -EPROBE_DEFER, the regulator can be obtained later and all other > errors are fatal. > > Signed-off-by: Kishon Vijay Abraham I > Tested-by: Tony Lindgren I bisected boot failures on Panda ES with multi_v7_defconfig down to this commit on last night's -next build: http://arm-soc.lixom.net/bootlogs/next/next-20150828/pandaes-arm-multi_v7_defconfig.html -Olof -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] ARM: OMAP2+: omap-device: fix race deferred probe of omap_hsmmc vs omap_device_late_init
Kernel fails to boot 50% of times (form build to build) with RT-patchset applied due to the following race - on late boot stages deferred_probe_work_func->omap_hsmmc_probe races with omap_device_late_ini. The same issue has been reported now on linux-next (4.3) by Keerthy [1] late_initcall - deferred_probe_initcal() tries to re-probe all pending driver's probe. - later on, some driver is probing in this case It's cpsw.c (but could be any other drivers) cpsw_init - platform_driver_register - really_probe - driver_bound - driver_deferred_probe_trigger and boot proceed. So, at this moment we have deferred_probe_work_func scheduled. late_initcall_sync - omap_device_late_init - omap_device_idle CPU1CPU2 - deferred_probe_work_func - really_probe - omap_hsmmc_probe - pm_runtime_get_sync late_initcall_sync - omap_device_late_init if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { if (od->_state == OMAP_DEVICE_STATE_ENABLED) { - omap_device_idle [ops - IP is disabled] - [fail] - pm_runtime_put_sync - omap_hsmmc_runtime_suspend [ooops!] == log == omap_hsmmc 480b4000.mmc: unable to get vmmc regulator -517 davinci_mdio 48485000.mdio: davinci mdio revision 1.6 davinci_mdio 48485000.mdio: detected phy mask fff3 libphy: 48485000.mdio: probed davinci_mdio 48485000.mdio: phy[2]: device 48485000.mdio:02, driver unknown davinci_mdio 48485000.mdio: phy[3]: device 48485000.mdio:03, driver unknown omap_hsmmc 480b4000.mmc: unable to get vmmc regulator -517 cpsw 48484000.ethernet: Detected MACID = b4:99:4c:c7:d2:48 cpsw 48484000.ethernet: cpsw: Detected MACID = b4:99:4c:c7:d2:49 hctosys: unable to open rtc device (rtc0) omap_hsmmc 480b4000.mmc: omap_device_late_idle: enabled but no driver. Idling ldousb: disabling Unhandled fault: imprecise external abort (0x1406) at 0x [] *pgd= Internal error: : 1406 [#1] PREEMPT SMP ARM Modules linked in: CPU: 1 PID: 58 Comm: kworker/u4:1 Not tainted 4.1.2-rt1-00467-g6da3c0a-dirty #5 Hardware name: Generic DRA74X (Flattened Device Tree) Workqueue: deferwq deferred_probe_work_func task: ee6ddb00 ti: edd3c000 task.ti: edd3c000 PC is at omap_hsmmc_runtime_suspend+0x1c/0x12c LR is at _od_runtime_suspend+0xc/0x24 pc : []lr : []psr: a013 sp : edd3dda0 ip : ee6ddb00 fp : c07be540 r10: r9 : c07be540 r8 : 0008 r7 : r6 : ee646c10 r5 : ee646c10 r4 : edd79380 r3 : fa0b4100 r2 : r1 : r0 : ee646c10 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 8000406a DAC: 0015 Process kworker/u4:1 (pid: 58, stack limit = 0xedd3c218) Stack: (0xedd3dda0 to 0xedd3e000) dda0: ee646c70 ee646c10 c0029584 0008 c0029590 ee646c70 ee646c10 ddc0: c0029584 c03adfb8 ee646c10 0004 000c c03adff0 ee646c10 0004 dde0: 000c c03ae4ec edd3c000 ee646c10 0004 ee646c70 0004 de00: fa0b4000 c03aec20 ee6ddb00 ee646c10 0004 ee646c70 ee646c10 fdfb de20: edd79380 fa0b4000 c03aee90 fdfb edd79000 ee646c00 c0474290 de40: edda24c0 edd79380 edc81f00 0200 0001 c06dd488 de60: edda3960 ee646c10 ee646c10 c0824cc4 fdfb c0880c94 0002 edc92600 de80: c0836378 c03a7f84 ee646c10 c0824cc4 c0880c80 c0880c94 c03a6568 dea0: ee646c10 c03a66ac ee4f8000 0001 edc92600 c03a4b40 dec0: ee404c94 edc83c4c ee646c10 ee646c10 ee646c44 c03a63c4 ee646c10 ee646c10 dee0: c0814448 c03a5aa8 ee646c10 c0814220 edd3c000 c03a5ec0 c0814250 ee6be400 df00: edd3c000 c004e5bc ee6ddb01 0078 ee6ddb00 ee4f8000 ee6be418 edd3c000 df20: ee4f8028 0088 c0836045 ee4f8000 ee6be400 c004e928 ee4f8028 df40: c004e8ec ee6bf1c0 ee6be400 c004e8ec df60: c0053450 2e56fa97 afdffbd7 ee6be400 df80: edd3df80 edd3df80 edd3df90 edd3df90 edd3dfac ee6bf1c0 dfa0: c0053384 c000f668 dfc0: dfe0: 0013 f1fc9d7e febfbdff [] (omap_hsmmc_runtime_suspend) from [] (_od_runtime_suspend+0xc/0x24) [] (_od_runtime_suspend) from [] (__rpm_callback+0x24/0x3c) [] (__rpm_callback) from [] (rpm_callback+0x20/0x80) [] (rpm_callback) from [] (rpm_suspend+0xe4/0x618) [] (rpm_suspend) from [] (__pm_runtime_idle+0x60/0x80) [] (__pm_runtime_idle) from [] (omap_hsmmc_probe+0x6bc/0xa7c) [] (omap_hsmmc_probe) from [] (platform_drv_probe+0x44/0xa4) [] (platform_drv_probe) fr
[PATCH v4] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
Reconfigure and restart audio when display is enabled, if audio playback was active before. This is needed in a situation when an audio+video stream application opens the audio stream before the video. When video stream is opened the display mode may change and that aborts audio playback, because the display is momentarily turned off. The audio configuration is stored when it is successfully applied and a boolean is set when the audio playback is started and unset when stopped. This data is used to reconfigure the audio when display is re-enabled. The audio playback is aborted if the reconfiguration fails. A new spin lock is introduced in order to protect state variables related to audio playback status. This is needed for the transition from display enabled state (when audio start/stop commands can be written to HW) to display disabled state (when audio start/stop commands update only the hdmi.audio_playing variable) to always serialize correctly with the start/stop audio commands. The already existing mutex can not be used, because the audio start and stop commands are executed in atomic context. For example: when display is turned back on we take the spinlock and we can be sure that the audio start/stop status will not change while we update the HW according to hdmi.audio_playing state and set hdmi.display_enabled to true. After releasing the lock hdmi.display_enabled is true and all audio_start and audio_stop commands write their stuff directly to HW. Signed-off-by: Jyri Sarha --- Fixed one bad sentece in the description. drivers/video/fbdev/omap2/dss/hdmi.h | 9 - drivers/video/fbdev/omap2/dss/hdmi4.c | 66 +- drivers/video/fbdev/omap2/dss/hdmi5.c | 76 --- 3 files changed, 124 insertions(+), 27 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index e4a32fe..53616b0 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -351,13 +351,20 @@ struct omap_hdmi { struct regulator *vdda_reg; bool core_enabled; - bool display_enabled; struct omap_dss_device output; struct platform_device *audio_pdev; void (*audio_abort_cb)(struct device *dev); int wp_idlemode; + + bool audio_configured; + struct omap_dss_audio audio_config; + + /* This lock should be taken when booleans bellow are touched. */ + spinlock_t audio_playing_lock; + bool audio_playing; + bool display_enabled; }; #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 6d3aa3f..94c8d55 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -321,9 +321,22 @@ static int read_edid(u8 *buf, int len) return r; } +static void hdmi_start_audio_stream(struct omap_hdmi *hd) +{ + hdmi_wp_audio_enable(&hd->wp, true); + hdmi4_audio_start(&hd->core, &hd->wp); +} + +static void hdmi_stop_audio_stream(struct omap_hdmi *hd) +{ + hdmi4_audio_stop(&hd->core, &hd->wp); + hdmi_wp_audio_enable(&hd->wp, false); +} + static int hdmi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &hdmi.output; + unsigned long flags; int r = 0; DSSDBG("ENTER hdmi_display_enable\n"); @@ -342,7 +355,21 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev) goto err0; } + if (hdmi.audio_configured) { + r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, + hdmi.cfg.timings.pixelclock); + if (r) { + DSSERR("Error restoring audio configuration: %d", r); + hdmi.audio_abort_cb(&hdmi.pdev->dev); + hdmi.audio_configured = false; + } + } + + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + if (hdmi.audio_configured && hdmi.audio_playing) + hdmi_start_audio_stream(&hdmi); hdmi.display_enabled = true; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); mutex_unlock(&hdmi.lock); return 0; @@ -354,17 +381,19 @@ err0: static void hdmi_display_disable(struct omap_dss_device *dssdev) { + unsigned long flags; + DSSDBG("Enter hdmi_display_disable\n"); mutex_lock(&hdmi.lock); - if (hdmi.audio_pdev && hdmi.audio_abort_cb) - hdmi.audio_abort_cb(&hdmi.audio_pdev->dev); + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + hdmi_stop_audio_stream(&hdmi); + hdmi.display_enabled = false; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); hdmi_power_off_full(dssdev); - hdmi.display_enabled = false; - mutex_unlock(&hdmi.lock); } @@ -568,6 +597,8 @@ static int hdmi_audio_shutdown(struc
[PATCH v3] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
Reconfigure and restart audio when display is enabled, if audio playback was active before. This is needed in a situation when an audio+video stream application opens the audio stream before the video. When video stream is opened the display mode may change and that would aborted audio playback, because the display is momentarily turned off. The audio configuration is stored when it is successfully applied and a boolean is set when the audio playback is started and unset when stopped. This data is used to reconfigure the audio when display is re-enabled. The audio playback is aborted if the reconfiguration fails. A new spin lock is introduced in order to protect state variables related to audio playback status. This is needed for the transition from display enabled state (when audio start/stop commands can be written to HW) to display disabled state (when audio start/stop commands update only the hdmi.audio_playing variable) to always serialize correctly with the start/stop audio commands. The already existing mutex can not be used, because the audio start and stop commands are executed in atomic context. For example: when display is turned back on we take the spinlock and we can be sure that the audio start/stop status will not change while we update the HW according to hdmi.audio_playing state and set hdmi.display_enabled to true. After releasing the lock hdmi.display_enabled is true and all audio_start and audio_stop commands write their stuff directly to HW. Signed-off-by: Jyri Sarha --- drivers/video/fbdev/omap2/dss/hdmi.h | 9 - drivers/video/fbdev/omap2/dss/hdmi4.c | 66 +- drivers/video/fbdev/omap2/dss/hdmi5.c | 76 --- 3 files changed, 124 insertions(+), 27 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index e4a32fe..53616b0 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -351,13 +351,20 @@ struct omap_hdmi { struct regulator *vdda_reg; bool core_enabled; - bool display_enabled; struct omap_dss_device output; struct platform_device *audio_pdev; void (*audio_abort_cb)(struct device *dev); int wp_idlemode; + + bool audio_configured; + struct omap_dss_audio audio_config; + + /* This lock should be taken when booleans bellow are touched. */ + spinlock_t audio_playing_lock; + bool audio_playing; + bool display_enabled; }; #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 6d3aa3f..94c8d55 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -321,9 +321,22 @@ static int read_edid(u8 *buf, int len) return r; } +static void hdmi_start_audio_stream(struct omap_hdmi *hd) +{ + hdmi_wp_audio_enable(&hd->wp, true); + hdmi4_audio_start(&hd->core, &hd->wp); +} + +static void hdmi_stop_audio_stream(struct omap_hdmi *hd) +{ + hdmi4_audio_stop(&hd->core, &hd->wp); + hdmi_wp_audio_enable(&hd->wp, false); +} + static int hdmi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &hdmi.output; + unsigned long flags; int r = 0; DSSDBG("ENTER hdmi_display_enable\n"); @@ -342,7 +355,21 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev) goto err0; } + if (hdmi.audio_configured) { + r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, + hdmi.cfg.timings.pixelclock); + if (r) { + DSSERR("Error restoring audio configuration: %d", r); + hdmi.audio_abort_cb(&hdmi.pdev->dev); + hdmi.audio_configured = false; + } + } + + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + if (hdmi.audio_configured && hdmi.audio_playing) + hdmi_start_audio_stream(&hdmi); hdmi.display_enabled = true; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); mutex_unlock(&hdmi.lock); return 0; @@ -354,17 +381,19 @@ err0: static void hdmi_display_disable(struct omap_dss_device *dssdev) { + unsigned long flags; + DSSDBG("Enter hdmi_display_disable\n"); mutex_lock(&hdmi.lock); - if (hdmi.audio_pdev && hdmi.audio_abort_cb) - hdmi.audio_abort_cb(&hdmi.audio_pdev->dev); + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + hdmi_stop_audio_stream(&hdmi); + hdmi.display_enabled = false; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); hdmi_power_off_full(dssdev); - hdmi.display_enabled = false; - mutex_unlock(&hdmi.lock); } @@ -568,6 +597,8 @@ static int hdmi_audio_shutdown(struct device *dev) mutex_lock(
Re: [PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
On 08/28/15 16:04, Tomi Valkeinen wrote: ... The question is (which was my point in the earlier mail), we already have mutex, so why a new spinlock? I think the answer is that audio start/stop (anything else?) are called in atomic context, so mutex cannot be used. Yes, that is correct. Also (not exactly related to this patch), if the audio callbacks must be atomic, could we use a workqueue to run the audio start/stop work in non-atomic context? Protecting the whole hdmi state with a single mutex would be much nicer. The reason why the audio start and stop are done in atomic context is for audio synchronization to other audio devices or video stream to be more accurate. I guess in theory a work queue could be used to serialize the audio commands, but that would ruin the whole point of why the start and stop commands are atomic in the first place. Cheers, Jyri -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
Hi, On 28/08/15 15:24, Jyri Sarha wrote: > Reconfigure and restart audio when display is enabled, if audio > playback was active before. The audio configuration is stored when is 'is' -> 'it' above > is successfully applied and a boolean is set when playback has started > and unset when stopped. This data is used to reconfigure the audio > when display is re-enabled. Abort audio playback if reconfiguration > fails. It would be good to start the description by telling what the current problem is. And probably the subject could also be better... This fixes the audio playback when a video mode change happens (or such), right? > A new spin lock is introduced in order to protect state variables > related to audio playback status. This is needed for the transitions > from display enabled state (when audio start/stop commands can be > written to HW) to display disabled state (when audio start/stop > commands update only the hdmi.audio_playing variable) to always > serialize correctly with the start/stop audio commands. > > For example: when display is turned back on we take the spinlock and > we can be sure that the audio start/stop status won't change while we > update the HW according to hdmi.audio_playing state and set > hdmi.display_enabled to true. After releasing the lock > hdmi.display_enabled is true and all audio_start and audio_stop > commands write their stuff directly to HW. The question is (which was my point in the earlier mail), we already have mutex, so why a new spinlock? I think the answer is that audio start/stop (anything else?) are called in atomic context, so mutex cannot be used. Also (not exactly related to this patch), if the audio callbacks must be atomic, could we use a workqueue to run the audio start/stop work in non-atomic context? Protecting the whole hdmi state with a single mutex would be much nicer. > Signed-off-by: Jyri Sarha > --- > I dropped the ASoC maintainers from the recipient list as this patch > hardly concerns them. > > drivers/video/fbdev/omap2/dss/hdmi.h | 9 +++- > drivers/video/fbdev/omap2/dss/hdmi4.c | 69 +- > drivers/video/fbdev/omap2/dss/hdmi5.c | 79 > --- > 3 files changed, 130 insertions(+), 27 deletions(-) > > diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h > b/drivers/video/fbdev/omap2/dss/hdmi.h > index e4a32fe..e48aefd 100644 > --- a/drivers/video/fbdev/omap2/dss/hdmi.h > +++ b/drivers/video/fbdev/omap2/dss/hdmi.h > @@ -351,13 +351,20 @@ struct omap_hdmi { > struct regulator *vdda_reg; > > bool core_enabled; > - bool display_enabled; > > struct omap_dss_device output; > > struct platform_device *audio_pdev; > void (*audio_abort_cb)(struct device *dev); > int wp_idlemode; > + > + bool audio_configured; > + struct omap_dss_audio audio_config; > + > + /* This lock should be taken when booleas bellow is touched. */ typo above. Otherwise, looks much cleaner than the previous one. I tested it and worked fine for me: I could play audio while turning on and off the video output, and the audio would resume, except when the video was off for long enough. Tomi signature.asc Description: OpenPGP digital signature
Re: [PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
On 08/28/15 15:24, Jyri Sarha wrote: @@ -565,9 +594,14 @@ out: static int hdmi_audio_shutdown(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); + unsigned long flags; mutex_lock(&hd->lock); hd->audio_abort_cb = NULL; + hd->audio_configured = false; + spin_lock_irqsave(&hd->audio_playing_lock, flags); + hd->audio_playing = false; + spin_unlock_irqrestore(&hd->audio_playing_lock, flags); BTW, This extra locking (and the corresponding change in hdmi5.c) should not be needed. But it does not harm either. I'll fix that, but I'll wait first if there is anything else fix. Best regards, Jyri -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
Reconfigure and restart audio when display is enabled, if audio playback was active before. The audio configuration is stored when is is successfully applied and a boolean is set when playback has started and unset when stopped. This data is used to reconfigure the audio when display is re-enabled. Abort audio playback if reconfiguration fails. A new spin lock is introduced in order to protect state variables related to audio playback status. This is needed for the transitions from display enabled state (when audio start/stop commands can be written to HW) to display disabled state (when audio start/stop commands update only the hdmi.audio_playing variable) to always serialize correctly with the start/stop audio commands. For example: when display is turned back on we take the spinlock and we can be sure that the audio start/stop status won't change while we update the HW according to hdmi.audio_playing state and set hdmi.display_enabled to true. After releasing the lock hdmi.display_enabled is true and all audio_start and audio_stop commands write their stuff directly to HW. Signed-off-by: Jyri Sarha --- I dropped the ASoC maintainers from the recipient list as this patch hardly concerns them. drivers/video/fbdev/omap2/dss/hdmi.h | 9 +++- drivers/video/fbdev/omap2/dss/hdmi4.c | 69 +- drivers/video/fbdev/omap2/dss/hdmi5.c | 79 --- 3 files changed, 130 insertions(+), 27 deletions(-) diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index e4a32fe..e48aefd 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -351,13 +351,20 @@ struct omap_hdmi { struct regulator *vdda_reg; bool core_enabled; - bool display_enabled; struct omap_dss_device output; struct platform_device *audio_pdev; void (*audio_abort_cb)(struct device *dev); int wp_idlemode; + + bool audio_configured; + struct omap_dss_audio audio_config; + + /* This lock should be taken when booleas bellow is touched. */ + spinlock_t audio_playing_lock; + bool audio_playing; + bool display_enabled; }; #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 6d3aa3f..6b9817a 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -321,9 +321,22 @@ static int read_edid(u8 *buf, int len) return r; } +static void hdmi_start_audio_stream(struct omap_hdmi *hd) +{ + hdmi_wp_audio_enable(&hd->wp, true); + hdmi4_audio_start(&hd->core, &hd->wp); +} + +static void hdmi_stop_audio_stream(struct omap_hdmi *hd) +{ + hdmi4_audio_stop(&hd->core, &hd->wp); + hdmi_wp_audio_enable(&hd->wp, false); +} + static int hdmi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &hdmi.output; + unsigned long flags; int r = 0; DSSDBG("ENTER hdmi_display_enable\n"); @@ -342,7 +355,21 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev) goto err0; } + if (hdmi.audio_configured) { + r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, + hdmi.cfg.timings.pixelclock); + if (r) { + DSSERR("Error restoring audio configuration: %d", r); + hdmi.audio_abort_cb(&hdmi.pdev->dev); + hdmi.audio_configured = false; + } + } + + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + if (hdmi.audio_configured && hdmi.audio_playing) + hdmi_start_audio_stream(&hdmi); hdmi.display_enabled = true; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); mutex_unlock(&hdmi.lock); return 0; @@ -354,17 +381,19 @@ err0: static void hdmi_display_disable(struct omap_dss_device *dssdev) { + unsigned long flags; + DSSDBG("Enter hdmi_display_disable\n"); mutex_lock(&hdmi.lock); - if (hdmi.audio_pdev && hdmi.audio_abort_cb) - hdmi.audio_abort_cb(&hdmi.audio_pdev->dev); + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + hdmi_stop_audio_stream(&hdmi); + hdmi.display_enabled = false; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); hdmi_power_off_full(dssdev); - hdmi.display_enabled = false; - mutex_unlock(&hdmi.lock); } @@ -565,9 +594,14 @@ out: static int hdmi_audio_shutdown(struct device *dev) { struct omap_hdmi *hd = dev_get_drvdata(dev); + unsigned long flags; mutex_lock(&hd->lock); hd->audio_abort_cb = NULL; + hd->audio_configured = false; + spin_lock_irqsave(&hd->audio_playing_lock, flags); + hd->audio_playing = false; + spin_unlock_irqrestore(&hd-
Re: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init call completely
On 08/28/2015 12:24 PM, Keerthy wrote: On Thursday 27 August 2015 10:36 PM, Grygorii Strashko wrote: On 08/27/2015 07:38 PM, Tony Lindgren wrote: * Grygorii Strashko [150827 06:42]: Hi Tony, On 08/26/2015 09:10 PM, Tony Lindgren wrote: * Grygorii Strashko [150826 11:01]: Now Kernel fails to boot 50% of times (form build to build) with RT-patchset applied due to the following race - on late boot stages deferred_probe_work_func races with omap_device_late_ini late_initcall - deferred_probe_initcal() tries to re-probe all pending driver's probe. [In general, It's NOT expected to probe any other built-in drivers after deferred_probe_initcal() is finished, because most of late_initcall_sync/late_initcall functions expected that all driver or probed or deferred already.] - later on, some driver is probing in this case It's could cpsw.c (but could be any other drivers) cpsw_init - platform_driver_register - really_probe - driver_bound - driver_deferred_probe_trigger and boot proceed. So, at this moment we have deferred_probe_work_func scheduled. late_initcall_sync - omap_device_late_init - omap_device_idle CPU1CPU2 - deferred_probe_work_func - really_probe - omap_hsmmc_probe - pm_runtime_get_sync late_initcall_sync - omap_device_late_init if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { if (od->_state == OMAP_DEVICE_STATE_ENABLED) { - omap_device_idle [ops - IP is disabled, ] - [fail] - pm_runtime_put_sync - omap_hsmmc_runtime_suspend [ooops!] OK idling of unclaimed devices should not happen for deferred probe, it should only happen when there's no driver and no probing happening. Lets remove just remove omap_device_late_init completely as suggested by Tero Kristo: "How about remove omap_device_late_init call completely. I don't think it does anything useful at the moment; none of the omap devices get enabled outside runtime_pm, so there should be no need to explicitly disable the devices." I think this is still needed from PM point of view as otherwise we don't idle any devices that don't have a driver available. Or am I missing something? To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is not set in the deferred probe case. What do you think about below alternative? diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 4cb8fd9..72ebc4c 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data) if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE) return 0; - if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { + if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER && + od->_driver_status != BUS_NOTIFY_BIND_DRIVER) { if (od->_state == OMAP_DEVICE_STATE_ENABLED) { dev_warn(dev, "%s: enabled but no driver. Idling\n", __func__); Seems better to me if it really fixes the issue. My dra7-evm failed to boot on "2b186e5 Add linux-next specific files for 20150827" and this change restores boot. Will wait for confirmation from Keerthy. I confirm that with this patch the boot crash is fixed. Tested-by: Keerthy Without this patch i see this crash during boot: Thanks, Keerthy. I'll update and resend this new patch version. -- regards, -grygorii -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
On 08/28/15 13:37, Tomi Valkeinen wrote: On 26/08/15 16:11, Jyri Sarha wrote: diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index 7f87578..f352c4b 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -352,6 +352,7 @@ static int read_edid(u8 *buf, int len) static int hdmi_display_enable(struct omap_dss_device *dssdev) { struct omap_dss_device *out = &hdmi.output; + unsigned long flags; int r = 0; DSSDBG("ENTER hdmi_display_enable\n"); @@ -370,7 +371,37 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev) goto err0; } + if (hdmi.audio_configured) { + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + hdmi_wp_audio_core_req_enable(&hdmi.wp, false); + hdmi_wp_audio_enable(&hdmi.wp, false); + if (hdmi.wp_idlemode > 0) + REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, + hdmi.wp_idlemode, 3, 2); + hdmi.wp_idlemode = -1; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); Here I think the audio HW is always disabled already. It has to be, because the whole HDMI IP has been off. So the above should not be needed. + + r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, + hdmi.cfg.timings.pixelclock); + if (r) { + DSSERR("Error restoring audio configuration: %d", r); + hdmi.audio_abort_cb(&hdmi.pdev->dev); + hdmi.audio_configured = false; + } + } + + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); + if (hdmi.audio_configured && hdmi.audio_playing) { + /* No-idle while playing audio, store the old value */ + hdmi.wp_idlemode = + REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); + REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); + + hdmi_wp_audio_enable(&hdmi.wp, true); + hdmi_wp_audio_core_req_enable(&hdmi.wp, true); + } hdmi.display_enabled = true; + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); Maybe you've looked at the locking carefully, but it's not obvious to me. So is hdmi_audio_start and hdmi_audio_stop the only functions that are called from atomic context? Every other function is protected with the mutex? The idea is for the spinlock to make audio start, audio stop, and updates to hdmi.display_enabled and hdmi.audio_playing variable atomic. This is needed for the transitions from display enabled state (when audio start/stop commands can be written to HW) to display disabled state (when audio start/stop commands update only the hdmi.audio_playing variable) to always serialize correctly. IOW, the idea is to make sure the hdmi.audio_playing variable is always in sync with what is in the HW when hdmi.display_enabled == true. For example: when display is turned back on we take the spinlock and we can be sure that the audio start/stop status won't change while we update the HW according to current state and set hdmi.display_enabled to true. After releasing the lock hdmi.display_enabled is true and all audio_start and audio_stop commands write their stuff directly to HW. In theory, just making hdmi.display_enabled and hdmi.audio_playing atomic-variables and touching them always in correct oreder should be enough, but explaining the mechanism would then be even trickier. Cheers, Jyri -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] OMAPDSS: hdmi: Reconfigure and restart audio when display is enabled
On 26/08/15 16:11, Jyri Sarha wrote: > diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c > b/drivers/video/fbdev/omap2/dss/hdmi5.c > index 7f87578..f352c4b 100644 > --- a/drivers/video/fbdev/omap2/dss/hdmi5.c > +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c > @@ -352,6 +352,7 @@ static int read_edid(u8 *buf, int len) > static int hdmi_display_enable(struct omap_dss_device *dssdev) > { > struct omap_dss_device *out = &hdmi.output; > + unsigned long flags; > int r = 0; > > DSSDBG("ENTER hdmi_display_enable\n"); > @@ -370,7 +371,37 @@ static int hdmi_display_enable(struct omap_dss_device > *dssdev) > goto err0; > } > > + if (hdmi.audio_configured) { > + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); > + hdmi_wp_audio_core_req_enable(&hdmi.wp, false); > + hdmi_wp_audio_enable(&hdmi.wp, false); > + if (hdmi.wp_idlemode > 0) > + REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, > + hdmi.wp_idlemode, 3, 2); > + hdmi.wp_idlemode = -1; > + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); Here I think the audio HW is always disabled already. It has to be, because the whole HDMI IP has been off. So the above should not be needed. > + > + r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, > +hdmi.cfg.timings.pixelclock); > + if (r) { > + DSSERR("Error restoring audio configuration: %d", r); > + hdmi.audio_abort_cb(&hdmi.pdev->dev); > + hdmi.audio_configured = false; > + } > + } > + > + spin_lock_irqsave(&hdmi.audio_playing_lock, flags); > + if (hdmi.audio_configured && hdmi.audio_playing) { > + /* No-idle while playing audio, store the old value */ > + hdmi.wp_idlemode = > + REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); > + REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); > + > + hdmi_wp_audio_enable(&hdmi.wp, true); > + hdmi_wp_audio_core_req_enable(&hdmi.wp, true); > + } > hdmi.display_enabled = true; > + spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); Maybe you've looked at the locking carefully, but it's not obvious to me. So is hdmi_audio_start and hdmi_audio_stop the only functions that are called from atomic context? Every other function is protected with the mutex? Tomi signature.asc Description: OpenPGP digital signature
[PATCH] arm: omap2: vc: fix 'or' always true warning
From: Frans Klaver Fix the warning: arch/arm/mach-omap2/vc.c:302:47: warning: logical ‘or’ of collectively exhaustive tests is always true [-Wlogical-op] As we're toggling both CLKREQ and OFFMODE, we should also be checking OFFMODE. Signed-off-by: Frans Klaver --- arch/arm/mach-omap2/vc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 076fd20d7e5a..807bc79e3e3d 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -300,7 +300,7 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm) val = voltdm->read(OMAP3_PRM_POLCTRL_OFFSET); if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) || - (val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) { + (val & OMAP3430_PRM_POLCTRL_OFFMODE_POL)) { val |= OMAP3430_PRM_POLCTRL_CLKREQ_POL; val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL; pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity to 0x%x\n", -- 2.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init call completely
On Thursday 27 August 2015 10:36 PM, Grygorii Strashko wrote: On 08/27/2015 07:38 PM, Tony Lindgren wrote: * Grygorii Strashko [150827 06:42]: Hi Tony, On 08/26/2015 09:10 PM, Tony Lindgren wrote: * Grygorii Strashko [150826 11:01]: Now Kernel fails to boot 50% of times (form build to build) with RT-patchset applied due to the following race - on late boot stages deferred_probe_work_func races with omap_device_late_ini late_initcall - deferred_probe_initcal() tries to re-probe all pending driver's probe. [In general, It's NOT expected to probe any other built-in drivers after deferred_probe_initcal() is finished, because most of late_initcall_sync/late_initcall functions expected that all driver or probed or deferred already.] - later on, some driver is probing in this case It's could cpsw.c (but could be any other drivers) cpsw_init - platform_driver_register - really_probe - driver_bound - driver_deferred_probe_trigger and boot proceed. So, at this moment we have deferred_probe_work_func scheduled. late_initcall_sync - omap_device_late_init - omap_device_idle CPU1CPU2 - deferred_probe_work_func - really_probe - omap_hsmmc_probe - pm_runtime_get_sync late_initcall_sync - omap_device_late_init if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { if (od->_state == OMAP_DEVICE_STATE_ENABLED) { - omap_device_idle [ops - IP is disabled, ] - [fail] - pm_runtime_put_sync - omap_hsmmc_runtime_suspend [ooops!] OK idling of unclaimed devices should not happen for deferred probe, it should only happen when there's no driver and no probing happening. Lets remove just remove omap_device_late_init completely as suggested by Tero Kristo: "How about remove omap_device_late_init call completely. I don't think it does anything useful at the moment; none of the omap devices get enabled outside runtime_pm, so there should be no need to explicitly disable the devices." I think this is still needed from PM point of view as otherwise we don't idle any devices that don't have a driver available. Or am I missing something? To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is not set in the deferred probe case. What do you think about below alternative? diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 4cb8fd9..72ebc4c 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data) if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE) return 0; - if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) { + if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER && + od->_driver_status != BUS_NOTIFY_BIND_DRIVER) { if (od->_state == OMAP_DEVICE_STATE_ENABLED) { dev_warn(dev, "%s: enabled but no driver. Idling\n", __func__); Seems better to me if it really fixes the issue. My dra7-evm failed to boot on "2b186e5 Add linux-next specific files for 20150827" and this change restores boot. Will wait for confirmation from Keerthy. I confirm that with this patch the boot crash is fixed. Tested-by: Keerthy Without this patch i see this crash during boot: [2.423724] omap_hsmmc 4809c000.mmc: omap_device_late_idle: enabled but no driver. Idling [2.432959] ldousb: disabling [2.461630] Unhandled fault: imprecise external abort (0x1406) at 0x [2.461638] [ cut here ] [2.461654] WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x220/0x348() [2.461660] 4400.ocp:L3 Custom Error: MASTER MPU TARGET L4_PER1_P3 (Read): Data Access in User mode during Functional access [2.461665] Modules linked in: [2.461672] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc8-00084-gf1f35f0 #85 [2.461675] Hardware name: Generic DRA74X (Flattened Device Tree) [2.461690] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [2.461699] [] (show_stack) from [] (dump_stack+0x80/0x9c) [2.461709] [] (dump_stack) from [] (warn_slowpath_common+0x7c/0xb8) [2.461717] [] (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) [2.461726] [] (warn_slowpath_fmt) from [] (l3_interrupt_handler+0x220/0x348) [2.461739] [] (l3_interrupt_handler) from [] (handle_irq_event_percpu+0x64/0x204) [2.461748] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x40/0x64) [2.461758]