From patchwork Mon Aug 22 19:07:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 12951270 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C0B89C28D13 for ; Mon, 22 Aug 2022 19:19:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=cxb/qOlgEFjSW6AGCIlP15ca8R2RlLVp2sktGihknow=; b=WSjrr+0wFanxfZ 0ToavS8m3L/UuhREvm8R8k4COJhwvI2D/cnREt8KOoCXz3+1cv4v8JyfT5ts57ve93yOCgVoOkEv0 5JY6eekMhRG1J/YhETNR/PKJhKzcRiv6LnkFka86OxSz7ipQ4I6F2nGciwD5f+/TN35pnNV7dCbWO 8bw7NeZ3NI0XPduUn1akrUofTxXSYS377bruBmevUw4RBBhsLoguWgox3yFgL++7X1P0Kx+08j+PH kSI+sldMxK4aggxJFuK9oWJOCAr7VecChNxA7hSWjJtntQLVu/PAMUbGfn8NXNJ8345oVxfBah6MM NPx4nd6dKtBA7Yg3A/jA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oQCwI-00DxeP-9S; Mon, 22 Aug 2022 19:18:23 +0000 Received: from mail.baikalelectronics.com ([87.245.175.230]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oQCmS-00DrvC-Vo for linux-arm-kernel@lists.infradead.org; Mon, 22 Aug 2022 19:08:17 +0000 Received: from mail (mail.baikal.int [192.168.51.25]) by mail.baikalelectronics.com (Postfix) with ESMTP id 2A585DB3; Mon, 22 Aug 2022 22:11:00 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.com 2A585DB3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1661195460; bh=ZcQ3XBqEEpa5Cr3nLA0LgC2QC4fMFtsgZe8G2xxFXxE=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=QgVXChYRTQoyZGwDQ9zdd5gvm8b6R1M0M9lLMF38VQ37b4cHf5mumEHFtxWE+KSuf aXPc5bvGae+K1NufHSSftmyjKSj1Imj+gyhPO3FYE4OuqA6IpehnDK2E7bstZEuk7r W73ciDHyQD8gN+THymcJGIh5j2vIZyoxfFJrUqk8= Received: from localhost (192.168.168.10) by mail (192.168.51.25) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 22 Aug 2022 22:07:45 +0300 From: Serge Semin To: Rob Herring , Michal Simek , Borislav Petkov , Mauro Carvalho Chehab , Tony Luck , James Morse , Robert Richter CC: Serge Semin , Serge Semin , Alexey Malahov , Michail Ivanov , Pavel Parkhomenko , Punnaiah Choudary Kalluri , Manish Narani , Dinh Nguyen , Rob Herring , Krzysztof Kozlowski , , , , Subject: [PATCH 18/20] EDAC/synopsys: Drop unused platform-specific setup API Date: Mon, 22 Aug 2022 22:07:28 +0300 Message-ID: <20220822190730.27277-19-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20220822190730.27277-1-Sergey.Semin@baikalelectronics.ru> References: <20220822190730.27277-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220822_120813_635178_5EFE56E9 X-CRM114-Status: GOOD ( 25.96 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The driver now works with the Synopys DW uMCTL2 DDR IP-core only (Xilinx Zynq A05 DDRc support has been moved to the dedicated driver). Pretty much all the currently available IP-core revisions have got the same ECC and main DDR-config CSRs map. Thus there is no point in supporting the no longer used platform-specific API like the callbacks responsible for getting the ECC errors info, memory and device types, ECC state. All of that data can be retrieved in the same way on all the Synopys DW uMCTL2 DDR controller versions. Similarly there is no longer need in the DDR_ECC_INTR_SUPPORT and DDR_ECC_DATA_POISON_SUPPORT quirk flags since DW uMCTL2 always supports IRQs and data poisoning. Let's drop that infrastructure for good then. Signed-off-by: Serge Semin Reported-by: kernel test robot --- drivers/edac/synopsys_edac.c | 194 +++++++++-------------------------- 1 file changed, 51 insertions(+), 143 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 0cb84f183aed..e171c8d96274 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -31,9 +31,7 @@ #define SYNPS_EDAC_MOD_VER "1" /* DDR ECC Quirks */ -#define DDR_ECC_INTR_SUPPORT BIT(0) -#define DDR_ECC_DATA_POISON_SUPPORT BIT(1) -#define SYNPS_ZYNQMP_IRQ_REGS BIT(2) +#define SYNPS_ZYNQMP_IRQ_REGS BIT(0) /* Synopsys DDR memory controller registers that are relevant to ECC */ @@ -278,28 +276,20 @@ struct synps_edac_priv { }; /** - * struct synps_platform_data - synps platform data structure. - * @get_error_info: Get EDAC error info. - * @get_mtype: Get mtype. - * @get_dtype: Get dtype. - * @get_ecc_state: Get ECC state. - * @quirks: To differentiate IPs. + * struct synps_platform_data - Synopsys uMCTL2 DDRC platform data. + * @quirks: IP-core specific quirks. */ struct synps_platform_data { - int (*get_error_info)(struct synps_edac_priv *priv); - enum mem_type (*get_mtype)(const void __iomem *base); - enum dev_type (*get_dtype)(const void __iomem *base); - bool (*get_ecc_state)(void __iomem *base); - int quirks; + u32 quirks; }; /** - * zynqmp_get_error_info - Get the current ECC error info. + * synps_get_error_info - Get the current ECC error info. * @priv: DDR memory controller private instance data. * * Return: one if there is no error otherwise returns zero. */ -static int zynqmp_get_error_info(struct synps_edac_priv *priv) +static int synps_get_error_info(struct synps_edac_priv *priv) { struct synps_ecc_status *p; u32 regval, clearval; @@ -374,17 +364,11 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p) if (p->ce_cnt) { pinf = &p->ceinfo; - if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) { - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x", - pinf->row, pinf->col, pinf->bank, pinf->bankgrp, - pinf->bitpos, pinf->data); - } else { - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "Row %d Bank %d Col %d Bit: %d Data: 0x%08x", - pinf->row, pinf->bank, pinf->col, - pinf->bitpos, pinf->data); - } + + snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, + "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x", + pinf->row, pinf->col, pinf->bank, pinf->bankgrp, + pinf->bitpos, pinf->data); edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, p->ce_cnt, 0, 0, 0, 0, 0, -1, @@ -393,15 +377,10 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p) if (p->ue_cnt) { pinf = &p->ueinfo; - if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) { - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "Row %d Col %d Bank %d Bank Group %d", - pinf->row, pinf->col, pinf->bank, pinf->bankgrp); - } else { - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "Row %d Bank %d Col %d", - pinf->row, pinf->bank, pinf->col); - } + + snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, + "Row %d Col %d Bank %d Bank Group %d", + pinf->row, pinf->col, pinf->bank, pinf->bankgrp); edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, p->ue_cnt, 0, 0, 0, 0, 0, -1, @@ -460,13 +439,11 @@ static void disable_intr(struct synps_edac_priv *priv) */ static irqreturn_t intr_handler(int irq, void *dev_id) { - const struct synps_platform_data *p_data; struct mem_ctl_info *mci = dev_id; struct synps_edac_priv *priv; int status, regval; priv = mci->pvt_info; - p_data = priv->p_data; if (priv->p_data->quirks & SYNPS_ZYNQMP_IRQ_REGS) { regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST); @@ -475,7 +452,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id) return IRQ_NONE; } - status = p_data->get_error_info(priv); + status = synps_get_error_info(priv); if (status) return IRQ_NONE; @@ -489,34 +466,7 @@ static irqreturn_t intr_handler(int irq, void *dev_id) } /** - * check_errors - Check controller for ECC errors. - * @mci: EDAC memory controller instance. - * - * Check and post ECC errors. Called by the polling thread. - */ -static void check_errors(struct mem_ctl_info *mci) -{ - const struct synps_platform_data *p_data; - struct synps_edac_priv *priv; - int status; - - priv = mci->pvt_info; - p_data = priv->p_data; - - status = p_data->get_error_info(priv); - if (status) - return; - - priv->ce_cnt += priv->stat.ce_cnt; - priv->ue_cnt += priv->stat.ue_cnt; - handle_error(mci, &priv->stat); - - edac_dbg(3, "Total error count CE %d UE %d\n", - priv->ce_cnt, priv->ue_cnt); -} - -/** - * zynqmp_get_dtype - Return the controller memory width. + * synps_get_dtype - Return the controller memory width. * @base: DDR memory controller base address. * * Get the EDAC device type width appropriate for the current controller @@ -524,7 +474,7 @@ static void check_errors(struct mem_ctl_info *mci) * * Return: a device type width enumeration. */ -static enum dev_type zynqmp_get_dtype(const void __iomem *base) +static enum dev_type synps_get_dtype(const void __iomem *base) { u32 regval; @@ -548,14 +498,14 @@ static enum dev_type zynqmp_get_dtype(const void __iomem *base) } /** - * zynqmp_get_ecc_state - Return the controller ECC enable/disable status. + * synps_get_ecc_state - Return the controller ECC enable/disable status. * @base: DDR memory controller base address. * * Get the ECC enable/disable status for the controller. * * Return: a ECC status boolean i.e true/false - enabled/disabled. */ -static bool zynqmp_get_ecc_state(void __iomem *base) +static bool synps_get_ecc_state(void __iomem *base) { u32 regval; @@ -579,7 +529,7 @@ static u32 get_memsize(void) } /** - * zynqmp_get_mtype - Returns controller memory type. + * synps_get_mtype - Returns controller memory type. * @base: Synopsys ECC status structure. * * Get the EDAC memory type appropriate for the current controller @@ -587,7 +537,7 @@ static u32 get_memsize(void) * * Return: a memory type enumeration. */ -static enum mem_type zynqmp_get_mtype(const void __iomem *base) +static enum mem_type synps_get_mtype(const void __iomem *base) { enum mem_type mt; u32 memtype; @@ -616,14 +566,11 @@ static enum mem_type zynqmp_get_mtype(const void __iomem *base) static void init_csrows(struct mem_ctl_info *mci) { struct synps_edac_priv *priv = mci->pvt_info; - const struct synps_platform_data *p_data; struct csrow_info *csi; struct dimm_info *dimm; u32 size, row; int j; - p_data = priv->p_data; - for (row = 0; row < mci->nr_csrows; row++) { csi = mci->csrows[row]; size = get_memsize(); @@ -631,10 +578,10 @@ static void init_csrows(struct mem_ctl_info *mci) for (j = 0; j < csi->nr_channels; j++) { dimm = csi->channels[j]->dimm; dimm->edac_mode = EDAC_SECDED; - dimm->mtype = p_data->get_mtype(priv->baseaddr); + dimm->mtype = synps_get_mtype(priv->baseaddr); dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels; dimm->grain = SYNPS_EDAC_ERR_GRAIN; - dimm->dtype = p_data->get_dtype(priv->baseaddr); + dimm->dtype = synps_get_dtype(priv->baseaddr); } } } @@ -667,12 +614,7 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev) mci->dev_name = SYNPS_EDAC_MOD_STRING; mci->mod_name = SYNPS_EDAC_MOD_VER; - if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) { - edac_op_state = EDAC_OPSTATE_INT; - } else { - edac_op_state = EDAC_OPSTATE_POLL; - mci->edac_check = check_errors; - } + edac_op_state = EDAC_OPSTATE_INT; mci->ctl_page_to_phys = NULL; @@ -704,47 +646,6 @@ static int setup_irq(struct mem_ctl_info *mci, return 0; } -static const struct synps_platform_data zynqmp_edac_def = { - .get_error_info = zynqmp_get_error_info, - .get_mtype = zynqmp_get_mtype, - .get_dtype = zynqmp_get_dtype, - .get_ecc_state = zynqmp_get_ecc_state, - .quirks = (DDR_ECC_INTR_SUPPORT | SYNPS_ZYNQMP_IRQ_REGS -#ifdef CONFIG_EDAC_DEBUG - | DDR_ECC_DATA_POISON_SUPPORT -#endif - ), -}; - -static const struct synps_platform_data synopsys_edac_def = { - .get_error_info = zynqmp_get_error_info, - .get_mtype = zynqmp_get_mtype, - .get_dtype = zynqmp_get_dtype, - .get_ecc_state = zynqmp_get_ecc_state, - .quirks = (DDR_ECC_INTR_SUPPORT -#ifdef CONFIG_EDAC_DEBUG - | DDR_ECC_DATA_POISON_SUPPORT -#endif - ), -}; - - -static const struct of_device_id synps_edac_match[] = { - { - .compatible = "xlnx,zynqmp-ddrc-2.40a", - .data = (void *)&zynqmp_edac_def - }, - { - .compatible = "snps,ddrc-3.80a", - .data = (void *)&synopsys_edac_def - }, - { - /* end of table */ - } -}; - -MODULE_DEVICE_TABLE(of, synps_edac_match); - #ifdef CONFIG_EDAC_DEBUG /** @@ -1135,7 +1036,7 @@ static int mc_probe(struct platform_device *pdev) if (!p_data) return -ENODEV; - if (!p_data->get_ecc_state(baseaddr)) { + if (!synps_get_ecc_state(baseaddr)) { edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n"); return -ENXIO; } @@ -1162,11 +1063,9 @@ static int mc_probe(struct platform_device *pdev) mc_init(mci, pdev); - if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) { - rc = setup_irq(mci, pdev); - if (rc) - goto free_edac_mc; - } + rc = setup_irq(mci, pdev); + if (rc) + goto free_edac_mc; rc = edac_mc_add_mc(mci); if (rc) { @@ -1176,17 +1075,13 @@ static int mc_probe(struct platform_device *pdev) } #ifdef CONFIG_EDAC_DEBUG - if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) { - rc = edac_create_sysfs_attributes(mci); - if (rc) { - edac_printk(KERN_ERR, EDAC_MC, - "Failed to create sysfs entries\n"); - goto free_edac_mc; - } + rc = edac_create_sysfs_attributes(mci); + if (rc) { + edac_printk(KERN_ERR, EDAC_MC, "Failed to create sysfs entries\n"); + goto free_edac_mc; } - if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) - setup_address_map(priv); + setup_address_map(priv); #endif return rc; @@ -1208,12 +1103,10 @@ static int mc_remove(struct platform_device *pdev) struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct synps_edac_priv *priv = mci->pvt_info; - if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) - disable_intr(priv); + disable_intr(priv); #ifdef CONFIG_EDAC_DEBUG - if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) - edac_remove_sysfs_attributes(mci); + edac_remove_sysfs_attributes(mci); #endif edac_mc_del_mc(&pdev->dev); @@ -1222,6 +1115,21 @@ static int mc_remove(struct platform_device *pdev) return 0; } +static const struct synps_platform_data zynqmp_edac_def = { + .quirks = SYNPS_ZYNQMP_IRQ_REGS, +}; + +static const struct synps_platform_data synopsys_edac_def = { + .quirks = 0, +}; + +static const struct of_device_id synps_edac_match[] = { + { .compatible = "xlnx,zynqmp-ddrc-2.40a", .data = &zynqmp_edac_def }, + { .compatible = "snps,ddrc-3.80a", .data = &synopsys_edac_def }, + { } +}; +MODULE_DEVICE_TABLE(of, synps_edac_match); + static struct platform_driver synps_edac_mc_driver = { .driver = { .name = "synopsys-edac",