From patchwork Wed Sep 20 19:26:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393334 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 1B59DC04FF5 for ; Wed, 20 Sep 2023 19:29:18 +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=/DKKA57vsIIZiB6/M3ddgWRQVM7Xxkx3463CgdJsEK8=; b=lHmYybpfaYBz9F zPAavPce2u+lsZWzGGuWGXcENoQRoRFNIGSTVHckSKxLTVpWRKR4Vwnz7QPqJvFb9Qgw1OCDvJwou Z7ZUNZcxvIhXXzsdgv8vX6w0z8AKXDqd/Q3e+oFM43IiM/Eq8e0+W59byoZUAWCZ4gSXRRhqcRset eW2awTDK7C4TQRU045jTXbkE+kwu5HGcoYs0u14A7NsG/MucWQ5PFdFwsX08hxthEd/eopErXbHD3 Ie6N85+AUqVXk8SSkvXhu/jPjixgh1CXYYxAUi1ShcxnQjVpAvzLhUd35n/pmuTORo41TeyM9x2jo KfgOBN92lgqgG4gxspuA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sS-0040H2-29; Wed, 20 Sep 2023 19:28:48 +0000 Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sD-004064-1K for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:35 +0000 Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-5031426b626so347626e87.3 for ; Wed, 20 Sep 2023 12:28:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238109; x=1695842909; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0p8U90biBaY98m+/7YTgOwqeSiRSThvzebPVxAHZ0NU=; b=eXw9/Ps5qTFl0crp/k1F594Oe7mxjkGGkRHMDa3AxrY2zmGAg6frIOklpQdRjokp2g 9Gy7kRfIxlwRUOFzqJLPPWj/BUtdiZIm2o2NKnztGNjwLUwUvyMYyxD9SfO+3i/5GghI ecdqNhI1SrKeh7MQn2si3eK6+PQsNxENjV4djbmoc/TfMAijtzU3E4jxTituzZS09qi9 DC7USc5WzzLEODlOXtsqaMIJrj1HaY9UyxBMOnGDyCPQFRaZBCFQGKklzLwtViJEwjJb RuyGki8Dy2CB4wriwsl4lrVGwmCzm2Iki6HjgaKFHcJ31iPIAQUS84cmbdTbvbbpQGB0 EcFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238109; x=1695842909; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0p8U90biBaY98m+/7YTgOwqeSiRSThvzebPVxAHZ0NU=; b=rWcbJeJ7oeTSfUEZn0v8IbGAAkQUiTzqjkJ+hva2cjjUkOI41lh49AtdlWltWrUAS5 MxFF2/xlMaPvzDUnvwHAGeDXBWrlS4VynyDnIQojapDMIOwhP31N2keh/OdWlvDyZNbT Dl07p8ciZ04JX4OCc/+jW0wyicwfp24rl+6GhjSwQtt6lsJu75cX+gF2n5VeflGPftJU DFscmYCH0ni6KPSAYS/vJIbjCmXUF33Hf1fXk/eVj7OALmBddOIJwNaDPAJG+MQ6QMkc gj+ZSTXkXEedyIQZUW6TUGvH8Gd8kdZqnU/fcQjM7AyxLSujLt9VMdLBfilyPf5AE+Vd 9vyA== X-Gm-Message-State: AOJu0YxZ+xTCUyc0WRmjdW+dAxQch3PtfKvnB5SZqI2yCSUZsJx1bCuS MGUeTmKZGk06M5hLI8DgIw0= X-Google-Smtp-Source: AGHT+IGIdInnubjIeWh18A6utltiooTc5XhoZwMANbo8N+mo1k1GV2zYTk6K/MsLe6Nk9T2xrOWP9w== X-Received: by 2002:a05:6512:3da7:b0:503:38ef:eb54 with SMTP id k39-20020a0565123da700b0050338efeb54mr4177670lfv.37.1695238109286; Wed, 20 Sep 2023 12:28:29 -0700 (PDT) Received: from localhost ([83.149.21.189]) by smtp.gmail.com with ESMTPSA id q26-20020a05651232ba00b0050307bf2bcdsm1933853lfe.247.2023.09.20.12.28.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:28 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 04/18] EDAC/synopsys: Detach private data from mci instance Date: Wed, 20 Sep 2023 22:26:49 +0300 Message-ID: <20230920192806.29960-5-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122833_521090_799B569E X-CRM114-Status: GOOD ( 25.79 ) 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 A comprehensive DW uMCTL2 DDRC parameters detection procedure and some resources requests (clocks and resets) are about to be added to the driver. Since these parameters will be utilized in the various parts of the driver and in particular used for the Memory Controller data instance pre-initialization, they need to be: first retrieved before the MCI is allocated; second preserved in the driver private data. Therefore the best approach would be to add the parameters structure right into the driver private data and just allocate the data separately from the mem_ctl_info instance. For that: add a new static method snps_data_create(), which aside with the snps_edac_priv structure allocation will also perform the private data basic initialization like CSRs region mapping, device data getting, platform data pointer copying and spin-lock initialization; convert the snps_mc_init() method to snps_mc_create(), which from now will be used to allocate and initialize the mem_ctl_info structure instance. Note in order to have an access to the snps_edac_priv structure instance as before this change, the mem_ctl_info.pvt_info field will be initialized with the pointer to that structure instance. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 137 +++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 47 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index e08e9f3c81cb..e177a36646c0 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -242,6 +242,7 @@ struct snps_ecc_status { /** * struct snps_edac_priv - DDR memory controller private data. + * @pdev: Platform device. * @baseaddr: Base address of the DDR controller. * @reglock: Concurrent CSRs access lock. * @message: Buffer for framing the event specific info. @@ -255,6 +256,7 @@ struct snps_ecc_status { * @rank_shift: Bit shifts for rank bit. */ struct snps_edac_priv { + struct platform_device *pdev; void __iomem *baseaddr; spinlock_t reglock; char message[SNPS_EDAC_MSG_SIZE]; @@ -463,6 +465,34 @@ static irqreturn_t snps_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +/** + * snps_create_data - Create private data. + * @pdev: platform device. + * + * Return: Private data instance or negative errno. + */ +static struct snps_edac_priv *snps_create_data(struct platform_device *pdev) +{ + struct snps_edac_priv *priv; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return ERR_PTR(-ENOMEM); + + priv->baseaddr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->baseaddr)) + return ERR_CAST(priv->baseaddr); + + priv->p_data = of_device_get_match_data(&pdev->dev); + if (!priv->p_data) + return ERR_PTR(-ENODEV); + + priv->pdev = pdev; + spin_lock_init(&priv->reglock); + + return priv; +} + /** * snps_get_dtype - Return the controller memory width. * @base: DDR memory controller base address. @@ -594,18 +624,36 @@ static void snps_init_csrows(struct mem_ctl_info *mci) } /** - * snps_mc_init - Initialize one driver instance. - * @mci: EDAC memory controller instance. - * @pdev: platform device. + * snps_mc_create - Create and initialize MC instance. + * @priv: DDR memory controller private data. + * + * Allocate the EDAC memory controller descriptor and initialize it + * using the private data info. * - * Perform initialization of the EDAC memory controller instance and - * related driver-private data associated with the memory controller the - * instance is bound to. + * Return: MC data instance or negative errno. */ -static void snps_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev) +static struct mem_ctl_info *snps_mc_create(struct snps_edac_priv *priv) { - mci->pdev = &pdev->dev; - platform_set_drvdata(pdev, mci); + struct edac_mc_layer layers[2]; + struct mem_ctl_info *mci; + + layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; + layers[0].size = SNPS_EDAC_NR_CSROWS; + layers[0].is_virt_csrow = true; + layers[1].type = EDAC_MC_LAYER_CHANNEL; + layers[1].size = SNPS_EDAC_NR_CHANS; + layers[1].is_virt_csrow = false; + + mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 0); + if (!mci) { + edac_printk(KERN_ERR, EDAC_MC, + "Failed memory allocation for mc instance\n"); + return ERR_PTR(-ENOMEM); + } + + mci->pvt_info = priv; + mci->pdev = &priv->pdev->dev; + platform_set_drvdata(priv->pdev, mci); /* Initialize controller capabilities and configuration */ mci->mtype_cap = MEM_FLAG_LPDDR | MEM_FLAG_DDR2 | MEM_FLAG_LPDDR2 | @@ -625,24 +673,43 @@ static void snps_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev) mci->ctl_page_to_phys = NULL; snps_init_csrows(mci); + + return mci; } +/** + * snps_mc_free - Free MC instance. + * @mci: EDAC memory controller instance. + * + * Just revert what was done in the framework of the snps_mc_create(). + * + * Return: MC data instance or negative errno. + */ +static void snps_mc_free(struct mem_ctl_info *mci) +{ + struct snps_edac_priv *priv = mci->pvt_info; + + platform_set_drvdata(priv->pdev, NULL); + edac_mc_free(mci); +} -static int snps_setup_irq(struct mem_ctl_info *mci, struct platform_device *pdev) + + +static int snps_setup_irq(struct mem_ctl_info *mci) { struct snps_edac_priv *priv = mci->pvt_info; int ret, irq; - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq(priv->pdev, 0); if (irq < 0) { edac_printk(KERN_ERR, EDAC_MC, "No IRQ %d in DT\n", irq); return irq; } - ret = devm_request_irq(&pdev->dev, irq, snps_irq_handler, - 0, dev_name(&pdev->dev), mci); + ret = devm_request_irq(&priv->pdev->dev, irq, snps_irq_handler, + 0, dev_name(&priv->pdev->dev), mci); if (ret < 0) { edac_printk(KERN_ERR, EDAC_MC, "Failed to request IRQ\n"); return ret; @@ -1066,49 +1133,24 @@ static inline void snps_create_debugfs_nodes(struct mem_ctl_info *mci) {} */ static int snps_mc_probe(struct platform_device *pdev) { - const struct snps_platform_data *p_data; - struct edac_mc_layer layers[2]; struct snps_edac_priv *priv; struct mem_ctl_info *mci; - void __iomem *baseaddr; int rc; - baseaddr = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(baseaddr)) - return PTR_ERR(baseaddr); - - p_data = of_device_get_match_data(&pdev->dev); - if (!p_data) - return -ENODEV; + priv = snps_create_data(pdev); + if (IS_ERR(priv)) + return PTR_ERR(priv); if (!snps_get_ecc_state(baseaddr)) { edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n"); return -ENXIO; } - layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; - layers[0].size = SNPS_EDAC_NR_CSROWS; - layers[0].is_virt_csrow = true; - layers[1].type = EDAC_MC_LAYER_CHANNEL; - layers[1].size = SNPS_EDAC_NR_CHANS; - layers[1].is_virt_csrow = false; - - mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, - sizeof(struct snps_edac_priv)); - if (!mci) { - edac_printk(KERN_ERR, EDAC_MC, - "Failed memory allocation for mc instance\n"); - return -ENOMEM; - } - - priv = mci->pvt_info; - priv->baseaddr = baseaddr; - priv->p_data = p_data; - spin_lock_init(&priv->reglock); + mci = snps_mc_create(priv); + if (IS_ERR(mci)) + return PTR_ERR(mci); - snps_mc_init(mci, pdev); - - rc = snps_setup_irq(mci, pdev); + rc = snps_setup_irq(mci); if (rc) goto free_edac_mc; @@ -1124,7 +1166,7 @@ static int snps_mc_probe(struct platform_device *pdev) return 0; free_edac_mc: - edac_mc_free(mci); + snps_mc_free(mci); return rc; } @@ -1143,7 +1185,8 @@ static int snps_mc_remove(struct platform_device *pdev) snps_disable_irq(priv); edac_mc_del_mc(&pdev->dev); - edac_mc_free(mci); + + snps_mc_free(mci); return 0; }