mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
Merge "drivers: llcc edac: Add Cache Error Reporting driver for llcc"
This commit is contained in:
commit
1e336131de
2 changed files with 67 additions and 20 deletions
|
|
@ -550,6 +550,29 @@ 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
|
||||
select EDAC_PANIC_ON_CE
|
||||
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.
|
||||
|
||||
config EDAC_ASPEED
|
||||
tristate "Aspeed AST 2500 SoC"
|
||||
depends on MACH_ASPEED_G5
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/edac.h>
|
||||
|
|
@ -16,7 +16,13 @@
|
|||
|
||||
#define EDAC_LLCC "qcom_llcc"
|
||||
|
||||
#define LLCC_ERP_PANIC_ON_CE 1
|
||||
|
||||
#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
|
||||
|
|
@ -26,7 +32,7 @@
|
|||
#define LLCC_LB_CNT_SHIFT 28
|
||||
|
||||
/* Single & double bit syndrome register offsets */
|
||||
#define TRP_ECC_SB_ERR_SYN0 0x0002304c
|
||||
#define TRP_ECC_SB_ERR_SYN0 0x0002034c
|
||||
#define TRP_ECC_DB_ERR_SYN0 0x00020370
|
||||
#define DRP_ECC_SB_ERR_SYN0 0x0004204c
|
||||
#define DRP_ECC_DB_ERR_SYN0 0x00042070
|
||||
|
|
@ -76,6 +82,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,
|
||||
|
|
@ -292,6 +301,7 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl)
|
|||
struct llcc_drv_data *drv = edac_dev_ctl->pvt_info;
|
||||
irqreturn_t irq_rc = IRQ_NONE;
|
||||
u32 drp_error, trp_error, i;
|
||||
bool irq_handled = false;
|
||||
int ret;
|
||||
|
||||
/* Iterate over the banks and look for Tag RAM or Data RAM errors */
|
||||
|
|
@ -310,7 +320,7 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl)
|
|||
ret = dump_syn_reg(edev_ctl, LLCC_DRAM_UE, i);
|
||||
}
|
||||
if (!ret)
|
||||
irq_rc = IRQ_HANDLED;
|
||||
irq_handled = true;
|
||||
|
||||
ret = regmap_read(drv->regmap,
|
||||
drv->offsets[i] + TRP_INTERRUPT_0_STATUS,
|
||||
|
|
@ -326,12 +336,20 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl)
|
|||
ret = dump_syn_reg(edev_ctl, LLCC_TRAM_UE, i);
|
||||
}
|
||||
if (!ret)
|
||||
irq_rc = IRQ_HANDLED;
|
||||
irq_handled = true;
|
||||
}
|
||||
|
||||
if (irq_handled)
|
||||
irq_rc = IRQ_HANDLED;
|
||||
|
||||
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;
|
||||
|
|
@ -340,10 +358,6 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
|
|||
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,
|
||||
|
|
@ -358,32 +372,42 @@ 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;
|
||||
#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE
|
||||
edev_ctl->panic_on_ce = LLCC_ERP_PANIC_ON_CE;
|
||||
#endif
|
||||
edev_ctl->pvt_info = llcc_driv_data;
|
||||
|
||||
/* Request for ecc irq */
|
||||
ecc_irq = llcc_driv_data->ecc_irq;
|
||||
if (ecc_irq < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
rc = edac_device_add_device(edev_ctl);
|
||||
if (rc)
|
||||
goto out_mem;
|
||||
|
||||
platform_set_drvdata(pdev, edev_ctl);
|
||||
if (ecc_irq >= 0) {
|
||||
rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap);
|
||||
if (rc)
|
||||
goto out_dev;
|
||||
|
||||
/* 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_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
|
||||
"llcc_ecc", edev_ctl);
|
||||
if (rc)
|
||||
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;
|
||||
|
||||
platform_set_drvdata(pdev, edev_ctl);
|
||||
return rc;
|
||||
|
||||
out_dev:
|
||||
edac_device_del_device(edev_ctl->dev);
|
||||
out_mem:
|
||||
edac_device_free_ctl_info(edev_ctl);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue