Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1afaa0a authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

i5100_edac: convert driver to use the new edac ABI



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: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 702df640
Loading
Loading
Loading
Loading
+40 −50
Original line number Diff line number Diff line
@@ -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>
@@ -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,
@@ -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;

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

	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);
	/* Form out message */
	snprintf(detail, sizeof(detail),
		 "bank %u, cas %u, ras %u\n",
		 bank, cas, ras);

	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,
@@ -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;
	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
		"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);

	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,
@@ -843,11 +833,10 @@ 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);
@@ -855,21 +844,11 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
		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;
@@ -879,6 +858,9 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
				"DIMM%u",
				i5100_rank_to_slot(mci, chan, rank));
		}

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

@@ -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;
@@ -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;