Merge tag 'v3.10.72' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / edac / edac_mc.c
index 27e86d93826280a62744a559332bf0cd9bc03b3b..a9d98cdd11f4b1cfe07e4be94e8e29dafe8fa778 100644 (file)
@@ -48,6 +48,8 @@ static LIST_HEAD(mc_devices);
  */
 static void const *edac_mc_owner;
 
+static struct bus_type mc_bus[EDAC_MAX_MCS];
+
 unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
                                 unsigned len)
 {
@@ -557,7 +559,8 @@ static void edac_mc_workq_function(struct work_struct *work_req)
  *
  *             called with the mem_ctls_mutex held
  */
-static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec)
+static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec,
+                               bool init)
 {
        edac_dbg(0, "\n");
 
@@ -565,7 +568,9 @@ static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec)
        if (mci->op_state != OP_RUNNING_POLL)
                return;
 
-       INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function);
+       if (init)
+               INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function);
+
        mod_delayed_work(edac_workqueue, &mci->work, msecs_to_jiffies(msec));
 }
 
@@ -599,7 +604,7 @@ static void edac_mc_workq_teardown(struct mem_ctl_info *mci)
  *     user space has updated our poll period value, need to
  *     reset our workq delays
  */
-void edac_mc_reset_delay_period(int value)
+void edac_mc_reset_delay_period(unsigned long value)
 {
        struct mem_ctl_info *mci;
        struct list_head *item;
@@ -609,7 +614,7 @@ void edac_mc_reset_delay_period(int value)
        list_for_each(item, &mc_devices) {
                mci = list_entry(item, struct mem_ctl_info, link);
 
-               edac_mc_workq_setup(mci, (unsigned long) value);
+               edac_mc_workq_setup(mci, value, false);
        }
 
        mutex_unlock(&mem_ctls_mutex);
@@ -723,6 +728,11 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
        int ret = -EINVAL;
        edac_dbg(0, "\n");
 
+       if (mci->mc_idx >= EDAC_MAX_MCS) {
+               pr_warn_once("Too many memory controllers: %d\n", mci->mc_idx);
+               return -ENODEV;
+       }
+
 #ifdef CONFIG_EDAC_DEBUG
        if (edac_debug_level >= 3)
                edac_mc_dump_mci(mci);
@@ -762,6 +772,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
        /* set load time so that error rate can be tracked */
        mci->start_time = jiffies;
 
+       mci->bus = &mc_bus[mci->mc_idx];
+
        if (edac_create_sysfs_mci_device(mci)) {
                edac_mc_printk(mci, KERN_WARNING,
                        "failed to create sysfs device\n");
@@ -773,7 +785,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
                /* This instance is NOW RUNNING */
                mci->op_state = OP_RUNNING_POLL;
 
-               edac_mc_workq_setup(mci, edac_mc_get_poll_msec());
+               edac_mc_workq_setup(mci, edac_mc_get_poll_msec(), true);
        } else {
                mci->op_state = OP_RUNNING_INTERRUPT;
        }