From patchwork Tue Apr 20 16:52:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 12214775 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8AA50C433ED for ; Tue, 20 Apr 2021 17:00:50 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D1698613AB for ; Tue, 20 Apr 2021 17:00:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D1698613AB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; 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=hA0HS0eh8bvrqbZ3eDwHW6g7tBSJ4ZWqHdv/kChci/Y=; b=P+bNR8CJ2Qozo1ertxCbysq4v OZqcRBRarivf0e0q9gAdyxdrxqSaKfdzq6Y7/0bayN90JL8voc9U23NMOSK/rNbrEmFp+gx7P04w+ IW4etOTe21xS5p3xZybiLHvyOGN4p7FMJdO1N+iwD+vhGrmO1qAos7c2w2EQFG+BRrh6Fvn2Fk6Zl d6VDqc6b5v+kjOGFV2kUn2ADpS7ORuDx+39dnFEpaCEhzrLJFux8ts8/TPZExjCqzaH0PTuzJNqcw fXb8HftCErCYXQ9aI1DrpyzBYag3P/AZLfW+Z3dSnkl9UW5ssbhCyQKHNuUzt78iOG5OHHP1I2FDG OQt99HuRQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lYthU-00Ce9i-TO; Tue, 20 Apr 2021 16:58:13 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lYtbh-00CcEg-Tj for linux-arm-kernel@desiato.infradead.org; Tue, 20 Apr 2021 16:52:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=nbNREM9MVRvngBbGCYPgnKQCGnFytKAM5BhbBeZouuE=; b=gKxF+hvXlnerJ6ZlWRaFG4BU9Y samyNrhWWNnr5uMU9h/6hlZJHYVbg0AAN/cVIuZarY9VssuRPZiHHrt13nNEVNRe+3awubi5FbgPW WD3Vy/Rfmrr76z3WpeBduAYMfKWfNFdp6UxIjFzM/oYujTtmMlcKsjHuE8Xc38YJidQem3zCy0yMC oTygArTrIYIdp+7ScxVKKVwKjoLQVBCYzAMXL7Bb/tfDK+YZOfUgcXlu+kY4pgFGNnpgEVNBFPaOm cKyxKaYubwQdwDjzzSR2Tvft8WYBGsBgv1ygsBPDqVOS6Ru9gH4zBLNuV88aGBwe5LVNPi4MPG0wo l9c7/HKA==; Received: from mail-ed1-x529.google.com ([2a00:1450:4864:20::529]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lYtbd-00CHyV-94 for linux-arm-kernel@lists.infradead.org; Tue, 20 Apr 2021 16:52:12 +0000 Received: by mail-ed1-x529.google.com with SMTP id i3so20235000edt.1 for ; Tue, 20 Apr 2021 09:52:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nbNREM9MVRvngBbGCYPgnKQCGnFytKAM5BhbBeZouuE=; b=PjVEpdhPAe3tsBQZyTjeZFssfhYRm0QDGJSE3yB4q4ems3So8BoLn+nLbFEIgkpa8R 6kABPAx2alsIRecYr56j8fdw5E/m0PtBSg45NNLEWM6KS7jqc0LToOwAdSAh6XNSNNi+ wEIcC52uMuNgOqNPmomV5OhbCPBuv3jurnPN99rXCB6X04G4JGoDbICV0TfU1+/WwicK RVKH9ToxLuZwyT1q8BilEGDjbZUjF5m8LV4m+wGoa3sO+sApgCleG+nn4Uo9hLouto/Q FmDo+oYN8N8swVMwD0nwXF9vLoA3Qr/ckcw+YVnfj7lOWJOZlNda3D5QH/lY+bppeNX7 R92A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nbNREM9MVRvngBbGCYPgnKQCGnFytKAM5BhbBeZouuE=; b=uP8Z4ayIUcPnYGxJdZN894TNzvPWgdCtR03C0quvglGLXp1hOzduGlZhiFjx+c4Vv+ kDVIUfhBoM9iC7oXGyNWTAyUVrOevy6AfgvxgJp58LdkEQNN28tdost1Nfpksi+dpm3g Inu3DM7mOu9QByFUztBWccmw7IOeS5bPBxxStjjuGVr0yiHmGmCdIRMn8zRYegXSz5Hf f31EovPw/5/6q7DNkxdMRW1xYej6VjX81dtlv9DD+U6ZdPUxVnaG/8xF06Geu+QRTcZ9 TfeKx/8zYd516tV6hZyRVzDoWhZAOMS9YgjpBp+2RKERjNSwfeb+Dj31TDISgr5VRqZi oFuQ== X-Gm-Message-State: AOAM531HOAbhZBUsq55AB08TqImaM1Hk6zl68vJPUX3u6gKB2aVpIdQW qtylk0VH0GekPmCHumbCFn8= X-Google-Smtp-Source: ABdhPJxjNp6QYS0dZX/GCb5ZdTdF+vUy+D94Gtt9a8OBJDjp2jRDbIFviZQckm+5lMoqGD+6DSxuOA== X-Received: by 2002:aa7:dd4d:: with SMTP id o13mr34306002edw.53.1618937527482; Tue, 20 Apr 2021 09:52:07 -0700 (PDT) Received: from localhost ([62.96.65.119]) by smtp.gmail.com with ESMTPSA id bm13sm13437537ejb.75.2021.04.20.09.52.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 Apr 2021 09:52:06 -0700 (PDT) From: Thierry Reding To: Thierry Reding , Krzysztof Kozlowski Cc: Jon Hunter , Dmitry Osipenko , linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 06/10] memory: tegra: Parameterize interrupt handler Date: Tue, 20 Apr 2021 18:52:34 +0200 Message-Id: <20210420165237.3523732-7-thierry.reding@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210420165237.3523732-1-thierry.reding@gmail.com> References: <20210420165237.3523732-1-thierry.reding@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210420_095209_349273_444A214A X-CRM114-Status: GOOD ( 23.38 ) 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 From: Thierry Reding Tegra20 requires a slightly different interrupt handler than Tegra30 and later, so parameterize the handler, so that each SoC implementation can provide its own. While at it, also make IRQ support optional, which will help unify the Tegra186 memory controller driver with this one. Signed-off-by: Thierry Reding --- drivers/memory/tegra/mc.c | 154 ++++++++------------------------- drivers/memory/tegra/mc.h | 4 + drivers/memory/tegra/tegra20.c | 74 ++++++++++++++++ include/soc/tegra/mc.h | 2 + 4 files changed, 117 insertions(+), 117 deletions(-) diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index 36eac0a0df3c..515ffd948a37 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c @@ -492,32 +492,7 @@ int tegra30_mc_probe(struct tegra_mc *mc) return 0; } -const struct tegra_mc_ops tegra30_mc_ops = { - .probe = tegra30_mc_probe, -}; -#endif - -static const char *const status_names[32] = { - [ 1] = "External interrupt", - [ 6] = "EMEM address decode error", - [ 7] = "GART page fault", - [ 8] = "Security violation", - [ 9] = "EMEM arbitration error", - [10] = "Page fault", - [11] = "Invalid APB ASID update", - [12] = "VPR violation", - [13] = "Secure carveout violation", - [16] = "MTS carveout violation", -}; - -static const char *const error_names[8] = { - [2] = "EMEM decode error", - [3] = "TrustZone violation", - [4] = "Carveout violation", - [6] = "SMMU translation error", -}; - -static irqreturn_t tegra_mc_irq(int irq, void *data) +irqreturn_t tegra30_mc_handle_irq(int irq, void *data) { struct tegra_mc *mc = data; unsigned long status; @@ -614,78 +589,31 @@ static irqreturn_t tegra_mc_irq(int irq, void *data) return IRQ_HANDLED; } -static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data) -{ - struct tegra_mc *mc = data; - unsigned long status; - unsigned int bit; - - /* mask all interrupts to avoid flooding */ - status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask; - if (!status) - return IRQ_NONE; - - for_each_set_bit(bit, &status, 32) { - const char *direction = "read", *secure = ""; - const char *error = status_names[bit]; - const char *client, *desc; - phys_addr_t addr; - u32 value, reg; - u8 id, type; - - switch (BIT(bit)) { - case MC_INT_DECERR_EMEM: - reg = MC_DECERR_EMEM_OTHERS_STATUS; - value = mc_readl(mc, reg); - - id = value & mc->soc->client_id_mask; - desc = error_names[2]; - - if (value & BIT(31)) - direction = "write"; - break; - - case MC_INT_INVALID_GART_PAGE: - reg = MC_GART_ERROR_REQ; - value = mc_readl(mc, reg); - - id = (value >> 1) & mc->soc->client_id_mask; - desc = error_names[2]; - - if (value & BIT(0)) - direction = "write"; - break; - - case MC_INT_SECURITY_VIOLATION: - reg = MC_SECURITY_VIOLATION_STATUS; - value = mc_readl(mc, reg); - - id = value & mc->soc->client_id_mask; - type = (value & BIT(30)) ? 4 : 3; - desc = error_names[type]; - secure = "secure "; - - if (value & BIT(31)) - direction = "write"; - break; - - default: - continue; - } - - client = mc->soc->clients[id].name; - addr = mc_readl(mc, reg + sizeof(u32)); - - dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s)\n", - client, secure, direction, &addr, error, - desc); - } +const struct tegra_mc_ops tegra30_mc_ops = { + .probe = tegra30_mc_probe, + .handle_irq = tegra30_mc_handle_irq, +}; +#endif - /* clear interrupts */ - mc_writel(mc, status, MC_INTSTATUS); +const char *const status_names[32] = { + [ 1] = "External interrupt", + [ 6] = "EMEM address decode error", + [ 7] = "GART page fault", + [ 8] = "Security violation", + [ 9] = "EMEM arbitration error", + [10] = "Page fault", + [11] = "Invalid APB ASID update", + [12] = "VPR violation", + [13] = "Secure carveout violation", + [16] = "MTS carveout violation", +}; - return IRQ_HANDLED; -} +const char *const error_names[8] = { + [2] = "EMEM decode error", + [3] = "TrustZone violation", + [4] = "Carveout violation", + [6] = "SMMU translation error", +}; /* * Memory Controller (MC) has few Memory Clients that are issuing memory @@ -786,7 +714,6 @@ static int tegra_mc_probe(struct platform_device *pdev) { struct resource *res; struct tegra_mc *mc; - void *isr; u64 mask; int err; @@ -823,29 +750,22 @@ static int tegra_mc_probe(struct platform_device *pdev) return err; } -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (mc->soc == &tegra20_mc_soc) { - isr = tegra20_mc_irq; - } else -#endif - { - isr = tegra_mc_irq; - } - - mc->irq = platform_get_irq(pdev, 0); - if (mc->irq < 0) - return mc->irq; + if (mc->soc->ops && mc->soc->ops->handle_irq) { + mc->irq = platform_get_irq(pdev, 0); + if (mc->irq < 0) + return mc->irq; - WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n"); + WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n"); - mc_writel(mc, mc->soc->intmask, MC_INTMASK); + mc_writel(mc, mc->soc->intmask, MC_INTMASK); - err = devm_request_irq(&pdev->dev, mc->irq, isr, 0, - dev_name(&pdev->dev), mc); - if (err < 0) { - dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq, - err); - return err; + err = devm_request_irq(&pdev->dev, mc->irq, mc->soc->ops->handle_irq, 0, + dev_name(&pdev->dev), mc); + if (err < 0) { + dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", mc->irq, + err); + return err; + } } err = tegra_mc_reset_setup(mc); diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h index 731896169cf3..5459018541e1 100644 --- a/drivers/memory/tegra/mc.h +++ b/drivers/memory/tegra/mc.h @@ -135,9 +135,13 @@ extern const struct tegra_mc_soc tegra210_mc_soc; defined(CONFIG_ARCH_TEGRA_132_SOC) || \ defined(CONFIG_ARCH_TEGRA_210_SOC) int tegra30_mc_probe(struct tegra_mc *mc); +irqreturn_t tegra30_mc_handle_irq(int irq, void *data); extern const struct tegra_mc_ops tegra30_mc_ops; #endif +extern const char * const status_names[32]; +extern const char * const error_names[8]; + /* * These IDs are for internal use of Tegra ICC drivers. The ID numbers are * chosen such that they don't conflict with the device-tree ICC node IDs. diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c index 2c86c0d70d59..300f99dd0077 100644 --- a/drivers/memory/tegra/tegra20.c +++ b/drivers/memory/tegra/tegra20.c @@ -713,10 +713,84 @@ static int tegra20_mc_resume(struct tegra_mc *mc) return 0; } +static irqreturn_t tegra20_mc_handle_irq(int irq, void *data) +{ + struct tegra_mc *mc = data; + unsigned long status; + unsigned int bit; + + /* mask all interrupts to avoid flooding */ + status = mc_readl(mc, MC_INTSTATUS) & mc->soc->intmask; + if (!status) + return IRQ_NONE; + + for_each_set_bit(bit, &status, 32) { + const char *direction = "read", *secure = ""; + const char *error = status_names[bit]; + const char *client, *desc; + phys_addr_t addr; + u32 value, reg; + u8 id, type; + + switch (BIT(bit)) { + case MC_INT_DECERR_EMEM: + reg = MC_DECERR_EMEM_OTHERS_STATUS; + value = mc_readl(mc, reg); + + id = value & mc->soc->client_id_mask; + desc = error_names[2]; + + if (value & BIT(31)) + direction = "write"; + break; + + case MC_INT_INVALID_GART_PAGE: + reg = MC_GART_ERROR_REQ; + value = mc_readl(mc, reg); + + id = (value >> 1) & mc->soc->client_id_mask; + desc = error_names[2]; + + if (value & BIT(0)) + direction = "write"; + break; + + case MC_INT_SECURITY_VIOLATION: + reg = MC_SECURITY_VIOLATION_STATUS; + value = mc_readl(mc, reg); + + id = value & mc->soc->client_id_mask; + type = (value & BIT(30)) ? 4 : 3; + desc = error_names[type]; + secure = "secure "; + + if (value & BIT(31)) + direction = "write"; + break; + + default: + continue; + } + + client = mc->soc->clients[id].name; + addr = mc_readl(mc, reg + sizeof(u32)); + + dev_err_ratelimited(mc->dev, "%s: %s%s @%pa: %s (%s)\n", + client, secure, direction, &addr, error, + desc); + } + + /* clear interrupts */ + mc_writel(mc, status, MC_INTSTATUS); + + return IRQ_HANDLED; +} + static const struct tegra_mc_ops tegra20_mc_ops = { .probe = tegra20_mc_probe, .suspend = tegra20_mc_suspend, .resume = tegra20_mc_resume, + .handle_irq = tegra20_mc_handle_irq, }; const struct tegra_mc_soc tegra20_mc_soc = { diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h index fd19df3eb529..ce3cdcc7b596 100644 --- a/include/soc/tegra/mc.h +++ b/include/soc/tegra/mc.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -173,6 +174,7 @@ struct tegra_mc_ops { int (*probe)(struct tegra_mc *mc); int (*suspend)(struct tegra_mc *mc); int (*resume)(struct tegra_mc *mc); + irqreturn_t (*handle_irq)(int irq, void *data); }; struct tegra_mc_soc {