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

Commit 5db73cbf authored by Venkata Narendra Kumar Gutta's avatar Venkata Narendra Kumar Gutta
Browse files

drivers: edac: Add polling and other support to edac driver



This change is a squash of the following commits taken from
msm-4.14.

1. commit <fdbf8562530b98f> ("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, if the ECC IRQ number is not available,
default to polling based ECC to ensure that LLCC ECC errors do
not go by unnoticed.

2. commit <567f38265c98f79> ("drivers: edac: Allow IRQ line to
be shared")
Other drivers in the kernel might want to use the same interrupt
line that is used for llcc edac. Allow the interrupt line to be
shared with other drivers by marking the line as shared one.

Also, add required configs to control panic on correctable and
uncorrectable errors.

Change-Id: I4ef6a7aead8741e9a36eebf76c9cb44be3133981
Signed-off-by: default avatarVenkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>
parent f29a17af
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -515,4 +515,26 @@ config EDAC_QCOM
	  For debugging issues having to do with stability and overall system
	  health, you should probably say 'Y' here.

config EDAC_QCOM_LLCC_PANIC_ON_CE
        depends on EDAC_QCOM
        bool "panic on correctable errors - qcom llcc"
        help
          Forcibly cause kernel panic if a correctable error (CE) is
          detected, even though the error is (by definition) correctable and
          would otherwise result in no adverse system effects. This can reduce
          debugging times on hardware which my be operating at voltages or
          frequencies outside normal specifications.

          For production builds, you should definitely say 'N' here.

config EDAC_QCOM_LLCC_PANIC_ON_UE
        depends on EDAC_QCOM
        bool "Panic on uncorrectable errors - qcom llcc"
        help
          Forcibly cause a kernel panic if an uncorrectable error (UE) is
          detected. This can reduce debugging times on hardware which may be
          operating at voltages or frequencies outside normal specification.

          For production builds, you should probably say 'N' here.

endif # EDAC
+34 −11
Original line number Diff line number Diff line
@@ -16,7 +16,17 @@

#define EDAC_LLCC                       "qcom_llcc"

#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE
#define LLCC_ERP_PANIC_ON_CE            1
#else
#define LLCC_ERP_PANIC_ON_CE            0
#endif

#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE
#define LLCC_ERP_PANIC_ON_UE            1
#else
#define LLCC_ERP_PANIC_ON_UE            0
#endif

#define TRP_SYN_REG_CNT                 6
#define DRP_SYN_REG_CNT                 8
@@ -76,6 +86,9 @@
#define DRP0_INTERRUPT_ENABLE           BIT(6)
#define SB_DB_DRP_INTERRUPT_ENABLE      0x3

static int poll_msec = 5000;
module_param(poll_msec, int, 0444);

enum {
	LLCC_DRAM_CE = 0,
	LLCC_DRAM_UE,
@@ -336,6 +349,11 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl)
	return irq_rc;
}

static void qcom_llcc_poll_cache_errors(struct edac_device_ctl_info *edev_ctl)
{
	llcc_ecc_irq_handler(0, edev_ctl);
}

static int qcom_llcc_edac_probe(struct platform_device *pdev)
{
	struct llcc_drv_data *llcc_driv_data = pdev->dev.platform_data;
@@ -362,24 +380,29 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
	edev_ctl->dev_name = dev_name(dev);
	edev_ctl->ctl_name = "llcc";
	edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
	edev_ctl->panic_on_ce = LLCC_ERP_PANIC_ON_CE;
	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;
	}
		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;
	} else {
		rc = devm_request_irq(dev, ecc_irq, llcc_ecc_irq_handler,
			      IRQF_TRIGGER_HIGH, "llcc_ecc", edev_ctl);
			      IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
			      "llcc_ecc", edev_ctl);
		if (rc)
			goto out_dev;
	}

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

	platform_set_drvdata(pdev, edev_ctl);

	return rc;