diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c index 08e3d388e153..d78926742510 100644 --- a/drivers/soc/qcom/llcc-slice.c +++ b/drivers/soc/qcom/llcc-slice.c @@ -225,7 +225,7 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) u32 attr0_val; u32 max_cap_cacheline; u32 sz; - int ret; + int ret = 0; const struct llcc_slice_config *llcc_table; struct llcc_slice_desc desc; @@ -283,6 +283,7 @@ int qcom_llcc_probe(struct platform_device *pdev, struct resource *llcc_banks_res, *llcc_bcast_res; void __iomem *llcc_banks_base, *llcc_bcast_base; int ret, i; + struct platform_device *llcc_edac; drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) @@ -342,7 +343,20 @@ int qcom_llcc_probe(struct platform_device *pdev, mutex_init(&drv_data->lock); platform_set_drvdata(pdev, drv_data); - return qcom_llcc_cfg_program(pdev); + ret = qcom_llcc_cfg_program(pdev); + if (ret) + return ret; + + drv_data->ecc_irq = platform_get_irq(pdev, 0); + if (drv_data->ecc_irq >= 0) { + llcc_edac = platform_device_register_data(&pdev->dev, + "qcom_llcc_edac", -1, drv_data, + sizeof(*drv_data)); + if (IS_ERR(llcc_edac)) + dev_err(dev, "Failed to register llcc edac driver\n"); + } + + return ret; } EXPORT_SYMBOL_GPL(qcom_llcc_probe); diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index c681e795b587..2e4b34d2617e 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -78,6 +78,7 @@ struct llcc_slice_config { * @num_banks: Number of llcc banks * @bitmap: Bit map to track the active slice ids * @offsets: Pointer to the bank offsets array + * @ecc_irq: interrupt for llcc cache error detection and reporting */ struct llcc_drv_data { struct regmap *regmap; @@ -89,6 +90,7 @@ struct llcc_drv_data { u32 num_banks; unsigned long *bitmap; u32 *offsets; + int ecc_irq; }; #if IS_ENABLED(CONFIG_QCOM_LLCC)