Skip to content

Commit 6423d6d

Browse files
sumanannaPaul Walmsley
authored andcommitted
ARM: OMAP2+: hwmod: check for module address space during init
The hwmod init sequence involves initializing and idling all the hwmods during bootup. If a module class has sysconfig, the init sequence utilizes the module register base for performing any sysc configuration. The module address space is being removed from hwmod database and retrieved from the <reg> property of the corresponding DT node. If a hwmod does not have its corresponding DT node defined and the memory address space is not defined in the corresponding omap_hwmod_ocp_if, then the module register target address space would be NULL and any sysc programming would result in a NULL pointer dereference and a kernel boot hang. Handle this scenario by checking for a valid module address space during the _init of each hwmod, and leaving it in the registered state if no module register address base is defined in either of the hwmod data or the DT data. Signed-off-by: Suman Anna <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> Tested-by: Nishanth Menon <[email protected]> Acked-by: Tony Lindgren <[email protected]> [[email protected]: use -ENXIO rather than -ENOMEM to indicate a missing address space error; fixed checkpatch.pl problem] Signed-off-by: Paul Walmsley <[email protected]>
1 parent d0e639c commit 6423d6d

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

arch/arm/mach-omap2/omap_hwmod.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,21 +2361,23 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
23612361
* Cache the virtual address used by the MPU to access this IP block's
23622362
* registers. This address is needed early so the OCP registers that
23632363
* are part of the device's address space can be ioremapped properly.
2364-
* No return value.
2364+
*
2365+
* Returns 0 on success, -EINVAL if an invalid hwmod is passed, and
2366+
* -ENXIO on absent or invalid register target address space.
23652367
*/
2366-
static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
2368+
static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
23672369
{
23682370
struct omap_hwmod_addr_space *mem;
23692371
void __iomem *va_start = NULL;
23702372
struct device_node *np;
23712373

23722374
if (!oh)
2373-
return;
2375+
return -EINVAL;
23742376

23752377
_save_mpu_port_index(oh);
23762378

23772379
if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
2378-
return;
2380+
return -ENXIO;
23792381

23802382
mem = _find_mpu_rt_addr_space(oh);
23812383
if (!mem) {
@@ -2384,7 +2386,7 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
23842386

23852387
/* Extract the IO space from device tree blob */
23862388
if (!of_have_populated_dt())
2387-
return;
2389+
return -ENXIO;
23882390

23892391
np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
23902392
if (np)
@@ -2395,13 +2397,14 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
23952397

23962398
if (!va_start) {
23972399
pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
2398-
return;
2400+
return -ENXIO;
23992401
}
24002402

24012403
pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
24022404
oh->name, va_start);
24032405

24042406
oh->_mpu_rt_va = va_start;
2407+
return 0;
24052408
}
24062409

24072410
/**
@@ -2414,8 +2417,8 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
24142417
* registered at this point. This is the first of two phases for
24152418
* hwmod initialization. Code called here does not touch any hardware
24162419
* registers, it simply prepares internal data structures. Returns 0
2417-
* upon success or if the hwmod isn't registered, or -EINVAL upon
2418-
* failure.
2420+
* upon success or if the hwmod isn't registered or if the hwmod's
2421+
* address space is not defined, or -EINVAL upon failure.
24192422
*/
24202423
static int __init _init(struct omap_hwmod *oh, void *data)
24212424
{
@@ -2424,8 +2427,14 @@ static int __init _init(struct omap_hwmod *oh, void *data)
24242427
if (oh->_state != _HWMOD_STATE_REGISTERED)
24252428
return 0;
24262429

2427-
if (oh->class->sysc)
2428-
_init_mpu_rt_base(oh, NULL);
2430+
if (oh->class->sysc) {
2431+
r = _init_mpu_rt_base(oh, NULL);
2432+
if (r < 0) {
2433+
WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
2434+
oh->name);
2435+
return 0;
2436+
}
2437+
}
24292438

24302439
r = _init_clocks(oh, NULL);
24312440
if (r < 0) {

0 commit comments

Comments
 (0)