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

Commit fdbf8562 authored by Isaac J. Manjarres's avatar Isaac J. Manjarres
Browse files

drivers: edac: Use polling based ECC if there is no ECC IRQ



The current implementation of the LLCC's ECC mechanism
relies on an IRQ number being defined for ECC. When this
number is not available, there will not be any attempt to
see if ECC is necessary, which is not desirable.

Instead, if the ECC IRQ number is not available, default to
polling based ECC to ensure that LLCC ECC errors do not go
by unnoticed. Also, remove the EDAC_POLL_LLCC config,
as it is no longer necessary.

Change-Id: I003442400f4f42dcbfb1eaf4c57fe95449017e2a
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent 623a16f3
Loading
Loading
Loading
Loading
+0 −11
Original line number Diff line number Diff line
@@ -543,17 +543,6 @@ config EDAC_QCOM_LLCC
	  For debugging issues having to do with stability and overall system
	  health, you should probably say 'Y' here.

config EDAC_LLCC_POLL
	depends on EDAC_QCOM_LLCC
	bool "Poll on LLCC ECC registers - LLCC"
	help
	   This option chooses whether or not you want to poll on the LLCC
	   ECC registers. When this is enabled, the polling rate can be set as
	   a module parameter. By default, it will call the polling function
	   every second.
	   This option should only be used if the associated interrupt lines
	   are not enabled.

config EDAC_QCOM_LLCC_PANIC_ON_CE
	depends on EDAC_QCOM_LLCC
	bool "panic on correctable errors - qcom llcc"
+17 −32
Original line number Diff line number Diff line
@@ -79,15 +79,8 @@
#define DRP_TRP_INT_CLEAR	0x3
#define DRP_TRP_CNT_CLEAR	0x3

#ifdef CONFIG_EDAC_LLCC_POLL
static int poll_msec = 5000;
module_param(poll_msec, int, 0444);
#endif

static int interrupt_mode = 1;
module_param(interrupt_mode, int, 0444);
MODULE_PARM_DESC(interrupt_mode,
		 "Controls whether to use interrupt or poll mode");

enum {
	LLCC_DRAM_CE = 0,
@@ -341,12 +334,10 @@ static irqreturn_t qcom_llcc_check_cache_errors
	return irq_rc;
}

#ifdef CONFIG_EDAC_LLCC_POLL
static void qcom_llcc_poll_cache_errors(struct edac_device_ctl_info *edev_ctl)
{
	qcom_llcc_check_cache_errors(edev_ctl);
}
#endif

static irqreturn_t llcc_ecc_irq_handler
			(int irq, void *edev_ctl)
@@ -388,11 +379,6 @@ static int qcom_llcc_erp_probe(struct platform_device *pdev)
	edev_ctl->mod_name = dev_name(dev);
	edev_ctl->dev_name = dev_name(dev);
	edev_ctl->ctl_name = "llcc";
#ifdef CONFIG_EDAC_LLCC_POLL
	edev_ctl->poll_msec = poll_msec;
	edev_ctl->edac_check = qcom_llcc_poll_cache_errors;
	edev_ctl->defer_work = 1;
#endif
	edev_ctl->panic_on_ce = LLCC_ERP_PANIC_ON_CE;
	edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;

@@ -400,55 +386,54 @@ static int qcom_llcc_erp_probe(struct platform_device *pdev)
	drv->num_banks = num_banks;
	drv->llcc_map = llcc_map;

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

	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");
		rc = -ENOMEM;
		goto out_dev;
		goto out_mem;
	}

	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");
		goto out_dev;
		goto out_mem;
	}

	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");
		goto out_dev;
		goto out_mem;
	}

	platform_set_drvdata(pdev, edev_ctl);

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

	rc = platform_get_irq_byname(pdev, "ecc_irq");
	if (rc > 0) {
		drv->ecc_irq = rc;
		rc = devm_request_irq(dev, drv->ecc_irq, llcc_ecc_irq_handler,
				IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
				"llcc_ecc", edev_ctl);
		if (rc) {
			dev_err(dev, "failed to request ecc irq\n");
			goto out_dev;
			goto out_mem;
		}
	} else {
		dev_info(dev, "No ECC IRQ; defaulting to polling mode\n");
		edev_ctl->poll_msec = poll_msec;
		edev_ctl->edac_check = qcom_llcc_poll_cache_errors;
		edev_ctl->defer_work = 1;
	}

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

	platform_set_drvdata(pdev, edev_ctl);
	return 0;

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