Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / edac / edac_mc.c
index 64922c8..e6fd079 100644 (file)
@@ -114,8 +114,8 @@ static const struct kernel_param_ops edac_report_ops = {
 
 module_param_cb(edac_report, &edac_report_ops, &edac_report, 0644);
 
-unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
-                                unsigned len)
+unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
+                                    unsigned int len)
 {
        struct mem_ctl_info *mci = dimm->mci;
        int i, n, count = 0;
@@ -236,9 +236,9 @@ EXPORT_SYMBOL_GPL(edac_mem_types);
  * At return, the pointer 'p' will be incremented to be used on a next call
  * to this function.
  */
-void *edac_align_ptr(void **p, unsigned size, int n_elems)
+void *edac_align_ptr(void **p, unsigned int size, int n_elems)
 {
-       unsigned align, r;
+       unsigned int align, r;
        void *ptr = *p;
 
        *p += size * n_elems;
@@ -275,38 +275,37 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
 
 static void _edac_mc_free(struct mem_ctl_info *mci)
 {
-       int i, chn, row;
        struct csrow_info *csr;
-       const unsigned int tot_dimms = mci->tot_dimms;
-       const unsigned int tot_channels = mci->num_cschannel;
-       const unsigned int tot_csrows = mci->nr_csrows;
+       int i, chn, row;
 
        if (mci->dimms) {
-               for (i = 0; i < tot_dimms; i++)
+               for (i = 0; i < mci->tot_dimms; i++)
                        kfree(mci->dimms[i]);
                kfree(mci->dimms);
        }
+
        if (mci->csrows) {
-               for (row = 0; row < tot_csrows; row++) {
+               for (row = 0; row < mci->nr_csrows; row++) {
                        csr = mci->csrows[row];
-                       if (csr) {
-                               if (csr->channels) {
-                                       for (chn = 0; chn < tot_channels; chn++)
-                                               kfree(csr->channels[chn]);
-                                       kfree(csr->channels);
-                               }
-                               kfree(csr);
+                       if (!csr)
+                               continue;
+
+                       if (csr->channels) {
+                               for (chn = 0; chn < mci->num_cschannel; chn++)
+                                       kfree(csr->channels[chn]);
+                               kfree(csr->channels);
                        }
+                       kfree(csr);
                }
                kfree(mci->csrows);
        }
        kfree(mci);
 }
 
-struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
-                                  unsigned n_layers,
+struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
+                                  unsigned int n_layers,
                                   struct edac_mc_layer *layers,
-                                  unsigned sz_pvt)
+                                  unsigned int sz_pvt)
 {
        struct mem_ctl_info *mci;
        struct edac_mc_layer *layer;
@@ -314,9 +313,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        struct rank_info *chan;
        struct dimm_info *dimm;
        u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
-       unsigned pos[EDAC_MAX_LAYERS];
-       unsigned size, tot_dimms = 1, count = 1;
-       unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
+       unsigned int pos[EDAC_MAX_LAYERS];
+       unsigned int size, tot_dimms = 1, count = 1;
+       unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
        void *pvt, *p, *ptr = NULL;
        int i, j, row, chn, n, len, off;
        bool per_rank = false;
@@ -1235,9 +1234,13 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
        if (p > e->location)
                *(p - 1) = '\0';
 
-       /* Report the error via the trace interface */
-       grain_bits = fls_long(e->grain) + 1;
+       /* Sanity-check driver-supplied grain value. */
+       if (WARN_ON_ONCE(!e->grain))
+               e->grain = 1;
 
+       grain_bits = fls_long(e->grain - 1);
+
+       /* Report the error via the trace interface */
        if (IS_ENABLED(CONFIG_RAS))
                trace_mc_event(type, e->msg, e->label, e->error_count,
                               mci->mc_idx, e->top_layer, e->mid_layer,