I already did an RFC [1] that tried to do the same but I think this one is cleaner. If a hardware module is disabled in devicetree the address range will still be touched by omap_hwmod.c. If the corresponding module isn't powered this can lead to a crash of the kernel (for example rtc): [ 2.101166] omap_hwmod: rtc: enabling [ 2.105038] omap_hwmod: rtc: enabling clocks [ 2.109517] omap_hwmod: rtc: _omap4_enable_module: 2 [ 2.114917] Unhandled fault: external abort on non-linefetch (0x1028) at 0xf9e3e078 [ 2.122877] pgd = c0204000 [ 2.125747] [f9e3e078] *pgd=44e11452(bad) [ 2.129977] Internal error: : 1028 [#1] SMP ARM [ 2.134720] Modules linked in: [ 2.137959] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-00006-g8cdb736-dirty #221 [ 2.146188] Hardware name: Generic AM33XX (Flattened Device Tree) [ 2.152543] task: cb084000 task.stack: cb088000 [ 2.157305] PC is at _update_sysc_cache+0x28/0x98 [ 2.162232] LR is at _enable+0x1d8/0x288 [ 2.166355] pc : [<c03297c0>] lr : [<c0329f40>] psr: 40000013 [ 2.166355] sp : cb089ec8 ip : 00000000 fp : 00000000 [ 2.178342] r10: 0000014f r9 : c1337910 r8 : c12c783c [ 2.183804] r7 : c141d448 r6 : 00000000 r5 : c15846b8 r4 : c141cdc8 [ 2.190606] r3 : f9e3e078 r2 : c141d8f4 r1 : f9e3e000 r0 : c141cdc8 [ 2.197407] Flags: nZcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 2.204834] Control: 10c5387d Table: 80204019 DAC: 00000051 [ 2.210831] Process swapper/0 (pid: 1, stack limit = 0xcb088220) [ 2.217093] Stack: (0xcb089ec8 to 0xcb08a000) [ 2.221668] 9ec0: 00000000 a0000013 c141ce0c c141cdc8 c141cdf8 c141ce0c [ 2.230174] 9ee0: c12c7824 c1211f70 c140c30c c140c368 00000000 00000009 c141cdc8 c140c368 [ 2.238679] 9f00: 00000000 c12124c8 00000002 c12123dc 00000000 c0301f30 0000014f 0000014f [ 2.247185] 9f20: cfdffc00 cfdffcf0 c112c044 0000014f 0000014e c0361a90 c112a62c 00000000 [ 2.255689] 9f40: 00000002 00000002 cfdffcf0 00000000 c1436428 00000002 c1582dc0 c1582dc0 [ 2.264196] 9f60: 00000002 c1582dc0 c1582dc0 c12c783c c1337910 c1200de8 00000002 00000002 [ 2.272702] 9f80: 00000000 c12005a0 00000000 c0cd64c4 00000000 00000000 00000000 00000000 [ 2.281208] 9fa0: 00000000 c0cd64cc 00000000 c0307ef8 00000000 00000000 00000000 00000000 [ 2.289716] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 2.298219] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 fefff797 97eb77d5 [ 2.306739] [<c03297c0>] (_update_sysc_cache) from [<a0000013>] (0xa0000013) [ 2.314086] Code: e3110c01 e5901054 e6f13073 1a00000c (e5933000) [ 2.320465] ---[ end trace d06e062f91dfe35a ]--- [ 2.325386] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 2.325386] [ 2.334975] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b This patch will immediately set the disabled module to _HWMOD_STATE_DISABLED. Because the timers are disable to be hidden from the rest of the system, this patch checks if it's a timer and will in this case still enable the hw module. To be affected by this patch, the status in the devicetree needs to be changed to status = "disabled". This is more convenient then to have a separate flag as requested by the last RFC. I think something that is perhaps unwanted, when u-boot would power a hw module that should be disabled in Linux, Linux won't disable it anymore. Is this a usecase and what would be the expected behaviour? [1] http://marc.info/?l=linux-omap&m=146712955420293 Signed-off-by: Stefan Eichenberger <stefan.eichenberger@xxxxxxxxxxxxx> --- arch/arm/mach-omap2/omap_hwmod.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 3b47ded..63f7eb2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2462,6 +2462,21 @@ static int __init _init(struct omap_hwmod *oh, void *data) pr_warn("omap_hwmod: %s using broken dt data from %s\n", oh->name, np->name); + if (np) { + /* + * If a hw module is disabled the driver should not touch it. + * Timer modules are disabled by software to hide them from + * the system. Therefore timers should always be enabled. + */ + if (!of_device_is_available(np) && + strncmp("timer", oh->name, 5)) { + pr_debug("omap_hwmod: set %s to state disabled\n", + oh->name); + oh->_state = _HWMOD_STATE_DISABLED; + return 0; + } + } + r = _init_mpu_rt_base(oh, NULL, index, np); if (r < 0) { WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n", -- 2.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html