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

Commit 78144393 authored by Channagoud Kadabi's avatar Channagoud Kadabi
Browse files

drivers: edac: Update banks for edac sysfs entry



Pass the number of banks and bank name to edac framework to have sysfs
nodes created for each llcc bank for reading out the ce/ue error counts.
Add edac device before registering for interrupt, as the interrupt
handler uses edac device for interrupt processing and would result into
crash if there is any ecc error immidiately after registering the interrupt
and before adding the edac device.

Change-Id: I2c36458684feaf68a63203f871df91f862354e6a
Signed-off-by: default avatarChannagoud Kadabi <ckadabi@codeaurora.org>
parent 4bb2701f
Loading
Loading
Loading
Loading
+35 −24
Original line number Diff line number Diff line
@@ -291,7 +291,7 @@ static void dump_syn_reg(struct edac_device_ctl_info *edev_ctl,

	qcom_llcc_clear_errors(err_type, drv);

	errors[err_type].func(edev_ctl, 0, 0, errors[err_type].msg);
	errors[err_type].func(edev_ctl, 0, bank, errors[err_type].msg);
}

static void qcom_llcc_check_cache_errors
@@ -353,10 +353,26 @@ static int qcom_llcc_erp_probe(struct platform_device *pdev)
	struct erp_drvdata *drv;
	struct edac_device_ctl_info *edev_ctl;
	struct device *dev = &pdev->dev;
	u32 num_banks;
	struct regmap *llcc_map = NULL;

	llcc_map = syscon_node_to_regmap(dev->parent->of_node);
	if (IS_ERR(llcc_map)) {
		dev_err(dev, "no regmap for syscon llcc parent\n");
		return -ENOMEM;
	}

	/* Find the number of LLC banks supported */
	regmap_read(llcc_map, LLCC_COMMON_STATUS0,
		    &num_banks);

	num_banks &= LLCC_LB_CNT_MASK;
	num_banks >>= LLCC_LB_CNT_SHIFT;

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

	if (!edev_ctl)
		return -ENOMEM;
@@ -374,63 +390,58 @@ static int qcom_llcc_erp_probe(struct platform_device *pdev)
	edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;

	drv = edev_ctl->pvt_info;
	drv->num_banks = num_banks;
	drv->llcc_map = llcc_map;

	drv->llcc_map = syscon_node_to_regmap(dev->parent->of_node);
	if (IS_ERR(drv->llcc_map)) {
		dev_err(dev, "no regmap for syscon llcc parent\n");
		rc = -ENOMEM;
		goto out;
	}
	rc = edac_device_add_device(edev_ctl);
	if (rc)
		goto out_mem;

	if (interrupt_mode) {
		drv->ecc_irq = platform_get_irq_byname(pdev, "ecc_irq");
		if (!drv->ecc_irq) {
			rc = -ENODEV;
			goto out;
			goto out_dev;
		}

		rc = devm_request_irq(dev, drv->ecc_irq, llcc_ecc_irq_handler,
				IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl);
		if (rc) {
			dev_err(dev, "failed to request ecc irq\n");
			goto out;
			goto out_dev;
		}
	}

	/* Find the number of LLC banks supported */
	regmap_read(drv->llcc_map, LLCC_COMMON_STATUS0,
		    &drv->num_banks);

	drv->num_banks &= LLCC_LB_CNT_MASK;
	drv->num_banks >>= LLCC_LB_CNT_SHIFT;

	drv->llcc_banks = devm_kzalloc(&pdev->dev,
		sizeof(u32) * drv->num_banks, GFP_KERNEL);

	if (!drv->llcc_banks) {
		dev_err(dev, "Cannot allocate memory for llcc_banks\n");
		return -ENOMEM;
		rc = -ENOMEM;
		goto out_dev;
	}

	rc = of_property_read_u32_array(dev->parent->of_node,
			"qcom,llcc-banks-off", drv->llcc_banks, drv->num_banks);
	if (rc) {
		dev_err(dev, "Cannot read llcc-banks-off property\n");
		return -EINVAL;
		goto out_dev;
	}

	rc = of_property_read_u32(dev->parent->of_node,
			"qcom,llcc-broadcast-off", &drv->b_off);
	if (rc) {
		dev_err(dev, "Cannot read llcc-broadcast-off property\n");
		return -EINVAL;
		goto out_dev;
	}

	platform_set_drvdata(pdev, edev_ctl);

	rc = edac_device_add_device(edev_ctl);
out:
	if (rc)
	return 0;

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

	return rc;