Exemplo n.º 1
0
static int qcom_llcc_edac_probe(struct platform_device *pdev)
{
	struct llcc_drv_data *llcc_driv_data = pdev->dev.platform_data;
	struct edac_device_ctl_info *edev_ctl;
	struct device *dev = &pdev->dev;
	int ecc_irq;
	int rc;

	rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap);
	if (rc)
		return rc;

	/* Allocate edac control info */
	edev_ctl = edac_device_alloc_ctl_info(0, "qcom-llcc", 1, "bank",
					      llcc_driv_data->num_banks, 1,
					      NULL, 0,
					      edac_device_alloc_index());

	if (!edev_ctl)
		return -ENOMEM;

	edev_ctl->dev = dev;
	edev_ctl->mod_name = dev_name(dev);
	edev_ctl->dev_name = dev_name(dev);
	edev_ctl->ctl_name = "llcc";
	edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
	edev_ctl->pvt_info = llcc_driv_data;

	rc = edac_device_add_device(edev_ctl);
	if (rc)
		goto out_mem;

	platform_set_drvdata(pdev, edev_ctl);

	/* Request for ecc irq */
	ecc_irq = llcc_driv_data->ecc_irq;
	if (ecc_irq < 0) {
		rc = -ENODEV;
		goto out_dev;
	}
	rc = devm_request_irq(dev, ecc_irq, llcc_ecc_irq_handler,
			      IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl);
	if (rc)
		goto out_dev;

	return rc;

out_dev:
	edac_device_del_device(edev_ctl->dev);
out_mem:
	edac_device_free_ctl_info(edev_ctl);

	return rc;
}
static int octeon_l2c_probe(struct platform_device *pdev)
{
	struct edac_device_ctl_info *l2c;

	int num_tads = OCTEON_IS_MODEL(OCTEON_CN68XX) ? 4 : 1;

	/* 'Tags' are block 0, 'Data' is block 1*/
	l2c = edac_device_alloc_ctl_info(0, "l2c", num_tads, "l2c", 2, 0,
					 NULL, 0, edac_device_alloc_index());
	if (!l2c)
		return -ENOMEM;

	l2c->dev = &pdev->dev;
	platform_set_drvdata(pdev, l2c);
	l2c->dev_name = dev_name(&pdev->dev);

	l2c->mod_name = "octeon-l2c";
	l2c->ctl_name = "octeon_l2c_err";


	if (OCTEON_IS_OCTEON1PLUS()) {
		union cvmx_l2t_err l2t_err;
		union cvmx_l2d_err l2d_err;

		l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
		l2t_err.s.sec_intena = 0;	/* We poll */
		l2t_err.s.ded_intena = 0;
		cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);

		l2d_err.u64 = cvmx_read_csr(CVMX_L2D_ERR);
		l2d_err.s.sec_intena = 0;	/* We poll */
		l2d_err.s.ded_intena = 0;
		cvmx_write_csr(CVMX_L2T_ERR, l2d_err.u64);

		l2c->edac_check = octeon_l2c_poll_oct1;
	} else {
		/* OCTEON II */
		l2c->edac_check = octeon_l2c_poll_oct2;
	}

	if (edac_device_add_device(l2c) > 0) {
		pr_err("%s: edac_device_add_device() failed\n", __func__);
		goto err;
	}


	return 0;

err:
	edac_device_free_ctl_info(l2c);

	return -ENXIO;
}
Exemplo n.º 3
0
static int amd8111_dev_probe(struct pci_dev *dev,
				const struct pci_device_id *id)
{
	struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];

	dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
					dev_info->err_dev, NULL);

	if (!dev_info->dev) {
		printk(KERN_ERR "EDAC device not found:"
			"vendor %x, device %x, name %s\n",
			PCI_VENDOR_ID_AMD, dev_info->err_dev,
			dev_info->ctl_name);
		return -ENODEV;
	}

	if (pci_enable_device(dev_info->dev)) {
		pci_dev_put(dev_info->dev);
		printk(KERN_ERR "failed to enable:"
			"vendor %x, device %x, name %s\n",
			PCI_VENDOR_ID_AMD, dev_info->err_dev,
			dev_info->ctl_name);
		return -ENODEV;
	}

	/*
	 * we do not allocate extra private structure for
	 * edac_device_ctl_info, but make use of existing
	 * one instead.
	*/
	dev_info->edac_idx = edac_device_alloc_index();
	dev_info->edac_dev =
		edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
					   NULL, 0, 0,
					   NULL, 0, dev_info->edac_idx);
	if (!dev_info->edac_dev)
		return -ENOMEM;

	dev_info->edac_dev->pvt_info = dev_info;
	dev_info->edac_dev->dev = &dev_info->dev->dev;
	dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
	dev_info->edac_dev->ctl_name = dev_info->ctl_name;
	dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);

	if (edac_op_state == EDAC_OPSTATE_POLL)
		dev_info->edac_dev->edac_check = dev_info->check;

	if (dev_info->init)
		dev_info->init(dev_info);

	if (edac_device_add_device(dev_info->edac_dev) > 0) {
		printk(KERN_ERR "failed to add edac_dev for %s\n",
			dev_info->ctl_name);
		edac_device_free_ctl_info(dev_info->edac_dev);
		return -ENODEV;
	}

	printk(KERN_INFO "added one edac_dev on AMD8111 "
		"vendor %x, device %x, name %s\n",
		PCI_VENDOR_ID_AMD, dev_info->err_dev,
		dev_info->ctl_name);

	return 0;
}
Exemplo n.º 4
0
static int __devinit mpc85xx_l2_err_probe(struct of_device *op,
					  const struct of_device_id *match)
{
	struct edac_device_ctl_info *edac_dev;
	struct mpc85xx_l2_pdata *pdata;
	struct resource r;
	int res;

	if (!devres_open_group(&op->dev, mpc85xx_l2_err_probe, GFP_KERNEL))
		return -ENOMEM;

	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
					      "cpu", 1, "L", 1, 2, NULL, 0,
					      edac_dev_idx);
	if (!edac_dev) {
		devres_release_group(&op->dev, mpc85xx_l2_err_probe);
		return -ENOMEM;
	}

	pdata = edac_dev->pvt_info;
	pdata->name = "mpc85xx_l2_err";
	pdata->irq = NO_IRQ;
	edac_dev->dev = &op->dev;
	dev_set_drvdata(edac_dev->dev, edac_dev);
	edac_dev->ctl_name = pdata->name;
	edac_dev->dev_name = pdata->name;

	res = of_address_to_resource(op->node, 0, &r);
	if (res) {
		printk(KERN_ERR "%s: Unable to get resource for "
		       "L2 err regs\n", __func__);
		goto err;
	}

	/* we only need the error registers */
	r.start += 0xe00;

	if (!devm_request_mem_region(&op->dev, r.start,
				     r.end - r.start + 1, pdata->name)) {
		printk(KERN_ERR "%s: Error while requesting mem region\n",
		       __func__);
		res = -EBUSY;
		goto err;
	}

	pdata->l2_vbase = devm_ioremap(&op->dev, r.start, r.end - r.start + 1);
	if (!pdata->l2_vbase) {
		printk(KERN_ERR "%s: Unable to setup L2 err regs\n", __func__);
		res = -ENOMEM;
		goto err;
	}

	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDET, ~0);

	orig_l2_err_disable = in_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS);

	/* clear the err_dis */
	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, 0);

	edac_dev->mod_name = EDAC_MOD_STR;

	if (edac_op_state == EDAC_OPSTATE_POLL)
		edac_dev->edac_check = mpc85xx_l2_check;

	mpc85xx_set_l2_sysfs_attributes(edac_dev);

	pdata->edac_idx = edac_dev_idx++;

	if (edac_device_add_device(edac_dev) > 0) {
		debugf3("%s(): failed edac_device_add_device()\n", __func__);
		goto err;
	}

	if (edac_op_state == EDAC_OPSTATE_INT) {
		pdata->irq = irq_of_parse_and_map(op->node, 0);
		res = devm_request_irq(&op->dev, pdata->irq,
				       mpc85xx_l2_isr, IRQF_DISABLED,
				       "[EDAC] L2 err", edac_dev);
		if (res < 0) {
			printk(KERN_ERR
			       "%s: Unable to requiest irq %d for "
			       "MPC85xx L2 err\n", __func__, pdata->irq);
			irq_dispose_mapping(pdata->irq);
			res = -ENODEV;
			goto err2;
		}

		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for L2 Err\n",
		       pdata->irq);

		edac_dev->op_state = OP_RUNNING_INTERRUPT;

		out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, L2_EIE_MASK);
	}

	devres_remove_group(&op->dev, mpc85xx_l2_err_probe);

	debugf3("%s(): success\n", __func__);
	printk(KERN_INFO EDAC_MOD_STR " L2 err registered\n");

	return 0;

err2:
	edac_device_del_device(&op->dev);
err:
	devres_release_group(&op->dev, mpc85xx_l2_err_probe);
	edac_device_free_ctl_info(edac_dev);
	return res;
}
static int __devinit highbank_l2_err_probe(struct platform_device *pdev)
{
	struct edac_device_ctl_info *dci;
	struct hb_l2_drvdata *drvdata;
	struct resource *r;
	int res = 0;

	dci = edac_device_alloc_ctl_info(sizeof(*drvdata), "cpu",
		1, "L", 1, 2, NULL, 0, 0);
	if (!dci)
		return -ENOMEM;

	drvdata = dci->pvt_info;
	dci->dev = &pdev->dev;
	platform_set_drvdata(pdev, dci);

	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
		return -ENOMEM;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "Unable to get mem resource\n");
		res = -ENODEV;
		goto err;
	}

	if (!devm_request_mem_region(&pdev->dev, r->start,
				     resource_size(r), dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "Error while requesting mem region\n");
		res = -EBUSY;
		goto err;
	}

	drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
	if (!drvdata->base) {
		dev_err(&pdev->dev, "Unable to map regs\n");
		res = -ENOMEM;
		goto err;
	}

	drvdata->db_irq = platform_get_irq(pdev, 0);
	res = devm_request_irq(&pdev->dev, drvdata->db_irq,
			       highbank_l2_err_handler,
			       0, dev_name(&pdev->dev), dci);
	if (res < 0)
		goto err;

	drvdata->sb_irq = platform_get_irq(pdev, 1);
	res = devm_request_irq(&pdev->dev, drvdata->sb_irq,
			       highbank_l2_err_handler,
			       0, dev_name(&pdev->dev), dci);
	if (res < 0)
		goto err;

	dci->mod_name = dev_name(&pdev->dev);
	dci->dev_name = dev_name(&pdev->dev);

	if (edac_device_add_device(dci))
		goto err;

	devres_close_group(&pdev->dev, NULL);
	return 0;
err:
	devres_release_group(&pdev->dev, NULL);
	edac_device_free_ctl_info(dci);
	return res;
}
Exemplo n.º 6
0
/**
 * pl310_edac_l2_probe - Check controller and bind driver
 * @pdev:	Pointer to the platform_device struct
 *
 * This routine probes a specific arm,pl310-cache instance for binding
 * with the driver.
 *
 * Return: 0 if the controller instance was successfully bound to the
 * driver; otherwise, < 0 on error.
 */
static int pl310_edac_l2_probe(struct platform_device *pdev)
{
	struct edac_device_ctl_info *dci;
	struct pl310_edac_l2_priv *priv;
	int rc;
	struct resource *res;
	void __iomem *baseaddr;
	u32 regval;

	/* Get the data from the platform device */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	baseaddr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(baseaddr))
		return PTR_ERR(baseaddr);

	/* Check for the ecc enable status */
	if (pl310_edac_l2_get_paritystate(baseaddr) == false) {
		dev_err(&pdev->dev, "parity check not enabled\n");
		return -ENXIO;
	}

	dci = edac_device_alloc_ctl_info(sizeof(*priv), "l2cache",
					 1, "L", 1, 1, NULL, 0,
					 edac_device_alloc_index());
	if (IS_ERR(dci))
		return PTR_ERR(dci);

	priv = dci->pvt_info;
	priv->base = baseaddr;
	dci->dev = &pdev->dev;
	dci->mod_name = "pl310_edac_l2";
	dci->ctl_name = "pl310_l2_controller";
	dci->dev_name = dev_name(&pdev->dev);

	priv->irq = platform_get_irq(pdev, 0);
	rc = devm_request_irq(&pdev->dev, priv->irq,
				pl310_edac_l2_int_handler,
				0, dev_name(&pdev->dev), (void *)dci);
	if (rc < 0) {
		dci->edac_check = pl310_edac_l2_poll_handler;
		edac_op_state = EDAC_OPSTATE_POLL;
	}

	rc = edac_device_add_device(dci);
	if (rc) {
		dev_err(&pdev->dev, "failed to register with EDAC core\n");
		goto del_edac_device;
	}

	if (edac_op_state != EDAC_OPSTATE_POLL) {
		regval = readl(priv->base+L2X0_INTR_MASK);
		regval |= (L2X0_INTR_PARRD_MASK | L2X0_INTR_PARRT_MASK);
		writel(regval, priv->base+L2X0_INTR_MASK);
	}

	return rc;

del_edac_device:
	edac_device_del_device(&pdev->dev);
	edac_device_free_ctl_info(dci);

	return rc;
}
Exemplo n.º 7
0
/**
 * zynqmp_ocm_edac_probe - Check controller and bind driver
 * @pdev:	Pointer to the platform_device struct
 *
 * Probes a specific controller instance for binding with the driver.
 *
 * Return: 0 if the controller instance was successfully bound to the
 * driver; otherwise, < 0 on error.
 */
static int zynqmp_ocm_edac_probe(struct platform_device *pdev)
{
	struct edac_device_ctl_info *dci;
	struct zynqmp_ocm_edac_priv *priv;
	int irq, status;
	struct resource *res;
	void __iomem *baseaddr;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	baseaddr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(baseaddr))
		return PTR_ERR(baseaddr);

	if (!zynqmp_ocm_edac_get_eccstate(baseaddr)) {
		edac_printk(KERN_INFO, EDAC_DEVICE,
				"ECC not enabled - Disabling EDAC driver\n");
		return -ENXIO;
	}

	dci = edac_device_alloc_ctl_info(sizeof(*priv), ZYNQMP_OCM_EDAC_STRING,
			1, ZYNQMP_OCM_EDAC_STRING, 1, 0, NULL, 0, 0);
	if (!dci) {
		edac_printk(KERN_ERR, EDAC_DEVICE,
				"Unable to allocate EDAC device\n");
		return -ENOMEM;
	}

	priv = dci->pvt_info;
	platform_set_drvdata(pdev, dci);
	dci->dev = &pdev->dev;
	priv->baseaddr = baseaddr;
	dci->mod_name = pdev->dev.driver->name;
	dci->ctl_name = ZYNQMP_OCM_EDAC_STRING;
	dci->dev_name = dev_name(&pdev->dev);

	zynqmp_set_ocm_edac_sysfs_attributes(dci);
	if (edac_device_add_device(dci))
		goto free_dev_ctl;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		edac_printk(KERN_ERR, EDAC_DEVICE,
				"No irq %d in DT\n", irq);
		return irq;
	}

	status = devm_request_irq(&pdev->dev, irq,
		zynqmp_ocm_edac_intr_handler,
		0, dev_name(&pdev->dev), dci);
	if (status < 0) {
		edac_printk(KERN_ERR, EDAC_DEVICE, "Failed to request Irq\n");
		goto free_edac_dev;
	}

	writel(OCM_CEUE_MASK, priv->baseaddr + OCM_IEN_OFST);

	return 0;

free_edac_dev:
	edac_device_del_device(&pdev->dev);
free_dev_ctl:
	edac_device_free_ctl_info(dci);

	return -1;
}