]> Pileus Git - ~andy/linux/blobdiff - arch/arm/mach-omap2/omap_hwmod.c
ARM: OMAP2+: hwmod: check for module address space during init
[~andy/linux] / arch / arm / mach-omap2 / omap_hwmod.c
index d9ee0ff094d4bcfdd395131601664be618367073..3d5db8c83b3cb1ab228dae53ab16b4cca0542f82 100644 (file)
@@ -2361,21 +2361,23 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
  * Cache the virtual address used by the MPU to access this IP block's
  * registers.  This address is needed early so the OCP registers that
  * are part of the device's address space can be ioremapped properly.
- * No return value.
+ *
+ * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and
+ * -ENXIO on absent or invalid register target address space.
  */
-static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
+static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
 {
        struct omap_hwmod_addr_space *mem;
        void __iomem *va_start = NULL;
        struct device_node *np;
 
        if (!oh)
-               return;
+               return -EINVAL;
 
        _save_mpu_port_index(oh);
 
        if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
-               return;
+               return -ENXIO;
 
        mem = _find_mpu_rt_addr_space(oh);
        if (!mem) {
@@ -2384,7 +2386,7 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
 
                /* Extract the IO space from device tree blob */
                if (!of_have_populated_dt())
-                       return;
+                       return -ENXIO;
 
                np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
                if (np)
@@ -2395,13 +2397,14 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
 
        if (!va_start) {
                pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
-               return;
+               return -ENXIO;
        }
 
        pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
                 oh->name, va_start);
 
        oh->_mpu_rt_va = va_start;
+       return 0;
 }
 
 /**
@@ -2414,8 +2417,8 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
  * registered at this point.  This is the first of two phases for
  * hwmod initialization.  Code called here does not touch any hardware
  * registers, it simply prepares internal data structures.  Returns 0
- * upon success or if the hwmod isn't registered, or -EINVAL upon
- * failure.
+ * upon success or if the hwmod isn't registered or if the hwmod's
+ * address space is not defined, or -EINVAL upon failure.
  */
 static int __init _init(struct omap_hwmod *oh, void *data)
 {
@@ -2424,8 +2427,14 @@ static int __init _init(struct omap_hwmod *oh, void *data)
        if (oh->_state != _HWMOD_STATE_REGISTERED)
                return 0;
 
-       if (oh->class->sysc)
-               _init_mpu_rt_base(oh, NULL);
+       if (oh->class->sysc) {
+               r = _init_mpu_rt_base(oh, NULL);
+               if (r < 0) {
+                       WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n",
+                            oh->name);
+                       return 0;
+               }
+       }
 
        r = _init_clocks(oh, NULL);
        if (r < 0) {