RDMA/bnxt_re: Fix system crash during RDMA resource initialization
[linux-2.6-block.git] / drivers / bus / ti-sysc.c
index c9bac9dc4637e7b8ce9ad3eb15e484added77f79..e4fe954e63a9be53b74397c825bf4f57b06dcca5 100644 (file)
@@ -498,32 +498,29 @@ static int sysc_check_registers(struct sysc *ddata)
 
 /**
  * syc_ioremap - ioremap register space for the interconnect target module
- * @ddata: deviec driver data
+ * @ddata: device driver data
  *
  * Note that the interconnect target module registers can be anywhere
- * within the first child device address space. For example, SGX has
- * them at offset 0x1fc00 in the 32MB module address space. We just
- * what we need around the interconnect target module registers.
+ * within the interconnect target module range. For example, SGX has
+ * them at offset 0x1fc00 in the 32MB module address space. And cpsw
+ * has them at offset 0x1200 in the CPSW_WR child. Usually the
+ * the interconnect target module registers are at the beginning of
+ * the module range though.
  */
 static int sysc_ioremap(struct sysc *ddata)
 {
-       u32 size = 0;
-
-       if (ddata->offsets[SYSC_SYSSTATUS] >= 0)
-               size = ddata->offsets[SYSC_SYSSTATUS];
-       else if (ddata->offsets[SYSC_SYSCONFIG] >= 0)
-               size = ddata->offsets[SYSC_SYSCONFIG];
-       else if (ddata->offsets[SYSC_REVISION] >= 0)
-               size = ddata->offsets[SYSC_REVISION];
-       else
-               return -EINVAL;
+       int size;
 
-       size &= 0xfff00;
-       size += SZ_256;
+       size = max3(ddata->offsets[SYSC_REVISION],
+                   ddata->offsets[SYSC_SYSCONFIG],
+                   ddata->offsets[SYSC_SYSSTATUS]);
+
+       if (size < 0 || (size + sizeof(u32)) > ddata->module_size)
+               return -EINVAL;
 
        ddata->module_va = devm_ioremap(ddata->dev,
                                        ddata->module_pa,
-                                       size);
+                                       size + sizeof(u32));
        if (!ddata->module_va)
                return -EIO;
 
@@ -1224,10 +1221,10 @@ static int sysc_child_suspend_noirq(struct device *dev)
        if (!pm_runtime_status_suspended(dev)) {
                error = pm_generic_runtime_suspend(dev);
                if (error) {
-                       dev_err(dev, "%s error at %i: %i\n",
-                               __func__, __LINE__, error);
+                       dev_warn(dev, "%s busy at %i: %i\n",
+                                __func__, __LINE__, error);
 
-                       return error;
+                       return 0;
                }
 
                error = sysc_runtime_suspend(ddata->dev);