static int cpc925_probe()

in cpc925_edac.c [906:1011]


static int cpc925_probe(struct platform_device *pdev)
{
	static int edac_mc_idx;
	struct mem_ctl_info *mci;
	struct edac_mc_layer layers[2];
	void __iomem *vbase;
	struct cpc925_mc_pdata *pdata;
	struct resource *r;
	int res = 0, nr_channels;

	edac_dbg(0, "%s platform device found!\n", pdev->name);

	if (!devres_open_group(&pdev->dev, cpc925_probe, GFP_KERNEL)) {
		res = -ENOMEM;
		goto out;
	}

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		cpc925_printk(KERN_ERR, "Unable to get resource\n");
		res = -ENOENT;
		goto err1;
	}

	if (!devm_request_mem_region(&pdev->dev,
				     r->start,
				     resource_size(r),
				     pdev->name)) {
		cpc925_printk(KERN_ERR, "Unable to request mem region\n");
		res = -EBUSY;
		goto err1;
	}

	vbase = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!vbase) {
		cpc925_printk(KERN_ERR, "Unable to ioremap device\n");
		res = -ENOMEM;
		goto err2;
	}

	nr_channels = cpc925_mc_get_channels(vbase) + 1;

	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
	layers[0].size = CPC925_NR_CSROWS;
	layers[0].is_virt_csrow = true;
	layers[1].type = EDAC_MC_LAYER_CHANNEL;
	layers[1].size = nr_channels;
	layers[1].is_virt_csrow = false;
	mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers,
			    sizeof(struct cpc925_mc_pdata));
	if (!mci) {
		cpc925_printk(KERN_ERR, "No memory for mem_ctl_info\n");
		res = -ENOMEM;
		goto err2;
	}

	pdata = mci->pvt_info;
	pdata->vbase = vbase;
	pdata->edac_idx = edac_mc_idx++;
	pdata->name = pdev->name;

	mci->pdev = &pdev->dev;
	platform_set_drvdata(pdev, mci);
	mci->dev_name = dev_name(&pdev->dev);
	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
	mci->edac_cap = EDAC_FLAG_SECDED;
	mci->mod_name = CPC925_EDAC_MOD_STR;
	mci->ctl_name = pdev->name;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		mci->edac_check = cpc925_mc_check;

	mci->ctl_page_to_phys = NULL;
	mci->scrub_mode = SCRUB_SW_SRC;
	mci->set_sdram_scrub_rate = NULL;
	mci->get_sdram_scrub_rate = cpc925_get_sdram_scrub_rate;

	cpc925_init_csrows(mci);

	/* Setup memory controller registers */
	cpc925_mc_init(mci);

	if (edac_mc_add_mc(mci) > 0) {
		cpc925_mc_printk(mci, KERN_ERR, "Failed edac_mc_add_mc()\n");
		goto err3;
	}

	cpc925_add_edac_devices(vbase);

	/* get this far and it's successful */
	edac_dbg(0, "success\n");

	res = 0;
	goto out;

err3:
	cpc925_mc_exit(mci);
	edac_mc_free(mci);
err2:
	devm_release_mem_region(&pdev->dev, r->start, resource_size(r));
err1:
	devres_release_group(&pdev->dev, cpc925_probe);
out:
	return res;
}