Skip to content

Commit

Permalink
i5100_edac: convert driver to use the new edac ABI
Browse files Browse the repository at this point in the history
The legacy edac ABI is going to be removed. Port the driver to use
and benefit from the new API functionality.

Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Mauro Carvalho Chehab committed May 28, 2012
1 parent 702df64 commit d1afaa0
Showing 1 changed file with 40 additions and 50 deletions.
90 changes: 40 additions & 50 deletions drivers/edac/i5100_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
* rows for each respective channel are laid out one after another,
* the first half belonging to channel 0, the second half belonging
* to channel 1.
*
* This driver is for DDR2 DIMMs, and it uses chip select to select among the
* several ranks. However, instead of showing memories as ranks, it outputs
* them as DIMM's. An internal table creates the association between ranks
* and DIMM's.
*/
#include <linux/module.h>
#include <linux/init.h>
Expand Down Expand Up @@ -410,14 +415,6 @@ static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
return csrow / priv->ranksperchan;
}

static unsigned i5100_rank_to_csrow(const struct mem_ctl_info *mci,
int chan, int rank)
{
const struct i5100_priv *priv = mci->pvt_info;

return chan * priv->ranksperchan + rank;
}

static void i5100_handle_ce(struct mem_ctl_info *mci,
int chan,
unsigned bank,
Expand All @@ -427,21 +424,17 @@ static void i5100_handle_ce(struct mem_ctl_info *mci,
unsigned ras,
const char *msg)
{
const int csrow = i5100_rank_to_csrow(mci, chan, rank);
char *label = NULL;
char detail[80];

if (mci->csrows[csrow].channels[0].dimm)
label = mci->csrows[csrow].channels[0].dimm->label;
/* Form out message */
snprintf(detail, sizeof(detail),
"bank %u, cas %u, ras %u\n",
bank, cas, ras);

printk(KERN_ERR
"CE chan %d, bank %u, rank %u, syndrome 0x%lx, "
"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
chan, bank, rank, syndrome, cas, ras,
csrow, label, msg);

mci->ce_count++;
mci->csrows[csrow].ce_count++;
mci->csrows[csrow].channels[0].ce_count++;
edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
0, 0, syndrome,
chan, rank, -1,
msg, detail, NULL);
}

static void i5100_handle_ue(struct mem_ctl_info *mci,
Expand All @@ -453,20 +446,17 @@ static void i5100_handle_ue(struct mem_ctl_info *mci,
unsigned ras,
const char *msg)
{
const int csrow = i5100_rank_to_csrow(mci, chan, rank);
char *label = NULL;

if (mci->csrows[csrow].channels[0].dimm)
label = mci->csrows[csrow].channels[0].dimm->label;
char detail[80];

printk(KERN_ERR
"UE chan %d, bank %u, rank %u, syndrome 0x%lx, "
"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
chan, bank, rank, syndrome, cas, ras,
csrow, label, msg);
/* Form out message */
snprintf(detail, sizeof(detail),
"bank %u, cas %u, ras %u\n",
bank, cas, ras);

mci->ue_count++;
mci->csrows[csrow].ue_count++;
edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
0, 0, syndrome,
chan, rank, -1,
msg, detail, NULL);
}

static void i5100_read_log(struct mem_ctl_info *mci, int chan,
Expand Down Expand Up @@ -843,42 +833,34 @@ static void __devinit i5100_init_interleaving(struct pci_dev *pdev,
static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
{
int i;
unsigned long total_pages = 0UL;
struct i5100_priv *priv = mci->pvt_info;
struct dimm_info *dimm;

for (i = 0; i < mci->nr_csrows; i++) {
for (i = 0; i < mci->tot_dimms; i++) {
struct dimm_info *dimm;
const unsigned long npages = i5100_npages(mci, i);
const unsigned chan = i5100_csrow_to_chan(mci, i);
const unsigned rank = i5100_csrow_to_rank(mci, i);

if (!npages)
continue;

/*
* FIXME: these two are totally bogus -- I don't see how to
* map them correctly to this structure...
*/
mci->csrows[i].csrow_idx = i;
mci->csrows[i].mci = mci;
mci->csrows[i].nr_channels = 1;
mci->csrows[i].channels[0].csrow = mci->csrows + i;
total_pages += npages;
dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers,
chan, rank, 0);

dimm = mci->csrows[i].channels[0].dimm;
dimm->nr_pages = npages;
if (npages) {
total_pages += npages;

dimm->grain = 32;
dimm->dtype = (priv->mtr[chan][rank].width == 4) ?
DEV_X4 : DEV_X8;
DEV_X4 : DEV_X8;
dimm->mtype = MEM_RDDR2;
dimm->edac_mode = EDAC_SECDED;
snprintf(dimm->label, sizeof(dimm->label),
"DIMM%u",
i5100_rank_to_slot(mci, chan, rank));
}

debugf2("dimm channel %d, rank %d, size %zd\n",
chan, rank, PAGES_TO_MiB(npages));
}
}

Expand All @@ -887,6 +869,7 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
{
int rc;
struct mem_ctl_info *mci;
struct edac_mc_layer layers[2];
struct i5100_priv *priv;
struct pci_dev *ch0mm, *ch1mm;
int ret = 0;
Expand Down Expand Up @@ -947,7 +930,14 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
goto bail_ch1;
}

mci = edac_mc_alloc(sizeof(*priv), ranksperch * 2, 1, 0);
layers[0].type = EDAC_MC_LAYER_CHANNEL;
layers[0].size = 2;
layers[0].is_virt_csrow = false;
layers[1].type = EDAC_MC_LAYER_SLOT;
layers[1].size = ranksperch;
layers[1].is_virt_csrow = true;
mci = new_edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
sizeof(*priv));
if (!mci) {
ret = -ENOMEM;
goto bail_disable_ch1;
Expand Down

0 comments on commit d1afaa0

Please sign in to comment.